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