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