0022769: Optimization of sewing algorithm
[occt.git] / src / ChFi3d / ChFi3d_Builder_C1.cxx
1 // File:        ChFi3d_Builder_3.cxx
2 // Created:     Wed Mar  9 15:48:03 1994
3 // Author:      Isabelle GRIGNON
4 //              <isg@zerox>
5
6 //  Modified by skv - Mon Jun  7 18:38:57 2004 OCC5898
7 //  Modified by skv - Thu Aug 21 11:55:58 2008 OCC20222
8
9 #include <ChFi3d_Builder.jxx>
10 #include <ChFi3d.hxx>
11 #include <ChFi3d_Builder_0.hxx>
12
13 #include <Precision.hxx>
14
15 #include <Standard_Failure.hxx>
16 #include <Standard_NotImplemented.hxx>
17 #include <StdFail_NotDone.hxx>
18
19
20 #include <gp_Pnt.hxx>
21 #include <gp_Dir.hxx>
22 #include <gp_Vec.hxx>
23 #include <gp_Ax3.hxx>
24 #include <gp_Pnt2d.hxx>
25 #include <gp_Vec2d.hxx>
26 #include <gp_Dir2d.hxx>
27 #include <gp_Elips.hxx>
28 #include <gp_Circ.hxx>
29
30 #include <ElCLib.hxx>
31 #include <ElSLib.hxx>
32
33 #include <Geom_Line.hxx>
34 #include <Geom_Circle.hxx>
35 #include <Geom_Ellipse.hxx>
36 #include <Geom_RectangularTrimmedSurface.hxx>
37 #include <Geom_Curve.hxx>
38 #include <Geom2d_Line.hxx>
39 #include <Geom2d_Curve.hxx>
40 #include <Geom_BSplineCurve.hxx>
41 #include <Geom_BSplineSurface.hxx>
42 #include <Geom_BezierSurface.hxx>
43 #include <Geom2d_BSplineCurve.hxx>
44 #include <Geom2dAdaptor_HCurve.hxx>
45 #include <Geom2d_TrimmedCurve.hxx>
46 #include <Geom2dInt_GInter.hxx>
47 #include <Geom_TrimmedCurve.hxx>
48 #include <GeomAPI_ExtremaCurveCurve.hxx>
49 #include <GeomAbs_Shape.hxx>
50 #include <GeomAdaptor_HCurve.hxx>
51 #include <GeomAdaptor_Surface.hxx>
52 #include <GeomAdaptor_HSurface.hxx>
53 #include <Geom_BoundedCurve.hxx>
54 #include <GeomLib.hxx>
55 #include <GeomInt_IntSS.hxx>
56 #include <GeomProjLib.hxx>
57
58 #include <Adaptor3d_HCurveOnSurface.hxx>
59 #include <Adaptor3d_CurveOnSurface.hxx>
60 #include <BRepAdaptor_HSurface.hxx>
61 #include <BRepAdaptor_Curve.hxx>
62 #include <BRepAdaptor_Curve2d.hxx>
63 #include <BRepAdaptor_HCurve2d.hxx>
64 #include <BRepAdaptor_HCurve.hxx>
65 #include <BRepAdaptor_Surface.hxx>
66 #include <BRepLib_MakeEdge.hxx>
67 #include <BRepAlgo_NormalProjection.hxx>
68 #include <BRepExtrema_ExtCC.hxx>
69 #include <BRep_Tool.hxx>
70 #include <BRepTools.hxx>
71 #include <BRep_Builder.hxx>
72 #include <IntCurveSurface_HInter.hxx>
73 #include <IntCurveSurface_IntersectionPoint.hxx>
74 #include <IntRes2d_IntersectionPoint.hxx>
75 #include <IntRes2d_Transition.hxx>
76 #include <Extrema_LocateExtCC.hxx>
77 #include <Extrema_POnCurv.hxx>
78 #include <Extrema_ExtPC2d.hxx>
79 #include <Extrema_ExtPC.hxx>
80 #include <Extrema_ExtPS.hxx>
81 #include <Extrema_ExtCC.hxx>
82
83 #include <TopoDS.hxx>
84 #include <TopoDS_Shape.hxx>
85 #include <TopoDS_Face.hxx>
86 #include <TopoDS_Edge.hxx>
87 #include <TopoDS_Vertex.hxx>
88
89 #include <TopAbs.hxx>
90 #include <TopAbs_ShapeEnum.hxx>
91 #include <TopAbs_Orientation.hxx>
92 #include <TopExp.hxx>
93 #include <TopExp_Explorer.hxx>
94 #include <TopLoc_Location.hxx>
95 #include <TopTools_ListIteratorOfListOfShape.hxx>
96
97 #include <TopOpeBRepDS_Point.hxx>
98 #include <TopOpeBRepDS_Curve.hxx>
99 #include <TopOpeBRepDS_Surface.hxx>
100 #include <TopOpeBRepDS_SurfaceCurveInterference.hxx>
101 #include <TopOpeBRepDS_CurvePointInterference.hxx>
102 #include <TopOpeBRepDS_DataStructure.hxx>
103 #include <TopOpeBRepDS_ListOfInterference.hxx>
104 #include <TopOpeBRepDS_ListIteratorOfListOfInterference.hxx>
105 #include <TopOpeBRepDS_SolidSurfaceInterference.hxx>
106 #include <TopOpeBRepDS_Kind.hxx>
107 #include <TopOpeBRepDS_Transition.hxx>
108 #include <TopTools_Array1OfShape.hxx>
109 #include <ChFiDS_HData.hxx>
110 #include <ChFiDS_SurfData.hxx>
111 #include <ChFiDS_CommonPoint.hxx>
112 #include <ChFiDS_FaceInterference.hxx>
113 #include <ChFiDS_SequenceOfSurfData.hxx>
114 #include <ChFiDS_Stripe.hxx>
115 #include <ChFiDS_ListIteratorOfListOfStripe.hxx>
116 #include <ChFiDS_Map.hxx>
117 #include <TColgp_Array1OfPnt.hxx>
118 #include <TColgp_Array1OfPnt2d.hxx>
119 #include <TColStd_Array1OfReal.hxx>
120 #include <TColStd_Array1OfInteger.hxx>
121
122 #ifdef DEB
123 # ifdef DRAW
124 #include <OSD_Chronometer.hxx>
125 #include <DrawTrSurf.hxx>
126 # endif //DRAW
127 //  Modified by Sergey KHROMOV - Thu Apr 11 12:23:40 2002 Begin
128 // The method
129 // ChFi3d_Builder::PerformMoreSurfdata(const Standard_Integer Index)
130 // is totally rewroted.
131 //  Modified by Sergey KHROMOV - Thu Apr 11 12:23:40 2002 End
132
133 extern Standard_Real  t_same,t_inter,t_sameinter;
134 extern void ChFi3d_InitChron(OSD_Chronometer& ch);
135 extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time);
136 #endif
137 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
138 #include <math_FunctionSample.hxx>
139 #include <Geom2dAdaptor_Curve.hxx>
140 #include <IntRes2d_IntersectionSegment.hxx>
141 //  Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 Begin
142 Standard_Boolean isTangentFaces(const TopoDS_Edge &theEdge,
143                                 const TopoDS_Face &theFace1,
144                                 const TopoDS_Face &theFace2);
145 //  Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 End
146
147 static Standard_Real recadre(const Standard_Real p,
148                              const Standard_Real ref,
149                              const Standard_Boolean isfirst,
150                              const Standard_Real first,
151                              const Standard_Real last)
152 {
153   Standard_Real pp = p;
154   if (isfirst) pp -= (last - first);
155   else pp += (last - first);
156   if (Abs(pp - ref) < Abs(p - ref)) return pp;
157   return p;
158 }
159
160 //=======================================================================
161 //function : Update
162 //purpose  : Calculate the intersection of the face at the end of 
163 //           the tangency line to update CommonPoint and its 
164 //           parameter in FaceInterference.
165 //=======================================================================
166
167 static Standard_Boolean Update(Handle(Adaptor3d_HSurface)& fb,
168                                Handle(Adaptor2d_HCurve2d)& pcfb,
169                                Handle(Adaptor3d_HSurface)& surf,
170                                ChFiDS_FaceInterference&  fi,
171                                ChFiDS_CommonPoint&       cp,
172                                gp_Pnt2d&                 p2dbout,
173                                const Standard_Boolean    isfirst,
174                                Standard_Real&            pared,
175                                Standard_Real&            wop,
176                                const Standard_Real       tol)
177 {
178   Adaptor3d_CurveOnSurface c1(pcfb,fb);
179   Handle(Geom2d_Curve) pc = fi.PCurveOnSurf();
180   Handle(Geom2dAdaptor_HCurve) hpc = new Geom2dAdaptor_HCurve(pc);
181   Adaptor3d_CurveOnSurface c2(hpc,surf);
182   Extrema_LocateExtCC ext(c1,c2,pared,wop);
183   if (ext.IsDone()) {
184     Standard_Real dist2 = ext.SquareDistance();
185     if (dist2 < tol * tol) {
186       Extrema_POnCurv ponc1,ponc2;
187       ext.Point(ponc1,ponc2);
188       Standard_Real parfb = ponc1.Parameter();
189       p2dbout = pcfb->Value(parfb);
190       pared = ponc1.Parameter();
191       wop = ponc2.Parameter();
192       fi.SetParameter(wop,isfirst);
193       cp.Reset();
194       cp.SetPoint(ponc1.Value());
195       return Standard_True;
196     }
197   }
198   return Standard_False;
199 }
200
201 //=======================================================================
202 //function : Update
203 //purpose  : Intersect surface <fb> and 3d curve <ct>
204 //           Update <isfirst> parameter of FaceInterference <fi> and point of
205 //           CommonPoint <cp>. Return new intersection parameters in <wop>
206 //           and <p2dbout>
207 //=======================================================================
208
209 static Standard_Boolean Update(Handle(Adaptor3d_HSurface)& fb,
210                                Handle(Adaptor3d_HCurve)&   ct,
211                                ChFiDS_FaceInterference&  fi,
212                                ChFiDS_CommonPoint&       cp,
213                                gp_Pnt2d&                 p2dbout,
214                                const Standard_Boolean    isfirst,
215                                Standard_Real&            wop)
216 {
217   IntCurveSurface_HInter Intersection;
218   //check if in KPart the limits of the tangency line 
219   //are already in place at this stage.
220   //Modif lvt : the periodic cases are reframed, espercially if nothing was found.
221   Standard_Real w,uf = ct->FirstParameter(),ul = ct->LastParameter();
222 #ifndef DEB
223   Standard_Real  wbis = 0.;
224 #else
225   Standard_Real  wbis;
226 #endif
227   Standard_Boolean isperiodic = ct->IsPeriodic(),recadrebis = Standard_False;
228   Intersection.Perform(ct,fb);
229   if (Intersection.IsDone()) {
230     Standard_Integer nbp = Intersection.NbPoints(),i,isol = 0,isolbis = 0;
231     Standard_Real dist = Precision::Infinite();
232     Standard_Real distbis = Precision::Infinite();
233     for (i = 1; i <= nbp; i++) {
234       w = Intersection.Point(i).W();
235       if (isperiodic) w = recadre(w,wop,isfirst,uf,ul);
236       if (uf <= w && ul >= w && Abs(w-wop) < dist) {
237         isol = i;
238         dist = Abs(w-wop);
239       }
240     }
241     if (isperiodic) {
242       for (i = 1; i <= nbp; i++) {
243         w = Intersection.Point(i).W();
244         if (uf <= w && ul >= w && Abs(w-wop) < distbis && (Abs(w-ul)<=0.01 || Abs(w-uf)<=0.01)) {
245           isolbis = i;
246           wbis = recadre(w,wop,isfirst,uf,ul);
247           distbis = Abs(wbis-wop);
248           recadrebis = Standard_True;
249         }
250       }
251     }
252     if (isol == 0 && isolbis == 0) {
253       return Standard_False;
254     }
255     if (!recadrebis) {
256       IntCurveSurface_IntersectionPoint pint = Intersection.Point(isol);
257       p2dbout.SetCoord(pint.U(),pint.V());
258       w = pint.W();
259       if (isperiodic) w = ElCLib::InPeriod(w,uf,ul);
260     }
261     else {
262       if (dist>distbis) {
263         IntCurveSurface_IntersectionPoint pint = Intersection.Point(isolbis);
264         p2dbout.SetCoord(pint.U(),pint.V());
265         w = wbis;
266       }
267       else {
268         IntCurveSurface_IntersectionPoint pint = Intersection.Point(isol);
269         p2dbout.SetCoord(pint.U(),pint.V());
270         w = pint.W();
271         w = ElCLib::InPeriod(w,uf,ul);
272       }
273     }
274     fi.SetParameter(w,isfirst);
275     cp.Reset();
276     cp.SetPoint(ct->Value(w));
277     wop = w;
278     return Standard_True;
279   }
280   return Standard_False;
281 }
282
283 //=======================================================================
284 //function : IntersUpdateOnSame
285 //purpose  : Intersect  curve <c3dFI> of ChFi-<Fop> interference with extended
286 //           surface <HBs> of <Fprol> . Return intersection parameters in
287 //           <FprolUV>, <c3dU> and updating <FIop> and <CPop>
288 //           <HGs> is a surface of ChFi
289 //           <Fop> is a face having 2 edges at corner with OnSame state
290 //           <Fprol> is a face non-adjacent to spine edge
291 //           <Vtx> is a corner vertex
292 //=======================================================================
293
294 static Standard_Boolean IntersUpdateOnSame(Handle(GeomAdaptor_HSurface)& HGs,
295                                            Handle(BRepAdaptor_HSurface)& HBs,
296                                            const Handle(Geom_Curve)&     c3dFI,
297                                            const TopoDS_Face&            Fop,
298                                            const TopoDS_Face&            Fprol,
299                                            const TopoDS_Edge&            Eprol,
300                                            const TopoDS_Vertex&          Vtx,
301                                            const Standard_Boolean        isFirst,
302                                            const Standard_Real           Tol,
303                                            ChFiDS_FaceInterference&      FIop,
304                                            ChFiDS_CommonPoint&           CPop,
305                                            gp_Pnt2d&                     FprolUV,
306                                            Standard_Real&                c3dU)
307 {
308   // add more or less restrictive criterions to
309   // decide if the intersection is done with the face at 
310   // extended end or if the end is sharp.
311   Standard_Real uf = FIop.FirstParameter();
312   Standard_Real ul = FIop.LastParameter();
313   Handle(GeomAdaptor_HCurve) Hc3df;
314   if (c3dFI->IsPeriodic()) Hc3df = new GeomAdaptor_HCurve(c3dFI);
315   else                     Hc3df = new GeomAdaptor_HCurve(c3dFI,uf,ul);
316
317   if ( Update(HBs,Hc3df,FIop,CPop,FprolUV,isFirst,c3dU) )
318     return Standard_True;
319
320   if (!isTangentFaces(Eprol,Fprol,Fop))
321     return Standard_False;
322
323   Handle(Geom2d_Curve) gpcprol = BRep_Tool::CurveOnSurface(Eprol,Fprol,uf,ul);
324   Handle(Geom2dAdaptor_HCurve) pcprol = new Geom2dAdaptor_HCurve(gpcprol);
325   Standard_Real partemp = BRep_Tool::Parameter(Vtx,Eprol);
326
327   return
328     Update(HBs,pcprol,HGs,FIop,CPop,FprolUV,isFirst,partemp,c3dU,Tol);
329 }
330
331 //=======================================================================
332 //function : Update
333 //purpose  : Calculate the extrema curveonsurf/curveonsurf to prefer 
334 //           the values concerning the trace on surf and the pcurve on the
335 //           face at end.
336 //=======================================================================
337
338 static Standard_Boolean Update(Handle(Adaptor3d_HSurface)& face,
339                                Handle(Adaptor2d_HCurve2d)& edonface,
340                                Handle(Adaptor3d_HSurface)& surf,
341                                ChFiDS_FaceInterference&  fi,
342                                ChFiDS_CommonPoint&       cp,
343                                const Standard_Boolean    isfirst)
344 {
345   if (!cp.IsOnArc()) return 0;
346   Adaptor3d_CurveOnSurface c1(edonface,face);
347   Standard_Real pared = cp.ParameterOnArc();
348   Standard_Real parltg = fi.Parameter(isfirst);
349   Handle(Geom2d_Curve) pc = fi.PCurveOnSurf();
350   Standard_Real f = fi.FirstParameter();
351   Standard_Real l = fi.LastParameter();
352   Standard_Real delta = 0.1 * ( l - f );
353   f = Max(f-delta,pc->FirstParameter());
354   l = Min(l+delta,pc->LastParameter());
355   Handle(Geom2dAdaptor_HCurve) hpc = new Geom2dAdaptor_HCurve(pc,f,l);
356   Adaptor3d_CurveOnSurface c2(hpc,surf);
357
358   Extrema_LocateExtCC ext(c1,c2,pared,parltg);
359   if (ext.IsDone()) {
360     Extrema_POnCurv ponc1,ponc2;
361     ext.Point(ponc1,ponc2);
362     pared = ponc1.Parameter();
363     parltg = ponc2.Parameter();
364     if ((parltg > f) && (parltg < l)) {
365       fi.SetParameter(parltg,isfirst);
366       cp.SetArc(cp.Tolerance(),cp.Arc(),pared,cp.TransitionOnArc());
367       return Standard_True;
368     }
369   }
370   return Standard_False;
371 }
372
373 //=======================================================================
374 //function : ChFi3d_ExtendSurface
375 //purpose  :
376 //=======================================================================
377
378 static void ChFi3d_ExtendSurface (Handle(Geom_Surface) & S ,
379                                   Standard_Integer & prol )
380 {
381   if (prol) return;
382   Handle(Geom_BSplineSurface) S1;
383   Handle(Geom_BezierSurface) S2;
384   Standard_Real length,umin,umax,vmin,vmax;
385   gp_Pnt P1,P2;
386   S->Bounds(umin,umax,vmin,vmax);
387   S->D0(umin,vmin,P1);
388   S->D0(umax,vmax,P2);
389   length=P1.Distance(P2);
390   prol=0;
391   S1=Handle(Geom_BSplineSurface)::DownCast(S);
392   S2=Handle(Geom_BezierSurface)::DownCast(S);
393   if (!S1.IsNull()) {
394                   GeomLib::ExtendSurfByLength(S1,length,1,Standard_False,
395                   Standard_True);
396                   GeomLib::ExtendSurfByLength(S1,length,1,Standard_True,
397                   Standard_True);
398                   GeomLib::ExtendSurfByLength(S1,length,1,Standard_False,
399                   Standard_False);
400                   GeomLib::ExtendSurfByLength(S1,length,1,Standard_True,
401                   Standard_False);
402                   S=S1;
403                   prol=1;
404    }
405    if (!S2.IsNull()) {
406                  GeomLib::ExtendSurfByLength(S2,length,1,Standard_False,
407                  Standard_True);
408                  GeomLib::ExtendSurfByLength(S2,length,1,Standard_True,
409                  Standard_True);
410                  GeomLib::ExtendSurfByLength(S2,length,1,Standard_False,
411                  Standard_False);
412                  GeomLib::ExtendSurfByLength(S2,length,1,Standard_True,
413                  Standard_False);
414                  S=S2;
415                  prol=2;
416
417   }
418 }
419
420 //=======================================================================
421 //function : ComputeCurve2d
422 //purpose  : calculate the 2d of the curve Ct on face Face
423 //=======================================================================
424
425 static void  ComputeCurve2d (Handle(Geom_Curve )& Ct,
426                        TopoDS_Face & Face,
427                        Handle(Geom2d_Curve) & C2d)
428 {
429   TopoDS_Edge E1;
430   TopTools_IndexedMapOfShape MapE1;
431   BRepLib_MakeEdge Bedge (Ct);
432   TopoDS_Edge edg =Bedge. Edge();
433   BRepAlgo_NormalProjection OrtProj;
434   OrtProj.Init(Face);
435   OrtProj.Add(edg);
436   OrtProj.SetParams(1.e-6, 1.e-6, GeomAbs_C1, 14, 16);
437   OrtProj.SetLimit(Standard_False);
438   OrtProj.Compute3d(Standard_False);
439   OrtProj.Build();
440   Standard_Real up1,up2;
441   if ( OrtProj.IsDone()) {
442     TopExp::MapShapes(OrtProj.Projection() ,TopAbs_EDGE, MapE1);
443     if (MapE1.Extent()!=0) {
444       TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(1));
445       E1=TopoDS::Edge(aLocalShape );
446 //      E1=TopoDS::Edge( TopoDS_Shape (MapE1(1)));
447       C2d=BRep_Tool::CurveOnSurface(E1,Face,up1,up2);
448     }
449   }
450 }
451
452 //=======================================================================
453 //function : ChFi3d_Recale
454 //purpose  :
455 //=======================================================================
456
457 static void ChFi3d_Recale(BRepAdaptor_Surface&   Bs,
458                           gp_Pnt2d&              p1,
459                           gp_Pnt2d&              p2,
460                           const Standard_Boolean refon1)
461 {
462   Handle(Geom_Surface) surf = Bs.ChangeSurface().Surface();
463   Handle(Geom_RectangularTrimmedSurface)
464     ts = Handle(Geom_RectangularTrimmedSurface)::DownCast(surf);
465   if (!ts.IsNull()) surf = ts->BasisSurface();
466   if (surf->IsUPeriodic()) {
467     Standard_Real u1 = p1.X(), u2 = p2.X();
468     Standard_Real uper = surf->UPeriod();
469     if (fabs(u2-u1) > 0.5*uper) {
470       if (u2<u1 && refon1) u2 += uper;
471       else if (u2<u1 && !refon1) u1 -= uper;
472       else if (u1<u2 && refon1) u2 -= uper;
473       else if (u1<u2 && !refon1) u1 += uper;
474     }
475     p1.SetX(u1); p2.SetX(u2);
476   }
477   if (surf->IsVPeriodic()) {
478     Standard_Real v1 = p1.Y(), v2 = p2.Y();
479     Standard_Real vper = surf->VPeriod();
480     if (fabs(v2-v1) > 0.5*vper) {
481       if (v2<v1 && refon1) v2 += vper;
482       else if (v2<v1 && !refon1) v1 -= vper;
483       else if (v1<v2 && refon1) v2 -= vper;
484       else if (v1<v2 && !refon1) v1 += vper;
485     }
486     p1.SetY(v1); p2.SetY(v2);
487   }
488 }
489
490 //=======================================================================
491 //function : ChFi3d_SelectStripe
492 //purpose  : find stripe with ChFiDS_OnSame state if <thePrepareOnSame> is True
493 //=======================================================================
494
495 Standard_Boolean ChFi3d_SelectStripe(ChFiDS_ListIteratorOfListOfStripe & It,
496                                      const TopoDS_Vertex& Vtx,
497                                      const Standard_Boolean thePrepareOnSame)
498 {
499   if (!thePrepareOnSame) return Standard_True;
500
501   for (; It.More(); It.Next()) {
502     Standard_Integer sens = 0;
503     Handle(ChFiDS_Stripe) stripe = It.Value();
504     ChFi3d_IndexOfSurfData(Vtx, stripe, sens);
505     ChFiDS_State stat;
506     if ( sens == 1 )
507       stat = stripe->Spine()->FirstStatus();
508     else
509       stat = stripe->Spine()->LastStatus();
510     if ( stat == ChFiDS_OnSame ) return Standard_True;
511   }
512
513   return Standard_False;
514 }
515 //=======================================================================
516 //function : PerformOneCorner
517 //purpose  : Calculate a corner with three edges and a fillet.
518 //           3 separate case: (22/07/94 only 1st is implemented)
519 //
520 //           - same concavity on three edges, intersection with the
521 //             face at end,
522 //           - concavity of 2 outgoing edges is opposite to the one of the fillet,
523 //             if the face at end is ready for that, the same in  case 1 on extended face,
524 //             otherwise a small cap is done with GeomFill,
525 //           - only one outgoing edge has concavity opposed to the edge of the
526 //             fillet and the third edge, the top of the corner is reread
527 //             in the empty of the fillet and closed, either by extending the face 
528 //             at end if it is plane and orthogonal to the
529 //             guiding edge, or by a cap of type GeomFill.
530 //
531 //           <thePrepareOnSame> means that only needed thing is redefinition
532 //           of intersection pameter of OnSame-Stripe with <Arcprol>
533 //           (eap, Arp 9 2002, occ266)
534 //=======================================================================
535
536 void ChFi3d_Builder::PerformOneCorner(const Standard_Integer Index,
537                                       const Standard_Boolean thePrepareOnSame)
538 {
539   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
540
541 #ifdef DEB
542   OSD_Chronometer ch;// init perf for PerformSetOfKPart
543 #endif
544   // the top,
545   const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index);
546   // The fillet is returned,
547   ChFiDS_ListIteratorOfListOfStripe StrIt;
548   StrIt.Initialize(myVDataMap(Index));
549   if ( ! ChFi3d_SelectStripe (StrIt, Vtx, thePrepareOnSame)) return;
550   Handle(ChFiDS_Stripe) stripe = StrIt.Value();
551   const Handle(ChFiDS_Spine) spine = stripe->Spine();
552   ChFiDS_SequenceOfSurfData& SeqFil =
553     stripe->ChangeSetOfSurfData()->ChangeSequence();
554   // SurfData and its CommonPoints,
555   Standard_Integer sens = 0;
556
557   // Choose proper SurfData
558   Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens);
559   Standard_Boolean isfirst = (sens == 1);
560   if (isfirst) {
561     for (; num<SeqFil.Length() && (
562          (SeqFil.Value(num)->IndexOfS1()==0) ||
563          (SeqFil.Value(num)->IndexOfS2()==0) ); ) {
564       SeqFil.Remove(num); // The surplus is removed
565     }
566   }
567   else {
568    for (; num>1 && (
569          (SeqFil.Value(num)->IndexOfS1()==0) ||
570          (SeqFil.Value(num)->IndexOfS2()==0) ); ) {
571      SeqFil.Remove(num);// The surplus is removed
572      num--;
573     }
574   }
575
576   Handle(ChFiDS_SurfData)& Fd = SeqFil.ChangeValue(num);
577   ChFiDS_CommonPoint& CV1 = Fd->ChangeVertex(isfirst,1);
578   ChFiDS_CommonPoint& CV2 = Fd->ChangeVertex(isfirst,2);
579   //To evaluate the new points.
580   Bnd_Box box1,box2;
581
582   // The cases of cap and intersection are processed separately.
583   // ----------------------------------------------------------
584   ChFiDS_State stat;
585   if (isfirst) stat = spine->FirstStatus();
586   else         stat = spine->LastStatus();
587   Standard_Boolean onsame = (stat == ChFiDS_OnSame);
588   TopoDS_Face Fv,Fad,Fop;
589   TopoDS_Edge Arcpiv,Arcprol,Arcspine;
590   if (isfirst) Arcspine = spine->Edges(1);
591   else         Arcspine = spine->Edges(spine->NbEdges());
592 #ifndef DEB
593   TopAbs_Orientation OArcprolv = TopAbs_FORWARD, OArcprolop = TopAbs_FORWARD;
594 #else
595   TopAbs_Orientation OArcprolv,OArcprolop;
596 #endif
597   Standard_Integer ICurve;
598   Handle(BRepAdaptor_HSurface) HBs  = new BRepAdaptor_HSurface();
599   Handle(BRepAdaptor_HSurface) HBad = new BRepAdaptor_HSurface();
600   Handle(BRepAdaptor_HSurface) HBop = new BRepAdaptor_HSurface();
601   BRepAdaptor_Surface& Bs  = HBs->ChangeSurface();
602   BRepAdaptor_Surface& Bad = HBad->ChangeSurface();
603   BRepAdaptor_Surface& Bop = HBop->ChangeSurface();
604   Handle(Geom_Curve) Cc;
605   Handle(Geom2d_Curve) Pc,Ps;
606   Standard_Real Ubid,Vbid;//,mu,Mu,mv,Mv;
607 #ifndef DEB
608   Standard_Real Udeb = 0.,Ufin = 0.;
609 #else
610   Standard_Real Udeb,Ufin;
611 #endif
612 //  gp_Pnt2d UVf1,UVl1,UVf2,UVl2;
613 //  Standard_Real Du,Dv,Step;
614   Standard_Boolean inters = Standard_True;
615   Standard_Integer IFadArc = 1, IFopArc = 2;
616   Fop = TopoDS::Face(DStr.Shape(Fd->Index(IFopArc)));
617   TopExp_Explorer ex;
618
619 #ifdef DEB
620   ChFi3d_InitChron(ch); // init perf condition  if (onsame)
621 #endif
622
623   if (onsame) {
624     if (!CV1.IsOnArc() && !CV2.IsOnArc())
625       Standard_Failure::Raise("Corner OnSame : no point on arc");
626     else if (CV1.IsOnArc() && CV2.IsOnArc()) {
627        Standard_Boolean sur1 = 0, sur2 = 0;
628       for(ex.Init(CV1.Arc(),TopAbs_VERTEX); ex.More(); ex.Next()) {
629         if (Vtx.IsSame(ex.Current())) {
630           sur1 = 1;
631           break;
632         }
633       }
634       for(ex.Init(CV2.Arc(),TopAbs_VERTEX); ex.More(); ex.Next()) {
635         if (Vtx.IsSame(ex.Current())) {
636           sur2 = 1;
637           break;
638         }
639       }
640       if (sur1 && sur2) {
641         TopoDS_Edge E[3];
642         E[0] = CV1.Arc(); E[1] = CV2.Arc(); E[2] = Arcspine;
643         if (ChFi3d_EdgeState(E,myEFMap) != ChFiDS_OnDiff) IFadArc = 2;
644       }
645       else if (sur2) IFadArc = 2;
646     }
647     else if (CV2.IsOnArc()) IFadArc = 2;
648     IFopArc = 3-IFadArc;
649
650     Arcpiv = Fd->Vertex(isfirst,IFadArc).Arc();
651     Fad = TopoDS::Face(DStr.Shape(Fd->Index(IFadArc)));
652     Fop = TopoDS::Face(DStr.Shape(Fd->Index(IFopArc)));
653     TopTools_ListIteratorOfListOfShape It;
654     // The face at end is returned without check of its unicity.
655     for(It.Initialize(myEFMap(Arcpiv));It.More();It.Next()) {
656       if (!Fad.IsSame(It.Value())) {
657         Fv = TopoDS::Face(It.Value());
658         break;
659       }
660     }
661
662     // Does the face at bout contain the Vertex ?
663     Standard_Boolean isinface = Standard_False;
664     for (ex.Init(Fv,TopAbs_VERTEX); ex.More(); ex.Next()) {
665       if (ex.Current().IsSame(Vtx)) {
666         isinface = Standard_True;
667         break;
668       }
669     }
670     if (!isinface && Fd->Vertex(isfirst,3-IFadArc).IsOnArc()) {
671       IFadArc = 3-IFadArc;
672       IFopArc = 3-IFopArc;
673       Arcpiv = Fd->Vertex(isfirst,IFadArc).Arc();
674       Fad = TopoDS::Face(DStr.Shape(Fd->Index(IFadArc)));
675       Fop = TopoDS::Face(DStr.Shape(Fd->Index(IFopArc)));
676       //TopTools_ListIteratorOfListOfShape It;
677      // The face at end is returned without check of its unicity.
678       for(It.Initialize(myEFMap(Arcpiv));It.More();It.Next()) {
679         if (!Fad.IsSame(It.Value())) {
680           Fv = TopoDS::Face(It.Value());
681           break;
682         }
683       }
684     }
685
686     if (Fv.IsNull()) StdFail_NotDone::Raise
687       ("OneCorner : face at end not found");
688
689     Fv.Orientation(TopAbs_FORWARD);
690     Fad.Orientation(TopAbs_FORWARD);
691     Fop.Orientation(TopAbs_FORWARD);
692
693     // The edge that will be extended is returned.
694     for(It.Initialize(myVEMap(Vtx));It.More() && Arcprol.IsNull();It.Next()) {
695       if (!Arcpiv.IsSame(It.Value())) {
696         for(ex.Init(Fv,TopAbs_EDGE); ex.More(); ex.Next()) {
697           if (It.Value().IsSame(ex.Current())) {
698             Arcprol = TopoDS::Edge(It.Value());
699             OArcprolv = ex.Current().Orientation();
700             break;
701           }
702         }
703       }
704     }
705     if (Arcprol.IsNull()) /*StdFail_NotDone::Raise
706       ("OneCorner : edge a prolonger non trouve");*/
707     {
708       PerformIntersectionAtEnd(Index);
709       return;
710     }
711     for(ex.Init(Fop,TopAbs_EDGE); ex.More(); ex.Next()) {
712       if (Arcprol.IsSame(ex.Current())) {
713         OArcprolop = ex.Current().Orientation();
714         break;
715       }
716     }
717     TopoDS_Face FFv;
718     Standard_Real tol;
719     Standard_Integer prol=0;
720     BRep_Builder BRE;
721     Handle(Geom_Surface ) Sface;
722     Sface=BRep_Tool::Surface(Fv);
723     ChFi3d_ExtendSurface(Sface,prol);
724     tol=BRep_Tool::Tolerance(Fv);
725     BRE.MakeFace(FFv,Sface,tol);
726     if (prol) {
727       Bs.Initialize(FFv,Standard_False);
728       DStr.SetNewSurface(Fv,Sface);
729     }
730     else Bs.Initialize(Fv,Standard_False);
731     Bad.Initialize(Fad);
732     Bop.Initialize(Fop);
733   }
734   //in case of OnSame it is necessary to modify the CommonPoint
735   //in the empty and its parameter in the FaceInterference.
736   //They are both returned in non const references. Attention the modifications are done behind
737   //de CV1,CV2,Fi1,Fi2.
738   ChFiDS_CommonPoint& CPopArc = Fd->ChangeVertex(isfirst,IFopArc);
739   ChFiDS_FaceInterference& FiopArc = Fd->ChangeInterference(IFopArc);
740   ChFiDS_CommonPoint& CPadArc = Fd->ChangeVertex(isfirst,IFadArc);
741   ChFiDS_FaceInterference& FiadArc = Fd->ChangeInterference(IFadArc);
742   //the parameter of the vertex in the air is initialiced with the value of 
743   //its opposite (point on arc).
744   Standard_Real wop = Fd->ChangeInterference(IFadArc).Parameter(isfirst);
745   Handle(Geom_Curve) c3df;
746   Handle(GeomAdaptor_HSurface)
747     HGs = new GeomAdaptor_HSurface(DStr.Surface(Fd->Surf()).Surface());
748   gp_Pnt2d p2dbout;
749
750   if (onsame) {
751
752     ChFiDS_CommonPoint saveCPopArc = CPopArc;
753     c3df = DStr.Curve(FiopArc.LineIndex()).Curve();
754
755     inters = IntersUpdateOnSame (HGs,HBs,c3df,Fop,Fv,Arcprol,Vtx,isfirst,10*tolesp, // in
756                                  FiopArc,CPopArc,p2dbout,wop);   // out
757
758     Handle(BRepAdaptor_HCurve2d) pced = new BRepAdaptor_HCurve2d();
759     pced->ChangeCurve2d().Initialize(CPadArc.Arc(),Fv);
760     // in the case of degenerated Fi, parameter difference can be even negative (eap, occ293)
761     if ((FiadArc.LastParameter() - FiadArc.FirstParameter()) > 10*tolesp)
762       Update(HBs,pced,HGs,FiadArc,CPadArc,isfirst);
763
764     if (thePrepareOnSame) {
765       //saveCPopArc.SetParameter(wop);
766       saveCPopArc.SetPoint(CPopArc.Point());
767       CPopArc = saveCPopArc;
768       return;
769     }
770   }
771   else {
772     inters = FindFace(Vtx,CV1,CV2,Fv,Fop);
773     if (!inters) {
774       PerformIntersectionAtEnd(Index);
775       return;
776     }
777     Bs.Initialize(Fv);
778     Handle(BRepAdaptor_HCurve2d) pced = new BRepAdaptor_HCurve2d();
779     pced->ChangeCurve2d().Initialize(CV1.Arc(),Fv);
780     Update(HBs,pced,HGs,Fd->ChangeInterferenceOnS1(),CV1,isfirst);
781     pced->ChangeCurve2d().Initialize(CV2.Arc(),Fv);
782     Update(HBs,pced,HGs,Fd->ChangeInterferenceOnS2(),CV2,isfirst);
783   }
784
785
786 #ifdef DEB
787  ChFi3d_ResultChron(ch,t_same); // result perf condition if (same)
788  ChFi3d_InitChron(ch); // init perf condition if (inters)
789 #endif
790
791   TopoDS_Edge edgecouture;
792   Standard_Boolean couture,intcouture=Standard_False;;
793   Standard_Real tolreached;
794 #ifndef DEB
795   Standard_Real  par1 =0.,par2 =0.;
796   Standard_Integer indpt = 0,Icurv1 = 0,Icurv2 = 0;
797 #else
798   Standard_Real  par1,par2;
799   Standard_Integer indpt,Icurv1,Icurv2;
800 #endif
801   Handle(Geom_TrimmedCurve) curv1,curv2;
802   Handle(Geom2d_Curve) c2d1,c2d2;
803
804   Standard_Integer Isurf=Fd->Surf();
805
806   if (inters) {
807     HGs = ChFi3d_BoundSurf(DStr,Fd,1,2);
808     const ChFiDS_FaceInterference& Fi1 = Fd->InterferenceOnS1();
809     const ChFiDS_FaceInterference& Fi2 = Fd->InterferenceOnS2();
810     TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4);
811     gp_Pnt2d pfil1,pfac1,pfil2,pfac2;
812     Handle(Geom2d_Curve) Hc1,Hc2;
813     if (onsame && IFopArc == 1) pfac1 = p2dbout;
814     else {
815       Hc1 = BRep_Tool::CurveOnSurface(CV1.Arc(),Fv,Ubid,Ubid);
816       pfac1 = Hc1->Value(CV1.ParameterOnArc());
817     }
818     if (onsame && IFopArc == 2) pfac2 = p2dbout;
819     else {
820       Hc2 = BRep_Tool::CurveOnSurface(CV2.Arc(),Fv,Ubid,Ubid);
821       pfac2 = Hc2->Value(CV2.ParameterOnArc());
822     }
823     if (Fi1.LineIndex() != 0) {
824       pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(isfirst));
825     }
826     else {
827       pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst));
828     }
829     if (Fi2.LineIndex() != 0) {
830       pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(isfirst));
831     }
832     else {
833       pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst));
834     }
835     if (onsame) ChFi3d_Recale(Bs,pfac1,pfac2,(IFadArc == 1));
836
837     Pardeb(1)= pfil1.X(); Pardeb(2) = pfil1.Y();
838     Pardeb(3)= pfac1.X(); Pardeb(4) = pfac1.Y();
839     Parfin(1)= pfil2.X(); Parfin(2) = pfil2.Y();
840     Parfin(3)= pfac2.X(); Parfin(4) = pfac2.Y();
841
842     Standard_Real uu1,uu2,vv1,vv2;
843     ChFi3d_Boite(pfac1,pfac2,uu1,uu2,vv1,vv2);
844     ChFi3d_BoundFac(Bs,uu1,uu2,vv1,vv2);
845
846     if (!ChFi3d_ComputeCurves(HGs,HBs,Pardeb,Parfin,Cc,
847                               Ps,
848                               Pc,tolesp,tol2d,tolreached))
849       Standard_Failure::Raise("OneCorner : echec calcul intersection");
850
851     Udeb = Cc->FirstParameter();
852     Ufin = Cc->LastParameter();
853
854     //  determine if the curve has an intersection with edge of sewing
855
856     ChFi3d_Couture(Fv,couture,edgecouture);
857
858     if (couture  && !BRep_Tool::Degenerated(edgecouture)) {
859
860       //Standard_Real Ubid,Vbid;
861       Handle (Geom_Curve) C=BRep_Tool::Curve(edgecouture,Ubid,Vbid);
862       Handle(Geom_TrimmedCurve) Ctrim=new Geom_TrimmedCurve (C,Ubid,Vbid);
863       GeomAdaptor_Curve cur1(Ctrim->BasisCurve());
864       GeomAdaptor_Curve cur2(Cc);
865       Extrema_ExtCC extCC (cur1,cur2);
866       if (extCC.IsDone()&&extCC.NbExt()!=0)
867       {
868         Standard_Integer imin=0;
869         Standard_Real distmin2 = RealLast();
870         for (Standard_Integer i = 1; i <= extCC.NbExt(); i++)
871           if (extCC.SquareDistance(i) < distmin2)
872           {
873             distmin2 = extCC.SquareDistance(i);
874             imin = i;
875           }
876         if (distmin2 <= Precision::Confusion() * Precision::Confusion())
877         {
878           Extrema_POnCurv ponc1,ponc2;
879           extCC.Points( imin, ponc1, ponc2 );
880           par1 = ponc1.Parameter();
881           par2 = ponc2.Parameter();
882           Standard_Real Tol = 1.e-4;
883           if (Abs(par2-Udeb) > Tol && Abs(Ufin-par2) > Tol)
884           {
885             gp_Pnt P1 = ponc1.Value();
886             TopOpeBRepDS_Point tpoint( P1, Tol );
887             indpt = DStr.AddPoint(tpoint);
888             intcouture = Standard_True;
889             curv1 = new Geom_TrimmedCurve(Cc,Udeb,par2);
890             curv2 = new Geom_TrimmedCurve(Cc,par2,Ufin);
891             TopOpeBRepDS_Curve tcurv1(curv1,tolreached);
892             TopOpeBRepDS_Curve tcurv2(curv2,tolreached);
893             Icurv1=DStr.AddCurve(tcurv1);
894             Icurv2=DStr.AddCurve(tcurv2);
895           }
896         }
897       }
898     }
899   }
900   else { // (!inters)
901     Standard_NotImplemented::Raise("OneCorner : bouchon non ecrit");
902   }
903   Standard_Integer IShape = DStr.AddShape(Fv);
904 #ifndef DEB
905   TopAbs_Orientation Et = TopAbs_FORWARD;
906 #else
907   TopAbs_Orientation Et;
908 #endif
909   if (IFadArc == 1) {
910     TopExp_Explorer Exp;
911     for (Exp.Init(Fv.Oriented(TopAbs_FORWARD),
912                   TopAbs_EDGE);Exp.More();Exp.Next()) {
913       if (Exp.Current().IsSame(CV1.Arc())) {
914         Et = TopAbs::Reverse(TopAbs::Compose
915                              (Exp.Current().Orientation(),
916                               CV1.TransitionOnArc()));
917         break;
918       }
919     }
920   }
921   else {
922     TopExp_Explorer Exp;
923     for (Exp.Init(Fv.Oriented(TopAbs_FORWARD),
924                               TopAbs_EDGE);Exp.More();Exp.Next()) {
925       if (Exp.Current().IsSame(CV2.Arc())) {
926         Et = TopAbs::Compose(Exp.Current().Orientation(),
927                              CV2.TransitionOnArc());
928         break;
929       }
930     }
931
932 //
933
934
935   }
936
937 #ifdef DEB
938   ChFi3d_ResultChron(ch ,t_inter); //result perf condition if (inter)
939   ChFi3d_InitChron(ch); // init perf condition  if (onsame && inters)
940 #endif
941
942   stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV1,DStr),isfirst,1);
943   stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV2,DStr),isfirst,2);
944
945   if (!intcouture) {
946 // there is no intersection with the sewing edge
947 // the curve Cc is stored in the stripe
948 // the storage in the DS is not done by FILDS.
949
950     TopOpeBRepDS_Curve Tc(Cc,tolreached);
951     ICurve = DStr.AddCurve(Tc);
952     Handle(TopOpeBRepDS_SurfaceCurveInterference)
953       Interfc = ChFi3d_FilCurveInDS(ICurve,IShape,Pc,Et);
954
955     // 31/01/02 akm vvv : (OCC119) Prevent the builder from creating
956     //                    intersecting fillets - they are bad.
957     Geom2dInt_GInter anIntersector;
958     Geom2dAdaptor_Curve aCorkPCurve (Pc, Udeb, Ufin);
959
960     // Take all the interferences with faces from all the stripes
961     // and look if their pcurves intersect our cork pcurve.
962     // Unfortunately, by this moment they do not exist in DStr.
963     ChFiDS_ListIteratorOfListOfStripe aStrIt(myListStripe);
964     for (; aStrIt.More(); aStrIt.Next())
965     {
966       Handle(ChFiDS_Stripe) aCheckStripe = aStrIt.Value();
967       Handle(ChFiDS_HData) aSeqData = aCheckStripe->SetOfSurfData();
968       // Loop on parts of the stripe
969       Standard_Integer iPart;
970       for (iPart=1; iPart<=aSeqData->Length(); iPart++)
971       {
972         Handle(ChFiDS_SurfData) aData = aSeqData->Value(iPart);
973         Geom2dAdaptor_Curve anOtherPCurve;
974         if (IShape == aData->IndexOfS1())
975         {
976     const Handle(Geom2d_Curve)& aPCurve = aData->InterferenceOnS1().PCurveOnFace();
977     if(aPCurve.IsNull())
978       continue;
979
980           anOtherPCurve.Load (aPCurve,
981                               aData->InterferenceOnS1().FirstParameter(),
982                               aData->InterferenceOnS1().LastParameter());
983         }
984         else if (IShape == aData->IndexOfS2())
985         {
986     const Handle(Geom2d_Curve)& aPCurve = aData->InterferenceOnS2().PCurveOnFace();
987     if(aPCurve.IsNull())
988       continue;
989
990           anOtherPCurve.Load (aPCurve,
991                               aData->InterferenceOnS2().FirstParameter(),
992                               aData->InterferenceOnS2().LastParameter());
993         }
994         else
995         {
996           // Normal case - no common surface
997           continue;
998         }
999         if (IsEqual(anOtherPCurve.LastParameter(),anOtherPCurve.FirstParameter()))
1000           // Degenerates
1001           continue;
1002         anIntersector.Perform (aCorkPCurve, anOtherPCurve,
1003                                tol2d, Precision::PConfusion());
1004         if (anIntersector.NbSegments() > 0 ||
1005             anIntersector.NbPoints() > 0)
1006           StdFail_NotDone::Raise ("OneCorner : fillets have too big radiuses");
1007       }
1008     }
1009     TopOpeBRepDS_ListIteratorOfListOfInterference
1010       anIter(DStr.ChangeShapeInterferences(IShape));
1011     for (; anIter.More(); anIter.Next())
1012     {
1013       Handle(TopOpeBRepDS_SurfaceCurveInterference) anOtherIntrf =
1014         Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(anIter.Value());
1015       // We need only interferences between cork face and curves
1016       // of intersection with another fillet surfaces
1017       if (anOtherIntrf.IsNull())
1018         continue;
1019       // Look if there is an intersection between pcurves
1020       Handle(Geom_TrimmedCurve) anOtherCur =
1021         Handle(Geom_TrimmedCurve)::DownCast(DStr.Curve (anOtherIntrf->Geometry()).Curve());
1022       if (anOtherCur.IsNull())
1023         continue;
1024       Geom2dAdaptor_Curve anOtherPCurve (anOtherIntrf->PCurve(),
1025                                          anOtherCur->FirstParameter(),
1026                                          anOtherCur->LastParameter());
1027       anIntersector.Perform (aCorkPCurve, anOtherPCurve,
1028                              tol2d, Precision::PConfusion());
1029       if (anIntersector.NbSegments() > 0 ||
1030           anIntersector.NbPoints() > 0)
1031         StdFail_NotDone::Raise ("OneCorner : fillets have too big radiuses");
1032     }
1033     // 31/01/02 akm ^^^
1034     DStr.ChangeShapeInterferences(IShape).Append(Interfc);
1035     //// modified by jgv, 26.03.02 for OCC32 ////
1036     ChFiDS_CommonPoint CV [2];
1037     CV[0] = CV1;
1038     CV[1] = CV2;
1039     for (Standard_Integer i = 0; i < 2; i++)
1040     {
1041       if (CV[i].IsOnArc() && ChFi3d_IsPseudoSeam( CV[i].Arc(), Fv ))
1042       {
1043         gp_Pnt2d pfac1, PcF, PcL;
1044         gp_Vec2d DerPc, DerHc;
1045         Standard_Real first, last, prm1, prm2;
1046         Standard_Boolean onfirst, FirstToPar;
1047         Handle(Geom2d_Curve) Hc = BRep_Tool::CurveOnSurface( CV[i].Arc(), Fv, first, last );
1048         pfac1 = Hc->Value( CV[i].ParameterOnArc() );
1049         PcF = Pc->Value( Udeb );
1050         PcL = Pc->Value( Ufin );
1051         onfirst = (pfac1.Distance(PcF) < pfac1.Distance(PcL))? Standard_True : Standard_False;
1052         if (onfirst)
1053           Pc->D1( Udeb, PcF, DerPc );
1054         else
1055         {
1056           Pc->D1( Ufin, PcL, DerPc );
1057           DerPc.Reverse();
1058         }
1059         Hc->D1( CV[i].ParameterOnArc(), pfac1, DerHc );
1060         if (DerHc.Dot(DerPc) > 0.)
1061         {
1062           prm1 = CV[i].ParameterOnArc();
1063           prm2 = last;
1064           FirstToPar = Standard_False;
1065         }
1066         else
1067         {
1068           prm1 = first;
1069           prm2 = CV[i].ParameterOnArc();
1070           FirstToPar = Standard_True;
1071         }
1072         Handle(Geom_Curve) Ct = BRep_Tool::Curve( CV[i].Arc(), first, last );
1073         Ct = new Geom_TrimmedCurve( Ct, prm1, prm2 );
1074         Standard_Real toled = BRep_Tool::Tolerance( CV[i].Arc() );
1075         TopOpeBRepDS_Curve tcurv( Ct, toled );
1076         Handle (TopOpeBRepDS_CurvePointInterference) Interfp1, Interfp2;
1077         Standard_Integer indcurv;
1078         indcurv = DStr.AddCurve( tcurv );
1079         Standard_Integer indpoint = (isfirst)? stripe->IndexFirstPointOnS1() : stripe->IndexLastPointOnS1();
1080         Standard_Integer indvertex = DStr.AddShape(Vtx);
1081         if (FirstToPar)
1082         {
1083           Interfp1 = ChFi3d_FilPointInDS( TopAbs_FORWARD,  indcurv, indvertex, prm1, Standard_True );
1084           Interfp2 = ChFi3d_FilPointInDS( TopAbs_REVERSED, indcurv, indpoint,  prm2, Standard_False );
1085         }
1086         else
1087         {
1088           Interfp1 = ChFi3d_FilPointInDS( TopAbs_FORWARD,  indcurv, indpoint,  prm1, Standard_False );
1089           Interfp2 = ChFi3d_FilPointInDS( TopAbs_REVERSED, indcurv, indvertex, prm2, Standard_True );
1090         }
1091         DStr.ChangeCurveInterferences(indcurv).Append(Interfp1);
1092         DStr.ChangeCurveInterferences(indcurv).Append(Interfp2);
1093         Standard_Integer indface = DStr.AddShape( Fv );
1094         Interfc = ChFi3d_FilCurveInDS( indcurv, indface, Hc, CV[i].Arc().Orientation() );
1095         DStr.ChangeShapeInterferences(indface).Append( Interfc );
1096         TopoDS_Edge aLocalEdge = CV[i].Arc();
1097         aLocalEdge.Reverse();
1098         Handle(Geom2d_Curve) HcR = BRep_Tool::CurveOnSurface( aLocalEdge, Fv, first, last );
1099         Interfc = ChFi3d_FilCurveInDS( indcurv, indface, HcR, aLocalEdge.Orientation() );
1100         DStr.ChangeShapeInterferences(indface).Append( Interfc );
1101         //modify degenerated edge
1102         Standard_Boolean DegenExist = Standard_False;
1103         TopoDS_Edge Edeg;
1104         TopExp_Explorer Explo( Fv, TopAbs_EDGE );
1105         for (; Explo.More(); Explo.Next())
1106         {
1107           const TopoDS_Edge& Ecur = TopoDS::Edge( Explo.Current() );
1108           if (BRep_Tool::Degenerated( Ecur ))
1109           {
1110             TopoDS_Vertex Vf, Vl;
1111             TopExp::Vertices( Ecur, Vf, Vl );
1112             if (Vf.IsSame(Vtx) || Vl.IsSame(Vtx))
1113             {
1114               DegenExist = Standard_True;
1115               Edeg = Ecur;
1116               break;
1117             }
1118           }
1119         }
1120         if (DegenExist)
1121         {
1122           Standard_Real fd, ld;
1123           Handle(Geom2d_Curve) Cd = BRep_Tool::CurveOnSurface( Edeg, Fv, fd, ld );
1124           Handle(Geom2d_TrimmedCurve) tCd = Handle(Geom2d_TrimmedCurve)::DownCast(Cd);
1125           if (! tCd.IsNull())
1126             Cd = tCd->BasisCurve();
1127           gp_Pnt2d P2d = (FirstToPar)? Hc->Value(first) : Hc->Value(last);
1128           Geom2dAPI_ProjectPointOnCurve Projector( P2d, Cd );
1129           Standard_Real par = Projector.LowerDistanceParameter();
1130           Standard_Integer Ideg = DStr.AddShape(Edeg);
1131           TopAbs_Orientation ori = (par < fd)? TopAbs_FORWARD : TopAbs_REVERSED; //if par<fd => par>ld
1132           Interfp1 = ChFi3d_FilPointInDS( ori, Ideg, indvertex, par, Standard_True );
1133           DStr.ChangeShapeInterferences(Ideg).Append(Interfp1);
1134         }
1135       }
1136     }
1137     /////////////////////////////////////////////
1138     stripe->ChangePCurve(isfirst)=Ps;
1139     stripe->SetCurve(ICurve,isfirst);
1140     stripe->SetParameters(isfirst,Udeb,Ufin);
1141   }
1142   else {
1143 // curves curv1 are curv2 stored in the DS
1144 // these curves will not be reconstructed by FILDS as
1145 // one places stripe->InDS(isfirst);
1146
1147     // interferences of curv1 and curv2 on Fv
1148     ComputeCurve2d(curv1,Fv,c2d1);
1149     Handle(TopOpeBRepDS_SurfaceCurveInterference) InterFv;
1150     InterFv = ChFi3d_FilCurveInDS(Icurv1,IShape,c2d1,Et);
1151     DStr.ChangeShapeInterferences(IShape).Append(InterFv);
1152     ComputeCurve2d(curv2,Fv,c2d2);
1153     InterFv = ChFi3d_FilCurveInDS(Icurv2,IShape,c2d2,Et);
1154     DStr.ChangeShapeInterferences(IShape).Append(InterFv);
1155      // interferences of curv1 and curv2 on Isurf
1156     if (Fd->Orientation()== Fv.Orientation()) Et=TopAbs::Reverse(Et);
1157     c2d1=new Geom2d_TrimmedCurve(Ps,Udeb,par2);
1158     InterFv = ChFi3d_FilCurveInDS(Icurv1,Isurf,c2d1,Et);
1159     DStr.ChangeSurfaceInterferences(Isurf).Append(InterFv);
1160     c2d2=new Geom2d_TrimmedCurve(Ps,par2,Ufin);
1161        InterFv = ChFi3d_FilCurveInDS(Icurv2,Isurf,c2d2,Et);
1162     DStr.ChangeSurfaceInterferences(Isurf).Append(InterFv);
1163
1164       // limitation of the sewing edge
1165     Standard_Integer Iarc=DStr.AddShape(edgecouture);
1166     Handle(TopOpeBRepDS_CurvePointInterference) Interfedge;
1167     TopAbs_Orientation ori;
1168     TopoDS_Vertex Vdeb,Vfin;
1169     Vdeb=TopExp::FirstVertex(edgecouture);
1170     Vfin=TopExp::LastVertex(edgecouture);
1171     Standard_Real pard,parf;
1172     pard=BRep_Tool::Parameter(Vdeb,edgecouture);
1173     parf=BRep_Tool::Parameter(Vfin,edgecouture);
1174     if (Abs(par1-pard)<Abs(parf-par1)) ori=TopAbs_FORWARD;
1175     else ori=TopAbs_REVERSED;
1176     Interfedge = ChFi3d_FilPointInDS(ori,Iarc,indpt,par1);
1177     DStr.ChangeShapeInterferences(Iarc).Append(Interfedge);
1178
1179     // creation of CurveInterferences from Icurv1 and Icurv2
1180     stripe->InDS(isfirst);
1181     Standard_Integer ind1= stripe->IndexPoint(isfirst,1);
1182     Standard_Integer ind2= stripe->IndexPoint(isfirst,2);
1183     Handle(TopOpeBRepDS_CurvePointInterference)
1184       interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv1,ind1,Udeb);
1185     DStr.ChangeCurveInterferences(Icurv1).Append(interfprol);
1186     interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv1,indpt,par2);
1187     DStr.ChangeCurveInterferences(Icurv1).Append(interfprol);
1188     interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv2,indpt,par2);
1189     DStr.ChangeCurveInterferences(Icurv2).Append(interfprol);
1190     interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv2,ind2,Ufin);
1191     DStr.ChangeCurveInterferences(Icurv2).Append(interfprol);
1192
1193   }
1194
1195   ChFi3d_EnlargeBox(HBs,Pc,Udeb,Ufin,box1,box2);
1196
1197   if (onsame && inters) {
1198     // VARIANT 1:
1199     // A small missing end of curve is added for the extension
1200     // of the face at end and the limitation of the opposing face.
1201
1202     //   VARIANT 2 : extend Arcprol, not create new small edge
1203     //   To do: modify for intcouture
1204     const Standard_Boolean variant1 = Standard_True;
1205
1206     // First of all the ponts are cut with the edge of the spine.
1207     Standard_Integer IArcspine = DStr.AddShape(Arcspine);
1208     Standard_Integer IVtx = DStr.AddShape(Vtx);
1209 #ifndef DEB
1210     TopAbs_Orientation OVtx = TopAbs_FORWARD;
1211 #else
1212     TopAbs_Orientation OVtx;
1213 #endif
1214     for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
1215         ex.More(); ex.Next()) {
1216       if (Vtx.IsSame(ex.Current())) {
1217         OVtx = ex.Current().Orientation();
1218         break;
1219       }
1220     }
1221     OVtx = TopAbs::Reverse(OVtx);
1222     Standard_Real parVtx = BRep_Tool::Parameter(Vtx,Arcspine);
1223     Handle(TopOpeBRepDS_CurvePointInterference)
1224       interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
1225     DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
1226
1227     // Now the missing curves are constructed.
1228     TopoDS_Vertex V2;
1229     for(ex.Init(Arcprol.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
1230         ex.More(); ex.Next()) {
1231       if (Vtx.IsSame(ex.Current()))
1232         OVtx = ex.Current().Orientation();
1233       else
1234         V2 =  TopoDS::Vertex(ex.Current());
1235     }
1236
1237     Handle(Geom2d_Curve) Hc;
1238     if (variant1)
1239       parVtx = BRep_Tool::Parameter(Vtx,Arcprol);
1240     else
1241       parVtx = BRep_Tool::Parameter(V2,Arcprol);
1242     const ChFiDS_FaceInterference& Fiop = Fd->Interference(IFopArc);
1243     gp_Pnt2d pop1, pop2, pv1, pv2;
1244     Hc = BRep_Tool::CurveOnSurface(Arcprol,Fop,Ubid,Ubid);
1245     pop1 = Hc->Value(parVtx);
1246     pop2 = Fiop.PCurveOnFace()->Value(Fiop.Parameter(isfirst));
1247     Hc = BRep_Tool::CurveOnSurface(Arcprol,Fv,Ubid,Ubid);
1248     pv1 = Hc->Value(parVtx);
1249     pv2 = p2dbout;
1250     ChFi3d_Recale(Bs,pv1,pv2,1);
1251     TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4);
1252     Pardeb(1) = pop1.X(); Pardeb(2) = pop1.Y();
1253     Pardeb(3) = pv1.X();  Pardeb(4) = pv1.Y();
1254     Parfin(1) = pop2.X(); Parfin(2) = pop2.Y();
1255     Parfin(3) = pv2.X();  Parfin(4) = pv2.Y();
1256     Standard_Real uu1,uu2,vv1,vv2;
1257     ChFi3d_Boite(pv1,pv2,uu1,uu2,vv1,vv2);
1258     ChFi3d_BoundFac(Bs,uu1,uu2,vv1,vv2);
1259     ChFi3d_Boite(pop1,pop2,uu1,uu2,vv1,vv2);
1260     ChFi3d_BoundFac(Bop,uu1,uu2,vv1,vv2);
1261
1262     Handle(Geom_Curve) zob3d;
1263     Handle(Geom2d_Curve) zob2dop, zob2dv;
1264     //Standard_Real tolreached;
1265     if (!ChFi3d_ComputeCurves(HBop,HBs,Pardeb,Parfin,zob3d,zob2dop,
1266                               zob2dv,tolesp,tol2d,tolreached))
1267       Standard_Failure::Raise("OneCorner : echec calcul intersection");
1268
1269     Udeb = zob3d->FirstParameter();
1270     Ufin = zob3d->LastParameter();
1271     TopOpeBRepDS_Curve Zob(zob3d,tolreached);
1272     Standard_Integer IZob = DStr.AddCurve(Zob);
1273
1274 // it is determined if Fop has an edge of sewing 
1275 // it is determined if the curve has an intersection with the edge of sewing
1276
1277     //TopoDS_Edge edgecouture;
1278     //Standard_Boolean couture;
1279     ChFi3d_Couture(Fop,couture,edgecouture);
1280
1281     if (couture  && !BRep_Tool::Degenerated(edgecouture)) {
1282       BRepLib_MakeEdge Bedge (zob3d);
1283       TopoDS_Edge edg =Bedge. Edge();
1284       BRepExtrema_ExtCC extCC (edgecouture,edg);
1285       if (extCC.IsDone()&&extCC.NbExt()!=0) {
1286         for (Standard_Integer i=1; i<=extCC.NbExt()&&!intcouture;i++) {
1287           if (extCC.SquareDistance(i)<=1.e-8) {
1288             par1=extCC.ParameterOnE1(i);
1289             par2=extCC.ParameterOnE2(i);
1290             gp_Pnt P1=extCC.PointOnE1(i);
1291             TopOpeBRepDS_Point tpoint(P1,1.e-4);
1292             indpt=DStr.AddPoint(tpoint);
1293             intcouture=Standard_True;
1294             curv1 = new Geom_TrimmedCurve(zob3d,Udeb,par2);
1295             curv2 = new Geom_TrimmedCurve(zob3d,par2,Ufin);
1296             TopOpeBRepDS_Curve tcurv1(curv1,tolreached);
1297             TopOpeBRepDS_Curve tcurv2(curv2,tolreached);
1298             Icurv1=DStr.AddCurve(tcurv1);
1299             Icurv2=DStr.AddCurve(tcurv2);
1300           }
1301         }
1302       }
1303     }
1304     if (intcouture) {
1305
1306 // interference of curv1 and curv2 on Ishape
1307       Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolv));
1308       ComputeCurve2d(curv1,Fop,c2d1);
1309       Handle(TopOpeBRepDS_SurfaceCurveInterference)
1310         InterFv = ChFi3d_FilCurveInDS(Icurv1,IShape,/*zob2dv*/c2d1,Et);
1311       DStr.ChangeShapeInterferences(IShape).Append(InterFv);
1312       ComputeCurve2d(curv2,Fop,c2d2);
1313       InterFv = ChFi3d_FilCurveInDS(Icurv2,IShape,/*zob2dv*/c2d2,Et);
1314       DStr.ChangeShapeInterferences(IShape).Append(InterFv);
1315
1316       // limitation of the sewing edge
1317       Standard_Integer Iarc=DStr.AddShape(edgecouture);
1318       Handle(TopOpeBRepDS_CurvePointInterference) Interfedge;
1319       TopAbs_Orientation ori;
1320       TopoDS_Vertex Vdeb,Vfin;
1321       Vdeb=TopExp::FirstVertex(edgecouture);
1322       Vfin=TopExp::LastVertex(edgecouture);
1323       Standard_Real pard,parf;
1324       pard=BRep_Tool::Parameter(Vdeb,edgecouture);
1325       parf=BRep_Tool::Parameter(Vfin,edgecouture);
1326       if (Abs(par1-pard)<Abs(parf-par1)) ori=TopAbs_REVERSED;
1327       else ori=TopAbs_FORWARD;
1328       Interfedge = ChFi3d_FilPointInDS(ori,Iarc,indpt,par1);
1329       DStr.ChangeShapeInterferences(Iarc).Append(Interfedge);
1330
1331     //  interference of curv1 and curv2 on Iop
1332       Standard_Integer Iop = DStr.AddShape(Fop);
1333       Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolop));
1334       Handle(TopOpeBRepDS_SurfaceCurveInterference)  Interfop;
1335       ComputeCurve2d(curv1,Fop,c2d1);
1336       Interfop  = ChFi3d_FilCurveInDS(Icurv1,Iop,c2d1,Et);
1337       DStr.ChangeShapeInterferences(Iop).Append(Interfop);
1338       ComputeCurve2d(curv2,Fop,c2d2);
1339       Interfop  = ChFi3d_FilCurveInDS(Icurv2,Iop,c2d2,Et);
1340       DStr.ChangeShapeInterferences(Iop).Append(Interfop);
1341       Handle(TopOpeBRepDS_CurvePointInterference)
1342         interfprol = ChFi3d_FilVertexInDS(TopAbs_FORWARD,Icurv1,IVtx,Udeb);
1343       DStr.ChangeCurveInterferences(Icurv1).Append(interfprol);
1344       interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv1,indpt,par2);
1345       DStr.ChangeCurveInterferences(Icurv1).Append(interfprol);
1346       Standard_Integer icc = stripe->IndexPoint(isfirst,IFopArc);
1347       interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv2,indpt,par2);
1348       DStr.ChangeCurveInterferences(Icurv2).Append(interfprol);
1349       interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv2,icc,Ufin);
1350       DStr.ChangeCurveInterferences(Icurv2).Append(interfprol);
1351     }
1352     else {
1353       Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolv));
1354       Handle(TopOpeBRepDS_SurfaceCurveInterference)
1355         InterFv = ChFi3d_FilCurveInDS(IZob,IShape,zob2dv,Et);
1356       DStr.ChangeShapeInterferences(IShape).Append(InterFv);
1357       Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolop));
1358       Standard_Integer Iop = DStr.AddShape(Fop);
1359       Handle(TopOpeBRepDS_SurfaceCurveInterference)
1360         Interfop = ChFi3d_FilCurveInDS(IZob,Iop,zob2dop,Et);
1361       DStr.ChangeShapeInterferences(Iop).Append(Interfop);
1362       Handle(TopOpeBRepDS_CurvePointInterference) interfprol;
1363       if (variant1)
1364         interfprol = ChFi3d_FilVertexInDS(TopAbs_FORWARD,IZob,IVtx,Udeb);
1365       else {
1366         Standard_Integer IV2 = DStr.AddShape(V2); // VARIANT 2
1367         interfprol = ChFi3d_FilVertexInDS(TopAbs_FORWARD,IZob,IV2,Udeb);
1368       }
1369       DStr.ChangeCurveInterferences(IZob).Append(interfprol);
1370       Standard_Integer icc = stripe->IndexPoint(isfirst,IFopArc);
1371       interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,IZob,icc,Ufin);
1372       DStr.ChangeCurveInterferences(IZob).Append(interfprol);
1373       if (variant1) {
1374         if (IFopArc == 1) box1.Add( zob3d->Value(Ufin) );
1375         else              box2.Add( zob3d->Value(Ufin) );
1376       }
1377       else {
1378         // cut off existing Arcprol
1379         Standard_Integer iArcprol = DStr.AddShape(Arcprol);
1380         interfprol = ChFi3d_FilPointInDS(OVtx,iArcprol,icc,Udeb);
1381         DStr.ChangeShapeInterferences(Arcprol).Append(interfprol);
1382       }
1383     }
1384   }
1385   ChFi3d_EnlargeBox(DStr,stripe,Fd,box1,box2,isfirst);
1386   if (CV1.IsOnArc()) {
1387     ChFi3d_EnlargeBox(CV1.Arc(),myEFMap(CV1.Arc()),CV1.ParameterOnArc(),box1);
1388   }
1389   if (CV2.IsOnArc()) {
1390     ChFi3d_EnlargeBox(CV2.Arc(),myEFMap(CV2.Arc()),CV2.ParameterOnArc(),box2);
1391   }
1392   if  (!CV1.IsVertex())
1393     ChFi3d_SetPointTolerance(DStr,box1,stripe->IndexPoint(isfirst,1));
1394   if (!CV2.IsVertex())
1395     ChFi3d_SetPointTolerance(DStr,box2,stripe->IndexPoint(isfirst,2));
1396
1397 #ifdef DEB
1398   ChFi3d_ResultChron(ch, t_sameinter);//result perf condition if (same &&inter)
1399 #endif
1400 }
1401
1402 //=======================================================================
1403 //function : cherche_face
1404 //purpose  : find face F belonging to the map, different from faces
1405 //           F1  F2 F3 and containing edge E
1406 //=======================================================================
1407
1408 static void cherche_face (const TopTools_ListOfShape & map,
1409                           const TopoDS_Edge & E,
1410                           const TopoDS_Face & F1,
1411                           const TopoDS_Face & F2,
1412                           const TopoDS_Face & F3,
1413                           TopoDS_Face &  F)
1414 { TopoDS_Face Fcur;
1415   Standard_Boolean trouve=Standard_False;
1416   TopTools_ListIteratorOfListOfShape It;
1417   Standard_Integer ie;
1418   for (It.Initialize(map);It.More()&&!trouve;It.Next())
1419   { Fcur=TopoDS::Face (It.Value());
1420     if (!Fcur.IsSame(F1) && !Fcur.IsSame(F2)&& !Fcur.IsSame(F3) )
1421     { TopTools_IndexedMapOfShape  MapE;
1422       TopExp::MapShapes( Fcur,TopAbs_EDGE,MapE);
1423       for ( ie=1; ie<= MapE.Extent()&&!trouve;  ie++)
1424       {
1425         TopoDS_Shape aLocalShape = TopoDS_Shape (MapE(ie));
1426         if (E.IsSame(TopoDS::Edge(aLocalShape)))
1427           //            if (E.IsSame(TopoDS::Edge(TopoDS_Shape (MapE(ie)))))
1428         { F= Fcur; trouve=Standard_True;}
1429       }
1430     }
1431   }
1432 }
1433
1434 //=======================================================================
1435 //function : cherche_edge1
1436 //purpose  : find common edge between faces F1 and F2
1437 //=======================================================================
1438
1439 static void cherche_edge1 (const TopoDS_Face & F1,
1440                     const TopoDS_Face & F2,
1441                           TopoDS_Edge & Edge)
1442 { Standard_Integer i,j;
1443   TopoDS_Edge Ecur1,Ecur2;
1444   Standard_Boolean trouve=Standard_False;
1445   TopTools_IndexedMapOfShape  MapE1,MapE2;
1446   TopExp::MapShapes( F1,TopAbs_EDGE,MapE1);
1447   TopExp::MapShapes( F2,TopAbs_EDGE,MapE2);
1448   for ( i=1; i<= MapE1.Extent()&&!trouve; i++)
1449       {
1450         TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i));
1451         Ecur1=TopoDS::Edge(aLocalShape);
1452 //      Ecur1=TopoDS::Edge(TopoDS_Shape (MapE1(i)));
1453         for ( j=1; j<= MapE2.Extent()&&!trouve; j++)
1454             {
1455               aLocalShape = TopoDS_Shape (MapE2(j));
1456               Ecur2=TopoDS::Edge(aLocalShape);
1457 //            Ecur2=TopoDS::Edge(TopoDS_Shape (MapE2(j)));
1458             if (Ecur2.IsSame(Ecur1))
1459                {Edge=Ecur1;trouve=Standard_True;}
1460             }
1461       }
1462 }
1463
1464 //=======================================================================
1465 //function : containV
1466 //purpose  : return true if vertex V belongs to F1
1467 //=======================================================================
1468
1469 static Standard_Boolean  containV(const TopoDS_Face & F1,
1470                            const TopoDS_Vertex & V)
1471 { Standard_Integer i;
1472   TopoDS_Vertex Vcur;
1473   Standard_Boolean trouve=Standard_False;
1474   Standard_Boolean contain=Standard_False;
1475   TopTools_IndexedMapOfShape  MapV;
1476   TopExp::MapShapes( F1,TopAbs_VERTEX,MapV);
1477   for ( i=1; i<= MapV.Extent()&&!trouve; i++)
1478       {
1479         TopoDS_Shape aLocalShape = TopoDS_Shape (MapV(i));
1480         Vcur=TopoDS::Vertex(aLocalShape);
1481 //      Vcur=TopoDS::Vertex(TopoDS_Shape (MapV(i)));
1482         if (Vcur.IsSame(V) )
1483             {contain=Standard_True; trouve=Standard_True;}
1484       }
1485   return contain;
1486 }
1487
1488 //=======================================================================
1489 //function : containE
1490 //purpose  : return true if edge E belongs to F1
1491 //=======================================================================
1492
1493 static Standard_Boolean  containE(const TopoDS_Face & F1,
1494                            const TopoDS_Edge & E)
1495 { Standard_Integer i;
1496   TopoDS_Edge Ecur;
1497   Standard_Boolean trouve=Standard_False;
1498   Standard_Boolean contain=Standard_False;
1499   TopTools_IndexedMapOfShape  MapE;
1500   TopExp::MapShapes( F1,TopAbs_EDGE,MapE);
1501   for ( i=1; i<= MapE.Extent()&&!trouve; i++)
1502       {
1503         TopoDS_Shape aLocalShape = TopoDS_Shape (MapE(i));
1504         Ecur=TopoDS::Edge(aLocalShape);
1505 //      Ecur=TopoDS::Edge(TopoDS_Shape (MapE(i)));
1506         if (Ecur.IsSame(E) )
1507             {contain=Standard_True; trouve=Standard_True;}
1508       }
1509   return contain;
1510 }
1511
1512
1513 //=======================================================================
1514 //function : IsShrink
1515 //purpose  : check if U (if <isU>==True) or V of points of <PC> is within
1516 //           <tol> from <Param>, check points between <Pf> and <Pl>
1517 //=======================================================================
1518
1519 static Standard_Boolean IsShrink(const Geom2dAdaptor_Curve PC,
1520                                  const Standard_Real       Pf,
1521                                  const Standard_Real       Pl,
1522                                  const Standard_Real       Param,
1523                                  const Standard_Boolean    isU,
1524                                  const Standard_Real       tol)
1525 {
1526   switch (PC.GetType()) {
1527   case GeomAbs_Line: {
1528     gp_Pnt2d P1 = PC.Value(Pf);
1529     gp_Pnt2d P2 = PC.Value(Pl);
1530     if (Abs(P1.Coord(isU ? 1 : 2) - Param) <= tol &&
1531         Abs(P2.Coord(isU ? 1 : 2) - Param) <= tol )
1532       return Standard_True;
1533     else
1534       return Standard_False;
1535   }
1536   case GeomAbs_BezierCurve:
1537   case GeomAbs_BSplineCurve: {
1538     math_FunctionSample aSample (Pf,Pl,10);
1539     Standard_Integer i;
1540     for (i=1; i<=aSample.NbPoints(); i++) {
1541       gp_Pnt2d P = PC.Value(aSample.GetParameter(i));
1542       if (Abs(P.Coord(isU ? 1 : 2) - Param) > tol )
1543         return Standard_False;
1544     }
1545     return Standard_True;
1546   }
1547   default:;
1548   }
1549   return Standard_False;
1550 }
1551 //=======================================================================
1552 //function : PerformIntersectionAtEnd
1553 //purpose  :
1554 //=======================================================================
1555
1556 void ChFi3d_Builder::PerformIntersectionAtEnd(const Standard_Integer Index)
1557 {
1558
1559   // intersection at end of fillet with at least two faces
1560   // process the following cases:
1561   // - top has n (n>3) adjacent edges
1562   // - top has 3 edges and fillet on one of edges touches
1563   //   more than one face
1564
1565 #ifdef DEB
1566   OSD_Chronometer ch;// init perf
1567 #endif
1568
1569   TopOpeBRepDS_DataStructure& DStr= myDS->ChangeDS();
1570   const Standard_Integer nn=15;
1571   ChFiDS_ListIteratorOfListOfStripe It;
1572   It.Initialize(myVDataMap(Index));
1573   Handle(ChFiDS_Stripe) stripe = It.Value();
1574   const Handle(ChFiDS_Spine) spine = stripe->Spine();
1575   ChFiDS_SequenceOfSurfData& SeqFil =
1576     stripe->ChangeSetOfSurfData()->ChangeSequence();
1577   const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index);
1578   Standard_Integer sens = 0,num,num1;
1579   Standard_Boolean couture=Standard_False,isfirst;
1580   //Standard_Integer sense;
1581   TopoDS_Edge edgelibre1,edgelibre2,EdgeSpine;
1582   Standard_Boolean bordlibre;
1583   // determine the number of faces and edges
1584   TopTools_Array1OfShape tabedg(0,nn);
1585   TopoDS_Face F1,F2;
1586   Standard_Integer nface=ChFi3d_nbface(myVFMap(Vtx));
1587   TopTools_ListIteratorOfListOfShape ItF;
1588   Standard_Integer nbarete;
1589   nbarete=ChFi3d_NbNotDegeneratedEdges(Vtx,myVEMap);
1590   ChFi3d_ChercheBordsLibres(myVEMap,Vtx,bordlibre,edgelibre1,edgelibre2);
1591   if (bordlibre) nbarete=(nbarete-2)/2 +2;
1592   else           nbarete=nbarete/2;
1593   // it is determined if there is an edge of sewing and it face
1594
1595   TopoDS_Face facecouture;
1596   TopoDS_Edge edgecouture;
1597
1598   Standard_Boolean trouve=Standard_False;
1599   for(ItF.Initialize(myVFMap(Vtx));ItF.More()&&!couture;ItF.Next()) {
1600     TopoDS_Face fcur = TopoDS::Face(ItF.Value());
1601     ChFi3d_CoutureOnVertex(fcur,Vtx,couture,edgecouture);
1602     if (couture)
1603       facecouture=fcur;
1604   }
1605   // it is determined if one of edges adjacent to the fillet is regular
1606   Standard_Boolean reg1,reg2;
1607   TopoDS_Edge Ecur,Eadj1,Eadj2;
1608   TopoDS_Face Fga,Fdr;
1609   TopoDS_Vertex Vbid1;
1610   Standard_Integer nbsurf,nbedge;
1611   reg1=Standard_False;
1612   reg2=Standard_False;
1613   nbsurf= SeqFil.Length();
1614   nbedge = spine->NbEdges();
1615   num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens);
1616   isfirst = (sens == 1);
1617   ChFiDS_State state;
1618   if (isfirst) {
1619     EdgeSpine=spine->Edges(1);
1620     num1=num+1;
1621     state = spine->FirstStatus();
1622   }
1623   else {
1624     EdgeSpine=spine->Edges(nbedge);
1625     num1=num-1;
1626     state = spine->LastStatus();
1627   }
1628   if (nbsurf!=nbedge && nbsurf!=1) {
1629     ChFi3d_edge_common_faces(myEFMap(EdgeSpine),F1,F2);
1630     if (F1.IsSame(facecouture)) Eadj1=edgecouture;
1631     else ChFi3d_cherche_element(Vtx,EdgeSpine,F1,Eadj1,Vbid1);
1632     ChFi3d_edge_common_faces(myEFMap(Eadj1),Fga,Fdr);
1633 //  Modified by Sergey KHROMOV - Fri Dec 21 17:57:32 2001 Begin
1634 //  reg1=BRep_Tool::Continuity(Eadj1,Fga,Fdr)!=GeomAbs_C0;
1635     reg1=isTangentFaces(Eadj1,Fga,Fdr);
1636 //  Modified by Sergey KHROMOV - Fri Dec 21 17:57:33 2001 End
1637     if (F2.IsSame(facecouture)) Eadj2=edgecouture;
1638     else ChFi3d_cherche_element(Vtx,EdgeSpine,F2,Eadj2,Vbid1);
1639     ChFi3d_edge_common_faces(myEFMap(Eadj2),Fga,Fdr);
1640 //  Modified by Sergey KHROMOV - Fri Dec 21 17:58:22 2001 Begin
1641 //  reg2=BRep_Tool::Continuity(Eadj2,Fga,Fdr)!=GeomAbs_C0;
1642     reg2=isTangentFaces(Eadj2,Fga,Fdr);
1643 //  Modified by Sergey KHROMOV - Fri Dec 21 17:58:24 2001 End
1644
1645 // two faces common to the edge are found
1646     if (reg1 || reg2) {
1647       Standard_Boolean compoint1=Standard_False;
1648       Standard_Boolean compoint2=Standard_False;
1649       ChFiDS_CommonPoint cp1, cp2;
1650       cp1 = SeqFil(num1)->ChangeVertex (isfirst,1);
1651       cp2 = SeqFil(num1)->ChangeVertex (isfirst,2);
1652       if (cp1.IsOnArc()) {
1653         if (cp1.Arc().IsSame(Eadj1)||cp1.Arc().IsSame(Eadj2))
1654           compoint1=Standard_True;
1655       }
1656       if (cp2.IsOnArc()) {
1657         if (cp2.Arc().IsSame(Eadj1)||cp2.Arc().IsSame(Eadj2))
1658           compoint2=Standard_True;
1659       }
1660       if (compoint1 && compoint2) {
1661         SeqFil.Remove(num);
1662         reg1=Standard_False; reg2=Standard_False;
1663       }
1664     }
1665   }
1666 // there is only one face at end if FindFace is true and if the face
1667 // is not the face with sewing edge
1668   TopoDS_Face face;
1669   Handle(ChFiDS_SurfData) Fd = SeqFil.ChangeValue(num);
1670   ChFiDS_CommonPoint& CV1 = Fd->ChangeVertex(isfirst,1);
1671   ChFiDS_CommonPoint& CV2 = Fd->ChangeVertex(isfirst,2);
1672   Standard_Boolean onecorner=Standard_False;
1673   if (FindFace(Vtx,CV1,CV2,face)) {
1674       if (!couture) onecorner =Standard_True;
1675       else if (!face.IsSame(facecouture))
1676             onecorner=Standard_True;
1677     }
1678   if (onecorner) {
1679     if (ChFi3d_Builder::MoreSurfdata(Index)) {
1680       ChFi3d_Builder::PerformMoreSurfdata(Index);
1681       return;
1682     }
1683   }
1684   if (!onecorner && (reg1||reg2) && !couture && state!=ChFiDS_OnSame) {
1685     PerformMoreThreeCorner (Index,1);
1686     return;
1687   }
1688   Handle(GeomAdaptor_HSurface) HGs = ChFi3d_BoundSurf(DStr,Fd,1,2);
1689   ChFiDS_FaceInterference Fi1 = Fd->InterferenceOnS1();
1690   ChFiDS_FaceInterference Fi2 = Fd->InterferenceOnS2();
1691   GeomAdaptor_Surface& Gs = HGs->ChangeSurface();
1692   Handle(BRepAdaptor_HSurface) HBs  = new BRepAdaptor_HSurface();
1693   BRepAdaptor_Surface& Bs  = HBs->ChangeSurface();
1694   Handle(Geom_Curve) Cc;
1695   Handle(Geom2d_Curve) Pc,Ps;
1696   Standard_Real Ubid,Vbid;
1697   TopAbs_Orientation orsurfdata;
1698   orsurfdata=Fd->Orientation();
1699   Standard_Integer IsurfPrev=0, Isurf=Fd->Surf();
1700   Handle(ChFiDS_SurfData) SDprev;
1701   if (num1>0 && num1<=SeqFil.Length()) {
1702     SDprev = SeqFil(num1);
1703     IsurfPrev = SDprev->Surf();
1704   }
1705   // calculate the orientation of curves at end
1706
1707   Standard_Real tolpt=1.e-4;
1708   Standard_Real tolreached;
1709   TopAbs_Orientation orcourbe,orface,orien;
1710
1711   stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV1,DStr),isfirst,1);
1712   stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV2,DStr),isfirst,2);
1713
1714 //  gp_Pnt p3d;
1715 //  gp_Pnt2d p2d;
1716   Standard_Real dist;
1717   Standard_Integer Ishape1=Fd->IndexOfS1();
1718 #ifndef DEB
1719   TopAbs_Orientation trafil1 = TopAbs_FORWARD;
1720 #else
1721   TopAbs_Orientation trafil1;
1722 #endif
1723   if (Ishape1 != 0) {
1724     if (Ishape1 > 0) {
1725       trafil1 = DStr.Shape(Ishape1).Orientation();
1726     }
1727 #ifdef DEB
1728     else {
1729       cout<<"erreur"<<endl;
1730     }
1731 #endif
1732     trafil1 = TopAbs::Compose(trafil1,Fd->Orientation());
1733
1734     trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi1.Transition()),trafil1);
1735   }
1736 #ifdef DEB
1737   else cout<<"erreur"<<endl;
1738 #endif
1739   // eap, Apr 22 2002, occ 293
1740 //   Fi1.PCurveOnFace()->D0(Fi1.LastParameter(),p2d);
1741 //   const Handle(Geom_Surface) Stemp =
1742 //     BRep_Tool::Surface(TopoDS::Face(DStr.Shape(Ishape1)));
1743 //   Stemp ->D0(p2d.X(),p2d.Y(),p3d);
1744 //   dist=p3d.Distance(CV1.Point());
1745 //   if (dist<tolpt) orcourbe=trafil1;
1746 //   else            orcourbe=TopAbs::Reverse(trafil1);
1747   if (!isfirst) orcourbe=trafil1;
1748   else          orcourbe=TopAbs::Reverse(trafil1);
1749
1750   // eap, Apr 22 2002, occ 293
1751   // variables to show OnSame situation
1752   Standard_Boolean isOnSame1, isOnSame2;
1753   // In OnSame situation, the case of degenerated FaceInterference curve
1754   // is probable when a corner cuts the ChFi3d earlier built on OnSame edge.
1755   // In such a case, chamfer face can partially shrink to a line and we need
1756   // to cut off that shrinked part
1757   // If <isOnSame1>, FaceInterference with F2 can be degenerated
1758   Standard_Boolean checkShrink, isShrink, isUShrink;
1759   isShrink = isUShrink = isOnSame1 = isOnSame2 = Standard_False;
1760   Standard_Real checkShrParam=0., prevSDParam=0.;
1761   gp_Pnt2d midP2d;
1762   Standard_Integer midIpoint=0;
1763
1764   // find Fi1,Fi2 lengths used to extend ChFi surface
1765   // and by the way define necessity to check shrink
1766   gp_Pnt2d P2d1=Fi1.PCurveOnSurf()->Value(Fi1.Parameter(isfirst));
1767   gp_Pnt2d P2d2=Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst));
1768   gp_Pnt aP1,aP2;
1769   HGs->D0( P2d1.X(),P2d1.Y(),aP1);
1770   HGs->D0( P2d2.X(),P2d2.Y(),aP2);
1771   Standard_Real Fi1Length=aP1.Distance(aP2);
1772 //  Standard_Real eps = Precision::Confusion();
1773   checkShrink = (Fi1Length <= Precision::Confusion());
1774   
1775   gp_Pnt2d P2d3=Fi2.PCurveOnSurf()->Value(Fi2.Parameter(isfirst));
1776   gp_Pnt2d P2d4=Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst));
1777   HGs->D0( P2d3.X(),P2d3.Y(),aP1);
1778   HGs->D0( P2d4.X(),P2d4.Y(),aP2);
1779   Standard_Real Fi2Length=aP1.Distance(aP2);
1780   checkShrink = checkShrink || (Fi2Length <= Precision::Confusion());
1781
1782   if (checkShrink) {
1783     if (Abs(P2d2.Y()-P2d4.Y()) <= Precision::PConfusion()) {
1784       isUShrink = Standard_False;
1785       checkShrParam = P2d2.Y();
1786     } else if (Abs(P2d2.X()-P2d4.X()) <= Precision::PConfusion()) {
1787       isUShrink = Standard_True;
1788       checkShrParam = P2d2.X();
1789     }
1790     else
1791       checkShrink = Standard_False;
1792   }
1793
1794   /***********************************************************************/
1795   //  find faces intersecting with the fillet and edges limiting intersections
1796   //  nbface is the nb of faces intersected, Face[i] contais the faces
1797   // to intersect (i=0.. nbface-1). Edge[i] contains edges limiting
1798   // the intersections (i=0 ..nbface)
1799   /**********************************************************************/
1800
1801   Standard_Integer nb = 1,nbface;
1802   TopoDS_Edge E1 ,E2, Edge[nn],E,Ei,edgesau;
1803   TopoDS_Face  facesau;
1804   Standard_Boolean oneintersection1=Standard_False;
1805   Standard_Boolean oneintersection2=Standard_False;
1806   TopoDS_Face Face[nn],F,F3;
1807   TopoDS_Vertex V1,V2,V,Vfin;
1808   Standard_Boolean  findonf1=Standard_False,findonf2=Standard_False;
1809   TopTools_ListIteratorOfListOfShape It3;
1810   F1=TopoDS::Face(DStr.Shape(Fd->IndexOfS1()));
1811   F2=TopoDS::Face(DStr.Shape(Fd->IndexOfS2()));
1812   F3=F1;
1813   if (couture || bordlibre) nface=nface+1;
1814   if (nface==3) nbface=2;
1815   else nbface=nface-2;
1816   if (!CV1.IsOnArc()||!CV2.IsOnArc()) {
1817     PerformMoreThreeCorner(Index,1);
1818     return;
1819   }
1820
1821   Edge[0]=CV1.Arc();
1822   Edge[nbface]=CV2.Arc();
1823   tabedg.SetValue(0,Edge[0]);
1824   tabedg.SetValue(nbface,Edge[nbface]);
1825   // processing of a fillet arriving on a vertex
1826   // edge contained in CV.Arc is not inevitably good
1827   // the edge concerned by the intersection is found
1828
1829   Standard_Real dist1,dist2;
1830   if (CV1.IsVertex()) {
1831     trouve=Standard_False;
1832     /*TopoDS_Vertex */V=CV1.Vertex();
1833     for (It3.Initialize(myVEMap(V));It3.More()&&!trouve;It3.Next()) {
1834       E=TopoDS::Edge (It3.Value());
1835       if (!E.IsSame(Edge[0])&&(containE(F1,E)))
1836         trouve=Standard_True;
1837     }
1838     TopoDS_Vertex Vt,V3,V4;
1839     V1=TopExp::FirstVertex(Edge[0]);
1840     V2=TopExp::LastVertex(Edge[0]);
1841     if (V.IsSame(V1)) Vt=V2;
1842     else Vt=V1;
1843     dist1=(BRep_Tool::Pnt(Vt)).Distance(BRep_Tool::Pnt(Vtx));
1844     V3=TopExp::FirstVertex(E);
1845     V4=TopExp::LastVertex(E);
1846     if (V.IsSame(V3)) Vt=V4;
1847     else Vt=V3;
1848     dist2=(BRep_Tool::Pnt(Vt)).Distance(BRep_Tool::Pnt(Vtx));
1849     if (dist2<dist1) {
1850       Edge[0]=E;
1851       TopAbs_Orientation ori;
1852       if (V2.IsSame(V3)||V1.IsSame(V4)) ori=CV1.TransitionOnArc();
1853       else ori=TopAbs::Reverse(CV1.TransitionOnArc());
1854       Standard_Real par= BRep_Tool::Parameter(V,Edge[0]);
1855       Standard_Real tol= CV1.Tolerance();
1856       CV1.SetArc(tol,Edge[0],par,ori);
1857     }
1858   }
1859
1860   if (CV2.IsVertex()) {
1861     trouve=Standard_False;
1862     /*TopoDS_Vertex*/ V=CV2.Vertex();
1863     for (It3.Initialize(myVEMap(V));It3.More()&&!trouve;It3.Next()) {
1864       E=TopoDS::Edge (It3.Value());
1865       if (!E.IsSame(Edge[2])&&(containE(F2,E)))
1866         trouve=Standard_True;
1867     }
1868     TopoDS_Vertex Vt,V3,V4;
1869     V1=TopExp::FirstVertex(Edge[2]);
1870     V2=TopExp::LastVertex(Edge[2]);
1871     if (V.IsSame(V1)) Vt=V2;
1872     else Vt=V1;
1873     dist1=(BRep_Tool::Pnt(Vt)).Distance(BRep_Tool::Pnt(Vtx));
1874     V3=TopExp::FirstVertex(E);
1875     V4=TopExp::LastVertex(E);
1876     if (V.IsSame(V3)) Vt=V4;
1877     else Vt=V3;
1878     dist2=(BRep_Tool::Pnt(Vt)).Distance(BRep_Tool::Pnt(Vtx));
1879     if (dist2<dist1) {
1880       Edge[2]=E;
1881       TopAbs_Orientation ori;
1882       if (V2.IsSame(V3)||V1.IsSame(V4)) ori=CV2.TransitionOnArc();
1883       else ori=TopAbs::Reverse(CV2.TransitionOnArc());
1884       Standard_Real par= BRep_Tool::Parameter(V,Edge[2]);
1885       Standard_Real tol= CV2.Tolerance();
1886       CV2.SetArc(tol,Edge[2],par,ori);
1887     }
1888   }
1889   if (!onecorner) {
1890     // If there is a regular edge, the faces adjacent to it 
1891     // are not in Fd->IndexOfS1 or Fd->IndexOfS2
1892
1893 //     TopoDS_Face Find1 ,Find2;
1894 //     if (isfirst)
1895 //       edge=stripe->Spine()->Edges(1);
1896 //     else  edge=stripe->Spine()->Edges(stripe->Spine()->NbEdges());
1897 //     It3.Initialize(myEFMap(edge));
1898 //     Find1=TopoDS::Face(It3.Value());
1899 //     trouve=Standard_False;
1900 //     for (It3.Initialize(myEFMap(edge));It3.More()&&!trouve;It3.Next()) {
1901 //       F=TopoDS::Face (It3.Value());
1902 //       if (!F.IsSame(Find1)) {
1903 //      Find2=F;trouve=Standard_True;
1904 //       }
1905 //     }
1906
1907     // if nface =3 there is a top with 3 edges and a fillet 
1908     // and their common points are on different faces 
1909     // otherwise there is a case when a top has more than 3 edges
1910
1911     if (nface==3) {
1912       if (CV1.IsVertex ()) findonf1=Standard_True;
1913       if (CV2.IsVertex ()) findonf2=Standard_True;
1914       if (!findonf1) {
1915         TopTools_IndexedMapOfShape  MapV;
1916         TopExp::MapShapes(Edge[0], TopAbs_VERTEX, MapV);
1917         if (MapV.Extent()==2)
1918           if (!MapV(1).IsSame(Vtx) && !MapV(2).IsSame(Vtx))
1919             findonf1=Standard_True;
1920       }
1921       if (!findonf2) {
1922         TopTools_IndexedMapOfShape  MapV;
1923         TopExp::MapShapes(Edge[2], TopAbs_VERTEX, MapV);
1924         if (MapV.Extent()==2)
1925           if (!MapV(1).IsSame(Vtx) && !MapV(2).IsSame(Vtx))
1926             findonf2=Standard_True;
1927       }
1928
1929       // detect and process OnSame situatuation
1930       if (state == ChFiDS_OnSame) {
1931         TopoDS_Edge threeE[3];
1932         ChFi3d_cherche_element(Vtx,EdgeSpine, F1,threeE[0], V2);
1933         ChFi3d_cherche_element(Vtx,EdgeSpine, F2,threeE[1], V2);
1934         threeE[2] = EdgeSpine;
1935         if (ChFi3d_EdgeState(threeE,myEFMap) == ChFiDS_OnSame) {
1936           isOnSame1 = Standard_True;
1937           nb = 1;
1938           Edge[0] = threeE[0];
1939           ChFi3d_cherche_face1(myEFMap(Edge[0]),F1,Face[0]);
1940           if (findonf2)
1941             findonf1 = Standard_True; // not to look for Face[0] again
1942           else
1943             Edge[1]=CV2.Arc();
1944         }
1945         else {
1946           isOnSame2 = Standard_True;
1947         }
1948       }
1949
1950       // findonf1 findonf2 show if F1 and/or F2 are adjacent
1951       // to many faces at end
1952       // the faces at end and intersected edges are found
1953
1954       if (findonf1 && !isOnSame1) {
1955         if (CV1.TransitionOnArc()==TopAbs_FORWARD)
1956           V1=TopExp::FirstVertex(CV1.Arc());
1957         else
1958           V1=TopExp::LastVertex(CV1.Arc());
1959         ChFi3d_cherche_face1(myEFMap(CV1.Arc()),F1,Face[0]);
1960         nb=1;
1961         Ei=Edge[0];
1962         while (!V1.IsSame(Vtx)) {
1963           ChFi3d_cherche_element(V1,Ei,F1,E,V2);
1964           V1=V2; Ei=E;
1965           ChFi3d_cherche_face1(myEFMap(E),F1,Face[nb]);
1966           cherche_edge1(Face[nb-1],Face[nb],Edge[nb]);
1967           nb++;
1968           if (nb>=nn) Standard_Failure::Raise
1969             ("IntersectionAtEnd : the max number of faces reached");
1970         }
1971         if (!findonf2)  Edge[nb]=CV2.Arc();
1972       }
1973       if (findonf2  && !isOnSame2) {
1974         if (!findonf1 )  nb=1;
1975         V1=Vtx;
1976         if (CV2.TransitionOnArc()==TopAbs_FORWARD)
1977           Vfin=TopExp::LastVertex(CV2.Arc());
1978         else
1979           Vfin=TopExp::FirstVertex(CV2.Arc());
1980         if (!findonf1) ChFi3d_cherche_face1(myEFMap(CV1.Arc()),F1,Face[nb-1]);
1981         ChFi3d_cherche_element(V1,EdgeSpine,F2,E,V2);
1982         Ei=E;V1=V2;
1983         while (!V1.IsSame(Vfin)) {
1984           ChFi3d_cherche_element(V1,Ei,F2,E,V2);
1985           Ei=E;
1986           V1=V2;
1987           ChFi3d_cherche_face1(myEFMap(E),F2,Face[nb]);
1988           cherche_edge1(Face[nb-1],Face[nb],Edge[nb]);
1989           nb++;
1990           if (nb>=nn) Standard_Failure::Raise
1991             ("IntersectionAtEnd : the max number of faces reached");
1992         }
1993         Edge[nb]=CV2.Arc();
1994       }
1995       if (isOnSame2) {
1996         cherche_edge1(Face[nb-1],F2,Edge[nb]);
1997         Face[nb] = F2;
1998       }
1999
2000       nbface=nb;
2001     }
2002
2003     else {
2004
2005 //  this is the case when a top has more than three edges
2006 //  the faces and edges concerned are found
2007       Standard_Boolean /*trouve,*/possible1, possible2;
2008       trouve = possible1 = possible2 = Standard_False;
2009       TopExp_Explorer ex;
2010       nb=0;
2011       for (ex.Init(CV1.Arc(),TopAbs_VERTEX);ex.More();ex.Next()) {
2012         if (Vtx.IsSame(ex.Current())) possible1 = Standard_True;
2013       }
2014       for (ex.Init(CV2.Arc(),TopAbs_VERTEX);ex.More();ex.Next()) {
2015         if (Vtx.IsSame(ex.Current())) possible2 = Standard_True;
2016       }
2017       if ((possible1 && possible2) || (!possible1 && !possible2) || (nbarete > 4)) {
2018         while (!trouve) {
2019           nb++;
2020           if (nb!=1) F3=Face[nb-2];
2021           Face[nb-1]=F3;
2022           if (CV1.Arc().IsSame(edgelibre1))
2023             cherche_face(myVFMap(Vtx),edgelibre2,F1,F2,F3,Face[nb-1]);
2024           else if (CV1.Arc().IsSame(edgelibre2))
2025             cherche_face(myVFMap(Vtx),edgelibre1,F1,F2,F3,Face[nb-1]);
2026           else cherche_face(myVFMap(Vtx),Edge[nb-1],F1,F2,F3,Face[nb-1]);
2027           ChFi3d_cherche_edge(Vtx,tabedg,Face[nb-1],Edge[nb],V);
2028           tabedg.SetValue(nb,Edge[nb]);
2029           if (Edge[nb].IsSame(CV2.Arc())) trouve=Standard_True;
2030         }
2031         nbface=nb;
2032       }
2033       else {
2034         IntersectMoreCorner (Index);
2035         return;
2036       }
2037       if (nbarete==4) {
2038         // if two consecutive edges are G1 there is only one face of intersection
2039         Standard_Real ang1=0.0;
2040         TopoDS_Vertex Vcom;
2041         trouve=Standard_False;
2042         ChFi3d_cherche_vertex ( Edge[0],Edge[1],Vcom,trouve);
2043         if (Vcom.IsSame(Vtx)) ang1=ChFi3d_AngleEdge(Vtx,Edge[0],Edge[1]);
2044         if (Abs(ang1-PI)<0.01) {
2045           oneintersection1=Standard_True;
2046           facesau=Face[0];
2047           edgesau=Edge[1];
2048           Face[0]=Face[1];
2049           Edge[1]=Edge[2];
2050           nbface=1;
2051         }
2052
2053         if (!oneintersection1) {
2054           trouve=Standard_False;
2055           ChFi3d_cherche_vertex ( Edge[1],Edge[2],Vcom,trouve);
2056           if (Vcom.IsSame(Vtx)) ang1=ChFi3d_AngleEdge(Vtx,Edge[1],Edge[2]);
2057           if (Abs(ang1-PI)<0.01) {
2058             oneintersection2=Standard_True;
2059             facesau=Face[1];
2060             edgesau=Edge[1];
2061             Edge[1]=Edge[2];
2062             nbface=1;
2063           }
2064         }
2065       }
2066       else if (nbarete==5) {
2067         //pro15368
2068 //  Modified by Sergey KHROMOV - Fri Dec 21 18:07:43 2001 End
2069         Standard_Boolean isTangent0 = isTangentFaces(Edge[0],F1,Face[0]);
2070         Standard_Boolean isTangent1 = isTangentFaces(Edge[1],Face[0],Face[1]);
2071         Standard_Boolean isTangent2 = isTangentFaces(Edge[2],Face[1],Face[2]);
2072         if ((isTangent0 || isTangent2) && isTangent1) {
2073 //         GeomAbs_Shape cont0,cont1,cont2;
2074 //         cont0=BRep_Tool::Continuity(Edge[0],F1,Face[0]);
2075 //         cont1=BRep_Tool::Continuity(Edge[1],Face[0],Face[1]);
2076 //         cont2=BRep_Tool::Continuity(Edge[2],Face[1],Face[2]);
2077 //         if ((cont0!=GeomAbs_C0 || cont2!=GeomAbs_C0) && cont1!=GeomAbs_C0) {
2078 //  Modified by Sergey KHROMOV - Fri Dec 21 18:07:49 2001 Begin
2079           facesau=Face[0];
2080           edgesau=Edge[0];
2081           nbface=1;
2082           Edge[1]=Edge[3];
2083           Face[0]=Face[2];
2084           oneintersection1=Standard_True;
2085         }
2086       }
2087     }
2088   }
2089   else {
2090     nbface=1;
2091     Face[0]=face;
2092     Edge[1]=Edge[2];
2093   }
2094
2095   TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4);
2096   gp_Pnt2d pfil1,pfac1,pfil2,pfac2,pint,pfildeb;
2097   Handle(Geom2d_Curve) Hc1,Hc2;
2098   IntCurveSurface_HInter inters;
2099   Standard_Integer proledge[nn],prolface[nn+1];// last prolface[nn] is for Fd
2100   Standard_Integer shrink[nn];
2101   TopoDS_Face faceprol[nn];
2102   Standard_Integer indcurve[nn],indpoint2=0,indpoint1 = 0;
2103   Handle (TopOpeBRepDS_CurvePointInterference) Interfp1, Interfp2, Interfedge[nn];
2104   Handle (TopOpeBRepDS_SurfaceCurveInterference) Interfc,InterfPC[nn],InterfPS[nn];
2105   Standard_Real u2,v2,p1,p2,paredge1;
2106   Standard_Real  paredge2 = 0.,tolex = 1.e-4;
2107   Standard_Boolean extend=Standard_False;
2108   Handle(Geom_Surface) Sfacemoins1,Sface;
2109   /***************************************************************************/
2110   // calculate intersection of the fillet and each face
2111   // and storage in the DS
2112   /***************************************************************************/
2113   for (nb=1;nb<=nbface;nb++) {
2114     prolface[nb-1]=0;
2115     proledge[nb-1]=0;
2116     shrink  [nb-1]=0;
2117   }
2118   proledge[nbface]=0;
2119   prolface[nn]=0;
2120   if (oneintersection1||oneintersection2) faceprol[1]=facesau;
2121   if (!isOnSame1 && !isOnSame2)
2122     checkShrink = Standard_False;
2123   // in OnSame situation we need intersect Fd with Edge[0] or Edge[nbface] as well
2124   if (isOnSame1) nb=0;
2125   else           nb=1;
2126   Standard_Boolean intersOnSameFailed = Standard_False;
2127   
2128   for ( ; nb<=nbface; nb++) {
2129     extend=Standard_False;
2130     E2=Edge[nb];
2131     if (!nb)
2132       F=F1;
2133     else {
2134       F=Face[nb-1];
2135       if (!prolface[nb-1]) faceprol[nb-1]=F;
2136     }
2137     Sfacemoins1=BRep_Tool::Surface(F);
2138     Handle(Geom_Curve) cint;
2139     Handle(Geom2d_Curve) C2dint1, C2dint2,cface,cfacemoins1;
2140
2141     ///////////////////////////////////////////////////////
2142     // determine intersections of edges and the fillet
2143     // to find limitations of intersections face - fillet
2144     ///////////////////////////////////////////////////////
2145
2146     if (nb==1) {
2147       Hc1 = BRep_Tool::CurveOnSurface(Edge[0],Face[0],Ubid,Ubid);
2148       if (isOnSame1) {
2149         // update interference param on Fi1 and point of CV1
2150         if (prolface[0]) Bs.Initialize(faceprol[0], Standard_False);
2151         else             Bs.Initialize(Face[0], Standard_False);
2152         const Handle(Geom_Curve)& c3df = DStr.Curve(Fi1.LineIndex()).Curve();
2153         Standard_Real Ufi= Fi2.Parameter(isfirst);
2154         ChFiDS_FaceInterference& Fi = Fd->ChangeInterferenceOnS1();
2155         if (!IntersUpdateOnSame (HGs,HBs,c3df,F1,Face[0],Edge[0],Vtx,isfirst,10*tolesp, // in
2156                                  Fi,CV1,pfac1,Ufi))   // out
2157           Standard_Failure::Raise("IntersectionAtEnd: pb intersection Face - Fi");
2158         Fi1 = Fi;
2159         if (intersOnSameFailed) { // probable at fillet building
2160           // look for paredge2
2161           Geom2dAPI_ProjectPointOnCurve proj;
2162           if (C2dint2.IsNull()) proj.Init(pfac1,Hc1);
2163           else                  proj.Init(pfac1,C2dint2);
2164           paredge2 = proj.LowerDistanceParameter();
2165         }
2166         // update stripe point
2167         TopOpeBRepDS_Point tpoint (CV1.Point(),tolesp);
2168         indpoint1=DStr.AddPoint(tpoint);
2169         stripe->SetIndexPoint(indpoint1,isfirst,1);
2170         // reset arc of CV1
2171         TopoDS_Vertex vert1,vert2;
2172         TopExp::Vertices(Edge[0],vert1,vert2);
2173         TopAbs_Orientation arcOri = Vtx.IsSame(vert1) ? TopAbs_FORWARD : TopAbs_REVERSED;
2174         CV1.SetArc(tolesp,Edge[0],paredge2,arcOri);
2175       }
2176       else {
2177         if (Hc1.IsNull()) {
2178           // curve 2d not found. Sfacemoins1 is extended and projection is done there
2179           // CV1.Point ()
2180           ChFi3d_ExtendSurface(Sfacemoins1,prolface[0]);
2181           if (prolface[0]) {
2182             extend=Standard_True;
2183             BRep_Builder BRE;
2184             Standard_Real tol=BRep_Tool::Tolerance(F);
2185             BRE.MakeFace(faceprol[0],Sfacemoins1,F.Location(),tol);
2186             if (!isOnSame1) {
2187               GeomAdaptor_Surface Asurf;
2188               Asurf.Load(Sfacemoins1);
2189               Extrema_ExtPS ext (CV1.Point(),Asurf, tol,tol);
2190               Standard_Real  uc1,vc1;
2191               if (ext.IsDone()) {
2192                 ext.Point(1).Parameter(uc1,vc1);
2193                 pfac1.SetX(uc1);
2194                 pfac1.SetY(vc1);
2195               }
2196             }
2197           }
2198         }
2199         else
2200           pfac1 = Hc1->Value(CV1.ParameterOnArc());
2201       }
2202       paredge1=CV1.ParameterOnArc();
2203       if (Fi1.LineIndex() != 0) {
2204         pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(isfirst));}
2205       else {
2206         pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst));}
2207       pfildeb=pfil1;
2208     }
2209     else {
2210       pfil1=pfil2;
2211       paredge1=paredge2;
2212       pfac1=pint;
2213     }
2214
2215     if (nb!=nbface || isOnSame2) {
2216       Standard_Integer nbp;
2217
2218       Handle(Geom_Curve) C;
2219       C=BRep_Tool::Curve(E2,Ubid,Vbid);
2220       Handle(Geom_TrimmedCurve) Ctrim = new Geom_TrimmedCurve(C,Ubid,Vbid);
2221       Standard_Real Utrim,Vtrim;
2222       Utrim=Ctrim->BasisCurve()->FirstParameter();
2223       Vtrim=Ctrim->BasisCurve()->LastParameter();
2224       if (Ctrim->IsPeriodic()) {
2225         if (Ubid>Ctrim->Period()) {
2226           Ubid=(Utrim+Vtrim)/2;
2227           Vbid= Vtrim;
2228         }
2229         else {
2230           Ubid=Utrim;
2231           Vbid=(Utrim+Vtrim)/2;
2232         }
2233       }
2234       else {
2235         Ubid=Utrim;
2236         Vbid=Vtrim;
2237       }
2238       Handle(GeomAdaptor_HCurve) HC =
2239         new GeomAdaptor_HCurve(C,Ubid,Vbid);
2240       GeomAdaptor_Curve & Cad =HC->ChangeCurve();
2241       inters.Perform(HC, HGs);
2242       if ( !prolface[nn] && ( !inters.IsDone() || (inters.NbPoints()==0) )) {
2243         // extend surface of conge
2244         Handle(Geom_BSplineSurface) S1=
2245           Handle(Geom_BSplineSurface)::DownCast(DStr.Surface(Fd->Surf()).Surface());
2246         if (!S1.IsNull()) {
2247           Standard_Real length = 0.5 * Max(Fi1Length,Fi2Length);
2248           GeomLib::ExtendSurfByLength(S1,length,1,Standard_False,!isfirst);
2249           prolface[nn] = 1;
2250           if (!stripe->IsInDS(!isfirst)) {
2251             Gs.Load(S1);
2252             inters.Perform(HC, HGs);
2253             if (inters.IsDone()&& inters.NbPoints()!=0) {
2254               Fd->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(S1, DStr.ChangeSurface(Isurf).Tolerance())));
2255               Isurf=Fd->Surf();
2256             }
2257           }
2258         }
2259       }
2260       if (!inters.IsDone() || (inters.NbPoints()==0)) {
2261         Handle(Geom_BSplineCurve) cd=Handle(Geom_BSplineCurve)::DownCast(C);
2262         Handle(Geom_BezierCurve) cd1=Handle(Geom_BezierCurve)::DownCast(C);
2263         if (!cd.IsNull() || !cd1.IsNull() ) {
2264           BRep_Builder BRE;
2265           Sface=BRep_Tool::Surface(Face[nb]);
2266           ChFi3d_ExtendSurface(Sface,prolface[nb]);
2267           Standard_Real tol=BRep_Tool::Tolerance(F);
2268           BRE.MakeFace(faceprol[nb],Sface,Face[nb].Location(),tol);
2269           if (nb && !prolface[nb-1]) {
2270             ChFi3d_ExtendSurface(Sfacemoins1,prolface[nb-1]);
2271             if (prolface[nb-1]) {
2272               tol=BRep_Tool::Tolerance(F);
2273               BRE.MakeFace(faceprol[nb-1],Sfacemoins1,F.Location(),tol);
2274             }
2275           }
2276           else {
2277             Standard_Integer prol = 0;
2278             ChFi3d_ExtendSurface(Sfacemoins1,prol);
2279           }
2280           GeomInt_IntSS InterSS(Sfacemoins1,Sface,1.e-7,1,1,1);
2281           if (InterSS.IsDone()) {
2282             trouve=Standard_False;
2283             for (Standard_Integer i=1; i<=InterSS.NbLines() && !trouve; i++) {
2284               extend=Standard_True;
2285               cint= InterSS.Line(i);
2286               C2dint1= InterSS.LineOnS1(i);
2287               C2dint2= InterSS.LineOnS2(i);
2288               Cad.Load(cint);
2289               inters.Perform(HC, HGs);
2290               trouve=inters.IsDone()&&inters.NbPoints()!=0;
2291               // eap occ293, eval tolex on finally trimmed curves
2292 //               Handle(GeomAdaptor_HSurface) H1=new GeomAdaptor_HSurface(Sfacemoins1);
2293 //               Handle(GeomAdaptor_HSurface) H2=new GeomAdaptor_HSurface(Sface);
2294 //              tolex=ChFi3d_EvalTolReached(H1,C2dint1,H2,C2dint2,cint);
2295               tolex = InterSS.TolReached3d();
2296             }
2297           }
2298         }
2299       }
2300       if (inters.IsDone()) {
2301         nbp = inters.NbPoints();
2302         if (nbp==0) {
2303           if (nb==0 || nb==nbface) 
2304             intersOnSameFailed = Standard_True;
2305           else {
2306             PerformMoreThreeCorner (Index,1);
2307             return;
2308           }
2309         }
2310         else {
2311           gp_Pnt P=BRep_Tool::Pnt(Vtx);
2312           Standard_Real distmin=P.Distance(inters.Point(1).Pnt());
2313           nbp=1;
2314           for (Standard_Integer i=2;i<=inters.NbPoints();i++) {
2315             dist=P.Distance(inters.Point(i).Pnt());
2316             if (dist<distmin) {
2317               distmin=dist;
2318               nbp=i;
2319             }
2320           }
2321           gp_Pnt2d pt2d (inters.Point(nbp).U(),inters.Point(nbp).V());
2322           pfil2=pt2d;
2323           paredge2=inters.Point(nbp).W();
2324           if (!extend) {
2325             cfacemoins1=BRep_Tool::CurveOnSurface(E2,F,u2,v2);
2326             cface=BRep_Tool::CurveOnSurface(E2,Face[nb],u2,v2);
2327             cfacemoins1->D0(paredge2,pfac2);
2328             cface->D0(paredge2,pint);
2329           }
2330           else {
2331             C2dint1->D0(paredge2,pfac2);
2332             C2dint2->D0(paredge2,pint);
2333           }
2334         }
2335       }
2336       else Standard_Failure::Raise("IntersectionAtEnd: pb intersection Face cb");
2337     }
2338     else {
2339       Hc2 = BRep_Tool::CurveOnSurface(E2,Face[nbface-1],Ubid,Ubid);
2340       if (Hc2.IsNull()) {
2341         // curve 2d is not found,  Sfacemoins1 is extended CV2.Point() is projected there
2342
2343         ChFi3d_ExtendSurface(Sfacemoins1,prolface[0]);
2344         if (prolface[0]) {
2345           BRep_Builder BRE;
2346           extend=Standard_True;
2347           Standard_Real tol=BRep_Tool::Tolerance(F);
2348           BRE.MakeFace(faceprol[nb-1],Sfacemoins1,F.Location(),tol);
2349           GeomAdaptor_Surface Asurf;
2350           Asurf.Load(Sfacemoins1);
2351           Extrema_ExtPS ext (CV2.Point(),Asurf,tol,tol);
2352           Standard_Real  uc2,vc2;
2353           if (ext.IsDone()) {
2354             ext.Point(1).Parameter(uc2,vc2);
2355             pfac2.SetX(uc2);
2356             pfac2.SetY(vc2);
2357           }
2358         }
2359       }
2360       else pfac2 = Hc2->Value(CV2.ParameterOnArc());
2361       paredge2=CV2.ParameterOnArc();
2362       if (Fi2.LineIndex() != 0) {
2363         pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(isfirst));
2364       }
2365       else {
2366         pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst));
2367       }
2368     }
2369     if (!nb) continue; // found paredge1 on Edge[0] in OnSame situation on F1
2370
2371     if (nb==nbface && isOnSame2) {
2372       // update interference param on Fi2 and point of CV2
2373       if (prolface[nb-1]) Bs.Initialize(faceprol[nb-1]);
2374       else                Bs.Initialize(Face[nb-1]);
2375       const Handle(Geom_Curve)& c3df = DStr.Curve(Fi2.LineIndex()).Curve();
2376       Standard_Real Ufi= Fi1.Parameter(isfirst);
2377       ChFiDS_FaceInterference& Fi = Fd->ChangeInterferenceOnS2();
2378       if (!IntersUpdateOnSame (HGs,HBs,c3df,F2,F,Edge[nb],Vtx,isfirst,10*tolesp, // in
2379                                Fi,CV2,pfac2,Ufi))   // out
2380         Standard_Failure::Raise("IntersectionAtEnd: pb intersection Face - Fi");
2381       Fi2 = Fi;
2382       if (intersOnSameFailed) { // probable at fillet building
2383         // look for paredge2
2384         Geom2dAPI_ProjectPointOnCurve proj;
2385         if (extend)
2386           proj.Init(pfac2, C2dint2);
2387         else 
2388           proj.Init(pfac2, BRep_Tool::CurveOnSurface (E2,Face[nbface-1],Ubid,Ubid));
2389         paredge2 = proj.LowerDistanceParameter();
2390       }
2391       // update stripe point
2392       TopOpeBRepDS_Point tpoint (CV2.Point(),tolesp);
2393       indpoint2=DStr.AddPoint(tpoint);
2394       stripe->SetIndexPoint(indpoint2,isfirst,2);
2395       // reset arc of CV2
2396       TopoDS_Vertex vert1,vert2;
2397       TopExp::Vertices(Edge[nbface],vert1,vert2);
2398       TopAbs_Orientation arcOri = Vtx.IsSame(vert1) ? TopAbs_FORWARD : TopAbs_REVERSED;
2399       CV2.SetArc(tolesp,Edge[nbface],paredge2,arcOri);
2400     }
2401
2402
2403     if (prolface[nb-1]) Bs.Initialize(faceprol[nb-1]);
2404     else                Bs.Initialize(Face[nb-1]);
2405
2406     // offset of parameters if they are not in the same period
2407
2408     // commented by eap 30 May 2002 occ354
2409     // the following code may cause trimming a wrong part of periodic surface
2410     
2411 //     Standard_Real  deb,xx1,xx2;
2412 //     Standard_Boolean  moins2pi,moins2pi1,moins2pi2;
2413 //     if (DStr.Surface(Fd->Surf()).Surface()->IsUPeriodic()) {
2414 //       deb=pfildeb.X();
2415 //       xx1=pfil1.X();
2416 //       xx2=pfil2.X();
2417 //       moins2pi=Abs(deb)< Abs(Abs(deb)-2*PI);
2418 //       moins2pi1=Abs(xx1)< Abs(Abs(xx1)-2*PI);
2419 //       moins2pi2=Abs(xx2)< Abs(Abs(xx2)-2*PI);
2420 //       if (moins2pi1!=moins2pi2) {
2421 //         if  (moins2pi) {
2422 //           if (!moins2pi1) xx1=xx1-2*PI;
2423 //           if (!moins2pi2) xx2=xx2-2*PI;
2424 //         }
2425 //         else {
2426 //           if (moins2pi1) xx1=xx1+2*PI;
2427 //           if (moins2pi2) xx2=xx2+2*PI;
2428 //         }
2429 //       }
2430 //       pfil1.SetX(xx1);
2431 //       pfil2.SetX(xx2);
2432 //     }
2433 //     if (couture || Sfacemoins1->IsUPeriodic()) {
2434
2435 //       Standard_Real ufmin,ufmax,vfmin,vfmax;
2436 //       BRepTools::UVBounds(Face[nb-1],ufmin,ufmax,vfmin,vfmax);
2437 //       deb=ufmin;
2438 //       xx1=pfac1.X();
2439 //       xx2=pfac2.X();
2440 //       moins2pi=Abs(deb)< Abs(Abs(deb)-2*PI);
2441 //       moins2pi1=Abs(xx1)< Abs(Abs(xx1)-2*PI);
2442 //       moins2pi2=Abs(xx2)< Abs(Abs(xx2)-2*PI);
2443 //       if (moins2pi1!=moins2pi2) {
2444 //         if  (moins2pi) {
2445 //           if (!moins2pi1) xx1=xx1-2*PI;
2446 //           if (!moins2pi2) xx2=xx2-2*PI;
2447 //         }
2448 //         else {
2449 //           if (moins2pi1) xx1=xx1+2*PI;
2450 //           if (moins2pi2) xx2=xx2+2*PI;
2451 //         }
2452 //       }
2453 //       pfac1.SetX(xx1);
2454 //       pfac2.SetX(xx2);
2455 //     }
2456
2457     Pardeb(1)= pfil1.X();Pardeb(2) = pfil1.Y();
2458     Pardeb(3)= pfac1.X();Pardeb(4) = pfac1.Y();
2459     Parfin(1)= pfil2.X();Parfin(2) = pfil2.Y();
2460     Parfin(3)= pfac2.X();Parfin(4) = pfac2.Y();
2461
2462     Standard_Real uu1,uu2,vv1,vv2;
2463     ChFi3d_Boite(pfac1,pfac2,uu1,uu2,vv1,vv2);
2464     ChFi3d_BoundFac(Bs,uu1,uu2,vv1,vv2);
2465
2466
2467     //////////////////////////////////////////////////////////////////////
2468     // calculate intersections face - fillet
2469     //////////////////////////////////////////////////////////////////////
2470
2471     if (!ChFi3d_ComputeCurves(HGs,HBs,Pardeb,Parfin,Cc,
2472                               Ps,Pc,tolesp,tol2d,tolreached,nbface==1)) {
2473       PerformMoreThreeCorner (Index,1);
2474       return;
2475     }
2476     // storage of information in the data structure
2477
2478     // evaluate tolerances
2479     p1=Cc->FirstParameter();
2480     p2=Cc->LastParameter();
2481     Standard_Real to1,to2;
2482     gp_Pnt2d  p2d1,p2d2;
2483     gp_Pnt P1,P2,P3,P4,P5,P6,P7,P8;
2484     HGs->D0(Pardeb(1),Pardeb(2),P1);
2485     HGs->D0(Parfin(1),Parfin(2),P2);
2486     HBs->D0(Pardeb(3),Pardeb(4),P3);
2487     HBs->D0(Parfin(3),Parfin(4),P4);
2488     Pc->D0(p1,p2d1);
2489     Pc->D0(p2,p2d2);
2490     HBs->D0(p2d1.X(),p2d1.Y(),P7);
2491     HBs->D0(p2d2.X(),p2d2.Y(),P8);
2492     Ps->D0(p1,p2d1);
2493     Ps->D0(p2,p2d2);
2494     HGs->D0(p2d1.X(),p2d1.Y(),P5);
2495     HGs->D0(p2d2.X(),p2d2.Y(),P6);
2496     to1 = Max (P1.Distance(P5)+P3.Distance(P7), tolreached);
2497     to2 = Max (P2.Distance(P6)+P4.Distance(P8), tolreached);
2498
2499
2500     //////////////////////////////////////////////////////////////////////
2501     // storage in the DS of the intersection curve
2502     //////////////////////////////////////////////////////////////////////
2503
2504     Standard_Boolean Isvtx1=0;
2505     Standard_Boolean Isvtx2=0;
2506     Standard_Integer indice;
2507
2508     if (nb==1)
2509     {
2510       indpoint1 = stripe->IndexPoint(isfirst,1);
2511       if (!CV1.IsVertex()) {
2512         TopOpeBRepDS_Point& tpt= DStr.ChangePoint(indpoint1);
2513         tpt.Tolerance ( Max (tpt.Tolerance(), to1));
2514       }
2515       else  Isvtx1=1;
2516     }
2517     if (nb==nbface)
2518     {
2519       indpoint2 = stripe->IndexPoint(isfirst,2);
2520       if (!CV2.IsVertex()) {
2521         TopOpeBRepDS_Point& tpt= DStr.ChangePoint(indpoint2);
2522         tpt.Tolerance ( Max (tpt.Tolerance(), to2));
2523       }
2524       else Isvtx2=1;
2525     }
2526     else
2527     {
2528       gp_Pnt point =Cc->Value(Cc->LastParameter());
2529       TopOpeBRepDS_Point tpoint (point,to2);
2530       indpoint2=DStr.AddPoint(tpoint);
2531     }
2532     
2533     if (nb!=1)
2534     {
2535       TopOpeBRepDS_Point& tpt= DStr.ChangePoint(indpoint1);
2536       tpt.Tolerance ( Max (tpt.Tolerance(), to1));
2537     }
2538     TopOpeBRepDS_Curve tcurv3d( Cc,tolreached);
2539     indcurve[nb-1]= DStr.AddCurve(tcurv3d);
2540     Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve[nb-1],
2541                                  indpoint1,Cc->FirstParameter(),Isvtx1);
2542     Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve[nb-1],
2543                                  indpoint2,Cc->LastParameter(),Isvtx2);
2544
2545     DStr.ChangeCurveInterferences(indcurve[nb-1]).Append(Interfp1);
2546     DStr.ChangeCurveInterferences(indcurve[nb-1]).Append(Interfp2);
2547
2548     //////////////////////////////////////////////////////////////////////
2549     // storage for the face
2550     //////////////////////////////////////////////////////////////////////
2551
2552 #ifndef DEB
2553     TopAbs_Orientation ori = TopAbs_FORWARD;
2554 #else
2555     TopAbs_Orientation ori;
2556 #endif
2557     orface=Face[nb-1].Orientation();
2558     if (orface==orsurfdata ) orien = TopAbs::Reverse(orcourbe);
2559     else                     orien = orcourbe ;
2560     // limitation of edges of faces
2561     if (nb==1) {
2562       Standard_Integer Iarc1= DStr.AddShape(Edge[0]);
2563       Interfedge[0]= ChFi3d_FilPointInDS(CV1.TransitionOnArc(),Iarc1,
2564                                          indpoint1,paredge1,Isvtx1);
2565       //DStr.ChangeShapeInterferences(Edge[0]).Append(Interfp1);
2566     }
2567     if (nb==nbface) {
2568       Standard_Integer Iarc2= DStr.AddShape(Edge[nb]);
2569       Interfedge[nb]= ChFi3d_FilPointInDS(CV2.TransitionOnArc() ,Iarc2,
2570                                           indpoint2,paredge2,Isvtx2);
2571       //DStr.ChangeShapeInterferences(Edge[nb]).Append(Interfp2);
2572     }
2573
2574     if (nb!=nbface || oneintersection1 || oneintersection2) {
2575       if (nface==3) {
2576         V1= TopExp::FirstVertex(Edge[nb]);
2577         V2= TopExp::LastVertex(Edge[nb]);
2578         if (containV(F1,V1) || containV(F2,V1))
2579           ori=TopAbs_FORWARD;
2580         else if (containV(F1,V2) || containV(F2,V2))
2581           ori=TopAbs_REVERSED;
2582         else
2583           Standard_Failure::Raise("IntersectionAtEnd : pb orientation");
2584
2585         if (containV(F1,V1) && containV(F1,V2)) {
2586           dist1=(BRep_Tool::Pnt(V1)).Distance(BRep_Tool::Pnt(Vtx));
2587           dist2=(BRep_Tool::Pnt(V2)).Distance(BRep_Tool::Pnt(Vtx));
2588           if (dist1<dist2)  ori=TopAbs_FORWARD;
2589           else              ori=TopAbs_REVERSED;
2590         }
2591         if (containV(F2,V1) && containV(F2,V2)) {
2592           dist1=(BRep_Tool::Pnt(V1)).Distance(BRep_Tool::Pnt(Vtx));
2593           dist2=(BRep_Tool::Pnt(V2)).Distance(BRep_Tool::Pnt(Vtx));
2594           if (dist1<dist2)  ori=TopAbs_FORWARD;
2595           else              ori=TopAbs_REVERSED;
2596         }
2597       }
2598       else {
2599         if (TopExp::FirstVertex(Edge[nb]).IsSame(Vtx))
2600           ori= TopAbs_FORWARD;
2601         else ori=TopAbs_REVERSED;
2602       }
2603       if (!extend && !(oneintersection1 || oneintersection2)) {
2604         Standard_Integer Iarc2= DStr.AddShape(Edge[nb]);
2605         Interfedge[nb]= ChFi3d_FilPointInDS(ori,Iarc2,
2606                                             indpoint2,paredge2);
2607         //  DStr.ChangeShapeInterferences(Edge[nb]).Append(Interfp2);
2608       }
2609       else {
2610         if (!(oneintersection1 || oneintersection2) ) proledge[nb]=Standard_True;
2611         Standard_Integer indp1,indp2,ind;
2612         gp_Pnt pext;
2613         Standard_Real ubid,vbid;
2614         pext=BRep_Tool::Pnt(Vtx);
2615         GeomAdaptor_Curve cad;
2616         Handle(Geom_Curve) csau;
2617         if ( ! (oneintersection1 || oneintersection2)) {
2618           cad.Load(cint);
2619           csau=cint;
2620         }
2621         else {
2622           csau=BRep_Tool::Curve(edgesau,ubid,vbid );
2623           Handle(Geom_BoundedCurve) C1=
2624             Handle(Geom_BoundedCurve)::DownCast(csau);
2625           if (oneintersection1&&extend) {
2626             if (!C1.IsNull()) {
2627               gp_Pnt Pl;
2628               Pl=C1->Value(C1->LastParameter());
2629               //Standard_Boolean sens;
2630               sens=Pl.Distance(pext)<tolpt;
2631               GeomLib::ExtendCurveToPoint(C1,CV1.Point(),1,sens);
2632               csau=C1;
2633             }
2634           }
2635           else if (oneintersection2&&extend) {
2636             if (!C1.IsNull()) {
2637               gp_Pnt Pl;
2638               Pl=C1->Value(C1->LastParameter());
2639               //Standard_Boolean sens;
2640               sens=Pl.Distance(pext)<tolpt;
2641               GeomLib::ExtendCurveToPoint(C1,CV2.Point(),1,sens);
2642               csau=C1;
2643             }
2644           }
2645           cad.Load(csau);
2646         }
2647         Extrema_ExtPC ext(pext,cad,tolpt);
2648         Standard_Real par1, par2, par, ParVtx;
2649         Standard_Boolean vtx1=Standard_False;
2650         Standard_Boolean vtx2=Standard_False;
2651         par1=ext.Point(1).Parameter();
2652         ParVtx = par1;
2653         if (oneintersection1 || oneintersection2 ) {
2654           if (oneintersection2) {
2655             pext=CV2.Point();
2656             ind=indpoint2;
2657           }
2658           else {
2659             pext=CV1.Point();
2660             ind=indpoint1;
2661           }
2662           Extrema_ExtPC ext2(pext,cad,tolpt);
2663           par2=ext2.Point(1).Parameter();
2664         }
2665         else {
2666           par2=paredge2;
2667           ind=indpoint2;
2668         }
2669         if (par1>par2) {
2670           indp1=ind;
2671           indp2=DStr.AddShape(Vtx);
2672           vtx2=Standard_True;
2673           par=par1;
2674           par1=par2;
2675           par2=par;
2676         }
2677         else {
2678           indp1=DStr.AddShape(Vtx);
2679           indp2=ind;
2680           vtx1=Standard_True;
2681         }
2682         Handle(Geom_Curve) Ct=new Geom_TrimmedCurve (csau,par1,par2);
2683         TopAbs_Orientation orient;
2684         Cc->D0(Cc->FirstParameter(),P1);
2685         Cc->D0(Cc->LastParameter(),P2);
2686         Ct->D0(Ct->FirstParameter(),P3);
2687         Ct->D0(Ct->LastParameter(),P4);
2688         if (P2.Distance(P3)<tolpt || P1.Distance(P4)<tolpt) orient=orien;
2689         else orient=TopAbs::Reverse(orien);
2690         if (oneintersection1||oneintersection2) {
2691           indice=DStr.AddShape(Face[0]);
2692           if (extend) {
2693             DStr.SetNewSurface(Face[0],Sfacemoins1);
2694             ComputeCurve2d(Ct,faceprol[0],C2dint1);
2695           }
2696           else
2697           {
2698             TopoDS_Edge aLocalEdge = edgesau;
2699             if (edgesau.Orientation() != orient)
2700               aLocalEdge.Reverse();
2701             C2dint1 = BRep_Tool::CurveOnSurface(aLocalEdge,Face[0],ubid,vbid);
2702           }
2703         }
2704         else {
2705           indice=DStr.AddShape(Face[nb-1]);
2706           DStr.SetNewSurface(Face[nb-1],Sfacemoins1);
2707         }
2708         //// for periodic 3d curves ////
2709         if (cad.IsPeriodic())
2710         {
2711           gp_Pnt2d P2d = BRep_Tool::Parameters( Vtx, Face[0] );
2712           Geom2dAPI_ProjectPointOnCurve Projector( P2d, C2dint1 );
2713           par = Projector.LowerDistanceParameter();
2714           Standard_Real shift = par-ParVtx;
2715           if (Abs(shift) > Precision::Confusion())
2716           {
2717             par1 += shift;
2718             par2 += shift;
2719           }
2720         }
2721         ////////////////////////////////
2722
2723         Ct=new Geom_TrimmedCurve (csau,par1,par2);
2724         if (oneintersection1||oneintersection2) tolex=10*BRep_Tool::Tolerance(edgesau);
2725         if (extend) {
2726           Handle(GeomAdaptor_HSurface) H1, H2;
2727           H1=new GeomAdaptor_HSurface(Sfacemoins1);
2728           if (Sface.IsNull()) 
2729             tolex = Max (tolex, ChFi3d_EvalTolReached(H1,C2dint1,H1,C2dint1,Ct));
2730           else {
2731             H2=new GeomAdaptor_HSurface(Sface);
2732             tolex = Max (tolex, ChFi3d_EvalTolReached(H1,C2dint1,H2,C2dint2,Ct));
2733           }
2734         }
2735         TopOpeBRepDS_Curve tcurv( Ct,tolex);
2736         Standard_Integer indcurv;
2737         indcurv=DStr.AddCurve(tcurv);
2738         Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurv,indp1,par1,vtx1);
2739         Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurv,indp2,par2,vtx2);
2740         DStr.ChangeCurveInterferences(indcurv).Append(Interfp1);
2741         DStr.ChangeCurveInterferences(indcurv).Append(Interfp2);
2742
2743         Interfc=ChFi3d_FilCurveInDS(indcurv,indice ,C2dint1,orient);
2744         DStr.ChangeShapeInterferences(indice).Append(Interfc);
2745         if (oneintersection1||oneintersection2) {
2746           indice=DStr.AddShape(facesau);
2747           if (facesau.Orientation()==Face[0].Orientation())
2748             orient=TopAbs::Reverse(orient);
2749           if (extend) {
2750             ComputeCurve2d(Ct,faceprol[1],C2dint2);
2751
2752           }
2753           else
2754           {
2755             TopoDS_Edge aLocalEdge = edgesau;
2756             if (edgesau.Orientation() != orient)
2757               aLocalEdge.Reverse();
2758             C2dint2 = BRep_Tool::CurveOnSurface(aLocalEdge,facesau,ubid,vbid);
2759             //Reverse for case of edgesau on closed surface (Face[0] is equal to facesau)
2760           }
2761         }
2762         else {
2763           indice=DStr.AddShape(Face[nb]);
2764           DStr.SetNewSurface(Face[nb],Sface);
2765           if (Face[nb].Orientation()==Face[nb-1].Orientation())
2766             orient= TopAbs::Reverse(orient);
2767         }
2768         if (!bordlibre) {
2769           Interfc=ChFi3d_FilCurveInDS(indcurv,indice,C2dint2,orient);
2770           DStr.ChangeShapeInterferences(indice).Append(Interfc);
2771         }
2772       }
2773     }
2774
2775     if (checkShrink &&
2776         IsShrink(Ps,p1,p2,checkShrParam,isUShrink,Precision::Parametric(tolreached)))
2777     {
2778       shrink [nb-1] = 1;
2779       // store section face-chamf curve for previous SurfData
2780       // Suppose Fd and SDprev are parametrized similarly
2781       if (!isShrink) { // first time
2782         const ChFiDS_FaceInterference& Fi = SDprev->InterferenceOnS1();
2783         gp_Pnt2d UV = Fi.PCurveOnSurf()->Value(Fi.Parameter(isfirst));
2784         prevSDParam = isUShrink ? UV.X() : UV.Y();
2785       }
2786       gp_Pnt2d UV1=p2d1,UV2=p2d2;
2787       UV1.SetCoord(isUShrink ? 1 : 2, prevSDParam);
2788       UV2.SetCoord(isUShrink ? 1 : 2, prevSDParam);
2789       Standard_Real aTolreached;
2790       ChFi3d_ComputePCurv(Cc,UV1,UV2,Ps,
2791                           DStr.Surface(SDprev->Surf()).Surface(),
2792                           p1,p2,tolesp,aTolreached);
2793       TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(indcurve[nb-1]);
2794       TCurv.Tolerance(Max(TCurv.Tolerance(),aTolreached));
2795
2796       InterfPS[nb-1]=ChFi3d_FilCurveInDS(indcurve[nb-1],IsurfPrev,Ps,orcourbe);
2797       DStr.ChangeSurfaceInterferences(IsurfPrev).Append(InterfPS[nb-1]);
2798
2799       if (isOnSame2) {
2800         midP2d = p2d2;
2801         midIpoint = indpoint2;
2802       }
2803       else if (!isShrink) {
2804         midP2d = p2d1;
2805         midIpoint = indpoint1;
2806       }
2807       isShrink = Standard_True;
2808     } // end if shrink
2809
2810     
2811     indice=DStr.AddShape(Face[nb-1]);
2812     InterfPC[nb-1]=ChFi3d_FilCurveInDS(indcurve[nb-1],indice ,Pc,orien);
2813     if (!shrink [nb-1])
2814       InterfPS[nb-1]=ChFi3d_FilCurveInDS(indcurve[nb-1],Isurf,Ps,orcourbe);
2815     indpoint1=indpoint2;
2816
2817   } // end loop on faces being intersected with ChFi
2818
2819   
2820   if (isOnSame1) CV1.Reset();
2821   if (isOnSame2) CV2.Reset();
2822
2823   for(nb=1;nb<=nbface;nb++) {
2824     Standard_Integer indice=DStr.AddShape(Face[nb-1]);
2825     DStr.ChangeShapeInterferences(indice).Append(InterfPC[nb-1]);
2826     if (!shrink [nb-1])
2827       DStr.ChangeSurfaceInterferences(Isurf).Append(InterfPS[nb-1]);
2828     if (!proledge[nb-1])
2829       DStr.ChangeShapeInterferences(Edge[nb-1]).Append(Interfedge[nb-1]);
2830   }
2831   DStr.ChangeShapeInterferences(Edge[nbface]).Append(Interfedge[nbface]);
2832
2833   if (!isShrink)
2834     stripe->InDS(isfirst);
2835   else {
2836     // compute curves for !<isfirst> end of <Fd> and <isfirst> end of previous <SurfData>
2837
2838     // for Fd
2839     //Bnd_Box box;
2840     gp_Pnt2d UV, UV1 = midP2d, UV2 = midP2d;
2841     if (isOnSame1) 
2842       UV = UV2 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst));
2843     else 
2844       UV = UV1 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst));
2845     Standard_Real aTolreached;
2846     Handle(Geom_Curve) C3d;
2847     Handle(Geom_Surface) aSurf = DStr.Surface(Fd->Surf()).Surface();
2848     //box.Add(aSurf->Value(UV.X(), UV.Y()));
2849     
2850     ChFi3d_ComputeArete(CV1,UV1,CV2,UV2,aSurf, // in 
2851                         C3d,Ps,p1,p2,tolesp,tol2d,aTolreached,0); // out except tolers
2852
2853     indpoint1 = indpoint2 = midIpoint;
2854     gp_Pnt point;
2855     if (isOnSame1) {
2856       point = C3d->Value(p2);
2857       TopOpeBRepDS_Point tpoint (point,aTolreached);
2858       indpoint2=DStr.AddPoint(tpoint);
2859       UV = Ps->Value(p2);
2860     } else {
2861       point = C3d->Value(p1);
2862       TopOpeBRepDS_Point tpoint (point,aTolreached);
2863       indpoint1=DStr.AddPoint(tpoint);
2864       UV = Ps->Value(p1);
2865     }
2866     //box.Add(point);
2867     //box.Add(aSurf->Value(UV.X(), UV.Y()));
2868     
2869     TopOpeBRepDS_Curve Crv = TopOpeBRepDS_Curve(C3d,aTolreached);
2870     Standard_Integer Icurv = DStr.AddCurve(Crv);
2871     Interfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv,indpoint1,p1, Standard_False);
2872     Interfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv,indpoint2,p2, Standard_False);
2873     Interfc = ChFi3d_FilCurveInDS(Icurv,Isurf,Ps,orcourbe);
2874     DStr.ChangeCurveInterferences(Icurv).Append(Interfp1);
2875     DStr.ChangeCurveInterferences(Icurv).Append(Interfp2);
2876     DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc);
2877
2878     // for SDprev
2879     aSurf = DStr.Surface(SDprev->Surf()).Surface();
2880     UV1.SetCoord(isUShrink ? 1 : 2, prevSDParam);
2881     UV2.SetCoord(isUShrink ? 1 : 2, prevSDParam);
2882     
2883     ChFi3d_ComputePCurv(C3d,UV1,UV2,Pc,aSurf,p1,p2,tolesp,aTolreached);
2884     
2885     Crv.Tolerance(Max(Crv.Tolerance(),aTolreached));
2886     Interfc= ChFi3d_FilCurveInDS (Icurv,IsurfPrev,Pc,TopAbs::Reverse(orcourbe));
2887     DStr.ChangeSurfaceInterferences(IsurfPrev).Append(Interfc);
2888
2889     //UV = isOnSame1 ? UV2 : UV1;
2890     //box.Add(aSurf->Value(UV.X(), UV.Y()));
2891     //UV = Ps->Value(isOnSame1 ? p2 : p1);
2892     //box.Add(aSurf->Value(UV.X(), UV.Y()));
2893     //ChFi3d_SetPointTolerance(DStr,box, isOnSame1 ? indpoint2 : indpoint1);
2894     
2895     // to process properly this case in ChFi3d_FilDS()
2896     stripe->InDS(isfirst, 2);
2897     Fd->ChangeInterference(isOnSame1 ? 2 : 1).SetLineIndex(0);
2898     ChFiDS_CommonPoint& CPprev1 = SDprev->ChangeVertex( isfirst,isOnSame1 ? 2 : 1);
2899     ChFiDS_CommonPoint& CPlast1 = Fd->    ChangeVertex( isfirst,isOnSame1 ? 2 : 1);
2900     ChFiDS_CommonPoint& CPlast2 = Fd->    ChangeVertex(!isfirst,isOnSame1 ? 2 : 1);
2901     if (CPprev1.IsOnArc()) {
2902       CPlast1 = CPprev1;
2903       CPprev1.Reset();
2904       CPprev1.SetPoint(CPlast1.Point());
2905       CPlast2.Reset();
2906       CPlast2.SetPoint(CPlast1.Point());
2907     }
2908
2909     // in shrink case, self intersection is possible at <midIpoint>,
2910     // eval its tolerance intersecting Ps and Pcurve at end.
2911     // Find end curves closest to shrinked part
2912     for (nb=0; nb < nbface; nb++)
2913       if (isOnSame1 ? shrink [nb+1] : !shrink [nb]) break;
2914     Handle(Geom_Curve)   Cend = DStr.Curve(indcurve[nb]).Curve();
2915     Handle(Geom2d_Curve) PCend = InterfPS[nb]->PCurve();
2916     // point near which self intersection may occure
2917     TopOpeBRepDS_Point& Pds = DStr.ChangePoint(midIpoint);
2918     const gp_Pnt& Pvert = Pds.Point();
2919     Standard_Real tol = Pds.Tolerance();
2920
2921     Geom2dAdaptor_Curve PC1(Ps), PC2(PCend);
2922     Geom2dInt_GInter Intersector(PC1,PC2,Precision::PConfusion(),Precision::PConfusion());
2923     if (!Intersector.IsDone()) return;
2924     for (nb=1; nb <= Intersector.NbPoints(); nb++) {
2925       const IntRes2d_IntersectionPoint& ip = Intersector.Point(nb);
2926       gp_Pnt Pint = C3d->Value(ip.ParamOnFirst());
2927       tol = Max(tol, Pvert.Distance(Pint));
2928       Pint = Cend->Value(ip.ParamOnSecond());
2929       tol = Max(tol, Pvert.Distance(Pint));
2930     }
2931     for (nb=1; nb <= Intersector.NbSegments(); nb++) {
2932       const IntRes2d_IntersectionSegment& is = Intersector.Segment(nb);
2933       if (is.HasFirstPoint()) {
2934         const IntRes2d_IntersectionPoint& ip = is.FirstPoint();
2935         gp_Pnt Pint = C3d->Value(ip.ParamOnFirst());
2936         tol = Max(tol, Pvert.Distance(Pint));
2937         Pint = Cend->Value(ip.ParamOnSecond());
2938         tol = Max(tol, Pvert.Distance(Pint));
2939       }
2940       if (is.HasLastPoint()) {
2941         const IntRes2d_IntersectionPoint& ip = is.LastPoint();
2942         gp_Pnt Pint = C3d->Value(ip.ParamOnFirst());
2943         tol = Max(tol, Pvert.Distance(Pint));
2944         Pint = Cend->Value(ip.ParamOnSecond());
2945         tol = Max(tol, Pvert.Distance(Pint));
2946       }
2947     }
2948     Pds.Tolerance(tol);
2949   }
2950 }
2951
2952 //  Modified by Sergey KHROMOV - Thu Apr 11 12:23:40 2002 Begin
2953
2954 //=======================================================================
2955 //function : PerformMoreSurfdata
2956 //purpose  :  determine intersections at end on several surfdata
2957 //=======================================================================
2958 void ChFi3d_Builder::PerformMoreSurfdata(const Standard_Integer Index)
2959 {
2960   TopOpeBRepDS_DataStructure &DStr = myDS->ChangeDS();
2961   const ChFiDS_ListOfStripe  &aLOfStripe = myVDataMap(Index);
2962   Handle(ChFiDS_Stripe)       aStripe;
2963   Handle(ChFiDS_Spine)        aSpine;
2964   Standard_Real               aTol3d = 1.e-4;
2965
2966
2967   if (aLOfStripe.IsEmpty())
2968     return;
2969
2970   aStripe = aLOfStripe.First();
2971   aSpine  = aStripe->Spine();
2972
2973   ChFiDS_SequenceOfSurfData &aSeqSurfData =
2974                                aStripe->ChangeSetOfSurfData()->ChangeSequence();
2975   const TopoDS_Vertex       &aVtx         = myVDataMap.FindKey(Index);
2976   Standard_Integer           aSens        = 0;
2977   Standard_Integer           anInd        =
2978                                ChFi3d_IndexOfSurfData(aVtx,aStripe,aSens);
2979   Standard_Boolean           isFirst      = (aSens == 1);
2980   Standard_Integer           anIndPrev;
2981   Handle(ChFiDS_SurfData)    aSurfData;
2982   ChFiDS_CommonPoint         aCP1;
2983   ChFiDS_CommonPoint         aCP2;
2984
2985   aSurfData = aSeqSurfData.Value(anInd);
2986
2987   aCP1 = aSurfData->Vertex(isFirst,1);
2988   aCP2 = aSurfData->Vertex(isFirst,2);
2989
2990   Handle(Geom_Surface) aSurfPrev;
2991   Handle(Geom_Surface) aSurf;
2992   TopoDS_Face          aFace;
2993   TopoDS_Face          aNeighborFace;
2994
2995   FindFace(aVtx, aCP1, aCP2, aFace);
2996   aSurfPrev = BRep_Tool::Surface(aFace);
2997
2998   if (aSens==1) anIndPrev=anInd+1;
2999   else  anIndPrev=anInd-1;
3000
3001   TopoDS_Edge                        anArc1;
3002   TopoDS_Edge                        anArc2;
3003   TopTools_ListIteratorOfListOfShape anIter(myVEMap(aVtx));
3004   Standard_Boolean                   isFound = Standard_False;
3005
3006   for(; anIter.More() && !isFound; anIter.Next()) {
3007     anArc1 = TopoDS::Edge(anIter.Value());
3008
3009     if (containE(aFace, anArc1))
3010       isFound = Standard_True;
3011   }
3012
3013   isFound = Standard_False;
3014   anIter.Initialize(myVEMap(aVtx));
3015
3016   for(; anIter.More() && !isFound; anIter.Next()) {
3017     anArc2 = TopoDS::Edge(anIter.Value());
3018
3019     if (containE(aFace,anArc2) && !anArc2.IsSame(anArc1))
3020       isFound = Standard_True;
3021   }
3022
3023   // determination of common points aCP1onArc, aCP2onArc and aCP2NotonArc
3024   // aCP1onArc    is the point on arc of index anInd
3025   // aCP2onArc    is the point on arc of index anIndPrev
3026   // aCP2NotonArc is the point of index anIndPrev which is not on arc.
3027
3028   Standard_Boolean   is1stCP1OnArc;
3029   Standard_Boolean   is2ndCP1OnArc;
3030   ChFiDS_CommonPoint aCP1onArc;
3031   ChFiDS_CommonPoint aCP2onArc;
3032   ChFiDS_CommonPoint aCP2NotonArc;
3033
3034   aSurfData = aSeqSurfData.Value(anIndPrev);
3035   aCP1      = aSurfData->Vertex(isFirst,1);
3036   aCP2      = aSurfData->Vertex(isFirst,2);
3037
3038   if (aCP1.IsOnArc() &&
3039       (aCP1.Arc().IsSame(anArc1) || aCP1.Arc().IsSame(anArc2))) {
3040       aCP2onArc     = aCP1;
3041       aCP2NotonArc  = aCP2;
3042       is2ndCP1OnArc = Standard_True;
3043   } else if (aCP2.IsOnArc() &&
3044              (aCP2.Arc().IsSame(anArc1) || aCP2.Arc().IsSame(anArc2))) {
3045       aCP2onArc     = aCP2;
3046       aCP2NotonArc  = aCP1;
3047       is2ndCP1OnArc = Standard_False;
3048   } else
3049     return;
3050
3051   aSurfData = aSeqSurfData.Value(anInd);
3052   aCP1      = aSurfData->Vertex(isFirst,1);
3053   aCP2      = aSurfData->Vertex(isFirst,2);
3054
3055   if (aCP1.Point().Distance(aCP2onArc.Point()) <= aTol3d){
3056     aCP1onArc     = aCP2;
3057     is1stCP1OnArc = Standard_False;
3058   }
3059   else {
3060     aCP1onArc     = aCP1;
3061     is1stCP1OnArc = Standard_True;
3062   }
3063
3064   if (!aCP1onArc.IsOnArc())
3065     return;
3066
3067 // determination of neighbor surface
3068   Standard_Integer indSurface;
3069   if (is1stCP1OnArc)
3070     indSurface = myListStripe.First()->SetOfSurfData()->Value(anInd)->IndexOfS1();
3071   else
3072     indSurface = myListStripe.First()->SetOfSurfData()->Value(anInd)->IndexOfS2();
3073
3074   aNeighborFace = TopoDS::Face(myDS->Shape(indSurface));
3075
3076 // calculation of intersections
3077   Handle(Geom_Curve)   aCracc;
3078   Handle(Geom2d_Curve) aPCurv1;
3079   Standard_Real        aParf;
3080   Standard_Real        aParl;
3081   Standard_Real        aTolReached;
3082
3083   aSurfData = aSeqSurfData.Value(anInd);
3084
3085   if (isFirst)
3086     ChFi3d_ComputeArete(aSurfData->VertexLastOnS1(),
3087                         aSurfData->InterferenceOnS1().PCurveOnSurf()->
3088                         Value(aSurfData->InterferenceOnS1().LastParameter()),
3089                         aSurfData->VertexLastOnS2(),
3090                         aSurfData->InterferenceOnS2().PCurveOnSurf()->
3091                         Value(aSurfData->InterferenceOnS2().LastParameter()),
3092                         DStr.Surface(aSurfData->Surf()).Surface(),aCracc,aPCurv1,
3093                         aParf,aParl,aTol3d,tol2d,aTolReached,0);
3094   else
3095     ChFi3d_ComputeArete(aSurfData->VertexFirstOnS1(),
3096                         aSurfData->InterferenceOnS1().PCurveOnSurf()->
3097                         Value(aSurfData->InterferenceOnS1().FirstParameter()),
3098                         aSurfData->VertexFirstOnS2(),
3099                         aSurfData->InterferenceOnS2().PCurveOnSurf()->
3100                         Value(aSurfData->InterferenceOnS2().FirstParameter()),
3101                         DStr.Surface(aSurfData->Surf()).Surface(),aCracc,aPCurv1,
3102                         aParf,aParl,aTol3d,tol2d,aTolReached,0);
3103
3104 // calculation of the index of the line on anInd.
3105 // aPClineOnSurf is the pcurve on anInd.
3106 // aPClineOnFace is the pcurve on face.
3107   ChFiDS_FaceInterference  aFI;
3108
3109   if (is1stCP1OnArc)
3110     aFI = aSurfData->InterferenceOnS1();
3111   else
3112     aFI = aSurfData->InterferenceOnS2();
3113
3114   Handle(Geom_Curve)   aCline;
3115   Handle(Geom2d_Curve) aPClineOnSurf;
3116   Handle(Geom2d_Curve) aPClineOnFace;
3117   Standard_Integer     indLine;
3118
3119   indLine       = aFI.LineIndex();
3120   aCline        = DStr.Curve(aFI.LineIndex()).Curve();
3121   aPClineOnSurf = aFI.PCurveOnSurf();
3122   aPClineOnFace = aFI.PCurveOnFace();
3123
3124 // intersection between the SurfData number anInd and the Face aFace.
3125 // Obtaining of curves aCint1, aPCint11 and aPCint12.
3126   aSurf = DStr.Surface(aSurfData->Surf()).Surface();
3127
3128   GeomInt_IntSS                anInterSS(aSurfPrev,aSurf,1.e-7,1,1,1);
3129   Handle(Geom_Curve)           aCint1;
3130   Handle(Geom2d_Curve)         aPCint11;
3131   Handle(Geom2d_Curve)         aPCint12;
3132   Handle(GeomAdaptor_HSurface) H1 = new GeomAdaptor_HSurface(aSurfPrev);
3133   Handle(GeomAdaptor_HSurface) H2 = new GeomAdaptor_HSurface(aSurf);
3134   Standard_Real                aTolex1=0.;
3135   Standard_Integer             i;
3136   gp_Pnt                       aPext1;
3137   gp_Pnt                       aPext2;
3138   gp_Pnt                       aPext;
3139   Standard_Boolean             isPextFound;
3140
3141
3142   if (!anInterSS.IsDone())
3143     return;
3144
3145   isFound = Standard_False;
3146
3147   for (i = 1; i <= anInterSS.NbLines() && !isFound; i++) {
3148     aCint1   = anInterSS.Line(i);
3149     aPCint11 = anInterSS.LineOnS1(i);
3150     aPCint12 = anInterSS.LineOnS2(i);
3151     aTolex1  = ChFi3d_EvalTolReached(H1, aPCint11, H2, aPCint12, aCint1);
3152
3153     aCint1->D0(aCint1->FirstParameter(), aPext1);
3154     aCint1->D0(aCint1->LastParameter(),  aPext2);
3155
3156 //  Modified by skv - Mon Jun  7 18:38:57 2004 OCC5898 Begin
3157 //     if (aPext1.Distance(aCP1onArc.Point()) <= aTol3d ||
3158 //      aPext2.Distance(aCP1onArc.Point()))
3159     if (aPext1.Distance(aCP1onArc.Point()) <= aTol3d ||
3160         aPext2.Distance(aCP1onArc.Point()) <= aTol3d)
3161 //  Modified by skv - Mon Jun  7 18:38:58 2004 OCC5898 End
3162       isFound = Standard_True;
3163   }
3164
3165   if (!isFound)
3166     return;
3167
3168   if (aPext1.Distance(aCP2onArc.Point()) > aTol3d &&
3169       aPext1.Distance(aCP1onArc.Point()) > aTol3d) {
3170     aPext       = aPext1;
3171     isPextFound = Standard_True;
3172   } else if (aPext2.Distance(aCP2onArc.Point()) > aTol3d &&
3173              aPext2.Distance(aCP1onArc.Point()) > aTol3d) {
3174     aPext       = aPext2;
3175     isPextFound = Standard_True;
3176   } else {
3177     isPextFound = Standard_False;
3178   }
3179
3180
3181   Standard_Boolean  isDoSecondSection = Standard_False;
3182   Standard_Real     aPar=0.;
3183
3184   if (isPextFound) {
3185     GeomAdaptor_Curve aCad(aCracc);
3186     Extrema_ExtPC     anExt(aPext, aCad, aTol3d);
3187
3188     if (!anExt.IsDone())
3189       return;
3190
3191     isFound = Standard_False;
3192     for (i = 1; i <= anExt.NbExt() && !isFound; i++) {
3193       if (anExt.IsMin(i)) {
3194         gp_Pnt aProjPnt = anExt.Point(i).Value();
3195
3196         if (aPext.Distance(aProjPnt) <= aTol3d) {
3197           aPar              = anExt.Point(i).Parameter();
3198           isDoSecondSection = Standard_True;
3199         }
3200       }
3201     }
3202   }
3203
3204   Handle(Geom_Curve) aTrCracc;
3205   TopAbs_Orientation anOrSD1;
3206   TopAbs_Orientation anOrSD2;
3207   Standard_Integer   indShape;
3208
3209   anOrSD1   = aSurfData->Orientation();
3210   aSurfData = aSeqSurfData.Value(anIndPrev);
3211   anOrSD2   = aSurfData->Orientation();
3212   aSurf     = DStr.Surface(aSurfData->Surf()).Surface();
3213
3214 // The following variables will be used if isDoSecondSection is true
3215   Handle(Geom_Curve)           aCint2;
3216   Handle(Geom2d_Curve)         aPCint21;
3217   Handle(Geom2d_Curve)         aPCint22;
3218   Standard_Real                aTolex2=0.;
3219
3220   if (isDoSecondSection) {
3221     Standard_Real aPar1;
3222
3223     aCracc->D0(aCracc->FirstParameter(), aPext1);
3224
3225     if (aPext1.Distance(aCP2NotonArc.Point()) <= aTol3d)
3226       aPar1 = aCracc->FirstParameter();
3227     else
3228       aPar1 = aCracc->LastParameter();
3229
3230     if (aPar1 < aPar)
3231       aTrCracc = new Geom_TrimmedCurve (aCracc, aPar1, aPar);
3232     else
3233       aTrCracc = new Geom_TrimmedCurve (aCracc, aPar,  aPar1);
3234
3235 // Second section
3236     GeomInt_IntSS anInterSS2(aSurfPrev,aSurf,1.e-7,1,1,1);
3237
3238     if (!anInterSS2.IsDone())
3239       return;
3240
3241     H1 = new GeomAdaptor_HSurface(aSurfPrev);
3242     H2 = new GeomAdaptor_HSurface(aSurf);
3243
3244     isFound = Standard_False;
3245
3246     for (i = 1; i <= anInterSS2.NbLines() && !isFound; i++) {
3247       aCint2   = anInterSS2.Line(i);
3248       aPCint21 = anInterSS2.LineOnS1(i);
3249       aPCint22 = anInterSS2.LineOnS2(i);
3250       aTolex2  = ChFi3d_EvalTolReached(H1, aPCint21, H2, aPCint22, aCint2);
3251
3252       aCint2->D0(aCint2->FirstParameter(), aPext1);
3253       aCint2->D0(aCint2->LastParameter(),  aPext2);
3254
3255       if (aPext1.Distance(aCP2onArc.Point()) <= aTol3d ||
3256           aPext2.Distance(aCP2onArc.Point()) <= aTol3d)
3257         isFound = Standard_True;
3258     }
3259
3260     if (!isFound)
3261       return;
3262
3263   } else {
3264     aTrCracc = new Geom_TrimmedCurve(aCracc,
3265                                      aCracc->FirstParameter(),
3266                                      aCracc->LastParameter());
3267   }
3268
3269 // Storage of the data structure
3270
3271 // calculation of the orientation of line of surfdata number
3272 // anIndPrev which contains aCP2onArc
3273
3274   Handle(Geom2d_Curve) aPCraccS = GeomProjLib::Curve2d(aTrCracc,aSurf);
3275
3276   if (is2ndCP1OnArc) {
3277     aFI      = aSurfData->InterferenceOnS1();
3278     indShape = aSurfData->IndexOfS1();
3279   } else {
3280     aFI      = aSurfData->InterferenceOnS2();
3281     indShape = aSurfData->IndexOfS2();
3282   }
3283
3284   if (indShape <= 0)
3285     return;
3286
3287
3288
3289   TopAbs_Orientation aCurOrient;
3290
3291   aCurOrient = DStr.Shape(indShape).Orientation();
3292   aCurOrient = TopAbs::Compose(aCurOrient, aSurfData->Orientation());
3293   aCurOrient = TopAbs::Compose(TopAbs::Reverse(aFI.Transition()), aCurOrient);
3294
3295
3296 // Filling the data structure
3297   aSurfData   = aSeqSurfData.Value(anInd);
3298
3299   TopOpeBRepDS_Point aPtCP1(aCP1onArc.Point(),aCP1onArc.Tolerance());
3300   Standard_Integer   indCP1onArc = DStr.AddPoint(aPtCP1);
3301   Standard_Integer   indSurf1    = aSurfData->Surf();
3302   Standard_Integer   indArc1     = DStr.AddShape(aCP1onArc.Arc());
3303   Standard_Integer   indSol      = aStripe->SolidIndex();
3304
3305   Handle (TopOpeBRepDS_CurvePointInterference) anInterfp1;
3306   Handle (TopOpeBRepDS_CurvePointInterference) anInterfp2;
3307
3308   anInterfp1= ChFi3d_FilPointInDS(aCP1onArc.TransitionOnArc(), indArc1,
3309                                   indCP1onArc, aCP1onArc.ParameterOnArc());
3310   DStr.ChangeShapeInterferences(aCP1onArc.Arc()).Append(anInterfp1);
3311
3312   TopOpeBRepDS_ListOfInterference &SolidInterfs  =
3313                                    DStr.ChangeShapeInterferences(indSol);
3314   Handle(TopOpeBRepDS_SolidSurfaceInterference) SSI =
3315     new TopOpeBRepDS_SolidSurfaceInterference
3316                                       (TopOpeBRepDS_Transition(anOrSD1),
3317                                        TopOpeBRepDS_SOLID, indSol,
3318                                        TopOpeBRepDS_SURFACE, indSurf1);
3319   SolidInterfs.Append(SSI);
3320
3321 // deletion of Surface Data.
3322   aSeqSurfData.Remove(anInd);
3323
3324   if (!isFirst)
3325     anInd--;
3326
3327   aSurfData = aSeqSurfData.Value(anInd);
3328
3329 // definition of indices of common points in Data Structure
3330
3331   Standard_Integer indCP2onArc;
3332   Standard_Integer indCP2NotonArc;
3333
3334   if (is2ndCP1OnArc) {
3335     aStripe->SetIndexPoint(ChFi3d_IndexPointInDS(aCP2onArc,   DStr),isFirst,1);
3336     aStripe->SetIndexPoint(ChFi3d_IndexPointInDS(aCP2NotonArc,DStr),isFirst,2);
3337
3338     if (isFirst) {
3339       indCP2onArc    = aStripe->IndexFirstPointOnS1();
3340       indCP2NotonArc = aStripe->IndexFirstPointOnS2();
3341     } else {
3342       indCP2onArc    = aStripe->IndexLastPointOnS1();
3343       indCP2NotonArc = aStripe->IndexLastPointOnS2();
3344     }
3345   } else {
3346     aStripe->SetIndexPoint(ChFi3d_IndexPointInDS(aCP2onArc,   DStr),isFirst,2);
3347     aStripe->SetIndexPoint(ChFi3d_IndexPointInDS(aCP2NotonArc,DStr),isFirst,1);
3348
3349     if (isFirst) {
3350       indCP2onArc    = aStripe->IndexFirstPointOnS2();
3351       indCP2NotonArc = aStripe->IndexFirstPointOnS1();
3352     }
3353     else {
3354       indCP2onArc    = aStripe->IndexLastPointOnS2();
3355       indCP2NotonArc = aStripe->IndexLastPointOnS1();
3356     }
3357   }
3358
3359   Standard_Integer indPoint1;
3360   Standard_Integer indPoint2;
3361   gp_Pnt           aPoint1;
3362   gp_Pnt           aPoint2;
3363
3364   if (is2ndCP1OnArc)  {
3365     aFI      = aSurfData->InterferenceOnS1();
3366     indShape = aSurfData->IndexOfS1();
3367   } else {
3368     aFI      = aSurfData->InterferenceOnS2();
3369     indShape = aSurfData->IndexOfS2();
3370   }
3371
3372   gp_Pnt2d                                       aP2d;
3373   Handle (TopOpeBRepDS_SurfaceCurveInterference) anInterfc;
3374   TopAbs_Orientation                             anOrSurf = aCurOrient;
3375   TopAbs_Orientation                             anOrFace = aFace.Orientation();
3376   Standard_Integer                               indaFace = DStr.AddShape(aFace);
3377   Standard_Integer                               indPoint = indCP2onArc;
3378   Standard_Integer                               indCurve;
3379
3380   aFI.PCurveOnFace()->D0(aFI.LastParameter(), aP2d);
3381   Handle(Geom_Surface) Stemp2 =
3382                        BRep_Tool::Surface(TopoDS::Face(DStr.Shape(indShape)));
3383   Stemp2->D0(aP2d.X(), aP2d.Y(), aPoint2);
3384   aFI.PCurveOnFace()->D0(aFI.FirstParameter(), aP2d);
3385   Stemp2->D0(aP2d.X(), aP2d.Y(), aPoint1);
3386
3387   if (isDoSecondSection) {
3388     TopOpeBRepDS_Point tpoint(aPext,  aTolex2);
3389     TopOpeBRepDS_Curve tcint2(aCint2, aTolex2);
3390
3391     indPoint = DStr.AddPoint(tpoint);
3392     indCurve = DStr.AddCurve(tcint2);
3393
3394     aCint2->D0(aCint2->FirstParameter(), aPext1);
3395     aCint2->D0(aCint2->LastParameter(),  aPext2);
3396
3397     if (aPext1.Distance(aPext) <= aTol3d){
3398       indPoint1 = indPoint;
3399       indPoint2 = indCP2onArc;
3400     } else {
3401       indPoint1 = indCP2onArc;
3402       indPoint2 = indPoint;
3403     }
3404
3405 // define the orientation of aCint2
3406     if (aPext1.Distance(aPoint2) > aTol3d && aPext2.Distance(aPoint1) > aTol3d)
3407       anOrSurf = TopAbs::Reverse(anOrSurf);
3408
3409 // ---------------------------------------------------------------
3410 // storage of aCint2
3411     anInterfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD, indCurve,
3412                                      indPoint1, aCint2->FirstParameter());
3413     anInterfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED, indCurve,
3414                                      indPoint2, aCint2->LastParameter());
3415     DStr.ChangeCurveInterferences(indCurve).Append(anInterfp1);
3416     DStr.ChangeCurveInterferences(indCurve).Append(anInterfp2);
3417
3418   // interference of aCint2 on the SurfData number anIndPrev
3419     anInterfc = ChFi3d_FilCurveInDS(indCurve, aSurfData->Surf(),
3420                                     aPCint22, anOrSurf);
3421
3422     DStr.ChangeSurfaceInterferences(aSurfData->Surf()).Append(anInterfc);
3423   // interference of aCint2 on aFace
3424
3425     if (anOrFace == anOrSD2)
3426       anOrFace = TopAbs::Reverse(anOrSurf);
3427     else
3428       anOrFace = anOrSurf;
3429
3430     anInterfc = ChFi3d_FilCurveInDS(indCurve, indaFace, aPCint21, anOrFace);
3431     DStr.ChangeShapeInterferences(indaFace).Append(anInterfc);
3432   }
3433
3434   aTrCracc->D0(aTrCracc->FirstParameter(), aPext1);
3435   aTrCracc->D0(aTrCracc->LastParameter(),  aPext2);
3436   if (aPext1.Distance(aCP2NotonArc.Point()) <= aTol3d){
3437     indPoint1 = indCP2NotonArc;
3438     indPoint2 = indPoint;
3439   } else {
3440     indPoint1 = indPoint;
3441     indPoint2 = indCP2NotonArc;
3442   }
3443
3444 // Define the orientation of aTrCracc
3445   Standard_Boolean isToReverse;
3446   gp_Pnt           aP1;
3447   gp_Pnt           aP2;
3448   gp_Pnt           aP3;
3449   gp_Pnt           aP4;
3450
3451
3452   if (isDoSecondSection) {
3453     aTrCracc->D0(aTrCracc->FirstParameter(), aP1);
3454     aTrCracc->D0(aTrCracc->LastParameter(),  aP2);
3455     aCint2->D0(aCint2->FirstParameter(), aP3);
3456     aCint2->D0(aCint2->LastParameter(),  aP4);
3457     isToReverse = (aP1.Distance(aP4) > aTol3d && aP2.Distance(aP3) > aTol3d);
3458   } else {
3459     isToReverse = (aPext1.Distance(aPoint2) > aTol3d &&
3460                    aPext2.Distance(aPoint1) > aTol3d);
3461   }
3462
3463   if (isToReverse)
3464     anOrSurf = TopAbs::Reverse(anOrSurf);
3465
3466 // ---------------------------------------------------------------
3467 // storage of aTrCracc
3468   TopOpeBRepDS_Curve tct2(aTrCracc, aTolReached);
3469
3470   indCurve = DStr.AddCurve(tct2);
3471   anInterfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,indCurve,
3472                                    indPoint1, aTrCracc->FirstParameter());
3473   anInterfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED,indCurve,
3474                                    indPoint2, aTrCracc->LastParameter());
3475   DStr.ChangeCurveInterferences(indCurve).Append(anInterfp1);
3476   DStr.ChangeCurveInterferences(indCurve).Append(anInterfp2);
3477
3478   // interference of aTrCracc on the SurfData number anIndPrev
3479
3480   anInterfc = ChFi3d_FilCurveInDS(indCurve,aSurfData->Surf(),aPCraccS, anOrSurf);
3481   DStr.ChangeSurfaceInterferences(aSurfData->Surf()).Append(anInterfc);
3482   aStripe->InDS(isFirst);
3483
3484   // interference of aTrCracc on the SurfData number anInd
3485   if (anOrSD1 == anOrSD2)
3486     anOrSurf = TopAbs::Reverse(anOrSurf);
3487
3488   anInterfc = ChFi3d_FilCurveInDS(indCurve, indSurf1, aPCurv1, anOrSurf);