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