3ae4c9e21689d74eab05bdc1929b4aee61381df8
[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           anOtherPCurve.Load (aData->InterferenceOnS1().PCurveOnFace(),
977                               aData->InterferenceOnS1().FirstParameter(),
978                               aData->InterferenceOnS1().LastParameter());
979         }
980         else if (IShape == aData->IndexOfS2())
981         {
982           anOtherPCurve.Load (aData->InterferenceOnS2().PCurveOnFace(),
983                               aData->InterferenceOnS2().FirstParameter(),
984                               aData->InterferenceOnS2().LastParameter());
985         }
986         else
987         {
988           // Normal case - no common surface
989           continue;
990         }
991         if (IsEqual(anOtherPCurve.LastParameter(),anOtherPCurve.FirstParameter()))
992           // Degenerates
993           continue;
994         anIntersector.Perform (aCorkPCurve, anOtherPCurve,
995                                tol2d, Precision::PConfusion());
996         if (anIntersector.NbSegments() > 0 ||
997             anIntersector.NbPoints() > 0)
998           StdFail_NotDone::Raise ("OneCorner : fillets have too big radiuses");
999       }
1000     }
1001     TopOpeBRepDS_ListIteratorOfListOfInterference
1002       anIter(DStr.ChangeShapeInterferences(IShape));
1003     for (; anIter.More(); anIter.Next())
1004     {
1005       Handle(TopOpeBRepDS_SurfaceCurveInterference) anOtherIntrf =
1006         Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(anIter.Value());
1007       // We need only interferences between cork face and curves
1008       // of intersection with another fillet surfaces
1009       if (anOtherIntrf.IsNull())
1010         continue;
1011       // Look if there is an intersection between pcurves
1012       Handle(Geom_TrimmedCurve) anOtherCur =
1013         Handle(Geom_TrimmedCurve)::DownCast(DStr.Curve (anOtherIntrf->Geometry()).Curve());
1014       if (anOtherCur.IsNull())
1015         continue;
1016       Geom2dAdaptor_Curve anOtherPCurve (anOtherIntrf->PCurve(),
1017                                          anOtherCur->FirstParameter(),
1018                                          anOtherCur->LastParameter());
1019       anIntersector.Perform (aCorkPCurve, anOtherPCurve,
1020                              tol2d, Precision::PConfusion());
1021       if (anIntersector.NbSegments() > 0 ||
1022           anIntersector.NbPoints() > 0)
1023         StdFail_NotDone::Raise ("OneCorner : fillets have too big radiuses");
1024     }
1025     // 31/01/02 akm ^^^
1026     DStr.ChangeShapeInterferences(IShape).Append(Interfc);
1027     //// modified by jgv, 26.03.02 for OCC32 ////
1028     ChFiDS_CommonPoint CV [2];
1029     CV[0] = CV1;
1030     CV[1] = CV2;
1031     for (Standard_Integer i = 0; i < 2; i++)
1032     {
1033       if (CV[i].IsOnArc() && ChFi3d_IsPseudoSeam( CV[i].Arc(), Fv ))
1034       {
1035         gp_Pnt2d pfac1, PcF, PcL;
1036         gp_Vec2d DerPc, DerHc;
1037         Standard_Real first, last, prm1, prm2;
1038         Standard_Boolean onfirst, FirstToPar;
1039         Handle(Geom2d_Curve) Hc = BRep_Tool::CurveOnSurface( CV[i].Arc(), Fv, first, last );
1040         pfac1 = Hc->Value( CV[i].ParameterOnArc() );
1041         PcF = Pc->Value( Udeb );
1042         PcL = Pc->Value( Ufin );
1043         onfirst = (pfac1.Distance(PcF) < pfac1.Distance(PcL))? Standard_True : Standard_False;
1044         if (onfirst)
1045           Pc->D1( Udeb, PcF, DerPc );
1046         else
1047         {
1048           Pc->D1( Ufin, PcL, DerPc );
1049           DerPc.Reverse();
1050         }
1051         Hc->D1( CV[i].ParameterOnArc(), pfac1, DerHc );
1052         if (DerHc.Dot(DerPc) > 0.)
1053         {
1054           prm1 = CV[i].ParameterOnArc();
1055           prm2 = last;
1056           FirstToPar = Standard_False;
1057         }
1058         else
1059         {
1060           prm1 = first;
1061           prm2 = CV[i].ParameterOnArc();
1062           FirstToPar = Standard_True;
1063         }
1064         Handle(Geom_Curve) Ct = BRep_Tool::Curve( CV[i].Arc(), first, last );
1065         Ct = new Geom_TrimmedCurve( Ct, prm1, prm2 );
1066         Standard_Real toled = BRep_Tool::Tolerance( CV[i].Arc() );
1067         TopOpeBRepDS_Curve tcurv( Ct, toled );
1068         Handle (TopOpeBRepDS_CurvePointInterference) Interfp1, Interfp2;
1069         Standard_Integer indcurv;
1070         indcurv = DStr.AddCurve( tcurv );
1071         Standard_Integer indpoint = (isfirst)? stripe->IndexFirstPointOnS1() : stripe->IndexLastPointOnS1();
1072         Standard_Integer indvertex = DStr.AddShape(Vtx);
1073         if (FirstToPar)
1074         {
1075           Interfp1 = ChFi3d_FilPointInDS( TopAbs_FORWARD,  indcurv, indvertex, prm1, Standard_True );
1076           Interfp2 = ChFi3d_FilPointInDS( TopAbs_REVERSED, indcurv, indpoint,  prm2, Standard_False );
1077         }
1078         else
1079         {
1080           Interfp1 = ChFi3d_FilPointInDS( TopAbs_FORWARD,  indcurv, indpoint,  prm1, Standard_False );
1081           Interfp2 = ChFi3d_FilPointInDS( TopAbs_REVERSED, indcurv, indvertex, prm2, Standard_True );
1082         }
1083         DStr.ChangeCurveInterferences(indcurv).Append(Interfp1);
1084         DStr.ChangeCurveInterferences(indcurv).Append(Interfp2);
1085         Standard_Integer indface = DStr.AddShape( Fv );
1086         Interfc = ChFi3d_FilCurveInDS( indcurv, indface, Hc, CV[i].Arc().Orientation() );
1087         DStr.ChangeShapeInterferences(indface).Append( Interfc );
1088         TopoDS_Edge aLocalEdge = CV[i].Arc();
1089         aLocalEdge.Reverse();
1090         Handle(Geom2d_Curve) HcR = BRep_Tool::CurveOnSurface( aLocalEdge, Fv, first, last );
1091         Interfc = ChFi3d_FilCurveInDS( indcurv, indface, HcR, aLocalEdge.Orientation() );
1092         DStr.ChangeShapeInterferences(indface).Append( Interfc );
1093         //modify degenerated edge
1094         Standard_Boolean DegenExist = Standard_False;
1095         TopoDS_Edge Edeg;
1096         TopExp_Explorer Explo( Fv, TopAbs_EDGE );
1097         for (; Explo.More(); Explo.Next())
1098         {
1099           const TopoDS_Edge& Ecur = TopoDS::Edge( Explo.Current() );
1100           if (BRep_Tool::Degenerated( Ecur ))
1101           {
1102             TopoDS_Vertex Vf, Vl;
1103             TopExp::Vertices( Ecur, Vf, Vl );
1104             if (Vf.IsSame(Vtx) || Vl.IsSame(Vtx))
1105             {
1106               DegenExist = Standard_True;
1107               Edeg = Ecur;
1108               break;
1109             }
1110           }
1111         }
1112         if (DegenExist)
1113         {
1114           Standard_Real fd, ld;
1115           Handle(Geom2d_Curve) Cd = BRep_Tool::CurveOnSurface( Edeg, Fv, fd, ld );
1116           Handle(Geom2d_TrimmedCurve) tCd = Handle(Geom2d_TrimmedCurve)::DownCast(Cd);
1117           if (! tCd.IsNull())
1118             Cd = tCd->BasisCurve();
1119           gp_Pnt2d P2d = (FirstToPar)? Hc->Value(first) : Hc->Value(last);
1120           Geom2dAPI_ProjectPointOnCurve Projector( P2d, Cd );
1121           Standard_Real par = Projector.LowerDistanceParameter();
1122           Standard_Integer Ideg = DStr.AddShape(Edeg);
1123           TopAbs_Orientation ori = (par < fd)? TopAbs_FORWARD : TopAbs_REVERSED; //if par<fd => par>ld
1124           Interfp1 = ChFi3d_FilPointInDS( ori, Ideg, indvertex, par, Standard_True );
1125           DStr.ChangeShapeInterferences(Ideg).Append(Interfp1);
1126         }
1127       }
1128     }
1129     /////////////////////////////////////////////
1130     stripe->ChangePCurve(isfirst)=Ps;
1131     stripe->SetCurve(ICurve,isfirst);
1132     stripe->SetParameters(isfirst,Udeb,Ufin);
1133   }
1134   else {
1135 // curves curv1 are curv2 stored in the DS
1136 // these curves will not be reconstructed by FILDS as
1137 // one places stripe->InDS(isfirst);
1138
1139     // interferences of curv1 and curv2 on Fv
1140     ComputeCurve2d(curv1,Fv,c2d1);
1141     Handle(TopOpeBRepDS_SurfaceCurveInterference) InterFv;
1142     InterFv = ChFi3d_FilCurveInDS(Icurv1,IShape,c2d1,Et);
1143     DStr.ChangeShapeInterferences(IShape).Append(InterFv);
1144     ComputeCurve2d(curv2,Fv,c2d2);
1145     InterFv = ChFi3d_FilCurveInDS(Icurv2,IShape,c2d2,Et);
1146     DStr.ChangeShapeInterferences(IShape).Append(InterFv);
1147      // interferences of curv1 and curv2 on Isurf
1148     if (Fd->Orientation()== Fv.Orientation()) Et=TopAbs::Reverse(Et);
1149     c2d1=new Geom2d_TrimmedCurve(Ps,Udeb,par2);
1150     InterFv = ChFi3d_FilCurveInDS(Icurv1,Isurf,c2d1,Et);
1151     DStr.ChangeSurfaceInterferences(Isurf).Append(InterFv);
1152     c2d2=new Geom2d_TrimmedCurve(Ps,par2,Ufin);
1153        InterFv = ChFi3d_FilCurveInDS(Icurv2,Isurf,c2d2,Et);
1154     DStr.ChangeSurfaceInterferences(Isurf).Append(InterFv);
1155
1156       // limitation of the sewing edge
1157     Standard_Integer Iarc=DStr.AddShape(edgecouture);
1158     Handle(TopOpeBRepDS_CurvePointInterference) Interfedge;
1159     TopAbs_Orientation ori;
1160     TopoDS_Vertex Vdeb,Vfin;
1161     Vdeb=TopExp::FirstVertex(edgecouture);
1162     Vfin=TopExp::LastVertex(edgecouture);
1163     Standard_Real pard,parf;
1164     pard=BRep_Tool::Parameter(Vdeb,edgecouture);
1165     parf=BRep_Tool::Parameter(Vfin,edgecouture);
1166     if (Abs(par1-pard)<Abs(parf-par1)) ori=TopAbs_FORWARD;
1167     else ori=TopAbs_REVERSED;
1168     Interfedge = ChFi3d_FilPointInDS(ori,Iarc,indpt,par1);
1169     DStr.ChangeShapeInterferences(Iarc).Append(Interfedge);
1170
1171     // creation of CurveInterferences from Icurv1 and Icurv2
1172     stripe->InDS(isfirst);
1173     Standard_Integer ind1= stripe->IndexPoint(isfirst,1);
1174     Standard_Integer ind2= stripe->IndexPoint(isfirst,2);
1175     Handle(TopOpeBRepDS_CurvePointInterference)
1176       interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv1,ind1,Udeb);
1177     DStr.ChangeCurveInterferences(Icurv1).Append(interfprol);
1178     interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv1,indpt,par2);
1179     DStr.ChangeCurveInterferences(Icurv1).Append(interfprol);
1180     interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv2,indpt,par2);
1181     DStr.ChangeCurveInterferences(Icurv2).Append(interfprol);
1182     interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv2,ind2,Ufin);
1183     DStr.ChangeCurveInterferences(Icurv2).Append(interfprol);
1184
1185   }
1186
1187   ChFi3d_EnlargeBox(HBs,Pc,Udeb,Ufin,box1,box2);
1188
1189   if (onsame && inters) {
1190     // VARIANT 1:
1191     // A small missing end of curve is added for the extension
1192     // of the face at end and the limitation of the opposing face.
1193
1194     //   VARIANT 2 : extend Arcprol, not create new small edge
1195     //   To do: modify for intcouture
1196     const Standard_Boolean variant1 = Standard_True;
1197
1198     // First of all the ponts are cut with the edge of the spine.
1199     Standard_Integer IArcspine = DStr.AddShape(Arcspine);
1200     Standard_Integer IVtx = DStr.AddShape(Vtx);
1201 #ifndef DEB
1202     TopAbs_Orientation OVtx = TopAbs_FORWARD;
1203 #else
1204     TopAbs_Orientation OVtx;
1205 #endif
1206     for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
1207         ex.More(); ex.Next()) {
1208       if (Vtx.IsSame(ex.Current())) {
1209         OVtx = ex.Current().Orientation();
1210         break;
1211       }
1212     }
1213     OVtx = TopAbs::Reverse(OVtx);
1214     Standard_Real parVtx = BRep_Tool::Parameter(Vtx,Arcspine);
1215     Handle(TopOpeBRepDS_CurvePointInterference)
1216       interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
1217     DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
1218
1219     // Now the missing curves are constructed.
1220     TopoDS_Vertex V2;
1221     for(ex.Init(Arcprol.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
1222         ex.More(); ex.Next()) {
1223       if (Vtx.IsSame(ex.Current()))
1224         OVtx = ex.Current().Orientation();
1225       else
1226         V2 =  TopoDS::Vertex(ex.Current());
1227     }
1228
1229     Handle(Geom2d_Curve) Hc;
1230     if (variant1)
1231       parVtx = BRep_Tool::Parameter(Vtx,Arcprol);
1232     else
1233       parVtx = BRep_Tool::Parameter(V2,Arcprol);
1234     const ChFiDS_FaceInterference& Fiop = Fd->Interference(IFopArc);
1235     gp_Pnt2d pop1, pop2, pv1, pv2;
1236     Hc = BRep_Tool::CurveOnSurface(Arcprol,Fop,Ubid,Ubid);
1237     pop1 = Hc->Value(parVtx);
1238     pop2 = Fiop.PCurveOnFace()->Value(Fiop.Parameter(isfirst));
1239     Hc = BRep_Tool::CurveOnSurface(Arcprol,Fv,Ubid,Ubid);
1240     pv1 = Hc->Value(parVtx);
1241     pv2 = p2dbout;
1242     ChFi3d_Recale(Bs,pv1,pv2,1);
1243     TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4);
1244     Pardeb(1) = pop1.X(); Pardeb(2) = pop1.Y();
1245     Pardeb(3) = pv1.X();  Pardeb(4) = pv1.Y();
1246     Parfin(1) = pop2.X(); Parfin(2) = pop2.Y();
1247     Parfin(3) = pv2.X();  Parfin(4) = pv2.Y();
1248     Standard_Real uu1,uu2,vv1,vv2;
1249     ChFi3d_Boite(pv1,pv2,uu1,uu2,vv1,vv2);
1250     ChFi3d_BoundFac(Bs,uu1,uu2,vv1,vv2);
1251     ChFi3d_Boite(pop1,pop2,uu1,uu2,vv1,vv2);
1252     ChFi3d_BoundFac(Bop,uu1,uu2,vv1,vv2);
1253
1254     Handle(Geom_Curve) zob3d;
1255     Handle(Geom2d_Curve) zob2dop, zob2dv;
1256     //Standard_Real tolreached;
1257     if (!ChFi3d_ComputeCurves(HBop,HBs,Pardeb,Parfin,zob3d,zob2dop,
1258                               zob2dv,tolesp,tol2d,tolreached))
1259       Standard_Failure::Raise("OneCorner : echec calcul intersection");
1260
1261     Udeb = zob3d->FirstParameter();
1262     Ufin = zob3d->LastParameter();
1263     TopOpeBRepDS_Curve Zob(zob3d,tolreached);
1264     Standard_Integer IZob = DStr.AddCurve(Zob);
1265
1266 // it is determined if Fop has an edge of sewing 
1267 // it is determined if the curve has an intersection with the edge of sewing
1268
1269     //TopoDS_Edge edgecouture;
1270     //Standard_Boolean couture;
1271     ChFi3d_Couture(Fop,couture,edgecouture);
1272
1273     if (couture  && !BRep_Tool::Degenerated(edgecouture)) {
1274       BRepLib_MakeEdge Bedge (zob3d);
1275       TopoDS_Edge edg =Bedge. Edge();
1276       BRepExtrema_ExtCC extCC (edgecouture,edg);
1277       if (extCC.IsDone()&&extCC.NbExt()!=0) {
1278         for (Standard_Integer i=1; i<=extCC.NbExt()&&!intcouture;i++) {
1279           if (extCC.SquareDistance(i)<=1.e-8) {
1280             par1=extCC.ParameterOnE1(i);
1281             par2=extCC.ParameterOnE2(i);
1282             gp_Pnt P1=extCC.PointOnE1(i);
1283             TopOpeBRepDS_Point tpoint(P1,1.e-4);
1284             indpt=DStr.AddPoint(tpoint);
1285             intcouture=Standard_True;
1286             curv1 = new Geom_TrimmedCurve(zob3d,Udeb,par2);
1287             curv2 = new Geom_TrimmedCurve(zob3d,par2,Ufin);
1288             TopOpeBRepDS_Curve tcurv1(curv1,tolreached);
1289             TopOpeBRepDS_Curve tcurv2(curv2,tolreached);
1290             Icurv1=DStr.AddCurve(tcurv1);
1291             Icurv2=DStr.AddCurve(tcurv2);
1292           }
1293         }
1294       }
1295     }
1296     if (intcouture) {
1297
1298 // interference of curv1 and curv2 on Ishape
1299       Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolv));
1300       ComputeCurve2d(curv1,Fop,c2d1);
1301       Handle(TopOpeBRepDS_SurfaceCurveInterference)
1302         InterFv = ChFi3d_FilCurveInDS(Icurv1,IShape,/*zob2dv*/c2d1,Et);
1303       DStr.ChangeShapeInterferences(IShape).Append(InterFv);
1304       ComputeCurve2d(curv2,Fop,c2d2);
1305       InterFv = ChFi3d_FilCurveInDS(Icurv2,IShape,/*zob2dv*/c2d2,Et);
1306       DStr.ChangeShapeInterferences(IShape).Append(InterFv);
1307
1308       // limitation of the sewing edge
1309       Standard_Integer Iarc=DStr.AddShape(edgecouture);
1310       Handle(TopOpeBRepDS_CurvePointInterference) Interfedge;
1311       TopAbs_Orientation ori;
1312       TopoDS_Vertex Vdeb,Vfin;
1313       Vdeb=TopExp::FirstVertex(edgecouture);
1314       Vfin=TopExp::LastVertex(edgecouture);
1315       Standard_Real pard,parf;
1316       pard=BRep_Tool::Parameter(Vdeb,edgecouture);
1317       parf=BRep_Tool::Parameter(Vfin,edgecouture);
1318       if (Abs(par1-pard)<Abs(parf-par1)) ori=TopAbs_REVERSED;
1319       else ori=TopAbs_FORWARD;
1320       Interfedge = ChFi3d_FilPointInDS(ori,Iarc,indpt,par1);
1321       DStr.ChangeShapeInterferences(Iarc).Append(Interfedge);
1322
1323     //  interference of curv1 and curv2 on Iop
1324       Standard_Integer Iop = DStr.AddShape(Fop);
1325       Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolop));
1326       Handle(TopOpeBRepDS_SurfaceCurveInterference)  Interfop;
1327       ComputeCurve2d(curv1,Fop,c2d1);
1328       Interfop  = ChFi3d_FilCurveInDS(Icurv1,Iop,c2d1,Et);
1329       DStr.ChangeShapeInterferences(Iop).Append(Interfop);
1330       ComputeCurve2d(curv2,Fop,c2d2);
1331       Interfop  = ChFi3d_FilCurveInDS(Icurv2,Iop,c2d2,Et);
1332       DStr.ChangeShapeInterferences(Iop).Append(Interfop);
1333       Handle(TopOpeBRepDS_CurvePointInterference)
1334         interfprol = ChFi3d_FilVertexInDS(TopAbs_FORWARD,Icurv1,IVtx,Udeb);
1335       DStr.ChangeCurveInterferences(Icurv1).Append(interfprol);
1336       interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv1,indpt,par2);
1337       DStr.ChangeCurveInterferences(Icurv1).Append(interfprol);
1338       Standard_Integer icc = stripe->IndexPoint(isfirst,IFopArc);
1339       interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv2,indpt,par2);
1340       DStr.ChangeCurveInterferences(Icurv2).Append(interfprol);
1341       interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv2,icc,Ufin);
1342       DStr.ChangeCurveInterferences(Icurv2).Append(interfprol);
1343     }
1344     else {
1345       Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolv));
1346       Handle(TopOpeBRepDS_SurfaceCurveInterference)
1347         InterFv = ChFi3d_FilCurveInDS(IZob,IShape,zob2dv,Et);
1348       DStr.ChangeShapeInterferences(IShape).Append(InterFv);
1349       Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolop));
1350       Standard_Integer Iop = DStr.AddShape(Fop);
1351       Handle(TopOpeBRepDS_SurfaceCurveInterference)
1352         Interfop = ChFi3d_FilCurveInDS(IZob,Iop,zob2dop,Et);
1353       DStr.ChangeShapeInterferences(Iop).Append(Interfop);
1354       Handle(TopOpeBRepDS_CurvePointInterference) interfprol;
1355       if (variant1)
1356         interfprol = ChFi3d_FilVertexInDS(TopAbs_FORWARD,IZob,IVtx,Udeb);
1357       else {
1358         Standard_Integer IV2 = DStr.AddShape(V2); // VARIANT 2
1359         interfprol = ChFi3d_FilVertexInDS(TopAbs_FORWARD,IZob,IV2,Udeb);
1360       }
1361       DStr.ChangeCurveInterferences(IZob).Append(interfprol);
1362       Standard_Integer icc = stripe->IndexPoint(isfirst,IFopArc);
1363       interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,IZob,icc,Ufin);
1364       DStr.ChangeCurveInterferences(IZob).Append(interfprol);
1365       if (variant1) {
1366         if (IFopArc == 1) box1.Add( zob3d->Value(Ufin) );
1367         else              box2.Add( zob3d->Value(Ufin) );
1368       }
1369       else {
1370         // cut off existing Arcprol
1371         Standard_Integer iArcprol = DStr.AddShape(Arcprol);
1372         interfprol = ChFi3d_FilPointInDS(OVtx,iArcprol,icc,Udeb);
1373         DStr.ChangeShapeInterferences(Arcprol).Append(interfprol);
1374       }
1375     }
1376   }
1377   ChFi3d_EnlargeBox(DStr,stripe,Fd,box1,box2,isfirst);
1378   if (CV1.IsOnArc()) {
1379     ChFi3d_EnlargeBox(CV1.Arc(),myEFMap(CV1.Arc()),CV1.ParameterOnArc(),box1);
1380   }
1381   if (CV2.IsOnArc()) {
1382     ChFi3d_EnlargeBox(CV2.Arc(),myEFMap(CV2.Arc()),CV2.ParameterOnArc(),box2);
1383   }
1384   if  (!CV1.IsVertex())
1385     ChFi3d_SetPointTolerance(DStr,box1,stripe->IndexPoint(isfirst,1));
1386   if (!CV2.IsVertex())
1387     ChFi3d_SetPointTolerance(DStr,box2,stripe->IndexPoint(isfirst,2));
1388
1389 #ifdef DEB
1390   ChFi3d_ResultChron(ch, t_sameinter);//result perf condition if (same &&inter)
1391 #endif
1392 }
1393
1394 //=======================================================================
1395 //function : cherche_face
1396 //purpose  : find face F belonging to the map, different from faces
1397 //           F1  F2 F3 and containing edge E
1398 //=======================================================================
1399
1400 static void cherche_face (const TopTools_ListOfShape & map,
1401                           const TopoDS_Edge & E,
1402                           const TopoDS_Face & F1,
1403                           const TopoDS_Face & F2,
1404                           const TopoDS_Face & F3,
1405                           TopoDS_Face &  F)
1406 { TopoDS_Face Fcur;
1407   Standard_Boolean trouve=Standard_False;
1408   TopTools_ListIteratorOfListOfShape It;
1409   Standard_Integer ie;
1410   for (It.Initialize(map);It.More()&&!trouve;It.Next())
1411   { Fcur=TopoDS::Face (It.Value());
1412     if (!Fcur.IsSame(F1) && !Fcur.IsSame(F2)&& !Fcur.IsSame(F3) )
1413     { TopTools_IndexedMapOfShape  MapE;
1414       TopExp::MapShapes( Fcur,TopAbs_EDGE,MapE);
1415       for ( ie=1; ie<= MapE.Extent()&&!trouve;  ie++)
1416       {
1417         TopoDS_Shape aLocalShape = TopoDS_Shape (MapE(ie));
1418         if (E.IsSame(TopoDS::Edge(aLocalShape)))
1419           //            if (E.IsSame(TopoDS::Edge(TopoDS_Shape (MapE(ie)))))
1420         { F= Fcur; trouve=Standard_True;}
1421       }
1422     }
1423   }
1424 }
1425
1426 //=======================================================================
1427 //function : cherche_edge1
1428 //purpose  : find common edge between faces F1 and F2
1429 //=======================================================================
1430
1431 static void cherche_edge1 (const TopoDS_Face & F1,
1432                     const TopoDS_Face & F2,
1433                           TopoDS_Edge & Edge)
1434 { Standard_Integer i,j;
1435   TopoDS_Edge Ecur1,Ecur2;
1436   Standard_Boolean trouve=Standard_False;
1437   TopTools_IndexedMapOfShape  MapE1,MapE2;
1438   TopExp::MapShapes( F1,TopAbs_EDGE,MapE1);
1439   TopExp::MapShapes( F2,TopAbs_EDGE,MapE2);
1440   for ( i=1; i<= MapE1.Extent()&&!trouve; i++)
1441       {
1442         TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i));
1443         Ecur1=TopoDS::Edge(aLocalShape);
1444 //      Ecur1=TopoDS::Edge(TopoDS_Shape (MapE1(i)));
1445         for ( j=1; j<= MapE2.Extent()&&!trouve; j++)
1446             {
1447               aLocalShape = TopoDS_Shape (MapE2(j));
1448               Ecur2=TopoDS::Edge(aLocalShape);
1449 //            Ecur2=TopoDS::Edge(TopoDS_Shape (MapE2(j)));
1450             if (Ecur2.IsSame(Ecur1))
1451                {Edge=Ecur1;trouve=Standard_True;}
1452             }
1453       }
1454 }
1455
1456 //=======================================================================
1457 //function : containV
1458 //purpose  : return true if vertex V belongs to F1
1459 //=======================================================================
1460
1461 static Standard_Boolean  containV(const TopoDS_Face & F1,
1462                            const TopoDS_Vertex & V)
1463 { Standard_Integer i;
1464   TopoDS_Vertex Vcur;
1465   Standard_Boolean trouve=Standard_False;
1466   Standard_Boolean contain=Standard_False;
1467   TopTools_IndexedMapOfShape  MapV;
1468   TopExp::MapShapes( F1,TopAbs_VERTEX,MapV);
1469   for ( i=1; i<= MapV.Extent()&&!trouve; i++)
1470       {
1471         TopoDS_Shape aLocalShape = TopoDS_Shape (MapV(i));
1472         Vcur=TopoDS::Vertex(aLocalShape);
1473 //      Vcur=TopoDS::Vertex(TopoDS_Shape (MapV(i)));
1474         if (Vcur.IsSame(V) )
1475             {contain=Standard_True; trouve=Standard_True;}
1476       }
1477   return contain;
1478 }
1479
1480 //=======================================================================
1481 //function : containE
1482 //purpose  : return true if edge E belongs to F1
1483 //=======================================================================
1484
1485 static Standard_Boolean  containE(const TopoDS_Face & F1,
1486                            const TopoDS_Edge & E)
1487 { Standard_Integer i;
1488   TopoDS_Edge Ecur;
1489   Standard_Boolean trouve=Standard_False;
1490   Standard_Boolean contain=Standard_False;
1491   TopTools_IndexedMapOfShape  MapE;
1492   TopExp::MapShapes( F1,TopAbs_EDGE,MapE);
1493   for ( i=1; i<= MapE.Extent()&&!trouve; i++)
1494       {
1495         TopoDS_Shape aLocalShape = TopoDS_Shape (MapE(i));
1496         Ecur=TopoDS::Edge(aLocalShape);
1497 //      Ecur=TopoDS::Edge(TopoDS_Shape (MapE(i)));
1498         if (Ecur.IsSame(E) )
1499             {contain=Standard_True; trouve=Standard_True;}
1500       }
1501   return contain;
1502 }
1503
1504
1505 //=======================================================================
1506 //function : IsShrink
1507 //purpose  : check if U (if <isU>==True) or V of points of <PC> is within
1508 //           <tol> from <Param>, check points between <Pf> and <Pl>
1509 //=======================================================================
1510
1511 static Standard_Boolean IsShrink(const Geom2dAdaptor_Curve PC,
1512                                  const Standard_Real       Pf,
1513                                  const Standard_Real       Pl,
1514                                  const Standard_Real       Param,
1515                                  const Standard_Boolean    isU,
1516                                  const Standard_Real       tol)
1517 {
1518   switch (PC.GetType()) {
1519   case GeomAbs_Line: {
1520     gp_Pnt2d P1 = PC.Value(Pf);
1521     gp_Pnt2d P2 = PC.Value(Pl);
1522     if (Abs(P1.Coord(isU ? 1 : 2) - Param) <= tol &&
1523         Abs(P2.Coord(isU ? 1 : 2) - Param) <= tol )
1524       return Standard_True;
1525     else
1526       return Standard_False;
1527   }
1528   case GeomAbs_BezierCurve:
1529   case GeomAbs_BSplineCurve: {
1530     math_FunctionSample aSample (Pf,Pl,10);
1531     Standard_Integer i;
1532     for (i=1; i<=aSample.NbPoints(); i++) {
1533       gp_Pnt2d P = PC.Value(aSample.GetParameter(i));
1534       if (Abs(P.Coord(isU ? 1 : 2) - Param) > tol )
1535         return Standard_False;
1536     }
1537     return Standard_True;
1538   }
1539   default:;
1540   }
1541   return Standard_False;
1542 }
1543 //=======================================================================
1544 //function : PerformIntersectionAtEnd
1545 //purpose  :
1546 //=======================================================================
1547
1548 void ChFi3d_Builder::PerformIntersectionAtEnd(const Standard_Integer Index)
1549 {
1550
1551   // intersection at end of fillet with at least two faces
1552   // process the following cases:
1553   // - top has n (n>3) adjacent edges
1554   // - top has 3 edges and fillet on one of edges touches
1555   //   more than one face
1556
1557 #ifdef DEB
1558   OSD_Chronometer ch;// init perf
1559 #endif
1560
1561   TopOpeBRepDS_DataStructure& DStr= myDS->ChangeDS();
1562   const Standard_Integer nn=15;
1563   ChFiDS_ListIteratorOfListOfStripe It;
1564   It.Initialize(myVDataMap(Index));
1565   Handle(ChFiDS_Stripe) stripe = It.Value();
1566   const Handle(ChFiDS_Spine) spine = stripe->Spine();
1567   ChFiDS_SequenceOfSurfData& SeqFil =
1568     stripe->ChangeSetOfSurfData()->ChangeSequence();
1569   const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index);
1570   Standard_Integer sens = 0,num,num1;
1571   Standard_Boolean couture=Standard_False,isfirst;
1572   //Standard_Integer sense;
1573   TopoDS_Edge edgelibre1,edgelibre2,EdgeSpine;
1574   Standard_Boolean bordlibre;
1575   // determine the number of faces and edges
1576   TopTools_Array1OfShape tabedg(0,nn);
1577   TopoDS_Face F1,F2;
1578   Standard_Integer nface=ChFi3d_nbface(myVFMap(Vtx));
1579   TopTools_ListIteratorOfListOfShape ItF;
1580   Standard_Integer nbarete;
1581   nbarete=ChFi3d_NbNotDegeneratedEdges(Vtx,myVEMap);
1582   ChFi3d_ChercheBordsLibres(myVEMap,Vtx,bordlibre,edgelibre1,edgelibre2);
1583   if (bordlibre) nbarete=(nbarete-2)/2 +2;
1584   else           nbarete=nbarete/2;
1585   // it is determined if there is an edge of sewing and it face
1586
1587   TopoDS_Face facecouture;
1588   TopoDS_Edge edgecouture;
1589
1590   Standard_Boolean trouve=Standard_False;
1591   for(ItF.Initialize(myVFMap(Vtx));ItF.More()&&!couture;ItF.Next()) {
1592     TopoDS_Face fcur = TopoDS::Face(ItF.Value());
1593     ChFi3d_CoutureOnVertex(fcur,Vtx,couture,edgecouture);
1594     if (couture)
1595       facecouture=fcur;
1596   }
1597   // it is determined if one of edges adjacent to the fillet is regular
1598   Standard_Boolean reg1,reg2;
1599   TopoDS_Edge Ecur,Eadj1,Eadj2;
1600   TopoDS_Face Fga,Fdr;
1601   TopoDS_Vertex Vbid1;
1602   Standard_Integer nbsurf,nbedge;
1603   reg1=Standard_False;
1604   reg2=Standard_False;
1605   nbsurf= SeqFil.Length();
1606   nbedge = spine->NbEdges();
1607   num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens);
1608   isfirst = (sens == 1);
1609   ChFiDS_State state;
1610   if (isfirst) {
1611     EdgeSpine=spine->Edges(1);
1612     num1=num+1;
1613     state = spine->FirstStatus();
1614   }
1615   else {
1616     EdgeSpine=spine->Edges(nbedge);
1617     num1=num-1;
1618     state = spine->LastStatus();
1619   }
1620   if (nbsurf!=nbedge && nbsurf!=1) {
1621     ChFi3d_edge_common_faces(myEFMap(EdgeSpine),F1,F2);
1622     if (F1.IsSame(facecouture)) Eadj1=edgecouture;
1623     else ChFi3d_cherche_element(Vtx,EdgeSpine,F1,Eadj1,Vbid1);
1624     ChFi3d_edge_common_faces(myEFMap(Eadj1),Fga,Fdr);
1625 //  Modified by Sergey KHROMOV - Fri Dec 21 17:57:32 2001 Begin
1626 //  reg1=BRep_Tool::Continuity(Eadj1,Fga,Fdr)!=GeomAbs_C0;
1627     reg1=isTangentFaces(Eadj1,Fga,Fdr);
1628 //  Modified by Sergey KHROMOV - Fri Dec 21 17:57:33 2001 End
1629     if (F2.IsSame(facecouture)) Eadj2=edgecouture;
1630     else ChFi3d_cherche_element(Vtx,EdgeSpine,F2,Eadj2,Vbid1);
1631     ChFi3d_edge_common_faces(myEFMap(Eadj2),Fga,Fdr);
1632 //  Modified by Sergey KHROMOV - Fri Dec 21 17:58:22 2001 Begin
1633 //  reg2=BRep_Tool::Continuity(Eadj2,Fga,Fdr)!=GeomAbs_C0;
1634     reg2=isTangentFaces(Eadj2,Fga,Fdr);
1635 //  Modified by Sergey KHROMOV - Fri Dec 21 17:58:24 2001 End
1636
1637 // two faces common to the edge are found
1638     if (reg1 || reg2) {
1639       Standard_Boolean compoint1=Standard_False;
1640       Standard_Boolean compoint2=Standard_False;
1641       ChFiDS_CommonPoint cp1, cp2;
1642       cp1 = SeqFil(num1)->ChangeVertex (isfirst,1);
1643       cp2 = SeqFil(num1)->ChangeVertex (isfirst,2);
1644       if (cp1.IsOnArc()) {
1645         if (cp1.Arc().IsSame(Eadj1)||cp1.Arc().IsSame(Eadj2))
1646           compoint1=Standard_True;
1647       }
1648       if (cp2.IsOnArc()) {
1649         if (cp2.Arc().IsSame(Eadj1)||cp2.Arc().IsSame(Eadj2))
1650           compoint2=Standard_True;
1651       }
1652       if (compoint1 && compoint2) {
1653         SeqFil.Remove(num);
1654         reg1=Standard_False; reg2=Standard_False;
1655       }
1656     }
1657   }
1658 // there is only one face at end if FindFace is true and if the face
1659 // is not the face with sewing edge
1660   TopoDS_Face face;
1661   Handle(ChFiDS_SurfData) Fd = SeqFil.ChangeValue(num);
1662   ChFiDS_CommonPoint& CV1 = Fd->ChangeVertex(isfirst,1);
1663   ChFiDS_CommonPoint& CV2 = Fd->ChangeVertex(isfirst,2);
1664   Standard_Boolean onecorner=Standard_False;
1665   if (FindFace(Vtx,CV1,CV2,face)) {
1666       if (!couture) onecorner =Standard_True;
1667       else if (!face.IsSame(facecouture))
1668             onecorner=Standard_True;
1669     }
1670   if (onecorner) {
1671     if (ChFi3d_Builder::MoreSurfdata(Index)) {
1672       ChFi3d_Builder::PerformMoreSurfdata(Index);
1673       return;
1674     }
1675   }
1676   if (!onecorner && (reg1||reg2) && !couture && state!=ChFiDS_OnSame) {
1677     PerformMoreThreeCorner (Index,1);
1678     return;
1679   }
1680   Handle(GeomAdaptor_HSurface) HGs = ChFi3d_BoundSurf(DStr,Fd,1,2);
1681   ChFiDS_FaceInterference Fi1 = Fd->InterferenceOnS1();
1682   ChFiDS_FaceInterference Fi2 = Fd->InterferenceOnS2();
1683   GeomAdaptor_Surface& Gs = HGs->ChangeSurface();
1684   Handle(BRepAdaptor_HSurface) HBs  = new BRepAdaptor_HSurface();
1685   BRepAdaptor_Surface& Bs  = HBs->ChangeSurface();
1686   Handle(Geom_Curve) Cc;
1687   Handle(Geom2d_Curve) Pc,Ps;
1688   Standard_Real Ubid,Vbid;
1689   TopAbs_Orientation orsurfdata;
1690   orsurfdata=Fd->Orientation();
1691   Standard_Integer IsurfPrev=0, Isurf=Fd->Surf();
1692   Handle(ChFiDS_SurfData) SDprev;
1693   if (num1>0 && num1<=SeqFil.Length()) {
1694     SDprev = SeqFil(num1);
1695     IsurfPrev = SDprev->Surf();
1696   }
1697   // calculate the orientation of curves at end
1698
1699   Standard_Real tolpt=1.e-4;
1700   Standard_Real tolreached;
1701   TopAbs_Orientation orcourbe,orface,orien;
1702
1703   stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV1,DStr),isfirst,1);
1704   stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV2,DStr),isfirst,2);
1705
1706 //  gp_Pnt p3d;
1707 //  gp_Pnt2d p2d;
1708   Standard_Real dist;
1709   Standard_Integer Ishape1=Fd->IndexOfS1();
1710 #ifndef DEB
1711   TopAbs_Orientation trafil1 = TopAbs_FORWARD;
1712 #else
1713   TopAbs_Orientation trafil1;
1714 #endif
1715   if (Ishape1 != 0) {
1716     if (Ishape1 > 0) {
1717       trafil1 = DStr.Shape(Ishape1).Orientation();
1718     }
1719 #ifdef DEB
1720     else {
1721       cout<<"erreur"<<endl;
1722     }
1723 #endif
1724     trafil1 = TopAbs::Compose(trafil1,Fd->Orientation());
1725
1726     trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi1.Transition()),trafil1);
1727   }
1728 #ifdef DEB
1729   else cout<<"erreur"<<endl;
1730 #endif
1731   // eap, Apr 22 2002, occ 293
1732 //   Fi1.PCurveOnFace()->D0(Fi1.LastParameter(),p2d);
1733 //   const Handle(Geom_Surface) Stemp =
1734 //     BRep_Tool::Surface(TopoDS::Face(DStr.Shape(Ishape1)));
1735 //   Stemp ->D0(p2d.X(),p2d.Y(),p3d);
1736 //   dist=p3d.Distance(CV1.Point());
1737 //   if (dist<tolpt) orcourbe=trafil1;
1738 //   else            orcourbe=TopAbs::Reverse(trafil1);
1739   if (!isfirst) orcourbe=trafil1;
1740   else          orcourbe=TopAbs::Reverse(trafil1);
1741
1742   // eap, Apr 22 2002, occ 293
1743   // variables to show OnSame situation
1744   Standard_Boolean isOnSame1, isOnSame2;
1745   // In OnSame situation, the case of degenerated FaceInterference curve
1746   // is probable when a corner cuts the ChFi3d earlier built on OnSame edge.
1747   // In such a case, chamfer face can partially shrink to a line and we need
1748   // to cut off that shrinked part
1749   // If <isOnSame1>, FaceInterference with F2 can be degenerated
1750   Standard_Boolean checkShrink, isShrink, isUShrink;
1751   isShrink = isUShrink = isOnSame1 = isOnSame2 = Standard_False;
1752   Standard_Real checkShrParam=0., prevSDParam=0.;
1753   gp_Pnt2d midP2d;
1754   Standard_Integer midIpoint=0;
1755
1756   // find Fi1,Fi2 lengths used to extend ChFi surface
1757   // and by the way define necessity to check shrink
1758   gp_Pnt2d P2d1=Fi1.PCurveOnSurf()->Value(Fi1.Parameter(isfirst));
1759   gp_Pnt2d P2d2=Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst));
1760   gp_Pnt aP1,aP2;
1761   HGs->D0( P2d1.X(),P2d1.Y(),aP1);
1762   HGs->D0( P2d2.X(),P2d2.Y(),aP2);
1763   Standard_Real Fi1Length=aP1.Distance(aP2);
1764 //  Standard_Real eps = Precision::Confusion();
1765   checkShrink = (Fi1Length <= Precision::Confusion());
1766   
1767   gp_Pnt2d P2d3=Fi2.PCurveOnSurf()->Value(Fi2.Parameter(isfirst));
1768   gp_Pnt2d P2d4=Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst));
1769   HGs->D0( P2d3.X(),P2d3.Y(),aP1);
1770   HGs->D0( P2d4.X(),P2d4.Y(),aP2);
1771   Standard_Real Fi2Length=aP1.Distance(aP2);
1772   checkShrink = checkShrink || (Fi2Length <= Precision::Confusion());
1773
1774   if (checkShrink) {
1775     if (Abs(P2d2.Y()-P2d4.Y()) <= Precision::PConfusion()) {
1776       isUShrink = Standard_False;
1777       checkShrParam = P2d2.Y();
1778     } else if (Abs(P2d2.X()-P2d4.X()) <= Precision::PConfusion()) {
1779       isUShrink = Standard_True;
1780       checkShrParam = P2d2.X();
1781     }
1782     else
1783       checkShrink = Standard_False;
1784   }
1785
1786   /***********************************************************************/
1787   //  find faces intersecting with the fillet and edges limiting intersections
1788   //  nbface is the nb of faces intersected, Face[i] contais the faces
1789   // to intersect (i=0.. nbface-1). Edge[i] contains edges limiting
1790   // the intersections (i=0 ..nbface)
1791   /**********************************************************************/
1792
1793   Standard_Integer nb = 1,nbface;
1794   TopoDS_Edge E1 ,E2, Edge[nn],E,Ei,edgesau;
1795   TopoDS_Face  facesau;
1796   Standard_Boolean oneintersection1=Standard_False;
1797   Standard_Boolean oneintersection2=Standard_False;
1798   TopoDS_Face Face[nn],F,F3;
1799   TopoDS_Vertex V1,V2,V,Vfin;
1800   Standard_Boolean  findonf1=Standard_False,findonf2=Standard_False;
1801   TopTools_ListIteratorOfListOfShape It3;
1802   F1=TopoDS::Face(DStr.Shape(Fd->IndexOfS1()));
1803   F2=TopoDS::Face(DStr.Shape(Fd->IndexOfS2()));
1804   F3=F1;
1805   if (couture || bordlibre) nface=nface+1;
1806   if (nface==3) nbface=2;
1807   else nbface=nface-2;
1808   if (!CV1.IsOnArc()||!CV2.IsOnArc()) {
1809     PerformMoreThreeCorner(Index,1);
1810     return;
1811   }
1812
1813   Edge[0]=CV1.Arc();
1814   Edge[nbface]=CV2.Arc();
1815   tabedg.SetValue(0,Edge[0]);
1816   tabedg.SetValue(nbface,Edge[nbface]);
1817   // processing of a fillet arriving on a vertex
1818   // edge contained in CV.Arc is not inevitably good
1819   // the edge concerned by the intersection is found
1820
1821   Standard_Real dist1,dist2;
1822   if (CV1.IsVertex()) {
1823     trouve=Standard_False;
1824     /*TopoDS_Vertex */V=CV1.Vertex();
1825     for (It3.Initialize(myVEMap(V));It3.More()&&!trouve;It3.Next()) {
1826       E=TopoDS::Edge (It3.Value());
1827       if (!E.IsSame(Edge[0])&&(containE(F1,E)))
1828         trouve=Standard_True;
1829     }
1830     TopoDS_Vertex Vt,V3,V4;
1831     V1=TopExp::FirstVertex(Edge[0]);
1832     V2=TopExp::LastVertex(Edge[0]);
1833     if (V.IsSame(V1)) Vt=V2;
1834     else Vt=V1;
1835     dist1=(BRep_Tool::Pnt(Vt)).Distance(BRep_Tool::Pnt(Vtx));
1836     V3=TopExp::FirstVertex(E);
1837     V4=TopExp::LastVertex(E);
1838     if (V.IsSame(V3)) Vt=V4;
1839     else Vt=V3;
1840     dist2=(BRep_Tool::Pnt(Vt)).Distance(BRep_Tool::Pnt(Vtx));
1841     if (dist2<dist1) {
1842       Edge[0]=E;
1843       TopAbs_Orientation ori;
1844       if (V2.IsSame(V3)||V1.IsSame(V4)) ori=CV1.TransitionOnArc();
1845       else ori=TopAbs::Reverse(CV1.TransitionOnArc());
1846       Standard_Real par= BRep_Tool::Parameter(V,Edge[0]);
1847       Standard_Real tol= CV1.Tolerance();
1848       CV1.SetArc(tol,Edge[0],par,ori);
1849     }
1850   }
1851
1852   if (CV2.IsVertex()) {
1853     trouve=Standard_False;
1854     /*TopoDS_Vertex*/ V=CV2.Vertex();
1855     for (It3.Initialize(myVEMap(V));It3.More()&&!trouve;It3.Next()) {
1856       E=TopoDS::Edge (It3.Value());
1857       if (!E.IsSame(Edge[2])&&(containE(F2,E)))
1858         trouve=Standard_True;
1859     }
1860     TopoDS_Vertex Vt,V3,V4;
1861     V1=TopExp::FirstVertex(Edge[2]);
1862     V2=TopExp::LastVertex(Edge[2]);
1863     if (V.IsSame(V1)) Vt=V2;
1864     else Vt=V1;
1865     dist1=(BRep_Tool::Pnt(Vt)).Distance(BRep_Tool::Pnt(Vtx));
1866     V3=TopExp::FirstVertex(E);
1867     V4=TopExp::LastVertex(E);
1868     if (V.IsSame(V3)) Vt=V4;
1869     else Vt=V3;
1870     dist2=(BRep_Tool::Pnt(Vt)).Distance(BRep_Tool::Pnt(Vtx));
1871     if (dist2<dist1) {
1872       Edge[2]=E;
1873       TopAbs_Orientation ori;
1874       if (V2.IsSame(V3)||V1.IsSame(V4)) ori=CV2.TransitionOnArc();
1875       else ori=TopAbs::Reverse(CV2.TransitionOnArc());
1876       Standard_Real par= BRep_Tool::Parameter(V,Edge[2]);
1877       Standard_Real tol= CV2.Tolerance();
1878       CV2.SetArc(tol,Edge[2],par,ori);
1879     }
1880   }
1881   if (!onecorner) {
1882     // If there is a regular edge, the faces adjacent to it 
1883     // are not in Fd->IndexOfS1 or Fd->IndexOfS2
1884
1885 //     TopoDS_Face Find1 ,Find2;
1886 //     if (isfirst)
1887 //       edge=stripe->Spine()->Edges(1);
1888 //     else  edge=stripe->Spine()->Edges(stripe->Spine()->NbEdges());
1889 //     It3.Initialize(myEFMap(edge));
1890 //     Find1=TopoDS::Face(It3.Value());
1891 //     trouve=Standard_False;
1892 //     for (It3.Initialize(myEFMap(edge));It3.More()&&!trouve;It3.Next()) {
1893 //       F=TopoDS::Face (It3.Value());
1894 //       if (!F.IsSame(Find1)) {
1895 //      Find2=F;trouve=Standard_True;
1896 //       }
1897 //     }
1898
1899     // if nface =3 there is a top with 3 edges and a fillet 
1900     // and their common points are on different faces 
1901     // otherwise there is a case when a top has more than 3 edges
1902
1903     if (nface==3) {
1904       if (CV1.IsVertex ()) findonf1=Standard_True;
1905       if (CV2.IsVertex ()) findonf2=Standard_True;
1906       if (!findonf1) {
1907         TopTools_IndexedMapOfShape  MapV;
1908         TopExp::MapShapes(Edge[0], TopAbs_VERTEX, MapV);
1909         if (MapV.Extent()==2)
1910           if (!MapV(1).IsSame(Vtx) && !MapV(2).IsSame(Vtx))
1911             findonf1=Standard_True;
1912       }
1913       if (!findonf2) {
1914         TopTools_IndexedMapOfShape  MapV;
1915         TopExp::MapShapes(Edge[2], TopAbs_VERTEX, MapV);
1916         if (MapV.Extent()==2)
1917           if (!MapV(1).IsSame(Vtx) && !MapV(2).IsSame(Vtx))
1918             findonf2=Standard_True;
1919       }
1920
1921       // detect and process OnSame situatuation
1922       if (state == ChFiDS_OnSame) {
1923         TopoDS_Edge threeE[3];
1924         ChFi3d_cherche_element(Vtx,EdgeSpine, F1,threeE[0], V2);
1925         ChFi3d_cherche_element(Vtx,EdgeSpine, F2,threeE[1], V2);
1926         threeE[2] = EdgeSpine;
1927         if (ChFi3d_EdgeState(threeE,myEFMap) == ChFiDS_OnSame) {
1928           isOnSame1 = Standard_True;
1929           nb = 1;
1930           Edge[0] = threeE[0];
1931           ChFi3d_cherche_face1(myEFMap(Edge[0]),F1,Face[0]);
1932           if (findonf2)
1933             findonf1 = Standard_True; // not to look for Face[0] again
1934           else
1935             Edge[1]=CV2.Arc();
1936         }
1937         else {
1938           isOnSame2 = Standard_True;
1939         }
1940       }
1941
1942       // findonf1 findonf2 show if F1 and/or F2 are adjacent
1943       // to many faces at end
1944       // the faces at end and intersected edges are found
1945
1946       if (findonf1 && !isOnSame1) {
1947         if (CV1.TransitionOnArc()==TopAbs_FORWARD)
1948           V1=TopExp::FirstVertex(CV1.Arc());
1949         else
1950           V1=TopExp::LastVertex(CV1.Arc());
1951         ChFi3d_cherche_face1(myEFMap(CV1.Arc()),F1,Face[0]);
1952         nb=1;
1953         Ei=Edge[0];
1954         while (!V1.IsSame(Vtx)) {
1955           ChFi3d_cherche_element(V1,Ei,F1,E,V2);
1956           V1=V2; Ei=E;
1957           ChFi3d_cherche_face1(myEFMap(E),F1,Face[nb]);
1958           cherche_edge1(Face[nb-1],Face[nb],Edge[nb]);
1959           nb++;
1960           if (nb>=nn) Standard_Failure::Raise
1961             ("IntersectionAtEnd : the max number of faces reached");
1962         }
1963         if (!findonf2)  Edge[nb]=CV2.Arc();
1964       }
1965       if (findonf2  && !isOnSame2) {
1966         if (!findonf1 )  nb=1;
1967         V1=Vtx;
1968         if (CV2.TransitionOnArc()==TopAbs_FORWARD)
1969           Vfin=TopExp::LastVertex(CV2.Arc());
1970         else
1971           Vfin=TopExp::FirstVertex(CV2.Arc());
1972         if (!findonf1) ChFi3d_cherche_face1(myEFMap(CV1.Arc()),F1,Face[nb-1]);
1973         ChFi3d_cherche_element(V1,EdgeSpine,F2,E,V2);
1974         Ei=E;V1=V2;
1975         while (!V1.IsSame(Vfin)) {
1976           ChFi3d_cherche_element(V1,Ei,F2,E,V2);
1977           Ei=E;
1978           V1=V2;
1979           ChFi3d_cherche_face1(myEFMap(E),F2,Face[nb]);
1980           cherche_edge1(Face[nb-1],Face[nb],Edge[nb]);
1981           nb++;
1982           if (nb>=nn) Standard_Failure::Raise
1983             ("IntersectionAtEnd : the max number of faces reached");
1984         }
1985         Edge[nb]=CV2.Arc();
1986       }
1987       if (isOnSame2) {
1988         cherche_edge1(Face[nb-1],F2,Edge[nb]);
1989         Face[nb] = F2;
1990       }
1991
1992       nbface=nb;
1993     }
1994
1995     else {
1996
1997 //  this is the case when a top has more than three edges
1998 //  the faces and edges concerned are found
1999       Standard_Boolean /*trouve,*/possible1, possible2;
2000       trouve = possible1 = possible2 = Standard_False;
2001       TopExp_Explorer ex;
2002       nb=0;
2003       for (ex.Init(CV1.Arc(),TopAbs_VERTEX);ex.More();ex.Next()) {
2004         if (Vtx.IsSame(ex.Current())) possible1 = Standard_True;
2005       }
2006       for (ex.Init(CV2.Arc(),TopAbs_VERTEX);ex.More();ex.Next()) {
2007         if (Vtx.IsSame(ex.Current())) possible2 = Standard_True;
2008       }
2009       if ((possible1 && possible2) || (!possible1 && !possible2) || (nbarete > 4)) {
2010         while (!trouve) {
2011           nb++;
2012           if (nb!=1) F3=Face[nb-2];
2013           Face[nb-1]=F3;
2014           if (CV1.Arc().IsSame(edgelibre1))
2015             cherche_face(myVFMap(Vtx),edgelibre2,F1,F2,F3,Face[nb-1]);
2016           else if (CV1.Arc().IsSame(edgelibre2))
2017             cherche_face(myVFMap(Vtx),edgelibre1,F1,F2,F3,Face[nb-1]);
2018           else cherche_face(myVFMap(Vtx),Edge[nb-1],F1,F2,F3,Face[nb-1]);
2019           ChFi3d_cherche_edge(Vtx,tabedg,Face[nb-1],Edge[nb],V);
2020           tabedg.SetValue(nb,Edge[nb]);
2021           if (Edge[nb].IsSame(CV2.Arc())) trouve=Standard_True;
2022         }
2023         nbface=nb;
2024       }
2025       else {
2026         IntersectMoreCorner (Index);
2027         return;
2028       }
2029       if (nbarete==4) {
2030         // if two consecutive edges are G1 there is only one face of intersection
2031         Standard_Real ang1=0.0;
2032         TopoDS_Vertex Vcom;
2033         trouve=Standard_False;
2034         ChFi3d_cherche_vertex ( Edge[0],Edge[1],Vcom,trouve);
2035         if (Vcom.IsSame(Vtx)) ang1=ChFi3d_AngleEdge(Vtx,Edge[0],Edge[1]);
2036         if (Abs(ang1-PI)<0.01) {
2037           oneintersection1=Standard_True;
2038           facesau=Face[0];
2039           edgesau=Edge[1];
2040           Face[0]=Face[1];
2041           Edge[1]=Edge[2];
2042           nbface=1;
2043         }
2044
2045         if (!oneintersection1) {
2046           trouve=Standard_False;
2047           ChFi3d_cherche_vertex ( Edge[1],Edge[2],Vcom,trouve);
2048           if (Vcom.IsSame(Vtx)) ang1=ChFi3d_AngleEdge(Vtx,Edge[1],Edge[2]);
2049           if (Abs(ang1-PI)<0.01) {
2050             oneintersection2=Standard_True;
2051             facesau=Face[1];
2052             edgesau=Edge[1];
2053             Edge[1]=Edge[2];
2054             nbface=1;
2055           }
2056         }
2057       }
2058       else if (nbarete==5) {
2059         //pro15368
2060 //  Modified by Sergey KHROMOV - Fri Dec 21 18:07:43 2001 End
2061         Standard_Boolean isTangent0 = isTangentFaces(Edge[0],F1,Face[0]);
2062         Standard_Boolean isTangent1 = isTangentFaces(Edge[1],Face[0],Face[1]);
2063         Standard_Boolean isTangent2 = isTangentFaces(Edge[2],Face[1],Face[2]);
2064         if ((isTangent0 || isTangent2) && isTangent1) {
2065 //         GeomAbs_Shape cont0,cont1,cont2;
2066 //         cont0=BRep_Tool::Continuity(Edge[0],F1,Face[0]);
2067 //         cont1=BRep_Tool::Continuity(Edge[1],Face[0],Face[1]);
2068 //         cont2=BRep_Tool::Continuity(Edge[2],Face[1],Face[2]);
2069 //         if ((cont0!=GeomAbs_C0 || cont2!=GeomAbs_C0) && cont1!=GeomAbs_C0) {
2070 //  Modified by Sergey KHROMOV - Fri Dec 21 18:07:49 2001 Begin
2071           facesau=Face[0];
2072           edgesau=Edge[0];
2073           nbface=1;
2074           Edge[1]=Edge[3];
2075           Face[0]=Face[2];
2076           oneintersection1=Standard_True;
2077         }
2078       }
2079     }
2080   }
2081   else {
2082     nbface=1;
2083     Face[0]=face;
2084     Edge[1]=Edge[2];
2085   }
2086
2087   TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4);
2088   gp_Pnt2d pfil1,pfac1,pfil2,pfac2,pint,pfildeb;
2089   Handle(Geom2d_Curve) Hc1,Hc2;
2090   IntCurveSurface_HInter inters;
2091   Standard_Integer proledge[nn],prolface[nn+1];// last prolface[nn] is for Fd
2092   Standard_Integer shrink[nn];
2093   TopoDS_Face faceprol[nn];
2094   Standard_Integer indcurve[nn],indpoint2=0,indpoint1 = 0;
2095   Handle (TopOpeBRepDS_CurvePointInterference) Interfp1, Interfp2, Interfedge[nn];
2096   Handle (TopOpeBRepDS_SurfaceCurveInterference) Interfc,InterfPC[nn],InterfPS[nn];
2097   Standard_Real u2,v2,p1,p2,paredge1;
2098   Standard_Real  paredge2 = 0.,tolex = 1.e-4;
2099   Standard_Boolean extend=Standard_False;
2100   Handle(Geom_Surface) Sfacemoins1,Sface;
2101   /***************************************************************************/
2102   // calculate intersection of the fillet and each face
2103   // and storage in the DS
2104   /***************************************************************************/
2105   for (nb=1;nb<=nbface;nb++) {
2106     prolface[nb-1]=0;
2107     proledge[nb-1]=0;
2108     shrink  [nb-1]=0;
2109   }
2110   proledge[nbface]=0;
2111   prolface[nn]=0;
2112   if (oneintersection1||oneintersection2) faceprol[1]=facesau;
2113   if (!isOnSame1 && !isOnSame2)
2114     checkShrink = Standard_False;
2115   // in OnSame situation we need intersect Fd with Edge[0] or Edge[nbface] as well
2116   if (isOnSame1) nb=0;
2117   else           nb=1;
2118   Standard_Boolean intersOnSameFailed = Standard_False;
2119   
2120   for ( ; nb<=nbface; nb++) {
2121     extend=Standard_False;
2122     E2=Edge[nb];
2123     if (!nb)
2124       F=F1;
2125     else {
2126       F=Face[nb-1];
2127       if (!prolface[nb-1]) faceprol[nb-1]=F;
2128     }
2129     Sfacemoins1=BRep_Tool::Surface(F);
2130     Handle(Geom_Curve) cint;
2131     Handle(Geom2d_Curve) C2dint1, C2dint2,cface,cfacemoins1;
2132
2133     ///////////////////////////////////////////////////////
2134     // determine intersections of edges and the fillet
2135     // to find limitations of intersections face - fillet
2136     ///////////////////////////////////////////////////////
2137
2138     if (nb==1) {
2139       Hc1 = BRep_Tool::CurveOnSurface(Edge[0],Face[0],Ubid,Ubid);
2140       if (isOnSame1) {
2141         // update interference param on Fi1 and point of CV1
2142         if (prolface[0]) Bs.Initialize(faceprol[0], Standard_False);
2143         else             Bs.Initialize(Face[0], Standard_False);
2144         const Handle(Geom_Curve)& c3df = DStr.Curve(Fi1.LineIndex()).Curve();
2145         Standard_Real Ufi= Fi2.Parameter(isfirst);
2146         ChFiDS_FaceInterference& Fi = Fd->ChangeInterferenceOnS1();
2147         if (!IntersUpdateOnSame (HGs,HBs,c3df,F1,Face[0],Edge[0],Vtx,isfirst,10*tolesp, // in
2148                                  Fi,CV1,pfac1,Ufi))   // out
2149           Standard_Failure::Raise("IntersectionAtEnd: pb intersection Face - Fi");
2150         Fi1 = Fi;
2151         if (intersOnSameFailed) { // probable at fillet building
2152           // look for paredge2
2153           Geom2dAPI_ProjectPointOnCurve proj;
2154           if (C2dint2.IsNull()) proj.Init(pfac1,Hc1);
2155           else                  proj.Init(pfac1,C2dint2);
2156           paredge2 = proj.LowerDistanceParameter();
2157         }
2158         // update stripe point
2159         TopOpeBRepDS_Point tpoint (CV1.Point(),tolesp);
2160         indpoint1=DStr.AddPoint(tpoint);
2161         stripe->SetIndexPoint(indpoint1,isfirst,1);
2162         // reset arc of CV1
2163         TopoDS_Vertex vert1,vert2;
2164         TopExp::Vertices(Edge[0],vert1,vert2);
2165         TopAbs_Orientation arcOri = Vtx.IsSame(vert1) ? TopAbs_FORWARD : TopAbs_REVERSED;
2166         CV1.SetArc(tolesp,Edge[0],paredge2,arcOri);
2167       }
2168       else {
2169         if (Hc1.IsNull()) {
2170           // curve 2d not found. Sfacemoins1 is extended and projection is done there
2171           // CV1.Point ()
2172           ChFi3d_ExtendSurface(Sfacemoins1,prolface[0]);
2173           if (prolface[0]) {
2174             extend=Standard_True;
2175             BRep_Builder BRE;
2176             Standard_Real tol=BRep_Tool::Tolerance(F);
2177             BRE.MakeFace(faceprol[0],Sfacemoins1,F.Location(),tol);
2178             if (!isOnSame1) {
2179               GeomAdaptor_Surface Asurf;
2180               Asurf.Load(Sfacemoins1);
2181               Extrema_ExtPS ext (CV1.Point(),Asurf, tol,tol);
2182               Standard_Real  uc1,vc1;
2183               if (ext.IsDone()) {
2184                 ext.Point(1).Parameter(uc1,vc1);
2185                 pfac1.SetX(uc1);
2186                 pfac1.SetY(vc1);
2187               }
2188             }
2189           }
2190         }
2191         else
2192           pfac1 = Hc1->Value(CV1.ParameterOnArc());
2193       }
2194       paredge1=CV1.ParameterOnArc();
2195       if (Fi1.LineIndex() != 0) {
2196         pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(isfirst));}
2197       else {
2198         pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst));}
2199       pfildeb=pfil1;
2200     }
2201     else {
2202       pfil1=pfil2;
2203       paredge1=paredge2;
2204       pfac1=pint;
2205     }
2206
2207     if (nb!=nbface || isOnSame2) {
2208       Standard_Integer nbp;
2209
2210       Handle(Geom_Curve) C;
2211       C=BRep_Tool::Curve(E2,Ubid,Vbid);
2212       Handle(Geom_TrimmedCurve) Ctrim = new Geom_TrimmedCurve(C,Ubid,Vbid);
2213       Standard_Real Utrim,Vtrim;
2214       Utrim=Ctrim->BasisCurve()->FirstParameter();
2215       Vtrim=Ctrim->BasisCurve()->LastParameter();
2216       if (Ctrim->IsPeriodic()) {
2217         if (Ubid>Ctrim->Period()) {
2218           Ubid=(Utrim+Vtrim)/2;
2219           Vbid= Vtrim;
2220         }
2221         else {
2222           Ubid=Utrim;
2223           Vbid=(Utrim+Vtrim)/2;
2224         }
2225       }
2226       else {
2227         Ubid=Utrim;
2228         Vbid=Vtrim;
2229       }
2230       Handle(GeomAdaptor_HCurve) HC =
2231         new GeomAdaptor_HCurve(C,Ubid,Vbid);
2232       GeomAdaptor_Curve & Cad =HC->ChangeCurve();
2233       inters.Perform(HC, HGs);
2234       if ( !prolface[nn] && ( !inters.IsDone() || (inters.NbPoints()==0) )) {
2235         // extend surface of conge
2236         Handle(Geom_BSplineSurface) S1=
2237           Handle(Geom_BSplineSurface)::DownCast(DStr.Surface(Fd->Surf()).Surface());
2238         if (!S1.IsNull()) {
2239           Standard_Real length = 0.5 * Max(Fi1Length,Fi2Length);
2240           GeomLib::ExtendSurfByLength(S1,length,1,Standard_False,!isfirst);
2241           prolface[nn] = 1;
2242           if (!stripe->IsInDS(!isfirst)) {
2243             Gs.Load(S1);
2244             inters.Perform(HC, HGs);
2245             if (inters.IsDone()&& inters.NbPoints()!=0) {
2246               Fd->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(S1, DStr.ChangeSurface(Isurf).Tolerance())));
2247               Isurf=Fd->Surf();
2248             }
2249           }
2250         }
2251       }
2252       if (!inters.IsDone() || (inters.NbPoints()==0)) {
2253         Handle(Geom_BSplineCurve) cd=Handle(Geom_BSplineCurve)::DownCast(C);
2254         Handle(Geom_BezierCurve) cd1=Handle(Geom_BezierCurve)::DownCast(C);
2255         if (!cd.IsNull() || !cd1.IsNull() ) {
2256           BRep_Builder BRE;
2257           Sface=BRep_Tool::Surface(Face[nb]);
2258           ChFi3d_ExtendSurface(Sface,prolface[nb]);
2259           Standard_Real tol=BRep_Tool::Tolerance(F);
2260           BRE.MakeFace(faceprol[nb],Sface,Face[nb].Location(),tol);
2261           if (nb && !prolface[nb-1]) {
2262             ChFi3d_ExtendSurface(Sfacemoins1,prolface[nb-1]);
2263             if (prolface[nb-1]) {
2264               tol=BRep_Tool::Tolerance(F);
2265               BRE.MakeFace(faceprol[nb-1],Sfacemoins1,F.Location(),tol);
2266             }
2267           }
2268           else {
2269             Standard_Integer prol = 0;
2270             ChFi3d_ExtendSurface(Sfacemoins1,prol);
2271           }
2272           GeomInt_IntSS InterSS(Sfacemoins1,Sface,1.e-7,1,1,1);
2273           if (InterSS.IsDone()) {
2274             trouve=Standard_False;
2275             for (Standard_Integer i=1; i<=InterSS.NbLines() && !trouve; i++) {
2276               extend=Standard_True;
2277               cint= InterSS.Line(i);
2278               C2dint1= InterSS.LineOnS1(i);
2279               C2dint2= InterSS.LineOnS2(i);
2280               Cad.Load(cint);
2281               inters.Perform(HC, HGs);
2282               trouve=inters.IsDone()&&inters.NbPoints()!=0;
2283               // eap occ293, eval tolex on finally trimmed curves
2284 //               Handle(GeomAdaptor_HSurface) H1=new GeomAdaptor_HSurface(Sfacemoins1);
2285 //               Handle(GeomAdaptor_HSurface) H2=new GeomAdaptor_HSurface(Sface);
2286 //              tolex=ChFi3d_EvalTolReached(H1,C2dint1,H2,C2dint2,cint);
2287               tolex = InterSS.TolReached3d();
2288             }
2289           }
2290         }
2291       }
2292       if (inters.IsDone()) {
2293         nbp = inters.NbPoints();
2294         if (nbp==0) {
2295           if (nb==0 || nb==nbface) 
2296             intersOnSameFailed = Standard_True;
2297           else {
2298             PerformMoreThreeCorner (Index,1);
2299             return;
2300           }
2301         }
2302         else {
2303           gp_Pnt P=BRep_Tool::Pnt(Vtx);
2304           Standard_Real distmin=P.Distance(inters.Point(1).Pnt());
2305           nbp=1;
2306           for (Standard_Integer i=2;i<=inters.NbPoints();i++) {
2307             dist=P.Distance(inters.Point(i).Pnt());
2308             if (dist<distmin) {
2309               distmin=dist;
2310               nbp=i;
2311             }
2312           }
2313           gp_Pnt2d pt2d (inters.Point(nbp).U(),inters.Point(nbp).V());
2314           pfil2=pt2d;
2315           paredge2=inters.Point(nbp).W();
2316           if (!extend) {
2317             cfacemoins1=BRep_Tool::CurveOnSurface(E2,F,u2,v2);
2318             cface=BRep_Tool::CurveOnSurface(E2,Face[nb],u2,v2);
2319             cfacemoins1->D0(paredge2,pfac2);
2320             cface->D0(paredge2,pint);
2321           }
2322           else {
2323             C2dint1->D0(paredge2,pfac2);
2324             C2dint2->D0(paredge2,pint);
2325           }
2326         }
2327       }
2328       else Standard_Failure::Raise("IntersectionAtEnd: pb intersection Face cb");
2329     }
2330     else {
2331       Hc2 = BRep_Tool::CurveOnSurface(E2,Face[nbface-1],Ubid,Ubid);
2332       if (Hc2.IsNull()) {
2333         // curve 2d is not found,  Sfacemoins1 is extended CV2.Point() is projected there
2334
2335         ChFi3d_ExtendSurface(Sfacemoins1,prolface[0]);
2336         if (prolface[0]) {
2337           BRep_Builder BRE;
2338           extend=Standard_True;
2339           Standard_Real tol=BRep_Tool::Tolerance(F);
2340           BRE.MakeFace(faceprol[nb-1],Sfacemoins1,F.Location(),tol);
2341           GeomAdaptor_Surface Asurf;
2342           Asurf.Load(Sfacemoins1);
2343           Extrema_ExtPS ext (CV2.Point(),Asurf,tol,tol);
2344           Standard_Real  uc2,vc2;
2345           if (ext.IsDone()) {
2346             ext.Point(1).Parameter(uc2,vc2);
2347             pfac2.SetX(uc2);
2348             pfac2.SetY(vc2);
2349           }
2350         }
2351       }
2352       else pfac2 = Hc2->Value(CV2.ParameterOnArc());
2353       paredge2=CV2.ParameterOnArc();
2354       if (Fi2.LineIndex() != 0) {
2355         pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(isfirst));
2356       }
2357       else {
2358         pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst));
2359       }
2360     }
2361     if (!nb) continue; // found paredge1 on Edge[0] in OnSame situation on F1
2362
2363     if (nb==nbface && isOnSame2) {
2364       // update interference param on Fi2 and point of CV2
2365       if (prolface[nb-1]) Bs.Initialize(faceprol[nb-1]);
2366       else                Bs.Initialize(Face[nb-1]);
2367       const Handle(Geom_Curve)& c3df = DStr.Curve(Fi2.LineIndex()).Curve();
2368       Standard_Real Ufi= Fi1.Parameter(isfirst);
2369       ChFiDS_FaceInterference& Fi = Fd->ChangeInterferenceOnS2();
2370       if (!IntersUpdateOnSame (HGs,HBs,c3df,F2,F,Edge[nb],Vtx,isfirst,10*tolesp, // in
2371                                Fi,CV2,pfac2,Ufi))   // out
2372         Standard_Failure::Raise("IntersectionAtEnd: pb intersection Face - Fi");
2373       Fi2 = Fi;
2374       if (intersOnSameFailed) { // probable at fillet building
2375         // look for paredge2
2376         Geom2dAPI_ProjectPointOnCurve proj;
2377         if (extend)
2378           proj.Init(pfac2, C2dint2);
2379         else 
2380           proj.Init(pfac2, BRep_Tool::CurveOnSurface (E2,Face[nbface-1],Ubid,Ubid));
2381         paredge2 = proj.LowerDistanceParameter();
2382       }
2383       // update stripe point
2384       TopOpeBRepDS_Point tpoint (CV2.Point(),tolesp);
2385       indpoint2=DStr.AddPoint(tpoint);
2386       stripe->SetIndexPoint(indpoint2,isfirst,2);
2387       // reset arc of CV2
2388       TopoDS_Vertex vert1,vert2;
2389       TopExp::Vertices(Edge[nbface],vert1,vert2);
2390       TopAbs_Orientation arcOri = Vtx.IsSame(vert1) ? TopAbs_FORWARD : TopAbs_REVERSED;
2391       CV2.SetArc(tolesp,Edge[nbface],paredge2,arcOri);
2392     }
2393
2394
2395     if (prolface[nb-1]) Bs.Initialize(faceprol[nb-1]);
2396     else                Bs.Initialize(Face[nb-1]);
2397
2398     // offset of parameters if they are not in the same period
2399
2400     // commented by eap 30 May 2002 occ354
2401     // the following code may cause trimming a wrong part of periodic surface
2402     
2403 //     Standard_Real  deb,xx1,xx2;
2404 //     Standard_Boolean  moins2pi,moins2pi1,moins2pi2;
2405 //     if (DStr.Surface(Fd->Surf()).Surface()->IsUPeriodic()) {
2406 //       deb=pfildeb.X();
2407 //       xx1=pfil1.X();
2408 //       xx2=pfil2.X();
2409 //       moins2pi=Abs(deb)< Abs(Abs(deb)-2*PI);
2410 //       moins2pi1=Abs(xx1)< Abs(Abs(xx1)-2*PI);
2411 //       moins2pi2=Abs(xx2)< Abs(Abs(xx2)-2*PI);
2412 //       if (moins2pi1!=moins2pi2) {
2413 //         if  (moins2pi) {
2414 //           if (!moins2pi1) xx1=xx1-2*PI;
2415 //           if (!moins2pi2) xx2=xx2-2*PI;
2416 //         }
2417 //         else {
2418 //           if (moins2pi1) xx1=xx1+2*PI;
2419 //           if (moins2pi2) xx2=xx2+2*PI;
2420 //         }
2421 //       }
2422 //       pfil1.SetX(xx1);
2423 //       pfil2.SetX(xx2);
2424 //     }
2425 //     if (couture || Sfacemoins1->IsUPeriodic()) {
2426
2427 //       Standard_Real ufmin,ufmax,vfmin,vfmax;
2428 //       BRepTools::UVBounds(Face[nb-1],ufmin,ufmax,vfmin,vfmax);
2429 //       deb=ufmin;
2430 //       xx1=pfac1.X();
2431 //       xx2=pfac2.X();
2432 //       moins2pi=Abs(deb)< Abs(Abs(deb)-2*PI);
2433 //       moins2pi1=Abs(xx1)< Abs(Abs(xx1)-2*PI);
2434 //       moins2pi2=Abs(xx2)< Abs(Abs(xx2)-2*PI);
2435 //       if (moins2pi1!=moins2pi2) {
2436 //         if  (moins2pi) {
2437 //           if (!moins2pi1) xx1=xx1-2*PI;
2438 //           if (!moins2pi2) xx2=xx2-2*PI;
2439 //         }
2440 //         else {
2441 //           if (moins2pi1) xx1=xx1+2*PI;
2442 //           if (moins2pi2) xx2=xx2+2*PI;
2443 //         }
2444 //       }
2445 //       pfac1.SetX(xx1);
2446 //       pfac2.SetX(xx2);
2447 //     }
2448
2449     Pardeb(1)= pfil1.X();Pardeb(2) = pfil1.Y();
2450     Pardeb(3)= pfac1.X();Pardeb(4) = pfac1.Y();
2451     Parfin(1)= pfil2.X();Parfin(2) = pfil2.Y();
2452     Parfin(3)= pfac2.X();Parfin(4) = pfac2.Y();
2453
2454     Standard_Real uu1,uu2,vv1,vv2;
2455     ChFi3d_Boite(pfac1,pfac2,uu1,uu2,vv1,vv2);
2456     ChFi3d_BoundFac(Bs,uu1,uu2,vv1,vv2);
2457
2458
2459     //////////////////////////////////////////////////////////////////////
2460     // calculate intersections face - fillet
2461     //////////////////////////////////////////////////////////////////////
2462
2463     if (!ChFi3d_ComputeCurves(HGs,HBs,Pardeb,Parfin,Cc,
2464                               Ps,Pc,tolesp,tol2d,tolreached,nbface==1)) {
2465       PerformMoreThreeCorner (Index,1);
2466       return;
2467     }
2468     // storage of information in the data structure
2469
2470     // evaluate tolerances
2471     p1=Cc->FirstParameter();
2472     p2=Cc->LastParameter();
2473     Standard_Real to1,to2;
2474     gp_Pnt2d  p2d1,p2d2;
2475     gp_Pnt P1,P2,P3,P4,P5,P6,P7,P8;
2476     HGs->D0(Pardeb(1),Pardeb(2),P1);
2477     HGs->D0(Parfin(1),Parfin(2),P2);
2478     HBs->D0(Pardeb(3),Pardeb(4),P3);
2479     HBs->D0(Parfin(3),Parfin(4),P4);
2480     Pc->D0(p1,p2d1);
2481     Pc->D0(p2,p2d2);
2482     HBs->D0(p2d1.X(),p2d1.Y(),P7);
2483     HBs->D0(p2d2.X(),p2d2.Y(),P8);
2484     Ps->D0(p1,p2d1);
2485     Ps->D0(p2,p2d2);
2486     HGs->D0(p2d1.X(),p2d1.Y(),P5);
2487     HGs->D0(p2d2.X(),p2d2.Y(),P6);
2488     to1 = Max (P1.Distance(P5)+P3.Distance(P7), tolreached);
2489     to2 = Max (P2.Distance(P6)+P4.Distance(P8), tolreached);
2490
2491
2492     //////////////////////////////////////////////////////////////////////
2493     // storage in the DS of the intersection curve
2494     //////////////////////////////////////////////////////////////////////
2495
2496     Standard_Boolean Isvtx1=0;
2497     Standard_Boolean Isvtx2=0;
2498     Standard_Integer indice;
2499
2500     if (nb==1)
2501     {
2502       indpoint1 = stripe->IndexPoint(isfirst,1);
2503       if (!CV1.IsVertex()) {
2504         TopOpeBRepDS_Point& tpt= DStr.ChangePoint(indpoint1);
2505         tpt.Tolerance ( Max (tpt.Tolerance(), to1));
2506       }
2507       else  Isvtx1=1;
2508     }
2509     if (nb==nbface)
2510     {
2511       indpoint2 = stripe->IndexPoint(isfirst,2);
2512       if (!CV2.IsVertex()) {
2513         TopOpeBRepDS_Point& tpt= DStr.ChangePoint(indpoint2);
2514         tpt.Tolerance ( Max (tpt.Tolerance(), to2));
2515       }
2516       else Isvtx2=1;
2517     }
2518     else
2519     {
2520       gp_Pnt point =Cc->Value(Cc->LastParameter());
2521       TopOpeBRepDS_Point tpoint (point,to2);
2522       indpoint2=DStr.AddPoint(tpoint);
2523     }
2524     
2525     if (nb!=1)
2526     {
2527       TopOpeBRepDS_Point& tpt= DStr.ChangePoint(indpoint1);
2528       tpt.Tolerance ( Max (tpt.Tolerance(), to1));
2529     }
2530     TopOpeBRepDS_Curve tcurv3d( Cc,tolreached);
2531     indcurve[nb-1]= DStr.AddCurve(tcurv3d);
2532     Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurve[nb-1],
2533                                  indpoint1,Cc->FirstParameter(),Isvtx1);
2534     Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurve[nb-1],
2535                                  indpoint2,Cc->LastParameter(),Isvtx2);
2536
2537     DStr.ChangeCurveInterferences(indcurve[nb-1]).Append(Interfp1);
2538     DStr.ChangeCurveInterferences(indcurve[nb-1]).Append(Interfp2);
2539
2540     //////////////////////////////////////////////////////////////////////
2541     // storage for the face
2542     //////////////////////////////////////////////////////////////////////
2543
2544 #ifndef DEB
2545     TopAbs_Orientation ori = TopAbs_FORWARD;
2546 #else
2547     TopAbs_Orientation ori;
2548 #endif
2549     orface=Face[nb-1].Orientation();
2550     if (orface==orsurfdata ) orien = TopAbs::Reverse(orcourbe);
2551     else                     orien = orcourbe ;
2552     // limitation of edges of faces
2553     if (nb==1) {
2554       Standard_Integer Iarc1= DStr.AddShape(Edge[0]);
2555       Interfedge[0]= ChFi3d_FilPointInDS(CV1.TransitionOnArc(),Iarc1,
2556                                          indpoint1,paredge1,Isvtx1);
2557       //DStr.ChangeShapeInterferences(Edge[0]).Append(Interfp1);
2558     }
2559     if (nb==nbface) {
2560       Standard_Integer Iarc2= DStr.AddShape(Edge[nb]);
2561       Interfedge[nb]= ChFi3d_FilPointInDS(CV2.TransitionOnArc() ,Iarc2,
2562                                           indpoint2,paredge2,Isvtx2);
2563       //DStr.ChangeShapeInterferences(Edge[nb]).Append(Interfp2);
2564     }
2565
2566     if (nb!=nbface || oneintersection1 || oneintersection2) {
2567       if (nface==3) {
2568         V1= TopExp::FirstVertex(Edge[nb]);
2569         V2= TopExp::LastVertex(Edge[nb]);
2570         if (containV(F1,V1) || containV(F2,V1))
2571           ori=TopAbs_FORWARD;
2572         else if (containV(F1,V2) || containV(F2,V2))
2573           ori=TopAbs_REVERSED;
2574         else
2575           Standard_Failure::Raise("IntersectionAtEnd : pb orientation");
2576
2577         if (containV(F1,V1) && containV(F1,V2)) {
2578           dist1=(BRep_Tool::Pnt(V1)).Distance(BRep_Tool::Pnt(Vtx));
2579           dist2=(BRep_Tool::Pnt(V2)).Distance(BRep_Tool::Pnt(Vtx));
2580           if (dist1<dist2)  ori=TopAbs_FORWARD;
2581           else              ori=TopAbs_REVERSED;
2582         }
2583         if (containV(F2,V1) && containV(F2,V2)) {
2584           dist1=(BRep_Tool::Pnt(V1)).Distance(BRep_Tool::Pnt(Vtx));
2585           dist2=(BRep_Tool::Pnt(V2)).Distance(BRep_Tool::Pnt(Vtx));
2586           if (dist1<dist2)  ori=TopAbs_FORWARD;
2587           else              ori=TopAbs_REVERSED;
2588         }
2589       }
2590       else {
2591         if (TopExp::FirstVertex(Edge[nb]).IsSame(Vtx))
2592           ori= TopAbs_FORWARD;
2593         else ori=TopAbs_REVERSED;
2594       }
2595       if (!extend && !(oneintersection1 || oneintersection2)) {
2596         Standard_Integer Iarc2= DStr.AddShape(Edge[nb]);
2597         Interfedge[nb]= ChFi3d_FilPointInDS(ori,Iarc2,
2598                                             indpoint2,paredge2);
2599         //  DStr.ChangeShapeInterferences(Edge[nb]).Append(Interfp2);
2600       }
2601       else {
2602         if (!(oneintersection1 || oneintersection2) ) proledge[nb]=Standard_True;
2603         Standard_Integer indp1,indp2,ind;
2604         gp_Pnt pext;
2605         Standard_Real ubid,vbid;
2606         pext=BRep_Tool::Pnt(Vtx);
2607         GeomAdaptor_Curve cad;
2608         Handle(Geom_Curve) csau;
2609         if ( ! (oneintersection1 || oneintersection2)) {
2610           cad.Load(cint);
2611           csau=cint;
2612         }
2613         else {
2614           csau=BRep_Tool::Curve(edgesau,ubid,vbid );
2615           Handle(Geom_BoundedCurve) C1=
2616             Handle(Geom_BoundedCurve)::DownCast(csau);
2617           if (oneintersection1&&extend) {
2618             if (!C1.IsNull()) {
2619               gp_Pnt Pl;
2620               Pl=C1->Value(C1->LastParameter());
2621               //Standard_Boolean sens;
2622               sens=Pl.Distance(pext)<tolpt;
2623               GeomLib::ExtendCurveToPoint(C1,CV1.Point(),1,sens);
2624               csau=C1;
2625             }
2626           }
2627           else if (oneintersection2&&extend) {
2628             if (!C1.IsNull()) {
2629               gp_Pnt Pl;
2630               Pl=C1->Value(C1->LastParameter());
2631               //Standard_Boolean sens;
2632               sens=Pl.Distance(pext)<tolpt;
2633               GeomLib::ExtendCurveToPoint(C1,CV2.Point(),1,sens);
2634               csau=C1;
2635             }
2636           }
2637           cad.Load(csau);
2638         }
2639         Extrema_ExtPC ext(pext,cad,tolpt);
2640         Standard_Real par1, par2, par, ParVtx;
2641         Standard_Boolean vtx1=Standard_False;
2642         Standard_Boolean vtx2=Standard_False;
2643         par1=ext.Point(1).Parameter();
2644         ParVtx = par1;
2645         if (oneintersection1 || oneintersection2 ) {
2646           if (oneintersection2) {
2647             pext=CV2.Point();
2648             ind=indpoint2;
2649           }
2650           else {
2651             pext=CV1.Point();
2652             ind=indpoint1;
2653           }
2654           Extrema_ExtPC ext2(pext,cad,tolpt);
2655           par2=ext2.Point(1).Parameter();
2656         }
2657         else {
2658           par2=paredge2;
2659           ind=indpoint2;
2660         }
2661         if (par1>par2) {
2662           indp1=ind;
2663           indp2=DStr.AddShape(Vtx);
2664           vtx2=Standard_True;
2665           par=par1;
2666           par1=par2;
2667           par2=par;
2668         }
2669         else {
2670           indp1=DStr.AddShape(Vtx);
2671           indp2=ind;
2672           vtx1=Standard_True;
2673         }
2674         Handle(Geom_Curve) Ct=new Geom_TrimmedCurve (csau,par1,par2);
2675         TopAbs_Orientation orient;
2676         Cc->D0(Cc->FirstParameter(),P1);
2677         Cc->D0(Cc->LastParameter(),P2);
2678         Ct->D0(Ct->FirstParameter(),P3);
2679         Ct->D0(Ct->LastParameter(),P4);
2680         if (P2.Distance(P3)<tolpt || P1.Distance(P4)<tolpt) orient=orien;
2681         else orient=TopAbs::Reverse(orien);
2682         if (oneintersection1||oneintersection2) {
2683           indice=DStr.AddShape(Face[0]);
2684           if (extend) {
2685             DStr.SetNewSurface(Face[0],Sfacemoins1);
2686             ComputeCurve2d(Ct,faceprol[0],C2dint1);
2687           }
2688           else
2689           {
2690             TopoDS_Edge aLocalEdge = edgesau;
2691             if (edgesau.Orientation() != orient)
2692               aLocalEdge.Reverse();
2693             C2dint1 = BRep_Tool::CurveOnSurface(aLocalEdge,Face[0],ubid,vbid);
2694           }
2695         }
2696         else {
2697           indice=DStr.AddShape(Face[nb-1]);
2698           DStr.SetNewSurface(Face[nb-1],Sfacemoins1);
2699         }
2700         //// for periodic 3d curves ////
2701         if (cad.IsPeriodic())
2702         {
2703           gp_Pnt2d P2d = BRep_Tool::Parameters( Vtx, Face[0] );
2704           Geom2dAPI_ProjectPointOnCurve Projector( P2d, C2dint1 );
2705           par = Projector.LowerDistanceParameter();
2706           Standard_Real shift = par-ParVtx;
2707           if (Abs(shift) > Precision::Confusion())
2708           {
2709             par1 += shift;
2710             par2 += shift;
2711           }
2712         }
2713         ////////////////////////////////
2714
2715         Ct=new Geom_TrimmedCurve (csau,par1,par2);
2716         if (oneintersection1||oneintersection2) tolex=10*BRep_Tool::Tolerance(edgesau);
2717         if (extend) {
2718           Handle(GeomAdaptor_HSurface) H1, H2;
2719           H1=new GeomAdaptor_HSurface(Sfacemoins1);
2720           if (Sface.IsNull()) 
2721             tolex = Max (tolex, ChFi3d_EvalTolReached(H1,C2dint1,H1,C2dint1,Ct));
2722           else {
2723             H2=new GeomAdaptor_HSurface(Sface);
2724             tolex = Max (tolex, ChFi3d_EvalTolReached(H1,C2dint1,H2,C2dint2,Ct));
2725           }
2726         }
2727         TopOpeBRepDS_Curve tcurv( Ct,tolex);
2728         Standard_Integer indcurv;
2729         indcurv=DStr.AddCurve(tcurv);
2730         Interfp1=ChFi3d_FilPointInDS(TopAbs_FORWARD,indcurv,indp1,par1,vtx1);
2731         Interfp2=ChFi3d_FilPointInDS(TopAbs_REVERSED,indcurv,indp2,par2,vtx2);
2732         DStr.ChangeCurveInterferences(indcurv).Append(Interfp1);
2733         DStr.ChangeCurveInterferences(indcurv).Append(Interfp2);
2734
2735         Interfc=ChFi3d_FilCurveInDS(indcurv,indice ,C2dint1,orient);
2736         DStr.ChangeShapeInterferences(indice).Append(Interfc);
2737         if (oneintersection1||oneintersection2) {
2738           indice=DStr.AddShape(facesau);
2739           if (facesau.Orientation()==Face[0].Orientation())
2740             orient=TopAbs::Reverse(orient);
2741           if (extend) {
2742             ComputeCurve2d(Ct,faceprol[1],C2dint2);
2743
2744           }
2745           else
2746           {
2747             TopoDS_Edge aLocalEdge = edgesau;
2748             if (edgesau.Orientation() != orient)
2749               aLocalEdge.Reverse();
2750             C2dint2 = BRep_Tool::CurveOnSurface(aLocalEdge,facesau,ubid,vbid);
2751             //Reverse for case of edgesau on closed surface (Face[0] is equal to facesau)
2752           }
2753         }
2754         else {
2755           indice=DStr.AddShape(Face[nb]);
2756           DStr.SetNewSurface(Face[nb],Sface);
2757           if (Face[nb].Orientation()==Face[nb-1].Orientation())
2758             orient= TopAbs::Reverse(orient);
2759         }
2760         if (!bordlibre) {
2761           Interfc=ChFi3d_FilCurveInDS(indcurv,indice,C2dint2,orient);
2762           DStr.ChangeShapeInterferences(indice).Append(Interfc);
2763         }
2764       }
2765     }
2766
2767     if (checkShrink &&
2768         IsShrink(Ps,p1,p2,checkShrParam,isUShrink,Precision::Parametric(tolreached)))
2769     {
2770       shrink [nb-1] = 1;
2771       // store section face-chamf curve for previous SurfData
2772       // Suppose Fd and SDprev are parametrized similarly
2773       if (!isShrink) { // first time
2774         const ChFiDS_FaceInterference& Fi = SDprev->InterferenceOnS1();
2775         gp_Pnt2d UV = Fi.PCurveOnSurf()->Value(Fi.Parameter(isfirst));
2776         prevSDParam = isUShrink ? UV.X() : UV.Y();
2777       }
2778       gp_Pnt2d UV1=p2d1,UV2=p2d2;
2779       UV1.SetCoord(isUShrink ? 1 : 2, prevSDParam);
2780       UV2.SetCoord(isUShrink ? 1 : 2, prevSDParam);
2781       Standard_Real aTolreached;
2782       ChFi3d_ComputePCurv(Cc,UV1,UV2,Ps,
2783                           DStr.Surface(SDprev->Surf()).Surface(),
2784                           p1,p2,tolesp,aTolreached);
2785       TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(indcurve[nb-1]);
2786       TCurv.Tolerance(Max(TCurv.Tolerance(),aTolreached));
2787
2788       InterfPS[nb-1]=ChFi3d_FilCurveInDS(indcurve[nb-1],IsurfPrev,Ps,orcourbe);
2789       DStr.ChangeSurfaceInterferences(IsurfPrev).Append(InterfPS[nb-1]);
2790
2791       if (isOnSame2) {
2792         midP2d = p2d2;
2793         midIpoint = indpoint2;
2794       }
2795       else if (!isShrink) {
2796         midP2d = p2d1;
2797         midIpoint = indpoint1;
2798       }
2799       isShrink = Standard_True;
2800     } // end if shrink
2801
2802     
2803     indice=DStr.AddShape(Face[nb-1]);
2804     InterfPC[nb-1]=ChFi3d_FilCurveInDS(indcurve[nb-1],indice ,Pc,orien);
2805     if (!shrink [nb-1])
2806       InterfPS[nb-1]=ChFi3d_FilCurveInDS(indcurve[nb-1],Isurf,Ps,orcourbe);
2807     indpoint1=indpoint2;
2808
2809   } // end loop on faces being intersected with ChFi
2810
2811   
2812   if (isOnSame1) CV1.Reset();
2813   if (isOnSame2) CV2.Reset();
2814
2815   for(nb=1;nb<=nbface;nb++) {
2816     Standard_Integer indice=DStr.AddShape(Face[nb-1]);
2817     DStr.ChangeShapeInterferences(indice).Append(InterfPC[nb-1]);
2818     if (!shrink [nb-1])
2819       DStr.ChangeSurfaceInterferences(Isurf).Append(InterfPS[nb-1]);
2820     if (!proledge[nb-1])
2821       DStr.ChangeShapeInterferences(Edge[nb-1]).Append(Interfedge[nb-1]);
2822   }
2823   DStr.ChangeShapeInterferences(Edge[nbface]).Append(Interfedge[nbface]);
2824
2825   if (!isShrink)
2826     stripe->InDS(isfirst);
2827   else {
2828     // compute curves for !<isfirst> end of <Fd> and <isfirst> end of previous <SurfData>
2829
2830     // for Fd
2831     //Bnd_Box box;
2832     gp_Pnt2d UV, UV1 = midP2d, UV2 = midP2d;
2833     if (isOnSame1) 
2834       UV = UV2 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst));
2835     else 
2836       UV = UV1 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst));
2837     Standard_Real aTolreached;
2838     Handle(Geom_Curve) C3d;
2839     Handle(Geom_Surface) aSurf = DStr.Surface(Fd->Surf()).Surface();
2840     //box.Add(aSurf->Value(UV.X(), UV.Y()));
2841     
2842     ChFi3d_ComputeArete(CV1,UV1,CV2,UV2,aSurf, // in 
2843                         C3d,Ps,p1,p2,tolesp,tol2d,aTolreached,0); // out except tolers
2844
2845     indpoint1 = indpoint2 = midIpoint;
2846     gp_Pnt point;
2847     if (isOnSame1) {
2848       point = C3d->Value(p2);
2849       TopOpeBRepDS_Point tpoint (point,aTolreached);
2850       indpoint2=DStr.AddPoint(tpoint);
2851       UV = Ps->Value(p2);
2852     } else {
2853       point = C3d->Value(p1);
2854       TopOpeBRepDS_Point tpoint (point,aTolreached);
2855       indpoint1=DStr.AddPoint(tpoint);
2856       UV = Ps->Value(p1);
2857     }
2858     //box.Add(point);
2859     //box.Add(aSurf->Value(UV.X(), UV.Y()));
2860     
2861     TopOpeBRepDS_Curve Crv = TopOpeBRepDS_Curve(C3d,aTolreached);
2862     Standard_Integer Icurv = DStr.AddCurve(Crv);
2863     Interfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv,indpoint1,p1, Standard_False);
2864     Interfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv,indpoint2,p2, Standard_False);
2865     Interfc = ChFi3d_FilCurveInDS(Icurv,Isurf,Ps,orcourbe);
2866     DStr.ChangeCurveInterferences(Icurv).Append(Interfp1);
2867     DStr.ChangeCurveInterferences(Icurv).Append(Interfp2);
2868     DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc);
2869
2870     // for SDprev
2871     aSurf = DStr.Surface(SDprev->Surf()).Surface();
2872     UV1.SetCoord(isUShrink ? 1 : 2, prevSDParam);
2873     UV2.SetCoord(isUShrink ? 1 : 2, prevSDParam);
2874     
2875     ChFi3d_ComputePCurv(C3d,UV1,UV2,Pc,aSurf,p1,p2,tolesp,aTolreached);
2876     
2877     Crv.Tolerance(Max(Crv.Tolerance(),aTolreached));
2878     Interfc= ChFi3d_FilCurveInDS (Icurv,IsurfPrev,Pc,TopAbs::Reverse(orcourbe));
2879     DStr.ChangeSurfaceInterferences(IsurfPrev).Append(Interfc);
2880
2881     //UV = isOnSame1 ? UV2 : UV1;
2882     //box.Add(aSurf->Value(UV.X(), UV.Y()));
2883     //UV = Ps->Value(isOnSame1 ? p2 : p1);
2884     //box.Add(aSurf->Value(UV.X(), UV.Y()));
2885     //ChFi3d_SetPointTolerance(DStr,box, isOnSame1 ? indpoint2 : indpoint1);
2886     
2887     // to process properly this case in ChFi3d_FilDS()
2888     stripe->InDS(isfirst, 2);
2889     Fd->ChangeInterference(isOnSame1 ? 2 : 1).SetLineIndex(0);
2890     ChFiDS_CommonPoint& CPprev1 = SDprev->ChangeVertex( isfirst,isOnSame1 ? 2 : 1);
2891     ChFiDS_CommonPoint& CPlast1 = Fd->    ChangeVertex( isfirst,isOnSame1 ? 2 : 1);
2892     ChFiDS_CommonPoint& CPlast2 = Fd->    ChangeVertex(!isfirst,isOnSame1 ? 2 : 1);
2893     if (CPprev1.IsOnArc()) {
2894       CPlast1 = CPprev1;
2895       CPprev1.Reset();
2896       CPprev1.SetPoint(CPlast1.Point());
2897       CPlast2.Reset();
2898       CPlast2.SetPoint(CPlast1.Point());
2899     }
2900
2901     // in shrink case, self intersection is possible at <midIpoint>,
2902     // eval its tolerance intersecting Ps and Pcurve at end.
2903     // Find end curves closest to shrinked part
2904     for (nb=0; nb < nbface; nb++)
2905       if (isOnSame1 ? shrink [nb+1] : !shrink [nb]) break;
2906     Handle(Geom_Curve)   Cend = DStr.Curve(indcurve[nb]).Curve();
2907     Handle(Geom2d_Curve) PCend = InterfPS[nb]->PCurve();
2908     // point near which self intersection may occure
2909     TopOpeBRepDS_Point& Pds = DStr.ChangePoint(midIpoint);
2910     const gp_Pnt& Pvert = Pds.Point();
2911     Standard_Real tol = Pds.Tolerance();
2912
2913     Geom2dAdaptor_Curve PC1(Ps), PC2(PCend);
2914     Geom2dInt_GInter Intersector(PC1,PC2,Precision::PConfusion(),Precision::PConfusion());
2915     if (!Intersector.IsDone()) return;
2916     for (nb=1; nb <= Intersector.NbPoints(); nb++) {
2917       const IntRes2d_IntersectionPoint& ip = Intersector.Point(nb);
2918       gp_Pnt Pint = C3d->Value(ip.ParamOnFirst());
2919       tol = Max(tol, Pvert.Distance(Pint));
2920       Pint = Cend->Value(ip.ParamOnSecond());
2921       tol = Max(tol, Pvert.Distance(Pint));
2922     }
2923     for (nb=1; nb <= Intersector.NbSegments(); nb++) {
2924       const IntRes2d_IntersectionSegment& is = Intersector.Segment(nb);
2925       if (is.HasFirstPoint()) {
2926         const IntRes2d_IntersectionPoint& ip = is.FirstPoint();
2927         gp_Pnt Pint = C3d->Value(ip.ParamOnFirst());
2928         tol = Max(tol, Pvert.Distance(Pint));
2929         Pint = Cend->Value(ip.ParamOnSecond());
2930         tol = Max(tol, Pvert.Distance(Pint));
2931       }
2932       if (is.HasLastPoint()) {
2933         const IntRes2d_IntersectionPoint& ip = is.LastPoint();
2934         gp_Pnt Pint = C3d->Value(ip.ParamOnFirst());
2935         tol = Max(tol, Pvert.Distance(Pint));
2936         Pint = Cend->Value(ip.ParamOnSecond());
2937         tol = Max(tol, Pvert.Distance(Pint));
2938       }
2939     }
2940     Pds.Tolerance(tol);
2941   }
2942 }
2943
2944 //  Modified by Sergey KHROMOV - Thu Apr 11 12:23:40 2002 Begin
2945
2946 //=======================================================================
2947 //function : PerformMoreSurfdata
2948 //purpose  :  determine intersections at end on several surfdata
2949 //=======================================================================
2950 void ChFi3d_Builder::PerformMoreSurfdata(const Standard_Integer Index)
2951 {
2952   TopOpeBRepDS_DataStructure &DStr = myDS->ChangeDS();
2953   const ChFiDS_ListOfStripe  &aLOfStripe = myVDataMap(Index);
2954   Handle(ChFiDS_Stripe)       aStripe;
2955   Handle(ChFiDS_Spine)        aSpine;
2956   Standard_Real               aTol3d = 1.e-4;
2957
2958
2959   if (aLOfStripe.IsEmpty())
2960     return;
2961
2962   aStripe = aLOfStripe.First();
2963   aSpine  = aStripe->Spine();
2964
2965   ChFiDS_SequenceOfSurfData &aSeqSurfData =
2966                                aStripe->ChangeSetOfSurfData()->ChangeSequence();
2967   const TopoDS_Vertex       &aVtx         = myVDataMap.FindKey(Index);
2968   Standard_Integer           aSens        = 0;
2969   Standard_Integer           anInd        =
2970                                ChFi3d_IndexOfSurfData(aVtx,aStripe,aSens);
2971   Standard_Boolean           isFirst      = (aSens == 1);
2972   Standard_Integer           anIndPrev;
2973   Handle(ChFiDS_SurfData)    aSurfData;
2974   ChFiDS_CommonPoint         aCP1;
2975   ChFiDS_CommonPoint         aCP2;
2976
2977   aSurfData = aSeqSurfData.Value(anInd);
2978
2979   aCP1 = aSurfData->Vertex(isFirst,1);
2980   aCP2 = aSurfData->Vertex(isFirst,2);
2981
2982   Handle(Geom_Surface) aSurfPrev;
2983   Handle(Geom_Surface) aSurf;
2984   TopoDS_Face          aFace;
2985   TopoDS_Face          aNeighborFace;
2986
2987   FindFace(aVtx, aCP1, aCP2, aFace);
2988   aSurfPrev = BRep_Tool::Surface(aFace);
2989
2990   if (aSens==1) anIndPrev=anInd+1;
2991   else  anIndPrev=anInd-1;
2992
2993   TopoDS_Edge                        anArc1;
2994   TopoDS_Edge                        anArc2;
2995   TopTools_ListIteratorOfListOfShape anIter(myVEMap(aVtx));
2996   Standard_Boolean                   isFound = Standard_False;
2997
2998   for(; anIter.More() && !isFound; anIter.Next()) {
2999     anArc1 = TopoDS::Edge(anIter.Value());
3000
3001     if (containE(aFace, anArc1))
3002       isFound = Standard_True;
3003   }
3004
3005   isFound = Standard_False;
3006   anIter.Initialize(myVEMap(aVtx));
3007
3008   for(; anIter.More() && !isFound; anIter.Next()) {
3009     anArc2 = TopoDS::Edge(anIter.Value());
3010
3011     if (containE(aFace,anArc2) && !anArc2.IsSame(anArc1))
3012       isFound = Standard_True;
3013   }
3014
3015   // determination of common points aCP1onArc, aCP2onArc and aCP2NotonArc
3016   // aCP1onArc    is the point on arc of index anInd
3017   // aCP2onArc    is the point on arc of index anIndPrev
3018   // aCP2NotonArc is the point of index anIndPrev which is not on arc.
3019
3020   Standard_Boolean   is1stCP1OnArc;
3021   Standard_Boolean   is2ndCP1OnArc;
3022   ChFiDS_CommonPoint aCP1onArc;
3023   ChFiDS_CommonPoint aCP2onArc;
3024   ChFiDS_CommonPoint aCP2NotonArc;
3025
3026   aSurfData = aSeqSurfData.Value(anIndPrev);
3027   aCP1      = aSurfData->Vertex(isFirst,1);
3028   aCP2      = aSurfData->Vertex(isFirst,2);
3029
3030   if (aCP1.IsOnArc() &&
3031       (aCP1.Arc().IsSame(anArc1) || aCP1.Arc().IsSame(anArc2))) {
3032       aCP2onArc     = aCP1;
3033       aCP2NotonArc  = aCP2;
3034       is2ndCP1OnArc = Standard_True;
3035   } else if (aCP2.IsOnArc() &&
3036              (aCP2.Arc().IsSame(anArc1) || aCP2.Arc().IsSame(anArc2))) {
3037       aCP2onArc     = aCP2;
3038       aCP2NotonArc  = aCP1;
3039       is2ndCP1OnArc = Standard_False;
3040   } else
3041     return;
3042
3043   aSurfData = aSeqSurfData.Value(anInd);
3044   aCP1      = aSurfData->Vertex(isFirst,1);
3045   aCP2      = aSurfData->Vertex(isFirst,2);
3046
3047   if (aCP1.Point().Distance(aCP2onArc.Point()) <= aTol3d){
3048     aCP1onArc     = aCP2;
3049     is1stCP1OnArc = Standard_False;
3050   }
3051   else {
3052     aCP1onArc     = aCP1;
3053     is1stCP1OnArc = Standard_True;
3054   }
3055
3056   if (!aCP1onArc.IsOnArc())
3057     return;
3058
3059 // determination of neighbor surface
3060   Standard_Integer indSurface;
3061   if (is1stCP1OnArc)
3062     indSurface = myListStripe.First()->SetOfSurfData()->Value(anInd)->IndexOfS1();
3063   else
3064     indSurface = myListStripe.First()->SetOfSurfData()->Value(anInd)->IndexOfS2();
3065
3066   aNeighborFace = TopoDS::Face(myDS->Shape(indSurface));
3067
3068 // calculation of intersections
3069   Handle(Geom_Curve)   aCracc;
3070   Handle(Geom2d_Curve) aPCurv1;
3071   Standard_Real        aParf;
3072   Standard_Real        aParl;
3073   Standard_Real        aTolReached;
3074
3075   aSurfData = aSeqSurfData.Value(anInd);
3076
3077   if (isFirst)
3078     ChFi3d_ComputeArete(aSurfData->VertexLastOnS1(),
3079                         aSurfData->InterferenceOnS1().PCurveOnSurf()->
3080                         Value(aSurfData->InterferenceOnS1().LastParameter()),
3081                         aSurfData->VertexLastOnS2(),
3082                         aSurfData->InterferenceOnS2().PCurveOnSurf()->
3083                         Value(aSurfData->InterferenceOnS2().LastParameter()),
3084                         DStr.Surface(aSurfData->Surf()).Surface(),aCracc,aPCurv1,
3085                         aParf,aParl,aTol3d,tol2d,aTolReached,0);
3086   else
3087     ChFi3d_ComputeArete(aSurfData->VertexFirstOnS1(),
3088                         aSurfData->InterferenceOnS1().PCurveOnSurf()->
3089                         Value(aSurfData->InterferenceOnS1().FirstParameter()),
3090                         aSurfData->VertexFirstOnS2(),
3091                         aSurfData->InterferenceOnS2().PCurveOnSurf()->
3092                         Value(aSurfData->InterferenceOnS2().FirstParameter()),
3093                         DStr.Surface(aSurfData->Surf()).Surface(),aCracc,aPCurv1,
3094                         aParf,aParl,aTol3d,tol2d,aTolReached,0);
3095
3096 // calculation of the index of the line on anInd.
3097 // aPClineOnSurf is the pcurve on anInd.
3098 // aPClineOnFace is the pcurve on face.
3099   ChFiDS_FaceInterference  aFI;
3100
3101   if (is1stCP1OnArc)
3102     aFI = aSurfData->InterferenceOnS1();
3103   else
3104     aFI = aSurfData->InterferenceOnS2();
3105
3106   Handle(Geom_Curve)   aCline;
3107   Handle(Geom2d_Curve) aPClineOnSurf;
3108   Handle(Geom2d_Curve) aPClineOnFace;
3109   Standard_Integer     indLine;
3110
3111   indLine       = aFI.LineIndex();
3112   aCline        = DStr.Curve(aFI.LineIndex()).Curve();
3113   aPClineOnSurf = aFI.PCurveOnSurf();
3114   aPClineOnFace = aFI.PCurveOnFace();
3115
3116 // intersection between the SurfData number anInd and the Face aFace.
3117 // Obtaining of curves aCint1, aPCint11 and aPCint12.
3118   aSurf = DStr.Surface(aSurfData->Surf()).Surface();
3119
3120   GeomInt_IntSS                anInterSS(aSurfPrev,aSurf,1.e-7,1,1,1);
3121   Handle(Geom_Curve)           aCint1;
3122   Handle(Geom2d_Curve)         aPCint11;
3123   Handle(Geom2d_Curve)         aPCint12;
3124   Handle(GeomAdaptor_HSurface) H1 = new GeomAdaptor_HSurface(aSurfPrev);
3125   Handle(GeomAdaptor_HSurface) H2 = new GeomAdaptor_HSurface(aSurf);
3126   Standard_Real                aTolex1=0.;
3127   Standard_Integer             i;
3128   gp_Pnt                       aPext1;
3129   gp_Pnt                       aPext2;
3130   gp_Pnt                       aPext;
3131   Standard_Boolean             isPextFound;
3132
3133
3134   if (!anInterSS.IsDone())
3135     return;
3136
3137   isFound = Standard_False;
3138
3139   for (i = 1; i <= anInterSS.NbLines() && !isFound; i++) {
3140     aCint1   = anInterSS.Line(i);
3141     aPCint11 = anInterSS.LineOnS1(i);
3142     aPCint12 = anInterSS.LineOnS2(i);
3143     aTolex1  = ChFi3d_EvalTolReached(H1, aPCint11, H2, aPCint12, aCint1);
3144
3145     aCint1->D0(aCint1->FirstParameter(), aPext1);
3146     aCint1->D0(aCint1->LastParameter(),  aPext2);
3147
3148 //  Modified by skv - Mon Jun  7 18:38:57 2004 OCC5898 Begin
3149 //     if (aPext1.Distance(aCP1onArc.Point()) <= aTol3d ||
3150 //      aPext2.Distance(aCP1onArc.Point()))
3151     if (aPext1.Distance(aCP1onArc.Point()) <= aTol3d ||
3152         aPext2.Distance(aCP1onArc.Point()) <= aTol3d)
3153 //  Modified by skv - Mon Jun  7 18:38:58 2004 OCC5898 End
3154       isFound = Standard_True;
3155   }
3156
3157   if (!isFound)
3158     return;
3159
3160   if (aPext1.Distance(aCP2onArc.Point()) > aTol3d &&
3161       aPext1.Distance(aCP1onArc.Point()) > aTol3d) {
3162     aPext       = aPext1;
3163     isPextFound = Standard_True;
3164   } else if (aPext2.Distance(aCP2onArc.Point()) > aTol3d &&
3165              aPext2.Distance(aCP1onArc.Point()) > aTol3d) {
3166     aPext       = aPext2;
3167     isPextFound = Standard_True;
3168   } else {
3169     isPextFound = Standard_False;
3170   }
3171
3172
3173   Standard_Boolean  isDoSecondSection = Standard_False;
3174   Standard_Real     aPar=0.;
3175
3176   if (isPextFound) {
3177     GeomAdaptor_Curve aCad(aCracc);
3178     Extrema_ExtPC     anExt(aPext, aCad, aTol3d);
3179
3180     if (!anExt.IsDone())
3181       return;
3182
3183     isFound = Standard_False;
3184     for (i = 1; i <= anExt.NbExt() && !isFound; i++) {
3185       if (anExt.IsMin(i)) {
3186         gp_Pnt aProjPnt = anExt.Point(i).Value();
3187
3188         if (aPext.Distance(aProjPnt) <= aTol3d) {
3189           aPar              = anExt.Point(i).Parameter();
3190           isDoSecondSection = Standard_True;
3191         }
3192       }
3193     }
3194   }
3195
3196   Handle(Geom_Curve) aTrCracc;
3197   TopAbs_Orientation anOrSD1;
3198   TopAbs_Orientation anOrSD2;
3199   Standard_Integer   indShape;
3200
3201   anOrSD1   = aSurfData->Orientation();
3202   aSurfData = aSeqSurfData.Value(anIndPrev);
3203   anOrSD2   = aSurfData->Orientation();
3204   aSurf     = DStr.Surface(aSurfData->Surf()).Surface();
3205
3206 // The following variables will be used if isDoSecondSection is true
3207   Handle(Geom_Curve)           aCint2;
3208   Handle(Geom2d_Curve)         aPCint21;
3209   Handle(Geom2d_Curve)         aPCint22;
3210   Standard_Real                aTolex2=0.;
3211
3212   if (isDoSecondSection) {
3213     Standard_Real aPar1;
3214
3215     aCracc->D0(aCracc->FirstParameter(), aPext1);
3216
3217     if (aPext1.Distance(aCP2NotonArc.Point()) <= aTol3d)
3218       aPar1 = aCracc->FirstParameter();
3219     else
3220       aPar1 = aCracc->LastParameter();
3221
3222     if (aPar1 < aPar)
3223       aTrCracc = new Geom_TrimmedCurve (aCracc, aPar1, aPar);
3224     else
3225       aTrCracc = new Geom_TrimmedCurve (aCracc, aPar,  aPar1);
3226
3227 // Second section
3228     GeomInt_IntSS anInterSS2(aSurfPrev,aSurf,1.e-7,1,1,1);
3229
3230     if (!anInterSS2.IsDone())
3231       return;
3232
3233     H1 = new GeomAdaptor_HSurface(aSurfPrev);
3234     H2 = new GeomAdaptor_HSurface(aSurf);
3235
3236     isFound = Standard_False;
3237
3238     for (i = 1; i <= anInterSS2.NbLines() && !isFound; i++) {
3239       aCint2   = anInterSS2.Line(i);
3240       aPCint21 = anInterSS2.LineOnS1(i);
3241       aPCint22 = anInterSS2.LineOnS2(i);
3242       aTolex2  = ChFi3d_EvalTolReached(H1, aPCint21, H2, aPCint22, aCint2);
3243
3244       aCint2->D0(aCint2->FirstParameter(), aPext1);
3245       aCint2->D0(aCint2->LastParameter(),  aPext2);
3246
3247       if (aPext1.Distance(aCP2onArc.Point()) <= aTol3d ||
3248           aPext2.Distance(aCP2onArc.Point()) <= aTol3d)
3249         isFound = Standard_True;
3250     }
3251
3252     if (!isFound)
3253       return;
3254
3255   } else {
3256     aTrCracc = new Geom_TrimmedCurve(aCracc,
3257                                      aCracc->FirstParameter(),
3258                                      aCracc->LastParameter());
3259   }
3260
3261 // Storage of the data structure
3262
3263 // calculation of the orientation of line of surfdata number
3264 // anIndPrev which contains aCP2onArc
3265
3266   Handle(Geom2d_Curve) aPCraccS = GeomProjLib::Curve2d(aTrCracc,aSurf);
3267
3268   if (is2ndCP1OnArc) {
3269     aFI      = aSurfData->InterferenceOnS1();
3270     indShape = aSurfData->IndexOfS1();
3271   } else {
3272     aFI      = aSurfData->InterferenceOnS2();
3273     indShape = aSurfData->IndexOfS2();
3274   }
3275
3276   if (indShape <= 0)
3277     return;
3278
3279
3280
3281   TopAbs_Orientation aCurOrient;
3282
3283   aCurOrient = DStr.Shape(indShape).Orientation();
3284   aCurOrient = TopAbs::Compose(aCurOrient, aSurfData->Orientation());
3285   aCurOrient = TopAbs::Compose(TopAbs::Reverse(aFI.Transition()), aCurOrient);
3286
3287
3288 // Filling the data structure
3289   aSurfData   = aSeqSurfData.Value(anInd);
3290
3291   TopOpeBRepDS_Point aPtCP1(aCP1onArc.Point(),aCP1onArc.Tolerance());
3292   Standard_Integer   indCP1onArc = DStr.AddPoint(aPtCP1);
3293   Standard_Integer   indSurf1    = aSurfData->Surf();
3294   Standard_Integer   indArc1     = DStr.AddShape(aCP1onArc.Arc());
3295   Standard_Integer   indSol      = aStripe->SolidIndex();
3296
3297   Handle (TopOpeBRepDS_CurvePointInterference) anInterfp1;
3298   Handle (TopOpeBRepDS_CurvePointInterference) anInterfp2;
3299
3300   anInterfp1= ChFi3d_FilPointInDS(aCP1onArc.TransitionOnArc(), indArc1,
3301                                   indCP1onArc, aCP1onArc.ParameterOnArc());
3302   DStr.ChangeShapeInterferences(aCP1onArc.Arc()).Append(anInterfp1);
3303
3304   TopOpeBRepDS_ListOfInterference &SolidInterfs  =
3305                                    DStr.ChangeShapeInterferences(indSol);
3306   Handle(TopOpeBRepDS_SolidSurfaceInterference) SSI =
3307     new TopOpeBRepDS_SolidSurfaceInterference
3308                                       (TopOpeBRepDS_Transition(anOrSD1),
3309                                        TopOpeBRepDS_SOLID, indSol,
3310                                        TopOpeBRepDS_SURFACE, indSurf1);
3311   SolidInterfs.Append(SSI);
3312
3313 // deletion of Surface Data.
3314   aSeqSurfData.Remove(anInd);
3315
3316   if (!isFirst)
3317     anInd--;
3318
3319   aSurfData = aSeqSurfData.Value(anInd);
3320
3321 // definition of indices of common points in Data Structure
3322
3323   Standard_Integer indCP2onArc;
3324   Standard_Integer indCP2NotonArc;
3325
3326   if (is2ndCP1OnArc) {
3327     aStripe->SetIndexPoint(ChFi3d_IndexPointInDS(aCP2onArc,   DStr),isFirst,1);
3328     aStripe->SetIndexPoint(ChFi3d_IndexPointInDS(aCP2NotonArc,DStr),isFirst,2);
3329
3330     if (isFirst) {
3331       indCP2onArc    = aStripe->IndexFirstPointOnS1();
3332       indCP2NotonArc = aStripe->IndexFirstPointOnS2();
3333     } else {
3334       indCP2onArc    = aStripe->IndexLastPointOnS1();
3335       indCP2NotonArc = aStripe->IndexLastPointOnS2();
3336     }
3337   } else {
3338     aStripe->SetIndexPoint(ChFi3d_IndexPointInDS(aCP2onArc,   DStr),isFirst,2);
3339     aStripe->SetIndexPoint(ChFi3d_IndexPointInDS(aCP2NotonArc,DStr),isFirst,1);
3340
3341     if (isFirst) {
3342       indCP2onArc    = aStripe->IndexFirstPointOnS2();
3343       indCP2NotonArc = aStripe->IndexFirstPointOnS1();
3344     }
3345     else {
3346       indCP2onArc    = aStripe->IndexLastPointOnS2();
3347       indCP2NotonArc = aStripe->IndexLastPointOnS1();
3348     }
3349   }
3350
3351   Standard_Integer indPoint1;
3352   Standard_Integer indPoint2;
3353   gp_Pnt           aPoint1;
3354   gp_Pnt           aPoint2;
3355
3356   if (is2ndCP1OnArc)  {
3357     aFI      = aSurfData->InterferenceOnS1();
3358     indShape = aSurfData->IndexOfS1();
3359   } else {
3360     aFI      = aSurfData->InterferenceOnS2();
3361     indShape = aSurfData->IndexOfS2();
3362   }
3363
3364   gp_Pnt2d                                       aP2d;
3365   Handle (TopOpeBRepDS_SurfaceCurveInterference) anInterfc;
3366   TopAbs_Orientation                             anOrSurf = aCurOrient;
3367   TopAbs_Orientation                             anOrFace = aFace.Orientation();
3368   Standard_Integer                               indaFace = DStr.AddShape(aFace);
3369   Standard_Integer                               indPoint = indCP2onArc;
3370   Standard_Integer                               indCurve;
3371
3372   aFI.PCurveOnFace()->D0(aFI.LastParameter(), aP2d);
3373   Handle(Geom_Surface) Stemp2 =
3374                        BRep_Tool::Surface(TopoDS::Face(DStr.Shape(indShape)));
3375   Stemp2->D0(aP2d.X(), aP2d.Y(), aPoint2);
3376   aFI.PCurveOnFace()->D0(aFI.FirstParameter(), aP2d);
3377   Stemp2->D0(aP2d.X(), aP2d.Y(), aPoint1);
3378
3379   if (isDoSecondSection) {
3380     TopOpeBRepDS_Point tpoint(aPext,  aTolex2);
3381     TopOpeBRepDS_Curve tcint2(aCint2, aTolex2);
3382
3383     indPoint = DStr.AddPoint(tpoint);
3384     indCurve = DStr.AddCurve(tcint2);
3385
3386     aCint2->D0(aCint2->FirstParameter(), aPext1);
3387     aCint2->D0(aCint2->LastParameter(),  aPext2);
3388
3389     if (aPext1.Distance(aPext) <= aTol3d){
3390       indPoint1 = indPoint;
3391       indPoint2 = indCP2onArc;
3392     } else {
3393       indPoint1 = indCP2onArc;
3394       indPoint2 = indPoint;
3395     }
3396
3397 // define the orientation of aCint2
3398     if (aPext1.Distance(aPoint2) > aTol3d && aPext2.Distance(aPoint1) > aTol3d)
3399       anOrSurf = TopAbs::Reverse(anOrSurf);
3400
3401 // ---------------------------------------------------------------
3402 // storage of aCint2
3403     anInterfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD, indCurve,
3404                                      indPoint1, aCint2->FirstParameter());
3405     anInterfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED, indCurve,
3406                                      indPoint2, aCint2->LastParameter());
3407     DStr.ChangeCurveInterferences(indCurve).Append(anInterfp1);
3408     DStr.ChangeCurveInterferences(indCurve).Append(anInterfp2);
3409
3410   // interference of aCint2 on the SurfData number anIndPrev
3411     anInterfc = ChFi3d_FilCurveInDS(indCurve, aSurfData->Surf(),
3412                                     aPCint22, anOrSurf);
3413
3414     DStr.ChangeSurfaceInterferences(aSurfData->Surf()).Append(anInterfc);
3415   // interference of aCint2 on aFace
3416
3417     if (anOrFace == anOrSD2)
3418       anOrFace = TopAbs::Reverse(anOrSurf);
3419     else
3420       anOrFace = anOrSurf;
3421
3422     anInterfc = ChFi3d_FilCurveInDS(indCurve, indaFace, aPCint21, anOrFace);
3423     DStr.ChangeShapeInterferences(indaFace).Append(anInterfc);
3424   }
3425
3426   aTrCracc->D0(aTrCracc->FirstParameter(), aPext1);
3427   aTrCracc->D0(aTrCracc->LastParameter(),  aPext2);
3428   if (aPext1.Distance(aCP2NotonArc.Point()) <= aTol3d){
3429     indPoint1 = indCP2NotonArc;
3430     indPoint2 = indPoint;
3431   } else {
3432     indPoint1 = indPoint;
3433     indPoint2 = indCP2NotonArc;
3434   }
3435
3436 // Define the orientation of aTrCracc
3437   Standard_Boolean isToReverse;
3438   gp_Pnt           aP1;
3439   gp_Pnt           aP2;
3440   gp_Pnt           aP3;
3441   gp_Pnt           aP4;
3442
3443
3444   if (isDoSecondSection) {
3445     aTrCracc->D0(aTrCracc->FirstParameter(), aP1);
3446     aTrCracc->D0(aTrCracc->LastParameter(),  aP2);
3447     aCint2->D0(aCint2->FirstParameter(), aP3);
3448     aCint2->D0(aCint2->LastParameter(),  aP4);
3449     isToReverse = (aP1.Distance(aP4) > aTol3d && aP2.Distance(aP3) > aTol3d);
3450   } else {
3451     isToReverse = (aPext1.Distance(aPoint2) > aTol3d &&
3452                    aPext2.Distance(aPoint1) > aTol3d);
3453   }
3454
3455   if (isToReverse)
3456     anOrSurf = TopAbs::Reverse(anOrSurf);
3457
3458 // ---------------------------------------------------------------
3459 // storage of aTrCracc
3460   TopOpeBRepDS_Curve tct2(aTrCracc, aTolReached);
3461
3462   indCurve = DStr.AddCurve(tct2);
3463   anInterfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,indCurve,
3464                                    indPoint1, aTrCracc->FirstParameter());
3465   anInterfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED,indCurve,
3466                                    indPoint2, aTrCracc->LastParameter());
3467   DStr.ChangeCurveInterferences(indCurve).Append(anInterfp1);
3468   DStr.ChangeCurveInterferences(indCurve).Append(anInterfp2);
3469
3470   // interference of aTrCracc on the SurfData number anIndPrev
3471
3472   anInterfc = ChFi3d_FilCurveInDS(indCurve,aSurfData->Surf(),aPCraccS, anOrSurf);
3473   DStr.ChangeSurfaceInterferences(aSurfData->Surf()).Append(anInterfc);
3474   aStripe->InDS(isFirst);
3475
3476   // interference of aTrCracc on the SurfData number anInd
3477   if (anOrSD1 == anOrSD2)
3478     anOrSurf = TopAbs::Reverse(anOrSurf);
3479
3480   anInterfc = ChFi3d_FilCurveInDS(indCurve, indSurf1, aPCurv1, anOrSurf);
3481   DStr.ChangeSurfaceInterferences(indSurf1).Append(anInterfc);
3482
3483 // ---------------------------------------------------------------
3484 // storage of aCint1
3485
3486   aCint1->D0(aCint1->FirstParameter(),aPext1);
3487   if (aPext1.Distance(aCP1onArc.Point()) <= aTol3d){
3488     indPoint1 = indCP1onArc;
3489     indPoint2 = indPoint;
3490   } else {
3491     indPoint1 = indPoint;
3492     indPoint2 = indCP1onArc;
3493   }
3494
3495   //  definition of the orientation of aCint1
3496
3497   aCint1->D0(aCint1->FirstParameter(), aP1);
3498   aCint1->D0(aCint1->LastParameter(),  aP2);
3499   aTrCracc->D0(aTrCracc->FirstParameter(), aP3);
3500   aTrCracc->D0(aTrCracc->LastParameter(),  aP4);
3501
3502   if (aP1.Distance(aP4) > aTol3d && aP2.Distance(aP3) > aTol3d)
3503     anOrSurf=TopAbs::Reverse(anOrSurf);
3504
3505   TopOpeBRepDS_Curve aTCint1(aCint1, aTolex1);
3506   indCurve= DStr.AddCurve(aTCint1);
3507   anInterfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD, indCurve,
3508                                    indPoint1, aCint1->FirstParameter());
3509   anInterfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED, indCurve,
3510                                    indPoint2, aCint1->LastParameter());
3511   DStr.ChangeCurveInterferences(indCurve).Append(anInterfp1);
3512   DStr.ChangeCurveInterferences(indCurve).Append(anInterfp2);
3513
3514   // interference of aCint1 on the SurfData number anInd
3515
3516   anInterfc = ChFi3d_FilCurveInDS(indCurve, indSurf1, aPCint12, anOrSurf);
3517   DStr.ChangeSurfaceInterferences(indSurf1).Append(anInterfc);
3518
3519   // interference of aCint1 on aFace
3520
3521   anOrFace = aFace.Orientation();
3522
3523   if (anOrFace == anOrSD1)
3524     anOrFace = TopAbs::Reverse(anOrSurf);
3525   else
3526     anOrFace = anOrSurf;
3527
3528   anInterfc = ChFi3d_FilCurveInDS(indCurve, indaFace, aPCint11, anOrFace);
3529   DStr.ChangeShapeInterferences(indaFace).Append(anInterfc);
3530 // ---------------------------------------------------------------
3531 // storage of aCline passing through aCP1onArc and aCP2NotonArc
3532
3533   Handle(Geom_Curve) aTrCline   =
3534                      new Geom_TrimmedCurve(aCline, aCline->FirstParameter(),
3535                                                    aCline->LastParameter());
3536   Standard_Real      aTolerance = DStr.Curve(indLine).Tolerance();
3537   TopOpeBRepDS_Curve aTct3(aTrCline, aTolerance);
3538
3539   indCurve = DStr.AddCurve(aTct3);
3540
3541   aTrCline->D0(aTrCline->FirstParameter(),aPext1);
3542
3543   if (aPext1.Distance(aCP1onArc.Point()) < aTol3d) {
3544     indPoint1 = indCP1onArc;
3545     indPoint2 = indCP2NotonArc;
3546   } else {
3547     indPoint1 = indCP2NotonArc;
3548     indPoint2 = indCP1onArc;
3549   }
3550   //  definition of the orientation of aTrCline
3551
3552   aTrCline->D0(aTrCline->FirstParameter(), aP1);
3553   aTrCline->D0(aTrCline->LastParameter(),  aP2);
3554   aCint1->D0(aCint1->FirstParameter(), aP3);
3555   aCint1->D0(aCint1->LastParameter(),  aP4);
3556
3557   if (aP1.Distance(aP4) > aTol3d && aP2.Distance(aP3) > aTol3d)
3558     anOrSurf = TopAbs::Reverse(anOrSurf);
3559
3560   anInterfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,indCurve,
3561                                    indPoint1,aTrCline->FirstParameter());
3562   anInterfp2 = ChFi3d_FilPointInDS(TopAbs_REVERSED,indCurve,
3563                                    indPoint2,aTrCline->LastParameter());
3564   DStr.ChangeCurveInterferences(indCurve).Append(anInterfp1);
3565   DStr.ChangeCurveInterferences(indCurve).Append(anInterfp2);
3566
3567   // interference of aTrCline on the SurfData number anInd
3568
3569   anInterfc = ChFi3d_FilCurveInDS(indCurve, indSurf1, aPClineOnSurf, anOrSurf);
3570   DStr.ChangeSurfaceInterferences(indSurf1).Append(anInterfc);
3571
3572   // interference de ctlin par rapport a Fvoisin
3573   indShape = DStr.AddShape(aNeighborFace);
3574   anOrFace = aNeighborFace.Orientation();
3575
3576   if (anOrFace == anOrSD1)
3577     anOrFace = TopAbs::Reverse(anOrSurf);
3578   else
3579     anOrFace = anOrSurf;
3580
3581   anInterfc = ChFi3d_FilCurveInDS(indCurve, indShape, aPClineOnFace, anOrFace);
3582   DStr.ChangeShapeInterferences(indShape).Append(anInterfc);
3583 }
3584 //  Modified by Sergey KHROMOV - Thu Apr 11 12:23:40 2002 End
3585
3586 //==============================================================
3587 //function : FindFace
3588 //purpose  : attention it works only if there is only one common face 
3589 //           between P1,P2,V
3590 //===========================================================
3591
3592
3593 Standard_Boolean ChFi3d_Builder::FindFace(const TopoDS_Vertex& V,
3594                                           const ChFiDS_CommonPoint& P1,
3595                                           const ChFiDS_CommonPoint& P2,
3596                                           TopoDS_Face& Fv) const
3597 {
3598   TopoDS_Face Favoid;
3599   return FindFace(V,P1,P2,Fv,Favoid);
3600 }
3601
3602 Standard_Boolean ChFi3d_Builder::FindFace(const TopoDS_Vertex& V,
3603                                           const ChFiDS_CommonPoint& P1,
3604                                           const ChFiDS_CommonPoint& P2,
3605                                           TopoDS_Face& Fv,
3606                                           const TopoDS_Face& Favoid) const
3607 {
3608   if (P1.IsVertex() || P2.IsVertex()) {
3609 #ifdef DEB
3610     cout<<"change of face on vertex"<<endl;
3611 #endif
3612   }
3613   if (!(P1.IsOnArc() && P2.IsOnArc())) {
3614     return Standard_False;
3615   }
3616   TopTools_ListIteratorOfListOfShape It,Jt;
3617   Standard_Boolean Found = Standard_False, ContainsV = Standard_False;
3618   for(It.Initialize(myEFMap(P1.Arc()));It.More() && !Found;It.Next()) {
3619     Fv = TopoDS::Face(It.Value());
3620     if(!Fv.IsSame(Favoid)){
3621       for(Jt.Initialize(myEFMap(P2.Arc()));Jt.More() && !Found ;Jt.Next()) {
3622         if (TopoDS::Face(Jt.Value()).IsSame(Fv)) Found = Standard_True;
3623       }
3624     }
3625   }
3626   if (Found) {
3627     for(It.Initialize(myVFMap(V));It.More();It.Next()) {
3628       if (TopoDS::Face(It.Value()).IsSame(Fv)) {
3629         ContainsV = Standard_True;
3630         break;
3631       }
3632     }
3633   }
3634 #ifdef DEB
3635   if(!ContainsV){
3636     cout<<"FindFace : the extremity of the spine is not in the end face"<<endl;
3637   }
3638 #endif
3639   return Found;
3640 }
3641
3642 //=======================================================================
3643 //function : MoreSurfdata
3644 //purpose  : detects if the intersection at end concerns several Surfdata
3645 //=======================================================================
3646 Standard_Boolean ChFi3d_Builder::MoreSurfdata(const Standard_Integer Index) const
3647 {
3648   // intersection at end is created on several surfdata if :
3649   // - the number of surfdata concerning the vertex is more than 1.
3650   // - and if the last but one surfdata has one of commonpoints on one of 
3651   // two arcs, which constitute the intersections of the face at end and of the fillet
3652
3653   ChFiDS_ListIteratorOfListOfStripe It;
3654   It.Initialize(myVDataMap(Index));
3655   Handle(ChFiDS_Stripe)& stripe = It.Value();
3656   ChFiDS_SequenceOfSurfData& SeqFil =
3657     stripe->ChangeSetOfSurfData()->ChangeSequence();
3658   const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index);
3659   Standard_Integer sens = 0;
3660   Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens);
3661   Standard_Boolean isfirst = (sens == 1);
3662   Handle(ChFiDS_SurfData)& Fd = SeqFil.ChangeValue(num);
3663   ChFiDS_CommonPoint& CV1 = Fd->ChangeVertex(isfirst,1);
3664   ChFiDS_CommonPoint& CV2 = Fd->ChangeVertex(isfirst,2);
3665
3666   Standard_Integer num1,num2,nbsurf;
3667   TopoDS_Face Fv;
3668   Standard_Boolean inters,oksurf;
3669   nbsurf= stripe->SetOfSurfData()->Length();
3670   // Fv is the face at end
3671   inters = FindFace(Vtx,CV1,CV2,Fv);
3672   if (sens==1)  {
3673     num1=1;
3674     num2=num1+1;
3675   }
3676   else {
3677     num1=nbsurf;
3678     num2=num1-1;
3679   }
3680
3681   oksurf=Standard_False;
3682
3683   if (nbsurf!=1 && inters) {
3684
3685     // determination of arc1 and arc2 intersection of the fillet and the face at end
3686
3687     TopoDS_Edge arc1,arc2;
3688     TopTools_ListIteratorOfListOfShape ItE;
3689     Standard_Boolean trouve=Standard_False;
3690     for(ItE.Initialize(myVEMap(Vtx));ItE.More()&&!trouve;ItE.Next()) {
3691       arc1=TopoDS::Edge(ItE.Value());
3692       if (containE(Fv,arc1)) trouve=Standard_True;
3693     }
3694     trouve=Standard_False;
3695     for(ItE.Initialize(myVEMap(Vtx));ItE.More()&&!trouve;ItE.Next()) {
3696       arc2=TopoDS::Edge(ItE.Value());
3697       if (containE(Fv,arc2)&& !arc2.IsSame(arc1)) trouve=Standard_True;
3698     }
3699
3700     Handle(ChFiDS_SurfData) Fd1 = SeqFil.ChangeValue(num2);
3701     ChFiDS_CommonPoint& CV3 = Fd1->ChangeVertex(isfirst,1);
3702     ChFiDS_CommonPoint& CV4 = Fd1->ChangeVertex(isfirst,2);
3703
3704     if (CV3.IsOnArc()) {
3705       if (CV3.Arc().IsSame(arc1) ){
3706         if (CV1.Point().Distance(CV3.Point())<1.e-4)
3707           oksurf=Standard_True;
3708       }
3709       else if (CV3.Arc().IsSame(arc2)){
3710         if (CV2.Point().Distance(CV3.Point())<1.e-4)
3711           oksurf=Standard_True;
3712       }
3713     }
3714
3715     if (CV4.IsOnArc()) {
3716       if (CV1.Point().Distance(CV4.Point())<1.e-4)
3717         oksurf=Standard_True;
3718       else if  (CV4.Arc().IsSame(arc2)){
3719         if (CV2.Point().Distance(CV4.Point())<1.e-4)
3720           oksurf=Standard_True;
3721       }
3722     }
3723   }
3724   return oksurf;
3725 }
3726
3727
3728 //Case of fillets on top with 4 edges, one of them is on the same geometry as the edgeof the fillet
3729
3730
3731 void ChFi3d_Builder::IntersectMoreCorner(const Standard_Integer Index)
3732 {
3733   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
3734
3735 #ifdef DEB
3736   OSD_Chronometer ch;// init perf pour PerformSetOfKPart
3737 #endif
3738   // The fillet is returned,
3739   ChFiDS_ListIteratorOfListOfStripe StrIt;
3740   StrIt.Initialize(myVDataMap(Index));
3741   Handle(ChFiDS_Stripe) stripe = StrIt.Value();
3742   const Handle(ChFiDS_Spine) spine = stripe->Spine();
3743   ChFiDS_SequenceOfSurfData& SeqFil =
3744     stripe->ChangeSetOfSurfData()->ChangeSequence();
3745   // the top,
3746   const TopoDS_Vertex& Vtx = myVDataMap.FindKey(Index);
3747   // the SurfData concerned and its CommonPoints,
3748   Standard_Integer sens = 0;
3749
3750   // Choose the proper SurfData
3751   Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens);
3752   Standard_Boolean isfirst = (sens == 1);
3753   if (isfirst) {
3754     for (; num<SeqFil.Length() && (
3755          (SeqFil.Value(num)->IndexOfS1()==0) ||
3756          (SeqFil.Value(num)->IndexOfS2()==0) ); ) {
3757       SeqFil.Remove(num); // The surplus is removed
3758     }
3759   }
3760   else {
3761    for (; num>1 && (
3762          (SeqFil.Value(num)->IndexOfS1()==0) ||
3763          (SeqFil.Value(num)->IndexOfS2()==0) ); ) {
3764      SeqFil.Remove(num);// The surplus is removed
3765      num--;
3766     }
3767   }
3768
3769   Handle(ChFiDS_SurfData)& Fd = SeqFil.ChangeValue(num);
3770   ChFiDS_CommonPoint& CV1 = Fd->ChangeVertex(isfirst,1);
3771   ChFiDS_CommonPoint& CV2 = Fd->ChangeVertex(isfirst,2);
3772   //To evaluate the cloud of new points.
3773   Bnd_Box box1,box2;
3774
3775   // The cases of cap are processed separately from intersection.
3776   // ----------------------------------------------------------
3777
3778   TopoDS_Face Fv,Fad,Fop,Fopbis;
3779   TopoDS_Edge Arcpiv,Arcprol,Arcspine,Arcprolbis;
3780   if(isfirst) Arcspine = spine->Edges(1);
3781   else Arcspine = spine->Edges(spine->NbEdges());
3782   TopAbs_Orientation OArcprolbis;
3783 #ifndef DEB
3784   TopAbs_Orientation OArcprolv = TopAbs_FORWARD, OArcprolop = TopAbs_FORWARD;
3785 #else
3786   TopAbs_Orientation OArcprolv, OArcprolop;
3787 #endif
3788   Standard_Integer ICurve;
3789   Handle(BRepAdaptor_HSurface) HBs  = new BRepAdaptor_HSurface();
3790   Handle(BRepAdaptor_HSurface) HBad = new BRepAdaptor_HSurface();
3791   Handle(BRepAdaptor_HSurface) HBop = new BRepAdaptor_HSurface();
3792   BRepAdaptor_Surface& Bs  = HBs->ChangeSurface();
3793   BRepAdaptor_Surface& Bad = HBad->ChangeSurface();
3794   BRepAdaptor_Surface& Bop = HBop->ChangeSurface();
3795   Handle(Geom_Curve) Cc;
3796   Handle(Geom2d_Curve) Pc,Ps;
3797   Standard_Real Ubid,Vbid;//,mu,Mu,mv,Mv;
3798 #ifndef DEB
3799   Standard_Real Udeb = 0.,Ufin = 0.;
3800 #else
3801   Standard_Real Udeb,Ufin;
3802 #endif
3803   //gp_Pnt2d UVf1,UVl1,UVf2,UVl2;
3804   //Standard_Real Du,Dv,Step;
3805   Standard_Boolean inters = Standard_True;
3806   Standard_Integer IFadArc = 1, IFopArc = 2;
3807   Fop = TopoDS::Face(DStr.Shape(Fd->Index(IFopArc)));
3808   TopExp_Explorer ex;
3809
3810 #ifdef DEB
3811   ChFi3d_InitChron(ch); // init perf condition
3812 #endif
3813   {
3814     if(!CV1.IsOnArc() && !CV2.IsOnArc())
3815       Standard_Failure::Raise("Corner intersmore : no point on arc");
3816     else if(CV1.IsOnArc() && CV2.IsOnArc()){
3817       Standard_Boolean sur1 = 0, sur2 = 0;
3818       for(ex.Init(CV1.Arc(),TopAbs_VERTEX); ex.More(); ex.Next()){
3819         if(Vtx.IsSame(ex.Current())) {
3820           sur1 = 1;
3821           break;
3822         }
3823       }
3824       for(ex.Init(CV2.Arc(),TopAbs_VERTEX); ex.More(); ex.Next()){
3825         if(Vtx.IsSame(ex.Current())){
3826           sur2 = 1;
3827           break;
3828         }
3829       }
3830       if(sur2) IFadArc = 2;
3831     }
3832     else if(CV2.IsOnArc()) IFadArc = 2;
3833     IFopArc = 3-IFadArc;
3834
3835     Arcpiv = Fd->Vertex(isfirst,IFadArc).Arc();
3836     Fad = TopoDS::Face(DStr.Shape(Fd->Index(IFadArc)));
3837     Fop = TopoDS::Face(DStr.Shape(Fd->Index(IFopArc)));
3838     TopTools_ListIteratorOfListOfShape It;
3839     // The face at end is returned without control of its unicity.
3840     for(It.Initialize(myEFMap(Arcpiv));It.More();It.Next()) {
3841       if(!Fad.IsSame(It.Value())){
3842         Fv = TopoDS::Face(It.Value());
3843         break;
3844       }
3845     }
3846
3847     // does the face at end contain the Vertex ?
3848     Standard_Boolean isinface = Standard_False;
3849     for (ex.Init(Fv,TopAbs_VERTEX); ex.More(); ex.Next()){
3850       if (ex.Current().IsSame(Vtx)) {
3851         isinface = Standard_True;
3852         break;
3853       }
3854     }
3855     if (!isinface) {
3856       IFadArc = 3-IFadArc;
3857       IFopArc = 3-IFopArc;
3858       Arcpiv = Fd->Vertex(isfirst,IFadArc).Arc();
3859       Fad = TopoDS::Face(DStr.Shape(Fd->Index(IFadArc)));
3860       Fop = TopoDS::Face(DStr.Shape(Fd->Index(IFopArc)));
3861       //TopTools_ListIteratorOfListOfShape It;
3862     // The face at end is returned without control of its unicity.
3863      for(It.Initialize(myEFMap(Arcpiv));It.More();It.Next()) {
3864         if(!Fad.IsSame(It.Value())){
3865           Fv = TopoDS::Face(It.Value());
3866           break;
3867         }
3868       }
3869     }
3870
3871     if(Fv.IsNull()) StdFail_NotDone::Raise
3872       ("OneCorner : face at end is not found");
3873
3874     Fv.Orientation(TopAbs_FORWARD);
3875     Fad.Orientation(TopAbs_FORWARD);
3876
3877     // In the same way the edge to be extended is returned.
3878     for(It.Initialize(myVEMap(Vtx));It.More() && Arcprol.IsNull();It.Next()){
3879       if(!Arcpiv.IsSame(It.Value())){
3880         for(ex.Init(Fv,TopAbs_EDGE); ex.More(); ex.Next()){
3881           if(It.Value().IsSame(ex.Current())) {
3882             Arcprol = TopoDS::Edge(It.Value());
3883             OArcprolv = ex.Current().Orientation();
3884             break;
3885           }
3886         }
3887       }
3888     }
3889
3890     //Fopbis is the face containing the trace of fillet CP.Arc() which of does not contain Vtx.
3891     //Normallly Fobis is either the same as Fop (cylinder), or Fobis is G1 with Fop.
3892     Fopbis.Orientation(TopAbs_FORWARD);
3893
3894     //Fop calls the 4th face non-used for the vertex
3895     cherche_face(myVFMap(Vtx),Arcprol,Fad,Fv,Fv,Fopbis);
3896     Fop.Orientation(TopAbs_FORWARD);
3897
3898     if(Arcprol.IsNull()) StdFail_NotDone::Raise
3899       ("OneCorner : edge to be extended is not found");
3900     for(ex.Init(Fopbis,TopAbs_EDGE); ex.More(); ex.Next()){
3901       if(Arcprol.IsSame(ex.Current())) {
3902         OArcprolop = ex.Current().Orientation();
3903         break;
3904       }
3905     }
3906     TopoDS_Face FFv;
3907     Standard_Real tol;
3908     Standard_Integer prol;
3909     BRep_Builder BRE;
3910     Handle(Geom_Surface ) Sface;
3911     Sface=BRep_Tool::Surface(Fv);
3912     ChFi3d_ExtendSurface(Sface,prol);
3913     tol=BRep_Tool::Tolerance(Fv);
3914     BRE.MakeFace(FFv,Sface,tol);
3915     if (prol) {
3916       Bs.Initialize(FFv,Standard_False);
3917       DStr.SetNewSurface(Fv,Sface);
3918     }
3919     else Bs.Initialize(Fv,Standard_False);
3920     Bad.Initialize(Fad);
3921     Bop.Initialize(Fop);
3922   }
3923   // it is necessary to modify the CommonPoint
3924   // in the space and its parameter in FaceInterference.
3925   // So both of them are returned in references
3926   // non const. Attention the modifications are done behind
3927   // CV1,CV2,Fi1,Fi2.
3928   ChFiDS_CommonPoint& CPopArc = Fd->ChangeVertex(isfirst,IFopArc);
3929   ChFiDS_FaceInterference& FiopArc = Fd->ChangeInterference(IFopArc);
3930   ChFiDS_CommonPoint& CPadArc = Fd->ChangeVertex(isfirst,IFadArc);
3931   ChFiDS_FaceInterference& FiadArc = Fd->ChangeInterference(IFadArc);
3932   // the parameter of the vertex is initialized with the value 
3933   // of its opposing vertex (point on arc).
3934   Standard_Real wop = Fd->ChangeInterference(IFadArc).Parameter(isfirst);
3935   Handle(Geom_Curve) c3df;
3936   Handle(GeomAdaptor_HSurface)
3937     HGs = new GeomAdaptor_HSurface(DStr.Surface(Fd->Surf()).Surface());
3938   gp_Pnt2d p2dbout;
3939   {
3940
3941     // add here more or less restrictive criteria to
3942     // decide if the intersection with face is done at the
3943     // extended end or if there will be a cap on sharp end.
3944     c3df = DStr.Curve(FiopArc.LineIndex()).Curve();
3945     Standard_Real uf = FiopArc.FirstParameter();
3946     Standard_Real ul = FiopArc.LastParameter();
3947       Handle(GeomAdaptor_HCurve) Hc3df;
3948     if(c3df->IsPeriodic()){
3949       Hc3df = new GeomAdaptor_HCurve(c3df);
3950     }
3951     else{
3952       Hc3df = new GeomAdaptor_HCurve(c3df,uf,ul);
3953     }
3954     inters = Update(HBs,Hc3df,FiopArc,CPopArc,p2dbout,isfirst,wop);
3955 //  Modified by Sergey KHROMOV - Fri Dec 21 18:08:27 2001 Begin
3956 //  if(!inters && BRep_Tool::Continuity(Arcprol,Fv,Fop) != GeomAbs_C0){
3957     if(!inters && isTangentFaces(Arcprol,Fv,Fop)){
3958 //  Modified by Sergey KHROMOV - Fri Dec 21 18:08:29 2001 End
3959       // Arcprol is an edge of tangency, ultimate adjustment by an extrema curve/curve is attempted.
3960       Standard_Real ff,ll;
3961       Handle(Geom2d_Curve) gpcprol = BRep_Tool::CurveOnSurface(Arcprol,Fv,ff,ll);
3962       Handle(Geom2dAdaptor_HCurve) pcprol = new Geom2dAdaptor_HCurve(gpcprol);
3963       Standard_Real partemp = BRep_Tool::Parameter(Vtx,Arcprol);
3964       inters = Update(HBs,pcprol,HGs,FiopArc,CPopArc,p2dbout,
3965                       isfirst,partemp,wop,10*tolesp);
3966     }
3967     Handle(BRepAdaptor_HCurve2d) pced = new BRepAdaptor_HCurve2d();
3968     pced->ChangeCurve2d().Initialize(CPadArc.Arc(),Fv);
3969     Update(HBs,pced,HGs,FiadArc,CPadArc,isfirst);
3970   }
3971 #ifdef DEB
3972   ChFi3d_ResultChron(ch,t_same); // result perf condition if (same)
3973   ChFi3d_InitChron(ch); // init perf condition if (inters)
3974 #endif
3975
3976   TopoDS_Edge edgecouture;
3977   Standard_Boolean couture,intcouture=Standard_False;;
3978   Standard_Real tolreached;
3979 #ifndef DEB
3980   Standard_Real par1 = 0.,par2 = 0.;
3981   Standard_Integer indpt =0,Icurv1 =0,Icurv2 =0;
3982 #else
3983   Standard_Real par1,par2;
3984   Standard_Integer indpt,Icurv1,Icurv2;
3985 #endif
3986   Handle(Geom_TrimmedCurve) curv1,curv2;
3987   Handle(Geom2d_Curve) c2d1,c2d2;
3988
3989   Standard_Integer Isurf=Fd->Surf();
3990
3991   if (inters){
3992     HGs = ChFi3d_BoundSurf(DStr,Fd,1,2);
3993     const ChFiDS_FaceInterference& Fi1 = Fd->InterferenceOnS1();
3994     const ChFiDS_FaceInterference& Fi2 = Fd->InterferenceOnS2();
3995     TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4);
3996     gp_Pnt2d pfil1,pfac1,pfil2,pfac2;
3997     Handle(Geom2d_Curve) Hc1,Hc2;
3998     if( IFopArc == 1) pfac1 = p2dbout;
3999     else {
4000       Hc1 = BRep_Tool::CurveOnSurface(CV1.Arc(),Fv,Ubid,Ubid);
4001       pfac1 = Hc1->Value(CV1.ParameterOnArc());
4002     }
4003     if(IFopArc == 2) pfac2 = p2dbout;
4004     else {
4005       Hc2 = BRep_Tool::CurveOnSurface(CV2.Arc(),Fv,Ubid,Ubid);
4006       pfac2 = Hc2->Value(CV2.ParameterOnArc());
4007     }
4008     if(Fi1.LineIndex() != 0){
4009       pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(isfirst));
4010     }
4011     else{
4012       pfil1 = Fi1.PCurveOnSurf()->Value(Fi1.Parameter(!isfirst));
4013     }
4014     if(Fi2.LineIndex() != 0){
4015       pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(isfirst));
4016     }
4017     else{
4018       pfil2 = Fi2.PCurveOnSurf()->Value(Fi2.Parameter(!isfirst));
4019     }
4020     ChFi3d_Recale(Bs,pfac1,pfac2,(IFadArc == 1));
4021     Pardeb(1)= pfil1.X();Pardeb(2) = pfil1.Y();
4022     Pardeb(3)= pfac1.X();Pardeb(4) = pfac1.Y();
4023     Parfin(1)= pfil2.X();Parfin(2) = pfil2.Y();
4024     Parfin(3)= pfac2.X();Parfin(4) = pfac2.Y();
4025     Standard_Real uu1,uu2,vv1,vv2;
4026     ChFi3d_Boite(pfac1,pfac2,uu1,uu2,vv1,vv2);
4027     ChFi3d_BoundFac(Bs,uu1,uu2,vv1,vv2);
4028
4029     if (!ChFi3d_ComputeCurves(HGs,HBs,Pardeb,Parfin,Cc,
4030                               Ps,
4031                               Pc,tolesp,tol2d,tolreached))
4032     Standard_Failure::Raise("OneCorner : failed calculation intersection");
4033
4034     Udeb = Cc->FirstParameter();
4035     Ufin = Cc->LastParameter();
4036
4037     // check if the curve has an intersection with sewing edge
4038
4039     ChFi3d_Couture(Fv,couture,edgecouture);
4040
4041     if (couture  && !BRep_Tool::Degenerated(edgecouture)) {
4042
4043       //Standard_Real Ubid,Vbid;
4044       Handle (Geom_Curve) C=BRep_Tool::Curve(edgecouture,Ubid,Vbid);
4045       Handle(Geom_TrimmedCurve) Ctrim=new Geom_TrimmedCurve (C,Ubid,Vbid);
4046       GeomAdaptor_Curve cur1(Ctrim->BasisCurve());
4047       GeomAdaptor_Curve cur2(Cc);
4048       Extrema_ExtCC extCC (cur1,cur2);
4049       if (extCC.IsDone()&&extCC.NbExt()!=0)
4050         {
4051           Standard_Integer imin=0;
4052           Standard_Real dist2min = RealLast();
4053           for (Standard_Integer i = 1; i <= extCC.NbExt(); i++)
4054             if (extCC.SquareDistance(i) < dist2min)
4055               {
4056                 dist2min = extCC.SquareDistance(i);
4057                 imin = i;
4058               }
4059           if (dist2min <= Precision::Confusion() * Precision::Confusion())
4060             {
4061               Extrema_POnCurv ponc1,ponc2;
4062               extCC.Points( imin, ponc1, ponc2 );
4063               par1 = ponc1.Parameter();
4064               par2 = ponc2.Parameter();
4065               Standard_Real Tol = 1.e-4;
4066               if (Abs(par2-Udeb) > Tol && Abs(Ufin-par2) > Tol)
4067                 {
4068                   gp_Pnt P1=ponc1.Value();
4069                   TopOpeBRepDS_Point tpoint( P1, Tol );
4070                   indpt = DStr.AddPoint(tpoint);
4071                   intcouture = Standard_True;
4072                   curv1 = new Geom_TrimmedCurve(Cc,Udeb,par2);
4073                   curv2 = new Geom_TrimmedCurve(Cc,par2,Ufin);
4074                   TopOpeBRepDS_Curve tcurv1(curv1,tolreached);
4075                   TopOpeBRepDS_Curve tcurv2(curv2,tolreached);
4076                   Icurv1=DStr.AddCurve(tcurv1);
4077                   Icurv2=DStr.AddCurve(tcurv2);
4078                 }
4079             }
4080         }
4081     }
4082   }
4083
4084   else{
4085     Standard_NotImplemented::Raise("OneCorner : cap not written");
4086   }
4087   Standard_Integer IShape = DStr.AddShape(Fv);
4088 #ifndef DEB
4089   TopAbs_Orientation Et = TopAbs_FORWARD;
4090 #else
4091   TopAbs_Orientation Et;
4092 #endif
4093   if(IFadArc == 1){
4094     TopExp_Explorer Exp;
4095     for (Exp.Init(Fv.Oriented(TopAbs_FORWARD),
4096                   TopAbs_EDGE);Exp.More();Exp.Next()) {
4097       if (Exp.Current().IsSame(CV1.Arc())) {
4098         Et = TopAbs::Reverse(TopAbs::Compose
4099                              (Exp.Current().Orientation(),
4100                               CV1.TransitionOnArc()));
4101         break;
4102       }
4103     }
4104   }
4105   else{
4106     TopExp_Explorer Exp;
4107     for (Exp.Init(Fv.Oriented(TopAbs_FORWARD),
4108                   TopAbs_EDGE);Exp.More();Exp.Next()) {
4109       if (Exp.Current().IsSame(CV2.Arc())) {
4110         Et = TopAbs::Compose(Exp.Current().Orientation(),
4111                              CV2.TransitionOnArc());
4112         break;
4113       }
4114     }
4115
4116 //
4117
4118
4119   }
4120
4121 #ifdef DEB
4122   ChFi3d_ResultChron(ch ,t_inter); //result perf condition if (inter)
4123   ChFi3d_InitChron(ch); // init perf condition  if ( inters)
4124 #endif
4125
4126   stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV1,DStr),isfirst,1);
4127   stripe->SetIndexPoint(ChFi3d_IndexPointInDS(CV2,DStr),isfirst,2);
4128
4129   if (!intcouture) {
4130 // there is no intersection with edge of sewing
4131 // curve Cc is stored in the stripe
4132 // the storage in the DS is done by FILDS.
4133
4134     TopOpeBRepDS_Curve Tc(Cc,tolreached);
4135     ICurve = DStr.AddCurve(Tc);
4136     Handle(TopOpeBRepDS_SurfaceCurveInterference)
4137       Interfc = ChFi3d_FilCurveInDS(ICurve,IShape,Pc,Et);
4138     DStr.ChangeShapeInterferences(IShape).Append(Interfc);
4139     stripe->ChangePCurve(isfirst)=Ps;
4140     stripe->SetCurve(ICurve,isfirst);
4141     stripe->SetParameters(isfirst,Udeb,Ufin);
4142    }
4143   else {
4144 // curves curv1 and curv2 are stored in the DS
4145 // these curves are not reconstructed by FILDS as
4146 // stripe->InDS(isfirst) is placed;
4147
4148     // interferences of curv1 and curv2 on Fv
4149     ComputeCurve2d(curv1,Fv,c2d1);
4150     Handle(TopOpeBRepDS_SurfaceCurveInterference) InterFv;
4151     InterFv = ChFi3d_FilCurveInDS(Icurv1,IShape,c2d1,Et);
4152     DStr.ChangeShapeInterferences(IShape).Append(InterFv);
4153     ComputeCurve2d(curv2,Fv,c2d2);
4154     InterFv = ChFi3d_FilCurveInDS(Icurv2,IShape,c2d2,Et);
4155     DStr.ChangeShapeInterferences(IShape).Append(InterFv);
4156      // interferences of curv1 and curv2 on Isurf
4157     if (Fd->Orientation()== Fv.Orientation()) Et=TopAbs::Reverse(Et);
4158     c2d1=new Geom2d_TrimmedCurve(Ps,Udeb,par2);
4159     InterFv = ChFi3d_FilCurveInDS(Icurv1,Isurf,c2d1,Et);
4160     DStr.ChangeSurfaceInterferences(Isurf).Append(InterFv);
4161     c2d2=new Geom2d_TrimmedCurve(Ps,par2,Ufin);
4162        InterFv = ChFi3d_FilCurveInDS(Icurv2,Isurf,c2d2,Et);
4163     DStr.ChangeSurfaceInterferences(Isurf).Append(InterFv);
4164
4165       // limitation of the sewing edge
4166     Standard_Integer Iarc=DStr.AddShape(edgecouture);
4167     Handle(TopOpeBRepDS_CurvePointInterference) Interfedge;
4168     TopAbs_Orientation ori;
4169     TopoDS_Vertex Vdeb,Vfin;
4170     Vdeb=TopExp::FirstVertex(edgecouture);
4171     Vfin=TopExp::LastVertex(edgecouture);
4172     Standard_Real pard,parf;
4173     pard=BRep_Tool::Parameter(Vdeb,edgecouture);
4174     parf=BRep_Tool::Parameter(Vfin,edgecouture);
4175     if (Abs(par1-pard)<Abs(parf-par1)) ori=TopAbs_FORWARD;
4176     else ori=TopAbs_REVERSED;
4177     Interfedge = ChFi3d_FilPointInDS(ori,Iarc,indpt,par1);
4178     DStr.ChangeShapeInterferences(Iarc).Append(Interfedge);
4179
4180     // creation of CurveInterferences from Icurv1 and Icurv2
4181     stripe->InDS(isfirst);
4182     Standard_Integer ind1= stripe->IndexPoint(isfirst,1);
4183     Standard_Integer ind2= stripe->IndexPoint(isfirst,2);
4184     Handle(TopOpeBRepDS_CurvePointInterference)
4185       interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv1,ind1,Udeb);
4186     DStr.ChangeCurveInterferences(Icurv1).Append(interfprol);
4187     interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv1,indpt,par2);
4188     DStr.ChangeCurveInterferences(Icurv1).Append(interfprol);
4189     interfprol = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv2,indpt,par2);
4190     DStr.ChangeCurveInterferences(Icurv2).Append(interfprol);
4191     interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv2,ind2,Ufin);
4192     DStr.ChangeCurveInterferences(Icurv2).Append(interfprol);
4193
4194   }
4195
4196   ChFi3d_EnlargeBox(HBs,Pc,Udeb,Ufin,box1,box2);
4197
4198   if( inters){
4199 //
4200
4201     // The small end of curve missing for the extension
4202     // of the face at end and the limitation of the opposing face is added.
4203
4204     // Above all the points cut the points with the edge of the spine.
4205     Standard_Integer IArcspine = DStr.AddShape(Arcspine);
4206     Standard_Integer IVtx = DStr.AddShape(Vtx);
4207     TopAbs_Orientation OVtx2;
4208 #ifndef DEB
4209     TopAbs_Orientation OVtx = TopAbs_FORWARD;
4210 #else
4211     TopAbs_Orientation OVtx;
4212 #endif
4213     for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
4214         ex.More(); ex.Next()){
4215       if(Vtx.IsSame(ex.Current())) {
4216         OVtx = ex.Current().Orientation();
4217         break;
4218       }
4219     }
4220     OVtx = TopAbs::Reverse(OVtx);
4221     Standard_Real parVtx = BRep_Tool::Parameter(Vtx,Arcspine);
4222     Handle(TopOpeBRepDS_CurvePointInterference)
4223       interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
4224     DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
4225
4226
4227     //Modif of lvt to find the suite of Arcprol in the other face
4228     {
4229       TopTools_ListIteratorOfListOfShape It;
4230       for (It.Initialize(myVEMap(Vtx)); It.More(); It.Next()){
4231         if (!(Arcprol.IsSame(It.Value()) ||
4232               Arcspine.IsSame(It.Value()) ||
4233               Arcpiv.IsSame(It.Value()))) {
4234           Arcprolbis = TopoDS::Edge(It.Value());
4235           break;
4236         }
4237       }
4238     }
4239     //end of modif
4240
4241     //Now the missing curves are constructed.
4242     for(ex.Init(Arcprolbis.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
4243         ex.More(); ex.Next()){
4244       if(Vtx.IsSame(ex.Current())) {
4245         OVtx2 = ex.Current().Orientation();
4246         break;
4247       }
4248     }
4249     for(ex.Init(Arcprol.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
4250         ex.More(); ex.Next()){
4251       if(Vtx.IsSame(ex.Current())) {
4252         OVtx = ex.Current().Orientation();
4253         break;
4254       }
4255     }
4256 // it is checked if Fop has a sewing edge
4257
4258 //     TopoDS_Edge edgecouture;
4259 //     Standard_Boolean couture;
4260     ChFi3d_Couture(Fop,couture,edgecouture);
4261     Handle(Geom2d_Curve) Hc;
4262 //    parVtx = BRep_Tool::Parameter(Vtx,Arcprol);
4263     const ChFiDS_FaceInterference& Fiop = Fd->Interference(IFopArc);
4264     gp_Pnt2d pop1, pop2, pv1, pv2;
4265     //deb modif
4266     parVtx = BRep_Tool::Parameter(Vtx,Arcprolbis);
4267 //  Modified by skv - Thu Aug 21 11:55:58 2008 OCC20222 Begin
4268 //    if(Fop.IsSame(Fopbis)) OArcprolbis = OArcprolop;
4269 //    else OArcprolbis = Arcprolbis.Orientation();
4270     if(Fop.IsSame(Fopbis)) {
4271       OArcprolbis = OArcprolop;
4272     } else {
4273       for(ex.Init(Fop,TopAbs_EDGE); ex.More(); ex.Next()){
4274         if(Arcprolbis.IsSame(ex.Current())) {
4275           OArcprolbis = ex.Current().Orientation();
4276           break;
4277         }
4278       }
4279     }
4280 //  Modified by skv - Thu Aug 21 11:55:58 2008 OCC20222 End
4281     //fin modif
4282     Hc = BRep_Tool::CurveOnSurface(Arcprolbis,Fop,Ubid,Ubid);
4283     pop1 = Hc->Value(parVtx);
4284     pop2 = Fiop.PCurveOnFace()->Value(Fiop.Parameter(isfirst));
4285     Hc = BRep_Tool::CurveOnSurface(Arcprol,Fv,Ubid,Ubid);
4286     //modif
4287     parVtx = BRep_Tool::Parameter(Vtx,Arcprol);
4288     //fin modif
4289     pv1 = Hc->Value(parVtx);
4290     pv2 = p2dbout;
4291     ChFi3d_Recale(Bs,pv1,pv2,1);
4292     TColStd_Array1OfReal Pardeb(1,4),Parfin(1,4);
4293     Pardeb(1) = pop1.X(); Pardeb(2) = pop1.Y();
4294     Pardeb(3) = pv1.X();  Pardeb(4) = pv1.Y();
4295     Parfin(1) = pop2.X(); Parfin(2) = pop2.Y();
4296     Parfin(3) = pv2.X();  Parfin(4) = pv2.Y();
4297     Standard_Real uu1,uu2,vv1,vv2;
4298     ChFi3d_Boite(pv1,pv2,uu1,uu2,vv1,vv2);
4299     ChFi3d_BoundFac(Bs,uu1,uu2,vv1,vv2);
4300     ChFi3d_Boite(pop1,pop2,uu1,uu2,vv1,vv2);
4301     ChFi3d_BoundFac(Bop,uu1,uu2,vv1,vv2);
4302
4303     Handle(Geom_Curve) zob3d;
4304     Handle(Geom2d_Curve) zob2dop, zob2dv;
4305 //    Standard_Real tolreached;
4306     if (!ChFi3d_ComputeCurves(HBop,HBs,Pardeb,Parfin,zob3d,zob2dop,
4307                               zob2dv,tolesp,tol2d,tolreached))
4308       Standard_Failure::Raise("OneCorner : echec calcul intersection");
4309
4310     Udeb = zob3d->FirstParameter();
4311     Ufin = zob3d->LastParameter();
4312     TopOpeBRepDS_Curve Zob(zob3d,tolreached);
4313     Standard_Integer IZob = DStr.AddCurve(Zob);
4314
4315     // it is not determined if the curve has an intersection with the sewing edge
4316
4317
4318     {
4319       Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolv));
4320       Standard_Integer Iop = DStr.AddShape(Fop);
4321       Handle(TopOpeBRepDS_SurfaceCurveInterference)
4322         InterFv = ChFi3d_FilCurveInDS(IZob,IShape,zob2dv,Et);
4323       DStr.ChangeShapeInterferences(IShape).Append(InterFv);
4324       //OVtx = TopAbs::Reverse(OVtx);
4325 //  Modified by skv - Thu Aug 21 11:55:58 2008 OCC20222 Begin
4326 //      Et = TopAbs::Reverse(TopAbs::Compose(OVtx,OArcprolbis));
4327       Et = TopAbs::Reverse(TopAbs::Compose(OVtx2,OArcprolbis));
4328 //  Modified by skv - Thu Aug 21 11:55:58 2008 OCC20222 End
4329       //OVtx = TopAbs::Reverse(OVtx);
4330 //      Et = TopAbs::Reverse(Et);
4331       Handle(TopOpeBRepDS_SurfaceCurveInterference)
4332         Interfop = ChFi3d_FilCurveInDS(IZob,Iop,zob2dop,Et);
4333       DStr.ChangeShapeInterferences(Iop).Append(Interfop);
4334       Handle(TopOpeBRepDS_CurvePointInterference)
4335         interfprol = ChFi3d_FilVertexInDS(TopAbs_FORWARD,IZob,IVtx,Udeb);
4336       DStr.ChangeCurveInterferences(IZob).Append(interfprol);
4337       Standard_Integer icc = stripe->IndexPoint(isfirst,IFopArc);
4338       interfprol = ChFi3d_FilPointInDS(TopAbs_REVERSED,IZob,icc,Ufin);
4339       DStr.ChangeCurveInterferences(IZob).Append(interfprol);
4340
4341     }
4342   }
4343   ChFi3d_EnlargeBox(DStr,stripe,Fd,box1,box2,isfirst);
4344   if(CV1.IsOnArc()){
4345     ChFi3d_EnlargeBox(CV1.Arc(),myEFMap(CV1.Arc()),CV1.ParameterOnArc(),box1);
4346   }
4347   if(CV2.IsOnArc()){
4348     ChFi3d_EnlargeBox(CV2.Arc(),myEFMap(CV2.Arc()),CV2.ParameterOnArc(),box2);
4349   }
4350   if  (!CV1.IsVertex())
4351     ChFi3d_SetPointTolerance(DStr,box1,stripe->IndexPoint(isfirst,1));
4352   if (!CV2.IsVertex())
4353     ChFi3d_SetPointTolerance(DStr,box2,stripe->IndexPoint(isfirst,2));
4354
4355 #ifdef DEB
4356    ChFi3d_ResultChron(ch, t_sameinter);//result perf condition if (same &&inter)
4357 #endif
4358 }