ee641304821cdd8aace00829529d34afa837359e
[occt.git] / src / ChFi3d / ChFi3d_Builder_0.cxx
1 // Created on: 1993-12-16
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1993-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 ofv - Thu Feb 26 11:18:16 2004 OCC5246
18 //  Modified by skv - Fri Oct 24 14:24:47 2003 OCC4077
19 //  Modified by skv - Mon Jun 16 15:50:44 2003 OCC615
20
21 #include <ChFi3d.hxx>
22 #include <Precision.hxx>
23
24 #include <Standard_NotImplemented.hxx>
25 #include <Standard_ConstructionError.hxx>
26
27 #include <gp.hxx>
28 #include <gp_Circ.hxx>
29 #include <gp_Elips.hxx>
30 #include <gp_Lin.hxx>
31 #include <gp_Pnt.hxx>
32 #include <gp_Pnt2d.hxx>
33 #include <gp_Lin2d.hxx>
34 #include <ElCLib.hxx>
35 #include <ElSLib.hxx>
36 #include <BSplCLib.hxx>
37 #include <GeomLib.hxx>
38
39 #include <TColgp_Array1OfPnt2d.hxx>
40 #include <TColgp_Array1OfPnt.hxx>
41 #include <TColgp_Array1OfXYZ.hxx>
42 #include <TColStd_Array1OfInteger.hxx>
43 #include <TColStd_Array1OfReal.hxx>
44
45 #include <Geom_TrimmedCurve.hxx>
46 #include <Geom_BSplineCurve.hxx>
47 #include <Geom_Surface.hxx>
48 #include <Geom_CylindricalSurface.hxx>
49 #include <Geom_RectangularTrimmedSurface.hxx>
50 #include <Geom_Plane.hxx>
51 #include <Geom_Line.hxx>
52 #include <Geom_Circle.hxx>
53 #include <Geom_Ellipse.hxx>
54 #include <Geom2d_BezierCurve.hxx>
55 #include <Geom2d_BSplineCurve.hxx>
56 #include <Geom2d_Line.hxx>
57 #include <Geom2d_Circle.hxx>
58 #include <Geom2d_Ellipse.hxx>
59 #include <Geom2d_Hyperbola.hxx>
60 #include <Geom2d_Parabola.hxx>
61 #include <Geom2d_TrimmedCurve.hxx>
62 #include <Geom2d_Line.hxx>
63 #include <Geom2d_OffsetCurve.hxx>
64 #include <Geom2dAdaptor_Curve.hxx>
65 #include <Geom2dAdaptor_HCurve.hxx>
66 #include <Adaptor3d_TopolTool.hxx>
67 #include <Adaptor3d_CurveOnSurface.hxx>
68 #include <Adaptor3d_HCurveOnSurface.hxx>
69 #include <GeomAdaptor_HSurface.hxx>
70
71 #include <FairCurve_Batten.hxx>
72 #include <FairCurve_AnalysisCode.hxx>
73 #include <Convert_ParameterisationType.hxx>
74 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
75 #include <GeomConvert.hxx>
76 #include <GeomLib_Interpolate.hxx>
77 #include <GeomAPI_ProjectPointOnSurf.hxx>
78 #include <GeomAPI_ProjectPointOnCurve.hxx>
79 #include <GC_MakeCircle.hxx>
80 #include <BRepAdaptor_Curve.hxx>
81 #include <BRepAdaptor_HCurve.hxx>
82 #include <BRepAdaptor_HCurve2d.hxx>
83 #include <BRepAdaptor_Surface.hxx>
84 #include <BRepTopAdaptor_HVertex.hxx>
85
86 #include <BRep_Tool.hxx>
87 #include <BRep_Builder.hxx>
88 #include <BRepTools.hxx>
89 #include <BRepTools_WireExplorer.hxx>
90 #include <BRepLib.hxx>
91 #include <BRepLib_MakeEdge.hxx>
92 #include <BRepLib_MakeWire.hxx>
93 #include <BRepLib_MakeFace.hxx>
94
95 #include <TopAbs.hxx>
96 #include <TopoDS_Shape.hxx>
97 #include <TopoDS_Edge.hxx>
98 #include <TopoDS_Vertex.hxx>
99 #include <TopoDS_Wire.hxx>
100 #include <TopoDS_Face.hxx>
101 #include <TopExp.hxx>
102 #include <TopExp_Explorer.hxx>
103 #include <TopTools_Array1OfShape.hxx>
104
105
106 #include <GeomAbs_Shape.hxx>
107 #include <Bnd_Box2d.hxx>
108
109 //#include <math_FunctionSample.hxx>
110 //#include <math_FunctionAllRoots.hxx>
111 #include <GCPnts_AbscissaPoint.hxx>
112
113 #include <IntCurveSurface_TheQuadCurvFuncOfTheQuadCurvExactHInter.hxx>
114 #include <IntCurveSurface_HInter.hxx>
115 #include <IntCurveSurface_IntersectionPoint.hxx>
116 #include <IntSurf_Quadric.hxx>
117 #include <IntSurf_PntOn2S.hxx>
118 #include <IntSurf_LineOn2S.hxx>
119 #include <IntAna_QuadQuadGeo.hxx>
120 #include <IntAna2d_AnaIntersection.hxx>
121 #include <IntRes2d_IntersectionPoint.hxx>
122 #include <IntWalk_PWalking.hxx>
123 #include <IntPatch_WLine.hxx>
124 #include <Geom2dInt_GInter.hxx>
125 #include <GeomInt_WLApprox.hxx>
126 #include <GeomInt_IntSS.hxx>
127 #include <AppParCurves_MultiBSpCurve.hxx>
128 #include <Approx_SameParameter.hxx>
129
130 #include <TopAbs.hxx>
131 #include <TopoDS_Shape.hxx>
132 #include <TopoDS_Edge.hxx>
133 #include <TopExp.hxx>
134
135 #include <TopOpeBRepDS.hxx>
136 #include <TopOpeBRepDS_Surface.hxx>
137 #include <TopOpeBRepDS_Point.hxx>
138 #include <TopOpeBRepDS_SolidSurfaceInterference.hxx>
139 #include <TopOpeBRepDS_CurvePointInterference.hxx>
140 #include <TopOpeBRepDS_ListOfInterference.hxx>
141 #include <TopOpeBRepDS_InterferenceIterator.hxx>
142 #include <ProjLib_ProjectedCurve.hxx>
143
144 #include <BRepBlend_PointOnRst.hxx>
145
146 #include <ChFiDS_HData.hxx>
147 #include <ChFiDS_SurfData.hxx>
148 #include <ChFiDS_FaceInterference.hxx>
149 #include <ChFiDS_Spine.hxx>
150 #include <ChFiDS_FilSpine.hxx>
151 #include <ChFiDS_SequenceOfSurfData.hxx>
152 #include <ChFiDS_Regul.hxx>
153 #include <Law_Function.hxx>
154 #include <Law_Composite.hxx>
155 #include <GeomAPI_PointsToBSpline.hxx>
156 #include <GeomLProp_CLProps.hxx>
157
158 #include <ChFi3d_Builder_0.hxx>
159
160 #ifdef OCCT_DEBUG
161 #include <OSD_Chronometer.hxx>
162 extern Standard_Boolean ChFi3d_GetcontextFORCEBLEND(); 
163 extern Standard_Boolean ChFi3d_GettraceDRAWINT();
164 extern Standard_Boolean ChFi3d_GettraceDRAWENLARGE();
165 extern Standard_Boolean ChFi3d_GettraceDRAWSPINE();
166 extern Standard_Real  t_sameparam, t_batten;
167 extern void ChFi3d_SettraceDRAWINT(const Standard_Boolean b);
168 extern void ChFi3d_SettraceDRAWSPINE(const Standard_Boolean b);
169 extern void ChFi3d_InitChron(OSD_Chronometer& ch);
170 extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time);
171 #endif
172
173 #include <stdio.h>
174
175 #include <GeomAdaptor_HCurve.hxx>
176 #include <BRepAdaptor_HSurface.hxx>
177 #include <TopOpeBRepDS_SurfaceCurveInterference.hxx>
178
179 //=======================================================================
180 //function : ChFi3d_InPeriod
181 //purpose  : 
182 //=======================================================================
183 Standard_Real ChFi3d_InPeriod(const Standard_Real U, 
184   const Standard_Real UFirst, 
185   const Standard_Real ULast,
186   const Standard_Real Eps)
187 {
188   const Standard_Real period = ULast - UFirst;
189   Standard_Real u = U;
190   while (Eps < (UFirst-u)) u += period;
191   while (Eps > (ULast -u)) u -= period;
192   if ( u < UFirst) u = UFirst;
193   return u;
194 }
195 //=======================================================================
196 //function : Box 
197 //purpose  : Calculation of min/max uv of the fillet to intersect.
198 //=======================================================================
199 void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2,
200   Standard_Real& mu,Standard_Real& Mu,
201   Standard_Real& mv,Standard_Real& Mv)
202 {
203   mu = Min(p1.X(),p2.X()); Mu = Max(p1.X(),p2.X());
204   mv = Min(p1.Y(),p2.Y()); Mv = Max(p1.Y(),p2.Y());
205 }
206 //=======================================================================
207 //function : Box
208 //purpose  : Calculation of min/max uv of the fillet to intersect.
209 //=======================================================================
210 void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2,
211   const gp_Pnt2d& p3,const gp_Pnt2d& p4,
212   Standard_Real& Du,Standard_Real& Dv,
213   Standard_Real& mu,Standard_Real& Mu,
214   Standard_Real& mv,Standard_Real& Mv)
215 {
216   Standard_Real a,b;
217   a = Min(p1.X(),p2.X());  b = Min(p3.X(),p4.X()); mu = Min(a,b);
218   a = Max(p1.X(),p2.X());  b = Max(p3.X(),p4.X()); Mu = Max(a,b);
219   a = Min(p1.Y(),p2.Y());  b = Min(p3.Y(),p4.Y()); mv = Min(a,b);
220   a = Max(p1.Y(),p2.Y());  b = Max(p3.Y(),p4.Y()); Mv = Max(a,b);
221   Du = Mu - mu;
222   Dv = Mv - mv;
223 }
224 //=======================================================================
225 //function : EnlargeBox and its friends.
226 //purpose  : 
227 //=======================================================================
228 static Handle(Adaptor3d_HSurface) Geometry(TopOpeBRepDS_DataStructure& DStr,
229   const Standard_Integer      ind)
230 {
231   if(ind == 0) return Handle(Adaptor3d_HSurface)();
232   if(ind > 0) {
233     TopoDS_Face F = TopoDS::Face(DStr.Shape(ind));
234     if(F.IsNull()) return Handle(Adaptor3d_HSurface)();
235     Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface();
236     HS->ChangeSurface().Initialize(F,0);
237     return HS;
238   }
239   else{
240     Handle(Geom_Surface) S  = DStr.Surface(-ind).Surface();
241     if(S.IsNull()) return Handle(Adaptor3d_HSurface)();
242     return new GeomAdaptor_HSurface(S);
243   }
244 }
245 //=======================================================================
246 //function : ChFi3d_SetPointTolerance
247 //purpose  : 
248 //=======================================================================
249 void ChFi3d_SetPointTolerance(TopOpeBRepDS_DataStructure& DStr,
250   const Bnd_Box&              box,
251   const Standard_Integer      IP)
252 {
253   Standard_Real a,b,c,d,e,f,vtol;
254   box.Get(a,b,c,d,e,f); 
255   d-=a; e-=b; f-=c; 
256   d*=d; e*=e; f*=f;
257   vtol = sqrt(d + e + f) * 1.5;// on prend un petit rab.
258   DStr.ChangePoint(IP).Tolerance(vtol);
259 }
260 //=======================================================================
261 //function : ChFi3d_EnlargeBox
262 //purpose  : 
263 //=======================================================================
264 void ChFi3d_EnlargeBox(const Handle(Geom_Curve)& C,
265   const Standard_Real       wd,
266   const Standard_Real       wf,
267   Bnd_Box&                  box1,
268   Bnd_Box&                  box2)
269 {
270   box1.Add(C->Value(wd));
271   box2.Add(C->Value(wf));
272 }
273 //=======================================================================
274 //function : ChFi3d_EnlargeBox
275 //purpose  : 
276 //=======================================================================
277 void ChFi3d_EnlargeBox(const Handle(Adaptor3d_HSurface)& S,
278   const Handle(Geom2d_Curve)&     PC,
279   const Standard_Real             wd,
280   const Standard_Real             wf,
281   Bnd_Box&                        box1,
282   Bnd_Box&                        box2)
283 {
284   Standard_Real u,v;
285   PC->Value(wd).Coord(u,v);
286   box1.Add(S->Value(u,v));
287   PC->Value(wf).Coord(u,v);
288   box2.Add(S->Value(u,v));
289 }
290 //=======================================================================
291 //function : ChFi3d_EnlargeBox
292 //purpose  : 
293 //=======================================================================
294 void ChFi3d_EnlargeBox(const TopoDS_Edge&           E,
295   const TopTools_ListOfShape&  LF,
296   const Standard_Real          w,
297   Bnd_Box&                     box)
298
299 {
300   BRepAdaptor_Curve BC(E);
301   box.Add(BC.Value(w));
302   TopTools_ListIteratorOfListOfShape It;
303   for(It.Initialize(LF); It.More(); It.Next()) {
304     TopoDS_Face F = TopoDS::Face(It.Value());
305     if(!F.IsNull()) {
306       BC.Initialize(E,F);
307       box.Add(BC.Value(w));
308     }
309   }
310 }
311 //=======================================================================
312 //function : ChFi3d_EnlargeBox
313 //purpose  : 
314 //=======================================================================
315 void ChFi3d_EnlargeBox(TopOpeBRepDS_DataStructure&    DStr,
316   const Handle(ChFiDS_Stripe)&   st, 
317   const Handle(ChFiDS_SurfData)& sd,
318   Bnd_Box&                       b1,
319   Bnd_Box&                       b2,
320   const Standard_Boolean         isfirst)
321 {
322   Standard_Real u,v;
323   const ChFiDS_CommonPoint& cp1 = sd->Vertex(isfirst,1);
324   const ChFiDS_CommonPoint& cp2 = sd->Vertex(isfirst,2);
325   b1.Add(cp1.Point());
326   b2.Add(cp2.Point());
327   const ChFiDS_FaceInterference& fi1 = sd->InterferenceOnS1();
328   const ChFiDS_FaceInterference& fi2 = sd->InterferenceOnS2();
329   const Handle(Geom_Surface)& S = DStr.Surface(sd->Surf()).Surface();
330   const Handle(Geom2d_Curve)& pcs1 = fi1.PCurveOnSurf();
331   const Handle(Geom2d_Curve)& pcs2 = fi2.PCurveOnSurf();
332   const Handle(Geom_Curve)& c3d1 = DStr.Curve(fi1.LineIndex()).Curve();
333   const Handle(Geom_Curve)& c3d2 = DStr.Curve(fi2.LineIndex()).Curve();
334   Handle(Adaptor3d_HSurface) F1 = Geometry(DStr,sd->IndexOfS1());
335   Handle(Adaptor3d_HSurface) F2 = Geometry(DStr,sd->IndexOfS2());
336   Standard_Real p1 = fi1.Parameter(isfirst);
337   if(!c3d1.IsNull()) b1.Add(c3d1->Value(p1));
338   if(!pcs1.IsNull()) {
339     pcs1->Value(p1).Coord(u,v);
340     b1.Add(S->Value(u,v));
341   }
342   if(!F1.IsNull()) {
343     const Handle(Geom2d_Curve)& pcf1 = fi1.PCurveOnFace();
344     if(!pcf1.IsNull()) {
345       pcf1->Value(p1).Coord(u,v);
346       b1.Add(F1->Value(u,v));
347     }
348   }
349   Standard_Real p2 = fi2.Parameter(isfirst);
350   if(!c3d2.IsNull()) b2.Add(c3d2->Value(p2));
351   if(!pcs2.IsNull()) {
352     pcs2->Value(p2).Coord(u,v);
353     b2.Add(S->Value(u,v));
354   }
355   if(!F2.IsNull()) {
356     const Handle(Geom2d_Curve)& pcf2 = fi2.PCurveOnFace();
357     if(!pcf2.IsNull()) {
358       pcf2->Value(p2).Coord(u,v);
359       b2.Add(F2->Value(u,v));
360     }
361   }
362   if(!st.IsNull()) {
363     const Handle(Geom_Curve)& c3d = DStr.Curve(st->Curve(isfirst)).Curve();
364     const Handle(Geom2d_Curve)& c2d = st->PCurve(isfirst);
365     if(st->Orientation(isfirst) == TopAbs_FORWARD) st->Parameters(isfirst,p1,p2);
366     else st->Parameters(isfirst,p2,p1);
367     if(!c3d.IsNull()) {
368       b1.Add(c3d->Value(p1));
369       b2.Add(c3d->Value(p2));
370     }
371     if(!c2d.IsNull()) {
372       c2d->Value(p1).Coord(u,v);
373       b1.Add(S->Value(u,v)); 
374       c2d->Value(p2).Coord(u,v);
375       b2.Add(S->Value(u,v));
376     }
377   }
378 }
379 //=======================================================================
380 //function : conexfaces
381 //purpose  : 
382 //=======================================================================
383 void ChFi3d_conexfaces(const TopoDS_Edge& E,
384   TopoDS_Face&       F1,
385   TopoDS_Face&       F2,
386   const ChFiDS_Map&  EFMap)
387 {
388   TopTools_ListIteratorOfListOfShape It;
389   F1.Nullify();
390   F2.Nullify();
391   for(It.Initialize(EFMap(E));It.More();It.Next()) {  
392     if (F1.IsNull()) {
393       F1 = TopoDS::Face(It.Value());
394     }
395     else {
396       F2 = TopoDS::Face(It.Value());
397       if(!F2.IsSame(F1) || BRep_Tool::IsClosed(E,F1)) {
398         break;
399       }
400       else F2.Nullify();
401     }
402   }  
403 }
404 //=======================================================================
405 //function : EdgeState
406 //purpose  : check concavities for the tops with 3 edges.
407 //=======================================================================
408 ChFiDS_State ChFi3d_EdgeState(TopoDS_Edge* E,
409   const ChFiDS_Map&  EFMap)
410 {
411   ChFiDS_State sst;
412   Standard_Integer i,j;
413   TopoDS_Face F[3];
414   TopoDS_Face F1,F2,F3,F4,F5,F6;
415   ChFi3d_conexfaces(E[0],F1,F2,EFMap);
416   ChFi3d_conexfaces(E[1],F3,F4,EFMap);
417   ChFi3d_conexfaces(E[2],F5,F6,EFMap);
418   if(F1.IsSame(F2)) {
419     F[0] = F[1] = F1;
420     if(F1.IsSame(F3)) F[2] = F4;
421     else F[2] = F3;
422   }
423   else if(F3.IsSame(F4)) {
424     F[0] = F[2] = F3;
425     if(F3.IsSame(F1)) F[1] = F2;
426     else F[1] = F1;
427   }
428   else if(F5.IsSame(F6)) {
429     F[1] = F[2] = F5;
430     if(F5.IsSame(F1)) F[0] = F2;
431     else F[0] = F1;
432   }
433   else{
434     if(F1.IsSame(F3) || F1.IsSame(F4)) F[0] = F1;
435     else F[0] = F2;
436     if(F3.IsSame(F[0])) F[2] = F4;
437     else F[2] = F3;
438     if(F5.IsSame(F[2])) F[1] = F6;
439     else F[1] = F5;
440
441   }
442
443   if(F[0].IsNull() || F[1].IsNull() || F[2].IsNull()) sst = ChFiDS_FreeBoundary;
444   else{
445     TopAbs_Orientation o01,o02,o11,o12,o21,o22;
446     i=ChFi3d::ConcaveSide(F[0],F[1],E[0],o01,o02);
447     i=ChFi3d::ConcaveSide(F[0],F[2],E[1],o11,o12);
448     j=ChFi3d::ConcaveSide(F[1],F[2],E[2],o21,o22);
449     if(o01==o11 && o02==o21 && o12==o22) sst = ChFiDS_AllSame;
450     else if(o12==o22 || i ==10 || j ==10) sst = ChFiDS_OnDiff;
451     else sst = ChFiDS_OnSame;
452   }
453   return sst;
454 }
455 //=======================================================================
456 //function : evalconti
457 //purpose  : Method very fast to code regularities CN. It is necessary to 
458 //           refine the processing.
459 //=======================================================================
460 GeomAbs_Shape ChFi3d_evalconti(const TopoDS_Edge& /*E*/,
461   const TopoDS_Face& F1,
462   const TopoDS_Face& F2)
463 {
464   GeomAbs_Shape cont = GeomAbs_G1;
465   if(!F1.IsSame(F2)) return cont;
466   TopoDS_Face F = F1;
467   F.Orientation(TopAbs_FORWARD);
468   BRepAdaptor_Surface S(F,Standard_False);
469   GeomAbs_SurfaceType typ = S.GetType();
470   if(typ != GeomAbs_Cone && 
471     typ != GeomAbs_Sphere && 
472     typ != GeomAbs_Torus) return cont;
473   return GeomAbs_CN;
474 }
475 //modified by NIZNHY-PKV Wed Dec 15 11:22:35 2010f
476 //=======================================================================
477 //function : KParticular
478 //purpose  : 
479 //=======================================================================
480 Standard_Boolean ChFi3d_KParticular (const Handle(ChFiDS_Spine)& Spine,
481   const Standard_Integer      IE,
482   const BRepAdaptor_Surface&  S1,
483   const BRepAdaptor_Surface&  S2)
484 {
485   Standard_Boolean bRet;
486   //
487   bRet=Standard_True;
488   //
489   Handle(ChFiDS_FilSpine) fs = Handle(ChFiDS_FilSpine)::DownCast(Spine);
490   if(!fs.IsNull() && !fs->IsConstant(IE)) {
491     return !bRet;
492   }
493   //
494   Standard_Boolean bIsPlane1, bIsPlane2;
495   Standard_Real aPA;
496   GeomAbs_CurveType aCT;
497   GeomAbs_SurfaceType aST1, aST2;
498   //
499   aST1=S1.GetType();
500   aST2=S2.GetType();
501   bIsPlane1=(aST1==GeomAbs_Plane);
502   bIsPlane2=(aST2==GeomAbs_Plane);
503   if (!(bIsPlane1 || bIsPlane2)) {
504     return !bRet;
505   }
506   //
507   const BRepAdaptor_Surface& aS1=(bIsPlane1)? S1 : S2;
508   const BRepAdaptor_Surface& aS2=(bIsPlane1)? S2 : S1;
509   aST1=aS1.GetType();
510   aST2=aS2.GetType();
511   //
512   if (!(aST2==GeomAbs_Plane || aST2==GeomAbs_Cylinder || aST2==GeomAbs_Cone)) {
513     return !bRet;
514   } 
515   //
516   const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(IE);
517   aCT = bc.GetType();
518   if (!(aCT==GeomAbs_Line || aCT==GeomAbs_Circle)) {
519     return !bRet;
520   }
521   //
522   aPA=Precision::Angular();
523   //
524   if (aST2==GeomAbs_Plane){
525     if (aCT==GeomAbs_Line) { 
526       return bRet;
527     }
528   }
529   else if (aST2==GeomAbs_Cylinder) {
530     const gp_Dir& aD1=aS1.Plane().Axis().Direction();
531     const gp_Dir& aD2=aS2.Cylinder().Axis().Direction();
532     //
533     if (aCT==GeomAbs_Line && aD1.IsNormal(aD2, aPA)) {
534       return bRet;
535     }
536     else if (aCT==GeomAbs_Circle && aD1.IsParallel(aD2, aPA)) {
537       return bRet;
538     }
539   }
540   else if(aST2==GeomAbs_Cone) {
541     const gp_Dir& aD1=aS1.Plane().Axis().Direction();
542     const gp_Dir& aD2=aS2.Cone().Axis().Direction();
543     if (aCT == GeomAbs_Circle && aD1.IsParallel(aD2, aPA)) {
544       return bRet;
545     }
546   }  
547   return !bRet;    
548 }
549 //modified by NIZNHY-PKV Wed Dec 15 11:22:43 2010t
550 //=======================================================================
551 //function : BoundFac
552 //purpose  : Resize the limits of surface adjacent to the given box 
553 //           Useful for intersections with known extremities. 
554 //=======================================================================
555 void ChFi3d_BoundFac(BRepAdaptor_Surface& S,
556   const Standard_Real uumin,
557   const Standard_Real uumax,
558   const Standard_Real vvmin,
559   const Standard_Real vvmax,
560   const Standard_Boolean checknaturalbounds)
561 {
562   ChFi3d_BoundSrf(S.ChangeSurface(), uumin,uumax,vvmin,vvmax,checknaturalbounds);
563 }
564 //=======================================================================
565 //function : ChFi3d_BoundSrf
566 //purpose  : Resize the limits of surface adjacent to the given box 
567 //           Useful for intersections with known extremities.
568 //=======================================================================
569 void ChFi3d_BoundSrf(GeomAdaptor_Surface& S,
570   const Standard_Real uumin,
571   const Standard_Real uumax,
572   const Standard_Real vvmin,
573   const Standard_Real vvmax,
574   const Standard_Boolean checknaturalbounds)
575 {
576   Standard_Real umin = uumin, umax = uumax, vmin = vvmin, vmax = vvmax; 
577   Handle(Geom_Surface) surface = S.Surface();
578   Handle(Geom_RectangularTrimmedSurface) 
579     trs = Handle(Geom_RectangularTrimmedSurface)::DownCast(surface);
580   if(!trs.IsNull()) surface = trs->BasisSurface();
581   Standard_Real u1,u2,v1,v2;
582   surface->Bounds(u1,u2,v1,v2);
583   Standard_Real peru=0, perv=0;
584   if(surface->IsUPeriodic()) {
585     peru = surface->UPeriod();
586   }
587   if(surface->IsVPeriodic()) {
588     perv = surface->VPeriod();
589   }
590   Standard_Real Stepu = umax - umin;
591   Standard_Real Stepv = vmax - vmin;
592
593   //It is supposed that box uv is not null in at least 
594   //one direction.
595   Standard_Real scalu = S.UResolution(1.);
596   Standard_Real scalv = S.VResolution(1.);
597
598   Standard_Real step3du = Stepu/scalu; 
599   Standard_Real step3dv = Stepv/scalv;
600
601   if(step3du > step3dv) Stepv = step3du*scalv;
602   if(step3dv > step3du) Stepu = step3dv*scalu;
603
604   if (peru > 0) Stepu = 0.1 * (peru - (umax - umin));
605   if (perv > 0) Stepv = 0.1 * (perv - (vmax - vmin));
606
607   Standard_Real uu1 = umin - Stepu;
608   Standard_Real uu2 = umax + Stepu;
609   Standard_Real vv1 = vmin - Stepv;
610   Standard_Real vv2 = vmax + Stepv;
611   if(checknaturalbounds) {
612     if(!S.IsUPeriodic()) {uu1 = Max(uu1,u1);  uu2 = Min(uu2,u2);}
613     if(!S.IsVPeriodic()) {vv1 = Max(vv1,v1);  vv2 = Min(vv2,v2);}
614   }
615   S.Load(surface,uu1,uu2,vv1,vv2);
616 }
617 //=======================================================================
618 //function : ChFi3d_InterPlaneEdge
619 //purpose  : 
620 //=======================================================================
621 Standard_Boolean  ChFi3d_InterPlaneEdge (const Handle(Adaptor3d_HSurface)& Plan,
622   const Handle(Adaptor3d_HCurve)&  C,
623   Standard_Real& W,
624   const Standard_Boolean Sens,
625   const Standard_Real tolc)
626
627   IntCurveSurface_HInter Intersection;
628   Standard_Integer isol = 0, nbp ,iip;
629   Standard_Real uf = C->FirstParameter(),ul = C->LastParameter();
630   Standard_Real CW;
631
632   Intersection.Perform(C,Plan);
633
634   if(Intersection.IsDone()) {
635     nbp = Intersection.NbPoints();
636     for (iip = 1; iip <= nbp; iip++) {
637       CW = Intersection.Point(iip).W();
638       if(C->IsPeriodic())
639         CW = ElCLib::InPeriod(CW,uf-tolc,uf-tolc+C->Period());
640       if(uf - tolc <= CW && ul + tolc >= CW) {
641         if (isol == 0) {
642           isol = iip; W = CW;
643         }
644         else {
645           if      ( Sens && CW < W) {
646             W = CW; isol = iip;
647           }
648           else if (!Sens && CW > W) {
649             W = CW; isol = iip;
650           }
651         }
652       }
653     }
654   }
655   if(isol == 0) return Standard_False;
656   return Standard_True;
657 }
658 //=======================================================================
659 //function : ExtrSpineCarac
660 //purpose  : 
661 //=======================================================================
662 void ChFi3d_ExtrSpineCarac(const TopOpeBRepDS_DataStructure& DStr,
663   const Handle(ChFiDS_Stripe)& cd,
664   const Standard_Integer i,
665   const Standard_Real p,
666   const Standard_Integer jf,
667   const Standard_Integer sens,
668   gp_Pnt& P,
669   gp_Vec& V,
670   Standard_Real& R) //check if it is necessary to add D1,D2 and DR
671 {
672   // Attention for approximated surfaces it is assumed that e
673   // the parameters of the pcurve are the same as of  
674   // elspine used for its construction.
675   const Handle(Geom_Surface)& fffil = 
676     DStr.Surface(cd->SetOfSurfData()->Value(i)->Surf()).Surface();
677   gp_Pnt2d pp = cd->SetOfSurfData()->Value(i)->Interference(jf).
678     PCurveOnSurf()->Value(p);
679   GeomAdaptor_Surface gs(fffil);
680   P = fffil->Value(pp.X(),pp.Y());
681   gp_Pnt Pbid; gp_Vec Vbid;
682   switch (gs.GetType()) {
683   case GeomAbs_Cylinder :
684     {
685       gp_Cylinder cyl = gs.Cylinder();
686       R = cyl.Radius();
687       ElSLib::D1(pp.X(),pp.Y(),cyl,Pbid,Vbid,V);
688     }
689     break;
690   case GeomAbs_Torus :
691     {
692       gp_Torus tor = gs.Torus();
693       R = tor.MinorRadius();
694       ElSLib::D1(pp.X(),pp.Y(),tor,Pbid,V,Vbid);
695     }
696     break;
697   default:
698     { Standard_Integer nbelspine;
699     const Handle(ChFiDS_Spine)& sp = cd->Spine();
700     Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(sp);
701     nbelspine=sp->NbEdges();
702     Handle(ChFiDS_HElSpine) hels;
703     if   (nbelspine==1) hels = sp->ElSpine(1);
704     else hels = sp->ElSpine(p);
705     if(fsp->IsConstant()) { R = fsp->Radius(); }
706     else { R = fsp->Law(hels)->Value(p); }
707     hels->D1(p,Pbid,V);
708     }
709     break;
710   }
711   V.Normalize();
712   if(sens == 1) V.Reverse();
713 }
714 //=======================================================================
715 //function : ChFi3d_CircularSpine
716 //purpose  : Calculate a cicular guideline for the corner created from  
717 //           tangent points and vectors calculated at the extremities 
718 //           of guidelines of start and end fillets.
719 //=======================================================================
720 Handle(Geom_Circle) ChFi3d_CircularSpine(Standard_Real&      WFirst,
721   Standard_Real&      WLast,
722   const gp_Pnt&       Pdeb,
723   const gp_Vec&       Vdeb,
724   const gp_Pnt&       Pfin,
725   const gp_Vec&       Vfin,
726   const Standard_Real rad)
727 {
728   gp_Circ ccc;
729   gp_Pln Pl1(Pdeb,gp_Dir(Vdeb)),Pl2(Pfin,gp_Dir(Vfin));
730   IntAna_QuadQuadGeo LInt (Pl1,Pl2,Precision::Angular(),
731     Precision::Confusion());
732   gp_Lin li;
733   if (LInt.IsDone()) {
734     li = LInt.Line(1);
735     gp_Pnt cendeb = ElCLib::Value(ElCLib::Parameter(li,Pdeb),li);
736     gp_Pnt cenfin = ElCLib::Value(ElCLib::Parameter(li,Pfin),li);
737     gp_Vec vvdeb(cendeb,Pdeb);
738     gp_Vec vvfin(cenfin,Pfin);
739     gp_Dir dddeb(vvdeb);
740     gp_Dir ddfin(vvfin);
741     if(Vdeb.Crossed(vvdeb).Dot(Vfin.Crossed(vvfin)) > 0.) {
742       return Handle(Geom_Circle)();
743     }
744     gp_Ax2 circax2(cendeb,dddeb^ddfin,dddeb);
745     ccc.SetPosition(circax2);
746     ccc.SetRadius(rad);
747     WFirst = 0.;
748     WLast = dddeb.Angle(ddfin);
749     return new Geom_Circle(ccc);
750   }
751
752   return Handle(Geom_Circle)();
753 }
754 //=======================================================================
755 //function : ChFi3d_Spine
756 //purpose  : Calculates the poles of the guideline for the corner from
757 //           tangent points and vectors calculated at the extremities of
758 //           guidelines of start and end fillets.
759 //=======================================================================
760 Handle(Geom_BezierCurve) ChFi3d_Spine(const gp_Pnt&       pd,
761   gp_Vec&             vd,
762   const gp_Pnt&       pf,
763   gp_Vec&             vf,
764   const Standard_Real R)
765 {     
766   TColgp_Array1OfPnt pol(1,4);
767   const Standard_Real fac = 0.5 * tan((M_PI-vd.Angle(vf)) * 0.5);
768   pol(1) = pd;
769   vd.Multiply(fac*R);
770   pol(2).SetCoord(pd.X()+vd.X(),pd.Y()+vd.Y(),pd.Z()+vd.Z());
771   pol(4) = pf;
772   vf.Multiply(fac*R);
773   pol(3).SetCoord(pf.X()+vf.X(),pf.Y()+vf.Y(),pf.Z()+vf.Z());
774   return new Geom_BezierCurve(pol);
775 }
776 //=======================================================================
777 //function : IsInFront
778 //purpose  : Checks if surfdata i1 and i2 are face to face
779 //=======================================================================
780 Standard_Boolean ChFi3d_IsInFront(TopOpeBRepDS_DataStructure& DStr,
781   const Handle(ChFiDS_Stripe)& cd1, 
782   const Handle(ChFiDS_Stripe)& cd2,
783   const Standard_Integer i1,
784   const Standard_Integer i2,
785   const Standard_Integer sens1,
786   const Standard_Integer sens2,
787   Standard_Real& p1,
788   Standard_Real& p2,
789   TopoDS_Face& face,
790   Standard_Boolean& sameside,
791   Standard_Integer& jf1,
792   Standard_Integer& jf2,
793   Standard_Boolean& visavis,
794   const TopoDS_Vertex& Vtx,
795   const Standard_Boolean Check2dDistance,
796   const Standard_Boolean enlarge)
797 {
798   Standard_Boolean isf1 = (sens1 == 1), isf2 = (sens2 == 1);
799   const Handle(ChFiDS_SurfData)& fd1 = cd1->SetOfSurfData()->Value(i1);
800   const Handle(ChFiDS_SurfData)& fd2 = cd2->SetOfSurfData()->Value(i2);
801
802   TopAbs_Orientation Or,OrSave1,OrSave2,OrFace1,OrFace2;
803   visavis = Standard_False;
804   Standard_Real u1 = 0.,u2 = 0.; 
805   Standard_Boolean ss = 0,ok = 0;
806   Standard_Integer j1 = 0,j2 = 0;
807   TopoDS_Face ff;
808   if(fd1->IndexOfS1() == fd2->IndexOfS1()) { 
809     jf1 = 1; jf2 = 1; 
810     face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
811     OrSave1 = cd1->Orientation(jf1);
812     Or = OrFace1 = face.Orientation();
813     OrSave2 = cd2->Orientation(jf2);
814     OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
815     visavis = Standard_True;
816     sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
817     // The parameters of the other side are not used for orientation. This would raise problems
818     Standard_Integer kf1 = jf1, kf2 = jf2;
819     Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
820     Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
821     gp_Pnt2d P2d;
822     if (Check2dDistance)
823       P2d = BRep_Tool::Parameters( Vtx, face );
824     if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
825       u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
826       ok = 1;
827     }
828   }
829   if(fd1->IndexOfS2() == fd2->IndexOfS1()) { 
830     jf1 = 2; jf2 = 1; 
831     face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
832     OrSave1 = cd1->Orientation(jf1);
833     Or = OrFace1 = face.Orientation();
834     OrSave2 = cd2->Orientation(jf2);
835     OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
836     visavis = Standard_True;
837     sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
838     // The parameters of the other side are not used for orientation. This would raise problems
839     Standard_Integer kf1 = jf1, kf2 = jf2;
840     Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
841     Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
842     gp_Pnt2d P2d;
843     if (Check2dDistance)
844       P2d = BRep_Tool::Parameters( Vtx, face );
845     if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
846       Standard_Boolean restore = 
847         ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) || 
848         (j2 == jf2 && sens2*(p2 - u2) > 0.));
849       ok = 1;
850       if(restore) {
851         p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
852       }
853       else {
854         u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
855       }
856     }
857     //the re-initialization is added in case p1,... take wrong values
858     else if (ok) {
859       p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
860     }
861   }
862   if(fd1->IndexOfS1() == fd2->IndexOfS2()) { 
863     jf1 = 1; jf2 = 2; 
864     face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
865     OrSave1 = cd1->Orientation(jf1);
866     Or = OrFace1 = face.Orientation();
867     OrSave2 = cd2->Orientation(jf2);
868     OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
869     visavis = Standard_True;
870     sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
871     // The parameters of the other side are not used for orientation.
872     Standard_Integer kf1 = jf1, kf2 = jf2;
873     Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
874     Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
875     gp_Pnt2d P2d;
876     if (Check2dDistance)
877       P2d = BRep_Tool::Parameters( Vtx, face );
878     if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
879       Standard_Boolean restore = 
880         ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) || 
881         (j2 == jf2 && sens2*(p2 - u2) > 0.));
882       ok = 1;
883       if(restore) {
884         p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
885       }
886       else {
887         u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
888       }
889     }
890     //the re-initialization is added in case p1,... take wrong values
891     else if (ok) {
892       p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
893     }
894   }
895   if(fd1->IndexOfS2() == fd2->IndexOfS2()) { 
896     jf1 = 2; jf2 = 2; 
897     face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
898     OrSave1 = cd1->Orientation(jf1);
899     Or = OrFace1 = face.Orientation();
900     OrSave2 = cd2->Orientation(jf2);
901     OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
902     visavis = Standard_True;
903     sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
904     // The parameters of the other side are not used for orientation.
905     Standard_Integer kf1 = jf1, kf2 = jf2;
906     Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
907     Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
908     gp_Pnt2d P2d;
909     if (Check2dDistance)
910       P2d = BRep_Tool::Parameters( Vtx, face );
911     if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
912       Standard_Boolean restore = 
913         ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) || 
914         (j2 == jf2 && sens2*(p2 - u2) > 0.));
915       ok = 1;
916       if(restore) {
917         p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
918       }
919       else {
920         u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
921       }
922     }
923     //the re-initialization is added in case p1,... take wrong values
924     else if (ok) {
925       p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
926     }
927   }
928   return ok;
929 }
930 //=======================================================================
931 //function : recadre
932 //purpose  : 
933 //=======================================================================
934 static Standard_Real recadre(const Standard_Real p,
935   const Standard_Real ref,
936   const Standard_Integer sens,
937   const Standard_Real first,
938   const Standard_Real last)
939 {
940   const Standard_Real pp = p + (sens > 0 ? (first - last) : (last - first));
941   return ((Abs(pp - ref) < Abs(p - ref))? pp : p);
942 }
943 //=======================================================================
944 //function : ChFi3d_IntTraces
945 //purpose  : 
946 //=======================================================================
947 Standard_Boolean ChFi3d_IntTraces(const Handle(ChFiDS_SurfData)& fd1,
948   const Standard_Real            pref1,
949   Standard_Real&                 p1,
950   const Standard_Integer         jf1,
951   const Standard_Integer         sens1,
952   const Handle(ChFiDS_SurfData)& fd2,
953   const Standard_Real            pref2,
954   Standard_Real&                 p2,
955   const Standard_Integer         jf2,
956   const Standard_Integer         sens2,
957   const gp_Pnt2d&                RefP2d,
958   const Standard_Boolean         Check2dDistance,
959   const Standard_Boolean         enlarge)
960 {
961   Geom2dAdaptor_Curve C1;
962   Geom2dAdaptor_Curve C2;
963   // pcurves are enlarged to be sure that there is intersection
964   // additionally all periodic curves are taken and points on 
965   // them are filtered using a specific criterion.
966
967   Standard_Real first,last,delta = 0.;
968   first = fd1->Interference(jf1).FirstParameter();
969   last = fd1->Interference(jf1).LastParameter();
970   if ((last-first) < Precision::PConfusion())
971     return Standard_False;
972   if(enlarge) delta = Min(0.1,0.05*(last-first));
973   Handle(Geom2d_Curve) pcf1 = fd1->Interference(jf1).PCurveOnFace();
974   if(pcf1.IsNull()) return Standard_False;
975   Standard_Boolean isper1 = pcf1->IsPeriodic();
976   if(isper1) {
977     Handle(Geom2d_TrimmedCurve) tr1 = Handle(Geom2d_TrimmedCurve)::DownCast(pcf1);
978     if(!tr1.IsNull()) pcf1 = tr1->BasisCurve();
979     C1.Load(pcf1);
980   }
981   else C1.Load(pcf1,first-delta,last+delta);
982   Standard_Real first1 = pcf1->FirstParameter(), last1 = pcf1->LastParameter();
983
984   first = fd2->Interference(jf2).FirstParameter();
985   last = fd2->Interference(jf2).LastParameter();
986   if ((last-first) < Precision::PConfusion())
987     return Standard_False;
988   if(enlarge) delta = Min(0.1,0.05*(last-first));
989   Handle(Geom2d_Curve) pcf2 = fd2->Interference(jf2).PCurveOnFace();
990   if(pcf2.IsNull()) return Standard_False;
991   Standard_Boolean isper2 = pcf2->IsPeriodic();
992   if(isper2) {
993     Handle(Geom2d_TrimmedCurve) tr2 = Handle(Geom2d_TrimmedCurve)::DownCast(pcf2);
994     if(!tr2.IsNull()) pcf2 = tr2->BasisCurve();
995     C2.Load(pcf2);
996   }
997   else C2.Load(fd2->Interference(jf2).PCurveOnFace(),first-delta,last+delta);
998   Standard_Real first2 = pcf2->FirstParameter(), last2 = pcf2->LastParameter();
999
1000   IntRes2d_IntersectionPoint int2d;
1001   Geom2dInt_GInter Intersection;
1002   Standard_Integer nbpt,nbseg;
1003   gp_Pnt2d p2d;
1004   if(fd1->Interference(jf1).PCurveOnFace() == fd2->Interference(jf2).PCurveOnFace()) {
1005     Intersection.Perform(C1,
1006       Precision::PIntersection(),
1007       Precision::PIntersection());
1008   }
1009   else{
1010     Intersection.Perform(C1,C2,
1011       Precision::PIntersection(),
1012       Precision::PIntersection());
1013   }
1014   if (Intersection.IsDone()) {
1015     if (!Intersection.IsEmpty()) {
1016       nbseg = Intersection.NbSegments();
1017       if ( nbseg > 0 ) { 
1018       }
1019       nbpt = Intersection.NbPoints();
1020       if ( nbpt >= 1 ) {
1021         // The criteria sets to filter the found points in a strict way 
1022         // are missing. Two different criterions chosen somewhat randomly 
1023         // are used :
1024         // - periodic curves : closest to the border.
1025         // - non-periodic curves : the closest to the left of 2 curves
1026         //                             modulo sens1 and sens2
1027         int2d = Intersection.Point(1);
1028         p2d = int2d.Value();
1029         p1 = int2d.ParamOnFirst();
1030         p2 = int2d.ParamOnSecond();
1031         if(isper1) p1 = recadre(p1,pref1,sens1,first1,last1);
1032         if(isper2) p2 = recadre(p2,pref2,sens2,first2,last2);
1033         for(Standard_Integer i = 2; i<=nbpt; i++) {
1034           int2d = Intersection.Point(i);
1035           if(isper1) {
1036             Standard_Real pp1 = int2d.ParamOnFirst();
1037             pp1 = recadre(pp1,pref1,sens1,first1,last1);
1038             if((Abs(pp1 - pref1) < Abs(p1 - pref1))) {
1039               p1 = pp1;
1040               p2 = int2d.ParamOnSecond();
1041               p2d = int2d.Value();
1042             }
1043             //  Modified by skv - Mon Jun 16 15:51:21 2003 OCC615 Begin
1044             else if (Check2dDistance &&
1045               RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d)) {
1046                 Standard_Real pp2 = int2d.ParamOnSecond();
1047
1048                 if(isper2)
1049                   pp2 = recadre(pp2,pref2,sens2,first2,last2);
1050
1051                 p1  = pp1;
1052                 p2  = pp2;
1053                 p2d = int2d.Value();
1054             }
1055             //  Modified by skv - Mon Jun 16 15:51:22 2003 OCC615 End
1056           }
1057           else if(isper2) {
1058             Standard_Real pp2 = int2d.ParamOnSecond();
1059             pp2 = recadre(pp2,pref2,sens2,first2,last2);
1060             if((Abs(pp2 - pref2) < Abs(p2 - pref2))) {
1061               p2 = pp2;
1062               p1 = int2d.ParamOnFirst();
1063               p2d = int2d.Value();
1064             }
1065             //  Modified by skv - Mon Jun 16 15:51:21 2003 OCC615 Begin
1066             else if (Check2dDistance &&
1067               RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d)) {
1068                 Standard_Real pp1 = int2d.ParamOnFirst();
1069
1070                 if(isper1)
1071                   pp1 = recadre(pp1,pref1,sens1,first1,last1);
1072
1073                 p1  = pp1;
1074                 p2  = pp2;
1075                 p2d = int2d.Value();
1076             }
1077             //  Modified by skv - Mon Jun 16 15:51:22 2003 OCC615 End
1078           }
1079           else if(((int2d.ParamOnFirst() - p1)*sens1 < 0.) &&
1080             ((int2d.ParamOnSecond() - p2)*sens2 < 0.)) {
1081               p1 = int2d.ParamOnFirst();
1082               p2 = int2d.ParamOnSecond();
1083               p2d = int2d.Value();
1084           }
1085           else if((Abs(int2d.ParamOnFirst() - pref1) < Abs(p1 - pref1)) &&
1086             (Abs(int2d.ParamOnSecond() - pref2) < Abs(p2 - pref2))) {
1087               p1 = int2d.ParamOnFirst();
1088               p2 = int2d.ParamOnSecond();
1089               p2d = int2d.Value();
1090           }
1091           else if (Check2dDistance && RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d))
1092           {
1093             p1 = int2d.ParamOnFirst();
1094             p2 = int2d.ParamOnSecond();
1095             p2d = int2d.Value();
1096           }
1097         }
1098         return Standard_True; 
1099       }
1100       return Standard_False; 
1101     }
1102     else { return Standard_False; }
1103   }
1104   else { return Standard_False; }
1105
1106 //=======================================================================
1107 //function : Coefficient
1108 //purpose  : 
1109 //=======================================================================
1110 void ChFi3d_Coefficient(const gp_Vec& V3d,
1111   const gp_Vec& D1u,
1112   const gp_Vec& D1v,
1113   Standard_Real& DU,
1114   Standard_Real& DV) 
1115 {
1116   const Standard_Real AA = D1u.SquareMagnitude();
1117   const Standard_Real BB = D1u.Dot(D1v);
1118   const Standard_Real CC = D1v.SquareMagnitude();
1119   const Standard_Real DD = D1u.Dot(V3d);
1120   const Standard_Real EE = D1v.Dot(V3d);
1121   const Standard_Real Delta = AA*CC-BB*BB;
1122   DU = (DD*CC-EE*BB)/Delta;
1123   DV = (AA*EE-BB*DD)/Delta;
1124 }
1125 //=======================================================================
1126 //function : ReparamPcurv
1127 //purpose  : Dans le cas ou la pcurve est une BSpline on verifie 
1128 //           ses parametres et on la reparametre eventuellement.
1129 //=======================================================================
1130 void ChFi3d_ReparamPcurv(const Standard_Real Uf, 
1131   const Standard_Real Ul, 
1132   Handle(Geom2d_Curve)& Pcurv) 
1133 {
1134   if(Pcurv.IsNull()) return;
1135   Standard_Real upcf = Pcurv->FirstParameter();
1136   Standard_Real upcl = Pcurv->LastParameter();
1137   Handle(Geom2d_Curve) basis = Pcurv;
1138   Handle(Geom2d_TrimmedCurve) trpc = Handle(Geom2d_TrimmedCurve)::DownCast(Pcurv);
1139   if(!trpc.IsNull()) basis = trpc->BasisCurve();
1140   Handle(Geom2d_BSplineCurve) pc = Handle(Geom2d_BSplineCurve)::DownCast(basis);
1141   if(pc.IsNull()) return;
1142   if(Abs(upcf - pc->FirstParameter()) > Precision::PConfusion() ||
1143     Abs(upcl - pc->LastParameter()) > Precision::PConfusion()) {
1144       pc->Segment(upcf,upcl);
1145   }
1146   if(Abs(Uf - pc->FirstParameter()) > Precision::PConfusion() ||
1147     Abs(Ul - pc->LastParameter()) > Precision::PConfusion()) {
1148       TColgp_Array1OfPnt2d pol(1,pc->NbPoles());
1149       pc->Poles(pol);
1150       TColStd_Array1OfReal kn(1,pc->NbKnots());
1151       pc->Knots(kn);
1152       TColStd_Array1OfInteger mu(1,pc->NbKnots());
1153       pc->Multiplicities(mu);
1154       Standard_Integer deg = pc->Degree();
1155       BSplCLib::Reparametrize(Uf,Ul,kn);
1156       pc = new Geom2d_BSplineCurve(pol,kn,mu,deg);
1157   }
1158   Pcurv = pc;
1159 }
1160 //=======================================================================
1161 //function : ProjectPCurv
1162 //purpose  : Calculation of the pcurve corresponding to a line of intersection
1163 //           3d. Should be called only in analytic cases.
1164 //=======================================================================
1165 void ChFi3d_ProjectPCurv(const Handle(Adaptor3d_HCurve)&   HCg, 
1166   const Handle(Adaptor3d_HSurface)& HSg, 
1167   Handle(Geom2d_Curve)&           Pcurv,
1168   const Standard_Real             tol,
1169   Standard_Real&                  tolreached) 
1170 {
1171   if (HSg->GetType() != GeomAbs_BezierSurface &&
1172     HSg->GetType() != GeomAbs_BSplineSurface) {
1173
1174       ProjLib_ProjectedCurve Projc (HSg,HCg,tol);
1175       tolreached = Projc.GetTolerance();
1176       switch (Projc.GetType()) {
1177       case GeomAbs_Line : 
1178         {
1179           Pcurv = new Geom2d_Line(Projc.Line());
1180         }
1181         break;
1182       case GeomAbs_Circle :
1183         {
1184           Pcurv = new Geom2d_Circle(Projc.Circle());
1185         }
1186         break;
1187       case GeomAbs_Ellipse :
1188         {
1189           Pcurv = new Geom2d_Ellipse(Projc.Ellipse());
1190         }
1191         break;
1192       case GeomAbs_Hyperbola :
1193         {
1194           Pcurv = new Geom2d_Hyperbola(Projc.Hyperbola());
1195         }
1196         break;
1197       case GeomAbs_Parabola :
1198         {
1199           Pcurv = new Geom2d_Parabola(Projc.Parabola());
1200         }
1201         break;
1202       case GeomAbs_BezierCurve :
1203         {
1204           Pcurv = Projc.Bezier(); 
1205         }
1206         break;
1207       case GeomAbs_BSplineCurve :
1208         {
1209           Pcurv = Projc.BSpline();
1210         }
1211         break;
1212       default:
1213         Standard_NotImplemented::Raise("echec approximation de la pcurve ");
1214       }
1215   }
1216 }
1217 //=======================================================================
1218 //function : CheckSameParameter
1219 //purpose  : Controls a posteriori that sameparameter worked well
1220 //=======================================================================
1221 Standard_Boolean ChFi3d_CheckSameParameter (const Handle(Adaptor3d_HCurve)&   C3d,
1222   Handle(Geom2d_Curve)&           Pcurv,
1223   const Handle(Adaptor3d_HSurface)& S,
1224   const Standard_Real             tol3d,
1225   Standard_Real&                  tolreached)
1226 {
1227   tolreached = 0.;
1228   Standard_Real f = C3d->FirstParameter();
1229   Standard_Real l = C3d->LastParameter();
1230   Standard_Integer nbp = 45;
1231   Standard_Real step = 1./(nbp -1);
1232   for(Standard_Integer i = 0; i < nbp; i++) {
1233     Standard_Real t,u,v;
1234     t = step * i;
1235     t = (1-t) * f + t * l;
1236     Pcurv->Value(t).Coord(u,v);
1237     gp_Pnt pS = S->Value(u,v);
1238     gp_Pnt pC = C3d->Value(t);
1239     Standard_Real d2 = pS.SquareDistance(pC);
1240     tolreached = Max(tolreached,d2);
1241   }
1242   tolreached = sqrt(tolreached);
1243   if(tolreached > tol3d) {
1244     tolreached *= 2.;
1245     return Standard_False;
1246   }
1247   tolreached *= 2.;
1248   tolreached = Max(tolreached,Precision::Confusion());
1249   return Standard_True;
1250 }
1251 //=======================================================================
1252 //function : SameParameter
1253 //purpose  : Encapsulation of Sameparameter
1254 //=======================================================================
1255 Standard_Boolean ChFi3d_SameParameter(const Handle(Adaptor3d_HCurve)&   C3d,
1256   Handle(Geom2d_Curve)&           Pcurv,
1257   const Handle(Adaptor3d_HSurface)& S,
1258   const Standard_Real             tol3d,
1259   Standard_Real&                  tolreached)
1260 {
1261   if(ChFi3d_CheckSameParameter(C3d,Pcurv,S,tol3d,tolreached)) return Standard_True;
1262   Approx_SameParameter sp(C3d,Pcurv,S,tol3d);
1263   if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d();
1264   else if(!sp.IsDone() && !sp.IsSameParameter()) {
1265     return Standard_False;
1266   }
1267   tolreached = sp.TolReached();
1268   return Standard_True;
1269 }
1270 //=======================================================================
1271 //function : SameParameter
1272 //purpose  : Encapsulation de Sameparameter
1273 //=======================================================================
1274 Standard_Boolean ChFi3d_SameParameter(const Handle(Geom_Curve)&   C3d,
1275   Handle(Geom2d_Curve)&       Pcurv,
1276   const Handle(Geom_Surface)& S,
1277   const Standard_Real         Pardeb,
1278   const Standard_Real         Parfin,
1279   const Standard_Real         tol3d,
1280   Standard_Real&              tolreached)
1281 {
1282   /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface(S));
1283   /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve(C3d,Pardeb,Parfin));
1284   return ChFi3d_SameParameter(hc,Pcurv,hs,tol3d,tolreached);
1285 }
1286 //=======================================================================
1287 //function : ComputePCurv 
1288 //purpose  : Calculates a straight line in form of BSpline 
1289 //           to guarantee the same range and parameters as of the 
1290 //           reference 3D curve.
1291 //=======================================================================
1292 void ChFi3d_ComputePCurv(const Handle(Adaptor3d_HCurve)&   C3d,
1293   const gp_Pnt2d&                 UV1,
1294   const gp_Pnt2d&                 UV2,
1295   Handle(Geom2d_Curve)&           Pcurv,
1296   const Handle(Adaptor3d_HSurface)& S,
1297   const Standard_Real             Pardeb,
1298   const Standard_Real             Parfin,
1299   const Standard_Real             tol3d,
1300   Standard_Real&                  tolreached,
1301   const Standard_Boolean          reverse)
1302 {
1303   ChFi3d_ComputePCurv(UV1,UV2,Pcurv,Pardeb,Parfin,reverse);
1304   ChFi3d_SameParameter(C3d,Pcurv,S,tol3d,tolreached);
1305 }
1306 //=======================================================================
1307 //function : ComputePCurv 
1308 //purpose  : Calculates a straight line in form of BSpline 
1309 //           to guarantee the same range and parameters as of the 
1310 //           reference 3D curve.
1311 //=======================================================================
1312 void ChFi3d_ComputePCurv(const Handle(Geom_Curve)&   C3d,
1313   const gp_Pnt2d&             UV1,
1314   const gp_Pnt2d&             UV2,
1315   Handle(Geom2d_Curve)&       Pcurv,
1316   const Handle(Geom_Surface)& S,
1317   const Standard_Real         Pardeb,
1318   const Standard_Real         Parfin,
1319   const Standard_Real         tol3d,
1320   Standard_Real&              tolreached,
1321   const Standard_Boolean      reverse)
1322 {
1323   Handle(Adaptor3d_HSurface) hs(new GeomAdaptor_HSurface(S));
1324   Handle(Adaptor3d_HCurve) hc(new GeomAdaptor_HCurve(C3d,Pardeb,Parfin));
1325   ChFi3d_ComputePCurv(hc,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,reverse);
1326 }
1327 //=======================================================================
1328 //function : ComputePCurv 
1329 //purpose  : Calculates a straight line in form of BSpline 
1330 //           to guarantee the same range.
1331 //=======================================================================
1332 void ChFi3d_ComputePCurv(const gp_Pnt2d& UV1,
1333   const gp_Pnt2d& UV2,
1334   Handle(Geom2d_Curve)& Pcurv,
1335   const Standard_Real Pardeb,
1336   const Standard_Real Parfin,
1337   const Standard_Boolean reverse)
1338 {
1339   const Standard_Real tol = Precision::PConfusion();
1340   gp_Pnt2d p1,p2;
1341   if (!reverse) {
1342     p1 = UV1;
1343     p2 = UV2;
1344   }
1345   else {
1346     p1 = UV2;
1347     p2 = UV1;
1348   }
1349
1350   if (Abs(p1.X()-p2.X()) <= tol &&
1351     Abs((p2.Y()-p1.Y())-(Parfin-Pardeb)) <= tol) {
1352       gp_Pnt2d ppp(p1.X(),p1.Y()-Pardeb);
1353       Pcurv = new Geom2d_Line(ppp,gp::DY2d());
1354   }
1355   else if (Abs(p1.X()-p2.X()) <= tol &&
1356     Abs((p1.Y()-p2.Y())-(Parfin-Pardeb)) <= tol) {
1357       gp_Pnt2d ppp(p1.X(),p1.Y()+Pardeb);
1358       Pcurv = new Geom2d_Line(ppp,gp::DY2d().Reversed());
1359   }
1360   else if (Abs(p1.Y()-p2.Y()) <= tol &&
1361     Abs((p2.X()-p1.X())-(Parfin-Pardeb)) <= tol) {
1362       gp_Pnt2d ppp(p1.X()-Pardeb,p1.Y());
1363       Pcurv = new Geom2d_Line(ppp,gp::DX2d());
1364   }
1365   else if (Abs(p1.Y()-p2.Y()) <= tol &&
1366     Abs((p1.X()-p2.X())-(Parfin-Pardeb)) <= tol) {
1367       gp_Pnt2d ppp(p1.X()+Pardeb,p1.Y());
1368       Pcurv = new Geom2d_Line(ppp,gp::DX2d().Reversed());
1369   }
1370   else{
1371     TColgp_Array1OfPnt2d p(1,2);
1372     TColStd_Array1OfReal k(1,2);
1373     TColStd_Array1OfInteger m(1,2);
1374     m.Init(2);
1375     k(1) = Pardeb;
1376     k(2) = Parfin;
1377     p(1) = p1;
1378     p(2) = p2;
1379     Pcurv = new Geom2d_BSplineCurve(p,k,m,1);
1380   }
1381   Pcurv = new Geom2d_TrimmedCurve(Pcurv,Pardeb,Parfin);
1382 }
1383 //=======================================================================
1384 //function : ChFi3d_mkbound
1385 //purpose  : 
1386 //=======================================================================
1387 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Fac,
1388   Handle(Geom2d_Curve)& curv, 
1389   const Standard_Integer sens1,
1390   const gp_Pnt2d& pfac1,
1391   const gp_Vec2d& vfac1,
1392   const Standard_Integer sens2,
1393   const gp_Pnt2d& pfac2,
1394   const gp_Vec2d& vfac2,
1395   const Standard_Real t3d,
1396   const Standard_Real ta)
1397 {
1398   gp_Dir2d v1(vfac1);
1399   if(sens1 == 1) v1.Reverse();
1400   gp_Dir2d v2(vfac2);
1401   if(sens2 == 1) v2.Reverse();
1402   curv = ChFi3d_BuildPCurve(Fac,pfac1,v1,pfac2,v2,Standard_False);
1403   return ChFi3d_mkbound(Fac,curv,t3d,ta);
1404 }
1405 //=======================================================================
1406 //function : ChFi3d_mkbound
1407 //purpose  : 
1408 //=======================================================================
1409 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Surf,
1410   Handle(Geom2d_Curve)& curv,
1411   const Standard_Integer sens1,
1412   const gp_Pnt2d& p1,
1413   gp_Vec&   v1,
1414   const Standard_Integer sens2,
1415   const gp_Pnt2d& p2,
1416   gp_Vec& v2,
1417   const Standard_Real t3d,
1418   const Standard_Real ta)
1419 {
1420   if(sens1 == 1) v1.Reverse();
1421   if(sens2 == 1) v2.Reverse();
1422   curv = ChFi3d_BuildPCurve(Surf,p1,v1,p2,v2);
1423   return ChFi3d_mkbound(Surf,curv,t3d,ta);
1424 }
1425 //=======================================================================
1426 //function : ChFi3d_mkbound
1427 //purpose  : 
1428 //=======================================================================
1429 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Geom_Surface)& s,
1430   const gp_Pnt2d& p1,
1431   const gp_Pnt2d& p2,
1432   const Standard_Real t3d,
1433   const Standard_Real ta,
1434   const Standard_Boolean isfreeboundary)
1435 {
1436   Handle(Adaptor3d_HSurface) HS = new GeomAdaptor_HSurface(s);
1437   return ChFi3d_mkbound(HS,p1,p2,t3d,ta,isfreeboundary);
1438 }
1439 //=======================================================================
1440 //function : ChFi3d_mkbound
1441 //purpose  : 
1442 //=======================================================================
1443 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& HS,
1444   const gp_Pnt2d& p1,
1445   const gp_Pnt2d& p2,
1446   const Standard_Real t3d,
1447   const Standard_Real ta,
1448   const Standard_Boolean isfreeboundary)
1449 {
1450   TColgp_Array1OfPnt2d pol(1,2);
1451   pol(1)=p1;
1452   pol(2)=p2;
1453   Handle(Geom2d_Curve) curv = new Geom2d_BezierCurve(pol);
1454   return ChFi3d_mkbound(HS,curv,t3d,ta,isfreeboundary);
1455 }
1456 //=======================================================================
1457 //function : ChFi3d_mkbound
1458 //purpose  : 
1459 //=======================================================================
1460 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& HS,
1461   const Handle(Geom2d_Curve)& curv,
1462   const Standard_Real t3d,
1463   const Standard_Real ta,
1464   const Standard_Boolean isfreeboundary)
1465 {
1466   Handle(Geom2dAdaptor_HCurve) HC = new Geom2dAdaptor_HCurve(curv);
1467   Adaptor3d_CurveOnSurface COnS(HC,HS);
1468   if (isfreeboundary) {
1469     Handle(Adaptor3d_HCurveOnSurface) HCOnS = new Adaptor3d_HCurveOnSurface(COnS);
1470     return new GeomFill_SimpleBound(HCOnS,t3d,ta); 
1471   }
1472   return new GeomFill_BoundWithSurf(COnS,t3d,ta);
1473 }
1474 //=======================================================================
1475 //function : ChFi3d_mkbound
1476 //purpose  : 
1477 //=======================================================================
1478 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Fac,
1479   Handle(Geom2d_Curve)& curv, 
1480   const gp_Pnt2d& p1,
1481   const gp_Pnt2d& p2,
1482   const Standard_Real t3d,
1483   const Standard_Real ta,
1484   const Standard_Boolean isfreeboundary)
1485 {
1486   TColgp_Array1OfPnt2d pol(1,2);
1487   pol(1)=p1;
1488   pol(2)=p2;
1489   curv = new Geom2d_BezierCurve(pol);
1490   return ChFi3d_mkbound(Fac,curv,t3d,ta,isfreeboundary);
1491 }
1492 //=======================================================================
1493 //function : ChFi3d_BuildPCurve
1494 //purpose  : 
1495 //=======================================================================
1496 Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const gp_Pnt2d& p1,
1497   gp_Dir2d& d1,
1498   const gp_Pnt2d& p2,
1499   gp_Dir2d& d2,
1500   const Standard_Boolean redresse)
1501 {
1502   gp_Vec2d vref(p1,p2);
1503   gp_Dir2d dref(vref);
1504   Standard_Real mref = vref.Magnitude();
1505   if(redresse) {
1506     if(d1.Dot(dref) < 0.) d1.Reverse();
1507     if(d2.Dot(dref) > 0.) d2.Reverse();
1508   }
1509   //On fait une cubique a la mords moi le noeud
1510   TColgp_Array1OfPnt2d pol(1,4);
1511   pol(1)=p1;
1512   pol(4)=p2;
1513   Standard_Real Lambda1 = Max(Abs(d2.Dot(d1)),Abs(dref.Dot(d1)));
1514   Lambda1 = Max(0.5*mref*Lambda1,1.e-5);
1515   pol(2) = gp_Pnt2d(p1.XY()+Lambda1*d1.XY());
1516   Standard_Real Lambda2 = Max(Abs(d1.Dot(d2)),Abs(dref.Dot(d2)));
1517   Lambda2 = Max(0.5*mref*Lambda2,1.e-5);
1518   pol(3)=gp_Pnt2d(p2.XY()+Lambda2*d2.XY());
1519   return new Geom2d_BezierCurve(pol);
1520 }
1521 //=======================================================================
1522 //function : ChFi3d_BuildPCurve
1523 //purpose  : 
1524 //=======================================================================
1525 Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const Handle(Adaptor3d_HSurface)& Surf,
1526   const gp_Pnt2d&                 p1,
1527   const gp_Vec2d&                 v1,
1528   const gp_Pnt2d&                 p2,
1529   const gp_Vec2d&                 v2,
1530   const Standard_Boolean          redresse)
1531 {
1532   gp_Pnt2d pp1 = p1, pp2 = p2;
1533   gp_Vec2d vv1 = v1, vv2 = v2;
1534   const Standard_Real ures = Surf->UResolution(1.);
1535   const Standard_Real vres = Surf->VResolution(1.);
1536   const Standard_Real invures = 1./ures;
1537   const Standard_Real invvres = 1./vres;
1538   pp1.SetX(invures*pp1.X()); pp1.SetY(invvres*pp1.Y()); 
1539   pp2.SetX(invures*pp2.X()); pp2.SetY(invvres*pp2.Y()); 
1540   vv1.SetX(invures*vv1.X()); vv1.SetY(invvres*vv1.Y()); 
1541   vv2.SetX(invures*vv2.X()); vv2.SetY(invvres*vv2.Y()); 
1542   gp_Dir2d d1(vv1), d2(vv2);
1543   Handle(Geom2d_Curve) g2dc = ChFi3d_BuildPCurve(pp1,d1,pp2,d2,redresse);
1544   Handle(Geom2d_BezierCurve) pc = Handle(Geom2d_BezierCurve)::DownCast(g2dc);
1545   const Standard_Integer nbp = pc->NbPoles();
1546   for(Standard_Integer ip = 1; ip <= nbp; ip++) {
1547     gp_Pnt2d pol = pc->Pole(ip);
1548     pol.SetX(ures*pol.X()); pol.SetY(vres*pol.Y());
1549     pc->SetPole(ip,pol);
1550   }
1551   return pc;
1552 }
1553 //=======================================================================
1554 //function : ChFi3d_BuildPCurve
1555 //purpose  : 
1556 //=======================================================================
1557 Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const Handle(Adaptor3d_HSurface)& Surf,
1558   const gp_Pnt2d&                 p1,
1559   const gp_Vec&                   v1,
1560   const gp_Pnt2d&                 p2,
1561   const gp_Vec&                   v2,
1562   const Standard_Boolean          redresse)
1563 {
1564   gp_Vec D1u,D1v;
1565   gp_Pnt PP1,PP2;
1566   Standard_Real DU,DV;
1567   Surf->D1(p1.X(),p1.Y(),PP1,D1u,D1v);
1568   ChFi3d_Coefficient(v1,D1u,D1v,DU,DV);
1569   gp_Vec2d vv1(DU,DV);
1570   Surf->D1(p2.X(),p2.Y(),PP2,D1u,D1v);
1571   ChFi3d_Coefficient(v2,D1u,D1v,DU,DV);
1572   gp_Vec2d vv2(DU,DV);
1573   gp_Vec Vref(PP1,PP2);
1574   if(redresse) {
1575     if(Vref.Dot(v1) < 0.) vv1.Reverse();
1576     if(Vref.Dot(v2) > 0.) vv2.Reverse();
1577   }
1578   return ChFi3d_BuildPCurve(Surf,p1,vv1,p2,vv2,0);
1579 }
1580 //=======================================================================
1581 //function : ComputeArete
1582 //purpose  : 
1583 // to fill with s.d. a fillet with pcurves constructed as follows
1584 // firstpoint on S1 -------------edge:curve3d/pcurves--->lastpoint on S1
1585 //  |                                                              |
1586 //  |                                                              |
1587 //  |                                                              |
1588 // edge:curve 3d/pcurves           fillet                         edge
1589 //  |         attention it is necessary to test orientation of the fillet before|
1590 //  |         determining the transitions pcurves/fillet           |
1591 //  |                                                              |
1592 //  \/                                                             \/
1593 // firstpoint sur S2 -------------edge:courbe3d/pcurves--->lastpoint sur S2
1594 //
1595 //=======================================================================
1596 void  ChFi3d_ComputeArete(const ChFiDS_CommonPoint&   P1,
1597   const gp_Pnt2d&             UV1,
1598   const ChFiDS_CommonPoint&   P2,
1599   const gp_Pnt2d&             UV2,
1600   const Handle(Geom_Surface)& Surf,
1601   Handle(Geom_Curve)&         C3d,
1602   Handle(Geom2d_Curve)&       Pcurv,
1603   Standard_Real&              Pardeb,
1604   Standard_Real&              Parfin,
1605   const Standard_Real         tol3d,
1606   const Standard_Real         tol2d,
1607   Standard_Real&              tolreached,
1608   const Standard_Integer      IFlag)
1609   // IFlag=0 pcurve et courbe 3d 
1610   // IFlag>0 pcurve (parametrage impose si IFlag=2)
1611 {
1612   /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface());
1613   /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve());
1614
1615   tolreached = tol3d;
1616
1617   if (Abs(UV1.X()-UV2.X()) <= tol2d) {
1618     if (IFlag == 0) {
1619       Pardeb = UV1.Y();
1620       Parfin = UV2.Y();
1621       C3d = Surf->UIso(UV1.X());
1622       if(Pardeb > Parfin) {
1623         Pardeb = C3d->ReversedParameter(Pardeb);
1624         Parfin = C3d->ReversedParameter(Parfin);
1625         C3d->Reverse();
1626       }
1627       Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C3d);
1628       if(!tc.IsNull()) {
1629         C3d = tc->BasisCurve();
1630         if (C3d->IsPeriodic()) {
1631           ElCLib::AdjustPeriodic(C3d->FirstParameter(),C3d->LastParameter(),
1632             tol2d,Pardeb,Parfin);
1633         }
1634       }
1635     }
1636     if(IFlag != 1) {
1637       hs->ChangeSurface().Load(Surf);
1638       hc->ChangeCurve().Load(C3d,Pardeb,Parfin);
1639       const Handle(Adaptor3d_HCurve)& aHCurve = hc; // to avoid ambiguity
1640       ChFi3d_ComputePCurv(aHCurve,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,Standard_False);
1641     }
1642     else{
1643       Pcurv = new Geom2d_Line(UV1,gp_Vec2d(UV1,UV2));
1644     }
1645   }
1646   else if (Abs(UV1.Y()-UV2.Y())<=tol2d) {
1647     //iso v
1648     if (IFlag == 0) {
1649       Pardeb = UV1.X();
1650       Parfin = UV2.X();
1651       C3d = Surf->VIso(UV1.Y());
1652       if(Pardeb > Parfin) {
1653         Pardeb = C3d->ReversedParameter(Pardeb);
1654         Parfin = C3d->ReversedParameter(Parfin);
1655         C3d->Reverse();
1656       }
1657       Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C3d);
1658       if(!tc.IsNull()) {
1659         C3d = tc->BasisCurve();
1660         if (C3d->IsPeriodic()) {
1661           ElCLib::AdjustPeriodic(C3d->FirstParameter(),C3d->LastParameter(),
1662             tol2d,Pardeb,Parfin);
1663         }
1664       }
1665     }
1666     if(IFlag != 1) {
1667       hs->ChangeSurface().Load(Surf);
1668       hc->ChangeCurve().Load(C3d,Pardeb,Parfin);
1669       const Handle(Adaptor3d_HCurve)& aHCurve = hc; // to avoid ambiguity
1670       ChFi3d_ComputePCurv(aHCurve,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,Standard_False);
1671     }
1672     else{
1673       Pcurv = new Geom2d_Line(UV1,gp_Vec2d(UV1,UV2));
1674     }
1675   }
1676   else if (IFlag == 0) {
1677
1678     if (P1.IsVertex() || P2.IsVertex() || !P1.IsOnArc() || !P2.IsOnArc()) {
1679       // A straight line is constructed to avoid  
1680       // arc and tangent.
1681       TColgp_Array1OfPnt2d qoles(1,2);
1682       qoles(1)=UV1;
1683       qoles(2)=UV2;
1684       Pcurv = new Geom2d_BezierCurve(qoles);
1685     }
1686     else {
1687       BRepAdaptor_Curve C1(P1.Arc());
1688       gp_Pnt Pp;
1689       gp_Vec Vv1;
1690       C1.D1(P1.ParameterOnArc(),Pp,Vv1);
1691       C1.Initialize(P2.Arc());
1692       gp_Vec Vv2;
1693       C1.D1(P2.ParameterOnArc(),Pp,Vv2);
1694       hs->ChangeSurface().Load(Surf);
1695       Pcurv = ChFi3d_BuildPCurve(hs,UV1,Vv1,UV2,Vv2,Standard_True); 
1696       // There are some cases when PCurve constructed in this way  
1697       // leaves the surface, in particular if it results from an 
1698       // extension. A posteriori checking is required and if
1699       // the curve leaves the surface it is replaced by straight line UV1 UV2
1700       // non regarding the tangency with neighboring arcs!
1701       Bnd_Box2d bs;
1702       Standard_Real umin,umax,vmin,vmax;
1703       Surf->Bounds(umin,umax,vmin,vmax);
1704       bs.Update(umin,vmin,umax,vmax);
1705       Standard_Boolean aIN = Standard_True;
1706       for(Standard_Integer ii = 1; ii <= 4 && aIN; ii++) {
1707         if(bs.IsOut(Handle(Geom2d_BezierCurve)::DownCast (Pcurv)->Pole(ii))) {
1708           aIN = Standard_False;
1709           TColgp_Array1OfPnt2d qoles(1,2);
1710           qoles(1)=UV1;
1711           qoles(2)=UV2;
1712           Pcurv = new Geom2d_BezierCurve(qoles);
1713         }
1714       }
1715     }
1716     Geom2dAdaptor_Curve AC(Pcurv);
1717     Handle(Geom2dAdaptor_HCurve) AHC = 
1718       new Geom2dAdaptor_HCurve(AC);
1719     GeomAdaptor_Surface AS(Surf);
1720     Handle(GeomAdaptor_HSurface) AHS = 
1721       new GeomAdaptor_HSurface(AS);
1722     Adaptor3d_CurveOnSurface Cs(AHC,AHS);
1723     Pardeb = Cs.FirstParameter();
1724     Parfin = Cs.LastParameter();
1725     Standard_Real avtol;
1726     GeomLib::BuildCurve3d(tol3d,Cs,Pardeb,Parfin,C3d,tolreached,avtol);
1727   }
1728   else {
1729     hs->ChangeSurface().Load(Surf);
1730     hc->ChangeCurve().Load(C3d,Pardeb,Parfin);
1731     ChFi3d_ProjectPCurv(hc,hs,Pcurv,tol3d,tolreached);
1732     gp_Pnt2d p2d = Pcurv->Value(Pardeb);
1733     if(!UV1.IsEqual(p2d,Precision::PConfusion())) {
1734       gp_Vec2d v2d(p2d,UV1);
1735       Pcurv->Translate(v2d);
1736     }
1737   }
1738 }
1739 //=======================================================================
1740 //function : FilCurveInDS
1741 //purpose  : 
1742 //=======================================================================
1743 Handle(TopOpeBRepDS_SurfaceCurveInterference)  ChFi3d_FilCurveInDS
1744   (const Standard_Integer Icurv,
1745   const Standard_Integer Isurf,
1746   const Handle(Geom2d_Curve)& Pcurv,
1747   const TopAbs_Orientation Et)
1748 {
1749   Handle(TopOpeBRepDS_SurfaceCurveInterference) SC1;
1750   SC1 = new TopOpeBRepDS_SurfaceCurveInterference(TopOpeBRepDS_Transition(Et),
1751     TopOpeBRepDS_SURFACE,
1752     Isurf,TopOpeBRepDS_CURVE,Icurv,
1753     Pcurv);
1754   return SC1;
1755 }
1756 //=======================================================================
1757 //function : TrsfTrans
1758 //purpose  : 
1759 //           
1760 //=======================================================================
1761 TopAbs_Orientation ChFi3d_TrsfTrans(const IntSurf_TypeTrans T1) 
1762 {
1763   switch (T1)  {
1764   case IntSurf_In:  return TopAbs_FORWARD;
1765   case IntSurf_Out: return TopAbs_REVERSED;
1766   default:
1767     break;
1768   }
1769   return TopAbs_INTERNAL;
1770 }
1771 //=======================================================================
1772 //function : FilCommonPoint
1773 //purpose  : Loading of the common point
1774 //           management of the case when it happens on already existing vertex.
1775 //=======================================================================
1776 Standard_EXPORT void ChFi3d_FilCommonPoint(const BRepBlend_Extremity& SP,
1777   const IntSurf_TypeTrans TransLine,
1778   const Standard_Boolean Start,
1779   ChFiDS_CommonPoint& CP,
1780   const Standard_Real Tol)
1781 {
1782   //  BRep_Tool Outil;
1783   Standard_Real Dist, maxtol = Max(Tol,CP.Tolerance());
1784
1785   CP.SetPoint(SP.Value()); // One starts with the point and the vector
1786   if (SP.HasTangent()) {
1787     if (Start) {
1788       CP.SetVector(SP.Tangent().Reversed()); // The tangent is oriented to the exit
1789     }
1790     else {
1791       CP.SetVector(SP.Tangent());
1792     }
1793   }
1794
1795   CP.SetParameter(SP.ParameterOnGuide()); // and the parameter of the spine
1796
1797   if (SP.IsVertex()) { // the Vertex is loaded if required
1798     // (inside of a face)
1799     TopoDS_Vertex V =  
1800       Handle(BRepTopAdaptor_HVertex)::DownCast(SP.Vertex())->Vertex();
1801
1802     CP.SetVertex(V);  
1803     Dist = (SP.Value()).Distance(BRep_Tool::Pnt(V));
1804     //// modified by jgv, 18.09.02 for OCC571 ////
1805     //maxtol += Dist;
1806     maxtol = Max( Dist, maxtol );
1807     //////////////////////////////////////////////
1808     CP.SetPoint(BRep_Tool::Pnt(V));
1809
1810     //the sequence of arcs the information is known by thee vertex (ancestor)
1811     //in this case the transitions are not computed, it is done by this program
1812   }
1813
1814   if (SP.NbPointOnRst() != 0) { //  An arc, and/or a vertex is loaded
1815
1816     const BRepBlend_PointOnRst& PR = SP.PointOnRst(1);
1817     Handle(BRepAdaptor_HCurve2d) 
1818       Harc = Handle(BRepAdaptor_HCurve2d)::DownCast(PR.Arc());
1819     if(!Harc.IsNull()) {
1820
1821       Standard_Real DistF, DistL, LeParamAmoi;
1822       Standard_Integer Index_min;
1823       TopoDS_Edge E = Harc->ChangeCurve2d().Edge();
1824
1825       TopoDS_Vertex V[2];
1826       TopExp::Vertices(E, V[0], V[1]);
1827
1828       DistF = (SP.Value()).Distance(BRep_Tool::Pnt(V[0]));
1829       DistL = (SP.Value()).Distance(BRep_Tool::Pnt(V[1]));
1830       if (DistF<DistL) { Index_min = 0;
1831       Dist = DistF; }
1832       else             { Index_min = 1;
1833       Dist = DistL; }
1834
1835       if (Dist <= maxtol + BRep_Tool::Tolerance(V[Index_min]) ) { 
1836         // a prexisting vertex has been met
1837         CP.SetVertex(V[Index_min]); //the old vertex is loaded
1838         CP.SetPoint( BRep_Tool::Pnt(V[Index_min]) );
1839         maxtol = Max(BRep_Tool::Tolerance(V[Index_min]),maxtol);
1840         //// modified by jgv, 18.09.02 for OCC571 ////
1841         //maxtol += Dist;
1842         maxtol = Max( Dist, maxtol );
1843         //////////////////////////////////////////////
1844         LeParamAmoi = BRep_Tool::Parameter(V[Index_min], E);    
1845       }
1846       else {   // Creation of an arc only
1847         maxtol = Max(BRep_Tool::Tolerance(E),maxtol);
1848         maxtol = Max(SP.Tolerance(),maxtol);
1849         LeParamAmoi = PR.ParameterOnArc();
1850       }
1851
1852       // Definition of the arc
1853       TopAbs_Orientation Tr;
1854       TopAbs_Orientation Or = E.Orientation();
1855       if (Start) {
1856         Tr = TopAbs::Reverse(TopAbs::Compose(ChFi3d_TrsfTrans(TransLine),Or));
1857       }
1858       else {
1859         Tr = TopAbs::Compose(ChFi3d_TrsfTrans(TransLine),Or);
1860       }
1861       CP.SetArc(maxtol, E, LeParamAmoi, Tr);
1862     }
1863   }
1864   CP.SetTolerance(maxtol); // Finally, the tolerance.
1865 }
1866
1867 //=======================================================================
1868 //function : SolidIndex
1869 //purpose  : 
1870 //=======================================================================
1871 Standard_Integer ChFi3d_SolidIndex(const Handle(ChFiDS_Spine)&  sp,
1872   TopOpeBRepDS_DataStructure&  DStr,
1873   ChFiDS_Map&                  MapESo,
1874   ChFiDS_Map&                  MapESh)
1875 {
1876   if(sp.IsNull() || sp->NbEdges() == 0) 
1877     Standard_Failure::Raise("SolidIndex : Spine incomplete");
1878   TopoDS_Shape edref= sp->Edges(1);
1879   TopoDS_Shape shellousolid;
1880   if(!MapESo(edref).IsEmpty()) shellousolid = MapESo(edref).First();
1881   else shellousolid = MapESh(edref).First();
1882   const Standard_Integer solidindex = DStr.AddShape(shellousolid);
1883   return solidindex;
1884 }
1885 //=======================================================================
1886 //function : IndexPointInDS
1887 //purpose  : 
1888 //=======================================================================
1889 Standard_Integer  ChFi3d_IndexPointInDS(const ChFiDS_CommonPoint& P1,
1890   TopOpeBRepDS_DataStructure& DStr) 
1891 {
1892   if (P1.IsVertex()) {
1893     // --------------------------------->  !*!*!* 
1894     // Attention : it is necessary ti implement a mechanism 
1895     // controlling tolerance.
1896     BRep_Builder B;
1897     B.UpdateVertex(P1.Vertex(), P1.Point(), P1.Tolerance());
1898     return DStr.AddShape(P1.Vertex());
1899   }
1900   return DStr.AddPoint(TopOpeBRepDS_Point(P1.Point(),P1.Tolerance()));
1901 }
1902 //=======================================================================
1903 //function : FilPointInDS
1904 //purpose  : 
1905 //=======================================================================
1906 Handle(TopOpeBRepDS_CurvePointInterference) 
1907   ChFi3d_FilPointInDS(const TopAbs_Orientation Et,
1908   const Standard_Integer Ic,
1909   const Standard_Integer Ip,
1910   const Standard_Real Par,
1911   const Standard_Boolean IsVertex)
1912 {
1913   Handle(TopOpeBRepDS_CurvePointInterference) CP1;
1914   if (IsVertex)    
1915     CP1 = new TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
1916     TopOpeBRepDS_CURVE,Ic,
1917     TopOpeBRepDS_VERTEX,Ip,Par); 
1918   else
1919     CP1 = new TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
1920     TopOpeBRepDS_CURVE,Ic,
1921     TopOpeBRepDS_POINT,Ip,Par);
1922   return CP1;
1923 }
1924 //=======================================================================
1925 //function : FilVertexInDS
1926 //purpose  : 
1927 //=======================================================================
1928 Handle(TopOpeBRepDS_CurvePointInterference) 
1929   ChFi3d_FilVertexInDS(const TopAbs_Orientation Et,
1930   const Standard_Integer Ic,
1931   const Standard_Integer Ip,
1932   const Standard_Real Par)
1933 {
1934
1935   Handle(TopOpeBRepDS_CurvePointInterference) CP1 = new
1936     TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
1937     TopOpeBRepDS_CURVE,Ic,
1938     TopOpeBRepDS_VERTEX,Ip,Par);
1939   return CP1;
1940 }
1941 //=======================================================================
1942 //function : Orientation
1943 //purpose  : returns the orientation of the interference (the first found
1944 //           in the list).
1945 //=======================================================================
1946
1947 static Standard_Boolean
1948   ChFi3d_Orientation(const TopOpeBRepDS_ListOfInterference& LI,
1949   const Standard_Integer                 igros,
1950   const Standard_Integer                 ipetit,
1951   TopAbs_Orientation&                    Or,
1952   const Standard_Boolean                 isvertex = Standard_False,
1953   const Standard_Boolean                 aprendre = Standard_False)
1954 {
1955   //In case, when it is necessary to insert a point/vertex, it should be 
1956   //known if this is a point or a vertex, because their index can be the same.
1957   TopOpeBRepDS_Kind typepetit;
1958   if (isvertex)
1959     typepetit =  TopOpeBRepDS_VERTEX;
1960   else
1961     typepetit =  TopOpeBRepDS_POINT;
1962   TopOpeBRepDS_ListIteratorOfListOfInterference itLI(LI);
1963   for (; itLI.More(); itLI.Next() ) {
1964     const Handle(TopOpeBRepDS_Interference)& cur = itLI.Value(); 
1965     TopOpeBRepDS_Kind GK;
1966     TopOpeBRepDS_Kind SK;
1967     Standard_Integer S;
1968     Standard_Integer G;
1969     cur->GKGSKS(GK,G,SK,S);
1970     if (aprendre) {
1971       if ( S == igros && G == ipetit && GK == typepetit) {
1972         Or = cur->Transition().Orientation(TopAbs_IN);
1973         return Standard_True;
1974       }
1975     }
1976     else  {
1977       if ( S == igros && G == ipetit) {
1978         Or = cur->Transition().Orientation(TopAbs_IN);
1979         return Standard_True;
1980       } 
1981     }
1982   }
1983   return Standard_False;
1984 }
1985
1986 //=======================================================================
1987 //function : Contains
1988 //purpose  : Check if the interference does not already exist.
1989 //====================================================================
1990
1991 static Standard_Boolean ChFi3d_Contains
1992   (const TopOpeBRepDS_ListOfInterference& LI,
1993   const Standard_Integer                 igros,
1994   const Standard_Integer                 ipetit,
1995   const Standard_Boolean                 isvertex = Standard_False,
1996   const Standard_Boolean                 aprendre = Standard_False)                             
1997 {
1998   TopAbs_Orientation bidOr;
1999   return ChFi3d_Orientation(LI,igros,ipetit,bidOr,isvertex,aprendre);
2000 }
2001 //=======================================================================
2002 //function : QueryAddVertexInEdge
2003 //purpose  : 
2004 //=======================================================================
2005 static void QueryAddVertexInEdge(TopOpeBRepDS_ListOfInterference& LI,
2006   const Standard_Integer                 IC,
2007   const Standard_Integer                 IV,
2008   const Standard_Real                    par,
2009   const TopAbs_Orientation               Or)
2010 {
2011   TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
2012   for (; it.More(); it.Next() ) {
2013     const Handle(TopOpeBRepDS_Interference)& cur = it.Value();
2014     Handle(TopOpeBRepDS_CurvePointInterference) cpi (Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(cur));
2015     if(!cpi.IsNull()) {
2016       Standard_Integer newIV = cpi->Geometry();
2017       TopOpeBRepDS_Kind kv = cpi->GeometryType();
2018       TopAbs_Orientation newOr = cpi->Transition().Orientation(TopAbs_IN);
2019       Standard_Real newpar = cpi->Parameter();
2020       if(IV == newIV && kv == TopOpeBRepDS_VERTEX && 
2021         Or == newOr && Abs(par - newpar) < 1.e-10) {
2022           return;
2023       }
2024     }
2025   }
2026   Handle(TopOpeBRepDS_CurvePointInterference) interf = 
2027     ChFi3d_FilVertexInDS(Or,IC,IV,par);
2028   LI.Append(interf);
2029 }
2030
2031 //=======================================================================
2032 //function : CutEdge
2033 //purpose  : 
2034 //=======================================================================
2035 static void CutEdge(const TopoDS_Vertex&           V,
2036   const Handle(ChFiDS_SurfData)& SD,
2037   TopOpeBRepDS_DataStructure&    DStr,
2038   const Standard_Boolean         ,
2039   const Standard_Integer         ons)
2040 {
2041   if(!SD->IsOnCurve(ons)) return;
2042   Standard_Integer IC = SD->IndexOfC(ons);
2043   Standard_Integer IV = DStr.AddShape(V);
2044   TopOpeBRepDS_ListOfInterference& LI = DStr.ChangeShapeInterferences(IC);
2045   TopoDS_Edge E = TopoDS::Edge(DStr.Shape(IC));
2046   E.Orientation(TopAbs_FORWARD);
2047   TopExp_Explorer ex;
2048
2049   // process them checking that it has not been done already.
2050   for(ex.Init(E,TopAbs_VERTEX);ex.More();ex.Next()) {
2051     const TopoDS_Vertex& vv = TopoDS::Vertex(ex.Current());
2052     if(vv.IsSame(V)) {
2053       TopAbs_Orientation Or = TopAbs::Reverse(vv.Orientation());
2054       Standard_Real par = BRep_Tool::Parameter(vv,E);
2055       QueryAddVertexInEdge(LI,IC,IV,par,Or);
2056     }
2057   }
2058 }
2059 //=======================================================================
2060 //function : findIndexPoint
2061 //purpose  : returns in <ipon> index of point bounding a courve interfering
2062 //           with <Fd> and coinciding with last common point on <OnS> face
2063 //=======================================================================
2064 static Standard_Boolean 
2065   findIndexPoint(const TopOpeBRepDS_DataStructure& DStr,
2066   const Handle(ChFiDS_SurfData)&    Fd,
2067   const Standard_Integer            OnS,
2068   Standard_Integer&                 ipoin)
2069 {
2070   ipoin = 0;
2071   gp_Pnt P = Fd->Vertex(Standard_False,OnS).Point();
2072
2073   TopOpeBRepDS_ListIteratorOfListOfInterference SCIIt, CPIIt;
2074
2075   SCIIt.Initialize (DStr.SurfaceInterferences(Fd->Surf()));
2076   for (; SCIIt.More(); SCIIt.Next()) {
2077     Handle(TopOpeBRepDS_SurfaceCurveInterference) SCI =
2078       Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(SCIIt.Value());
2079     if (SCI.IsNull()) continue;
2080     CPIIt.Initialize (DStr.CurveInterferences(SCI->Geometry()));
2081     for (; CPIIt.More(); CPIIt.Next()) {
2082       Handle(TopOpeBRepDS_CurvePointInterference) CPI =
2083         Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(CPIIt.Value());
2084       if (CPI.IsNull()) continue;
2085       Standard_Integer iPoint = CPI->Geometry();
2086       TopOpeBRepDS_Point tp = DStr.Point(iPoint);
2087       if (P.IsEqual(tp.Point(), tp.Tolerance())) {
2088         ipoin = iPoint;
2089         return Standard_True;
2090       }
2091     }
2092   }
2093   return Standard_False;
2094 }
2095 //=======================================================================
2096 //function : FilDS
2097 //purpose  : 
2098 //=======================================================================
2099 void  ChFi3d_FilDS(const Standard_Integer       SolidIndex,
2100   const Handle(ChFiDS_Stripe)& CorDat,
2101   TopOpeBRepDS_DataStructure&  DStr,
2102   ChFiDS_Regularities&         reglist,
2103   const Standard_Real          tol3d,
2104   const Standard_Real          tol2d) 
2105 {
2106   //  BRep_Tool Outil;
2107   TopExp_Explorer ex;
2108   Handle(ChFiDS_Spine) spine = CorDat->Spine();
2109   Standard_Boolean Closed = Standard_False;
2110   Standard_Boolean Degene = 0, isVertex1 = 0, isVertex2 = 0, Singulier_en_Bout = 0;
2111   if(!spine.IsNull()) {
2112     Closed = spine->IsPeriodic();
2113   }
2114   const ChFiDS_SequenceOfSurfData& SeqFil = 
2115     CorDat->SetOfSurfData()->Sequence();
2116   Standard_Integer Ipoin1 = CorDat->IndexFirstPointOnS1();
2117   Standard_Integer Ipoin2 = CorDat->IndexFirstPointOnS2();
2118   Standard_Integer NumEdge = 1;
2119   TopoDS_Vertex BoutdeVtx; 
2120   Standard_Integer Icurv = 0;
2121   Standard_Integer Iarc1 = 0,Iarc2 = 0;
2122   TopAbs_Orientation trafil1 = TopAbs_FORWARD, trafil2 = TopAbs_FORWARD;
2123   Standard_Integer IcFil1,IcFil2,Isurf,Ishape1,Ishape2;
2124   Standard_Real Pardeb = 0.,Parfin = 0.;
2125   TopAbs_Orientation ET1;
2126   Handle(TopOpeBRepDS_CurvePointInterference) Interfp1,Interfp2;
2127   Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc1,Interfc2;
2128   Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc3,Interfc4;
2129   Handle(TopOpeBRepDS_CurvePointInterference) Interfp3,Interfp4;
2130   Handle(TopOpeBRepDS_CurvePointInterference) Interfp5,Interfp6;
2131   TopoDS_Face F;
2132   Handle(Geom2d_Curve) PCurv;
2133   TopOpeBRepDS_Curve Crv;
2134
2135   TopOpeBRepDS_ListOfInterference& SolidInterfs = 
2136     DStr.ChangeShapeInterferences(SolidIndex);
2137
2138   ChFiDS_Regul regcout; // for closed and tangent CD
2139   ChFiDS_Regul regfilfil; // for connections Surf/Surf
2140
2141   ChFiDS_CommonPoint V3;
2142   ChFiDS_CommonPoint V4;
2143
2144   // Nullify degenerated ChFi/Faces interferences, eap occ293
2145   Standard_Integer j;
2146   if (SeqFil.Length() > 1) {
2147     for (j=1; j<=SeqFil.Length(); j++) {
2148       Handle(ChFiDS_SurfData) Fd = SeqFil(j);
2149       Standard_Integer onS;
2150       for (onS=1; onS<=2; onS++) {
2151         const ChFiDS_FaceInterference& Fi = Fd->Interference(onS);
2152         IcFil1 = Fi.LineIndex();
2153         if (!IcFil1) continue;
2154         Standard_Real FiLen = Abs(Fi.FirstParameter()-Fi.LastParameter());
2155         if (FiLen > Precision::PConfusion()) continue;
2156         TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil1);
2157         cc.ChangeCurve().Nullify();
2158
2159         // care of CommonPoint, eap occ354
2160         if (j!=1 && j!=SeqFil.Length()) continue;
2161         Standard_Boolean isfirst = (j==1);
2162         Standard_Integer i = isfirst ? j+1 : j-1;
2163         ChFiDS_CommonPoint& CP1 = SeqFil(i)->ChangeVertex(isfirst,onS);
2164         if (Fd->Vertex(isfirst,onS).IsOnArc() && CP1.IsOnArc()) {
2165           ChFiDS_CommonPoint& CP2 = Fd->ChangeVertex(!isfirst,onS);
2166           CP1.Reset();
2167           CP1.SetPoint(CP2.Point());
2168           CP2.Reset();
2169           CP2.SetPoint(CP1.Point());
2170         }
2171       }
2172     }
2173   }
2174
2175   for (j=1; j<=SeqFil.Length(); j++) {
2176
2177     const Handle(ChFiDS_SurfData)& Fd = SeqFil(j);
2178     Isurf= Fd->Surf();
2179     Ishape1 = Fd->IndexOfS1();
2180     Ishape2 = Fd->IndexOfS2();
2181
2182     // eap, Apr 29 2002, occ 293
2183     // now IsInDS() returns nb of surfaces at end being in DS;
2184     // vars showing which end is in DS
2185     Standard_Boolean isInDS1 = Standard_False, isInDS2 = Standard_False;
2186     if (j <= CorDat->IsInDS(Standard_True)) {
2187       isInDS1 = Standard_True;
2188       isInDS2 = (j+1 <= CorDat->IsInDS(Standard_True));
2189     }
2190     if (SeqFil.Length()-j < CorDat->IsInDS(Standard_False)) {
2191       isInDS2 = Standard_True;
2192       isInDS1 = isInDS1 || SeqFil.Length()-j+1 < CorDat->IsInDS(Standard_False);
2193     }
2194
2195     // creation of SolidSurfaceInterference
2196
2197     Handle(TopOpeBRepDS_SolidSurfaceInterference) 
2198       SSI = new TopOpeBRepDS_SolidSurfaceInterference
2199       (TopOpeBRepDS_Transition(Fd->Orientation()),
2200       TopOpeBRepDS_SOLID,
2201       SolidIndex,
2202       TopOpeBRepDS_SURFACE,
2203       Isurf);
2204
2205     SolidInterfs.Append(SSI);
2206
2207     const ChFiDS_FaceInterference& Fi1 = Fd->InterferenceOnS1();
2208     const ChFiDS_FaceInterference& Fi2 = Fd->InterferenceOnS2();     
2209     const ChFiDS_CommonPoint& V1 = Fd->VertexFirstOnS1();
2210     const ChFiDS_CommonPoint& V2 = Fd->VertexFirstOnS2();
2211
2212     // Processing to manage double interferences
2213     if (j>1) {
2214       if (V1.IsOnArc() && V3.IsOnArc() && V1.Arc().IsSame(V3.Arc())) {
2215         //Iarc1 is initialized
2216         //Iarc1 = DStr.AddShape(V1.Arc());
2217         if (ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1) && 
2218           (V1.TransitionOnArc() != V3.TransitionOnArc()) ) {
2219             Interfp1= ChFi3d_FilPointInDS(V1.TransitionOnArc(),Iarc1,Ipoin1,
2220               V1.ParameterOnArc());
2221             DStr.ChangeShapeInterferences(V1.Arc()).Append(Interfp1);
2222         }
2223       }
2224
2225       if (V2.IsOnArc() && V4.IsOnArc() && V2.Arc().IsSame(V4.Arc())) {
2226         //Iarc2 is initialized
2227         //Iarc2 = DStr.AddShape(V2.Arc());
2228         if ( ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2)  && 
2229           (V2.TransitionOnArc() != V4.TransitionOnArc()) ) {
2230             Interfp2= ChFi3d_FilPointInDS(V2.TransitionOnArc(),Iarc2,Ipoin2,
2231               V2.ParameterOnArc());
2232             DStr.ChangeShapeInterferences(V2.Arc()).Append(Interfp2);
2233         }
2234       }
2235     }
2236
2237     V3 = Fd->VertexLastOnS1();
2238     V4 = Fd->VertexLastOnS2();
2239
2240     if(Ishape1 != 0) {
2241       if(Ishape1 > 0) {
2242         trafil1 = DStr.Shape(Ishape1).Orientation();
2243       }
2244       else{
2245         ChFi3d_Orientation(SolidInterfs,SolidIndex,-Ishape1,trafil1);
2246       }
2247       trafil1 = TopAbs::Compose(trafil1,Fd->Orientation());
2248       trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi1.Transition()),trafil1);
2249       trafil2 = TopAbs::Reverse(trafil1);
2250     }
2251     else{
2252       if(Ishape2 > 0) {
2253         trafil2 = DStr.Shape(Ishape2).Orientation();
2254       }
2255       else{
2256         ChFi3d_Orientation(SolidInterfs,SolidIndex,-Ishape2,trafil2);
2257       }
2258       trafil2 = TopAbs::Compose(trafil2,Fd->Orientation());
2259       trafil2 = TopAbs::Compose(TopAbs::Reverse(Fi2.Transition()),trafil2);
2260       trafil1 = TopAbs::Reverse(trafil2);
2261     }
2262
2263     ET1 = TopAbs::Reverse(trafil1);
2264
2265     // A small paragraph to process contacts of edges, which touch 
2266     // a vertex of the obstacle.
2267     if(V1.IsVertex() && Fd->IsOnCurve1()) {
2268       const TopoDS_Vertex& vv1 = V1.Vertex();
2269       CutEdge(vv1,Fd,DStr,1,1);
2270     }
2271     if(V2.IsVertex() && Fd->IsOnCurve2()) {
2272       const TopoDS_Vertex& vv2 = V2.Vertex();
2273       CutEdge(vv2,Fd,DStr,1,2);
2274     }
2275     if(V3.IsVertex() && Fd->IsOnCurve1()) {
2276       const TopoDS_Vertex& vv3 = V3.Vertex();
2277       CutEdge(vv3,Fd,DStr,0,1);
2278     }
2279     if(V4.IsVertex() && Fd->IsOnCurve2()) {
2280       const TopoDS_Vertex& vv4 = V4.Vertex();
2281       CutEdge(vv4,Fd,DStr,0,2);
2282     }
2283
2284     if (j == 1) {
2285       isVertex1 = V1.IsVertex();
2286       isVertex2 = V2.IsVertex();
2287       Singulier_en_Bout =  (V1.Point().IsEqual(V2.Point(), 0));
2288
2289       if (Singulier_en_Bout) {
2290         // Queue de Billard
2291         if ((!V1.IsVertex()) || (!V2.IsVertex())) {
2292
2293         }
2294         else {
2295           isVertex1 = isVertex2 = Standard_True; //caution...
2296           // The edge is removed from spine starting on this vertex.
2297           TopoDS_Edge Arcspine = spine->Edges(1);
2298           BoutdeVtx = V1.Vertex();
2299           Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2300           Standard_Integer IVtx = CorDat->IndexFirstPointOnS1();
2301
2302           TopAbs_Orientation OVtx = TopAbs_FORWARD;;
2303
2304           for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); 
2305             ex.More(); ex.Next()) {
2306               if(BoutdeVtx.IsSame(ex.Current())) {
2307                 OVtx = ex.Current().Orientation();
2308                 break;
2309               }
2310           }
2311           OVtx = TopAbs::Reverse(OVtx);
2312           Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2313           Handle(TopOpeBRepDS_CurvePointInterference) 
2314             interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2315           DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2316         }
2317       }
2318       else {
2319         if (V1.IsOnArc()) {
2320           Iarc1 = DStr.AddShape(V1.Arc()); 
2321           if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1) ) {
2322             Interfp1= ChFi3d_FilPointInDS(V1.TransitionOnArc(),Iarc1,Ipoin1,
2323               V1.ParameterOnArc(), isVertex1);
2324             DStr.ChangeShapeInterferences(V1.Arc()).Append(Interfp1);
2325           }
2326         }
2327
2328         if (V2.IsOnArc()) {
2329           Iarc2 = DStr.AddShape(V2.Arc());
2330           if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2) ) {
2331             Interfp2= ChFi3d_FilPointInDS(V2.TransitionOnArc(),Iarc2,Ipoin2,
2332               V2.ParameterOnArc(),isVertex2);
2333             DStr.ChangeShapeInterferences(V2.Arc()).Append(Interfp2);
2334           }
2335         }
2336       }
2337
2338       if (!isInDS1) {
2339         ET1 = TopAbs::Compose(ET1,CorDat->FirstPCurveOrientation());
2340         Icurv = CorDat->FirstCurve();
2341         if(Closed && !Singulier_en_Bout) {
2342           regcout.SetCurve(Icurv);
2343           regcout.SetS1(Isurf,Standard_False);
2344         }
2345         PCurv = CorDat->FirstPCurve();
2346         CorDat->FirstParameters(Pardeb,Parfin);
2347
2348         TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(Icurv);
2349         if (Li.IsEmpty()) {
2350           if(CorDat->FirstPCurveOrientation()==TopAbs_REVERSED) {
2351             Interfp1=ChFi3d_FilPointInDS
2352               (TopAbs_REVERSED,Icurv,Ipoin1,Parfin,isVertex1);
2353             Interfp2=ChFi3d_FilPointInDS
2354               (TopAbs_FORWARD,Icurv,Ipoin2,Pardeb,isVertex2);
2355           }
2356           else{
2357             Interfp1=ChFi3d_FilPointInDS
2358               (TopAbs_FORWARD,Icurv,Ipoin1,Pardeb,isVertex1);
2359             Interfp2=ChFi3d_FilPointInDS
2360               (TopAbs_REVERSED,Icurv,Ipoin2,Parfin,isVertex2);
2361           }
2362           Li.Append(Interfp1);
2363           Li.Append(Interfp2);
2364         }
2365         Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2366         DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2367         if (Ipoin1 == Ipoin2) {
2368           TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2369           TCurv.ChangeCurve().Nullify();
2370           Handle(TopOpeBRepDS_Interference) bidinterf;
2371           TCurv.SetSCI(Interfc1,bidinterf);         
2372         }
2373       }
2374     } // End of the Initial Processing (j==1)
2375     else {
2376       // ---- Interference between Fillets ------
2377
2378       if (!isInDS1) {// eap, Apr 29 2002, occ 293 
2379
2380         if (Degene && isVertex1) {
2381           // The edge is removed from the spine starting on this vertex.
2382           NumEdge++; // The previous edge of the vertex has already been found.
2383           TopoDS_Edge Arcspine = spine->Edges(NumEdge);
2384           Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2385           Standard_Integer IVtx = DStr.AddShape(BoutdeVtx);
2386           TopAbs_Orientation OVtx = TopAbs_FORWARD;
2387           for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); 
2388             ex.More(); ex.Next()) {
2389               if(BoutdeVtx.IsSame(ex.Current())) {
2390                 OVtx = ex.Current().Orientation();
2391                 break;
2392               }
2393           }
2394           OVtx = TopAbs::Reverse(OVtx);
2395           Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2396           Handle(TopOpeBRepDS_CurvePointInterference) 
2397             interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2398           DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2399         } // End of the removal
2400
2401         gp_Pnt2d UV1 = Fd->InterferenceOnS1().PCurveOnSurf()->
2402           Value(Fd->InterferenceOnS1().FirstParameter());
2403         gp_Pnt2d UV2 = Fd->InterferenceOnS2().PCurveOnSurf()-> 
2404           Value(Fd->InterferenceOnS2().FirstParameter());
2405         TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2406         if (Degene) {
2407           // pcurve is associated via SCI to TopOpeBRepDSCurve.
2408           ChFi3d_ComputePCurv(UV1,UV2,PCurv,Pardeb,Parfin);       
2409           Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2410           DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2411           TCurv.ChangeCurve().Nullify();
2412           Handle(TopOpeBRepDS_Interference) bidinterf;
2413           TCurv.SetSCI(Interfc1,bidinterf);           
2414         }
2415         else {
2416           regfilfil.SetS2(Isurf,Standard_False);
2417           reglist.Append(regfilfil);
2418           Standard_Real tolreached;
2419           ChFi3d_ComputePCurv(TCurv.ChangeCurve(),UV1,UV2,PCurv,
2420             DStr.Surface(Fd->Surf()).Surface(),
2421             Pardeb,Parfin,tol3d,tolreached);
2422           TCurv.Tolerance(Max(TCurv.Tolerance(),tolreached));
2423           Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2424           DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2425         }
2426       }
2427     } // End of Interference between fillets 
2428
2429     // ---- Interference Fillets / Faces
2430     IcFil1 = Fi1.LineIndex();
2431
2432     if (IcFil1!=0 ) {
2433       Interfc3= ChFi3d_FilCurveInDS (IcFil1,Isurf,
2434         Fi1.PCurveOnSurf(),trafil1);
2435       DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc3);
2436       Ishape1 = Fd->IndexOfS1();
2437       // Case of degenerated edge : pcurve is associated via SCI 
2438       // to TopOpeBRepDSCurve.
2439       TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil1);
2440       if(cc.Curve().IsNull()) {
2441         Handle(TopOpeBRepDS_Interference) bidinterf;
2442         cc.SetSCI(Interfc3,bidinterf);
2443       }
2444       else{
2445         ChFiDS_Regul regon1;
2446         regon1.SetCurve(IcFil1);
2447         regon1.SetS1(Isurf,Standard_False);
2448         if ( Ishape1 < 0 ) {
2449           Ishape1 = -Ishape1;
2450           regon1.SetS2(Ishape1,Standard_False);
2451           Interfc1=ChFi3d_FilCurveInDS(IcFil1,Ishape1,Fi1.PCurveOnFace(),
2452             Fi1.Transition()); 
2453           DStr.ChangeSurfaceInterferences(Ishape1).Append(Interfc1);      
2454         }
2455         else if ( Ishape1 > 0 ) {
2456           regon1.SetS2(Ishape1,Standard_True);
2457           Interfc1=ChFi3d_FilCurveInDS(IcFil1,Ishape1,Fi1.PCurveOnFace(),
2458             Fi1.Transition()); 
2459           DStr.ChangeShapeInterferences(Ishape1).Append(Interfc1);      
2460         }
2461         reglist.Append(regon1);
2462       }
2463       // Indice and type of the point at End
2464       Standard_Integer ipoin;
2465       Standard_Boolean isVertex = Fd->VertexLastOnS1().IsVertex();
2466       if (j == SeqFil.Length()) ipoin = CorDat->IndexLastPointOnS1();
2467       else if ( j == (SeqFil.Length()-1)  &&  /*Closed &&*/
2468         (DStr.Curve(SeqFil.Last()->InterferenceOnS1().
2469         LineIndex()).Curve().IsNull())) {
2470           if (Closed) {
2471             ipoin = CorDat->IndexFirstPointOnS1();
2472             isVertex = SeqFil(1)->VertexFirstOnS1().IsVertex();
2473           } else {
2474             ipoin = CorDat->IndexLastPointOnS1();
2475             isVertex = SeqFil.Last()->VertexLastOnS1().IsVertex();
2476           }
2477       }
2478       else if(DStr.Curve(IcFil1).Curve().IsNull()) {// Rotation !!
2479         ipoin = Ipoin1;
2480         isVertex = isVertex1;
2481       }
2482       else if ( ((j==1) || (j== SeqFil.Length()-1)) && 
2483         ( (Fd->VertexLastOnS1().Point().IsEqual(
2484         SeqFil(1)->VertexFirstOnS1().Point(), 1.e-7)) ||
2485         (Fd->VertexLastOnS1().Point().IsEqual(
2486         SeqFil(SeqFil.Length())->VertexLastOnS1().Point(), 1.e-7))) )
2487         // Case of SurfData cut in "Triangular" way.   
2488         ipoin=CorDat->IndexLastPointOnS1();
2489
2490       // eap, Apr 29 2002, occ 293
2491       else if (isInDS2 && findIndexPoint(DStr, Fd, 1, ipoin)) {
2492
2493       }
2494       else ipoin = ChFi3d_IndexPointInDS(Fd->VertexLastOnS1(),DStr);
2495
2496       TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(IcFil1);
2497
2498       if (!ChFi3d_Contains(Li,IcFil1,Ipoin1)) { 
2499
2500         Interfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,IcFil1,Ipoin1,
2501           Fi1.FirstParameter(),isVertex1);
2502         DStr.ChangeCurveInterferences(IcFil1).Append(Interfp1);
2503       }
2504       if (ipoin == Ipoin1 || !ChFi3d_Contains(Li,IcFil1,ipoin)) { 
2505         Interfp3 = ChFi3d_FilPointInDS(TopAbs_REVERSED,IcFil1,ipoin,
2506           Fi1.LastParameter(), isVertex);
2507         DStr.ChangeCurveInterferences(IcFil1).Append(Interfp3);
2508       }
2509       Ipoin1 = ipoin;
2510       isVertex1 = isVertex;
2511     }
2512
2513     IcFil2 = Fi2.LineIndex();
2514     if (IcFil2!=0) {
2515       Interfc4=ChFi3d_FilCurveInDS(IcFil2,Isurf,
2516         Fi2.PCurveOnSurf(),trafil2);
2517       DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc4);
2518       Ishape2 = Fd->IndexOfS2();
2519       // Case of degenerated edge : pcurve is associated via SCI 
2520       // to TopOpeBRepDSCurve.
2521       TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil2);
2522       if(cc.Curve().IsNull()) {
2523         Handle(TopOpeBRepDS_Interference) bidinterf;
2524         cc.SetSCI(Interfc4,bidinterf);
2525       }
2526       else{
2527         ChFiDS_Regul regon2;
2528         regon2.SetCurve(IcFil2);
2529         regon2.SetS1(Isurf,Standard_False);
2530         if ( Ishape2 < 0 ) {
2531           Ishape2 = -Ishape2;
2532           regon2.SetS2(Ishape2,Standard_False);
2533           Interfc2=ChFi3d_FilCurveInDS(IcFil2,Ishape2,Fi2.PCurveOnFace(),
2534             Fi2.Transition());
2535           DStr.ChangeSurfaceInterferences(Ishape2).Append(Interfc2);      
2536         }
2537         else if ( Ishape2 > 0 ) {
2538           regon2.SetS2(Ishape2,Standard_True);
2539           Interfc2=ChFi3d_FilCurveInDS(IcFil2,Ishape2,Fi2.PCurveOnFace(),
2540             Fi2.Transition());
2541           DStr.ChangeShapeInterferences(Ishape2).Append(Interfc2);      
2542         }
2543         reglist.Append(regon2);
2544       }
2545       // Indice and type of the point in End
2546       Standard_Integer ipoin;
2547       Standard_Boolean isVertex = Fd->VertexLastOnS2().IsVertex();
2548       if (j == SeqFil.Length() ) ipoin = CorDat->IndexLastPointOnS2();
2549       else if ( j == (SeqFil.Length()-1)  && /*Closed &&*/
2550         (DStr.Curve(SeqFil.Last()->InterferenceOnS2().
2551         LineIndex()).Curve().IsNull())) {
2552           if (Closed) {
2553             ipoin = CorDat->IndexFirstPointOnS2();
2554             isVertex = SeqFil(1)->VertexFirstOnS2().IsVertex();
2555           } else {
2556             ipoin = CorDat->IndexLastPointOnS2();
2557             isVertex = SeqFil.Last()->VertexLastOnS2().IsVertex();
2558           }
2559       }
2560       else if(DStr.Curve(IcFil2).Curve().IsNull()) { // Rotation !!
2561         ipoin = Ipoin2;
2562         isVertex = isVertex2;
2563       }
2564       else if(Fd->VertexLastOnS2().Point().IsEqual(
2565         Fd->VertexLastOnS1().Point(), 0) ) {  //Pinch !!
2566           ipoin = Ipoin1;
2567           isVertex = isVertex1;
2568       }
2569       else if ( ((j==1) || (j==SeqFil.Length()-1)) && 
2570         ( (Fd->VertexLastOnS2().Point().IsEqual(
2571         SeqFil(1)->VertexFirstOnS2().Point(), 1.e-7)) ||
2572         (Fd->VertexLastOnS2().Point().IsEqual(
2573         SeqFil(SeqFil.Length())->VertexLastOnS2().Point(), 1.e-7))) )
2574         // Case of SurfData cut in "Triangular" way.   
2575         ipoin=CorDat->IndexLastPointOnS2();
2576
2577       // eap, Apr 29 2002, occ 293
2578       else if (isInDS2 && findIndexPoint(DStr, Fd, 2, ipoin)) {
2579
2580       }
2581       else ipoin = ChFi3d_IndexPointInDS(Fd->VertexLastOnS2(),DStr);
2582
2583       TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(IcFil2);
2584
2585       if (!ChFi3d_Contains(Li,IcFil2,Ipoin2)) { 
2586         Interfp2 = ChFi3d_FilPointInDS(TopAbs_FORWARD,IcFil2,Ipoin2,
2587           Fi2.FirstParameter(), isVertex2);
2588         DStr.ChangeCurveInterferences(IcFil2).Append(Interfp2);
2589       }
2590       if (ipoin == Ipoin2 || !ChFi3d_Contains(Li,IcFil2,ipoin)) { 
2591         Interfp4= ChFi3d_FilPointInDS(TopAbs_REVERSED,IcFil2,ipoin,
2592           Fi2.LastParameter(), isVertex );
2593         DStr.ChangeCurveInterferences(IcFil2).Append(Interfp4);
2594       }
2595       Ipoin2 = ipoin;
2596       isVertex2 = isVertex;      
2597     }
2598
2599     ET1 = trafil1;
2600     if (j == SeqFil.Length()) {
2601       if (!isInDS2) {
2602         Icurv = CorDat->LastCurve();
2603         if(Closed && !Singulier_en_Bout && (Ipoin1!=Ipoin2)) {
2604           regcout.SetS2(Isurf,Standard_False);
2605           reglist.Append(regcout);
2606         }
2607         PCurv = CorDat->LastPCurve();
2608         ET1 = TopAbs::Compose(ET1,CorDat->LastPCurveOrientation());
2609         CorDat->LastParameters(Pardeb,Parfin);
2610         TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(Icurv);
2611         if (Li.IsEmpty()) {
2612           if(CorDat->LastPCurveOrientation()==TopAbs_REVERSED) {
2613             Interfp5=ChFi3d_FilPointInDS
2614               (TopAbs_REVERSED,Icurv,Ipoin1,Parfin, isVertex1);
2615             Interfp6=ChFi3d_FilPointInDS
2616               (TopAbs_FORWARD,Icurv,Ipoin2,Pardeb, isVertex2);
2617           }
2618           else{
2619             Interfp5=ChFi3d_FilPointInDS
2620               (TopAbs_FORWARD,Icurv,Ipoin1,Pardeb, isVertex1);
2621             Interfp6=ChFi3d_FilPointInDS
2622               (TopAbs_REVERSED,Icurv,Ipoin2,Parfin, isVertex2);
2623           }
2624           Li.Append(Interfp5);
2625           Li.Append(Interfp6);
2626         }
2627         Interfc1= ChFi3d_FilCurveInDS(Icurv,Isurf,PCurv,ET1);
2628         DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2629         if (Ipoin1 == Ipoin2) {
2630           TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2631           TCurv.ChangeCurve().Nullify();
2632           Handle(TopOpeBRepDS_Interference) bidinterf;
2633           TCurv.SetSCI( Interfc1, bidinterf);
2634           //         bidinterf = TCurv.GetSCI1(); 
2635           //      TCurv.SetSCI(bidinterf, Interfc1);        
2636         }
2637       }
2638     }
2639     else {
2640       //      Degene = (Fd->VertexLastOnS1().Point().IsEqual(
2641       //                Fd->VertexLastOnS2().Point(), 0) );
2642
2643       // eap, Apr 29 2002, occ 293 
2644       if (!isInDS2) {
2645
2646         Handle(Geom_Curve) C3d;
2647         Standard_Real tolreached;
2648         ChFi3d_ComputeArete(Fd->VertexLastOnS1(),
2649           Fd->InterferenceOnS1().PCurveOnSurf()->
2650           Value(Fd->InterferenceOnS1().LastParameter()),
2651           Fd->VertexLastOnS2(),
2652           Fd->InterferenceOnS2().PCurveOnSurf()->
2653           Value(Fd->InterferenceOnS2().LastParameter()),
2654           DStr.Surface(Fd->Surf()).Surface(),C3d,PCurv,
2655           Pardeb,Parfin,tol3d,tol2d,tolreached,0);
2656         Crv = TopOpeBRepDS_Curve(C3d,tolreached);
2657         Icurv = DStr.AddCurve(Crv);
2658         regfilfil.SetCurve(Icurv);
2659         regfilfil.SetS1(Isurf,Standard_False);
2660         Interfp5 = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv,Ipoin1,Pardeb, isVertex1);
2661         DStr.ChangeCurveInterferences(Icurv).Append(Interfp5);
2662         Interfp6= ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv,Ipoin2,Parfin, isVertex2);
2663         DStr.ChangeCurveInterferences(Icurv).Append(Interfp6);
2664         Interfc1= ChFi3d_FilCurveInDS(Icurv,Isurf,PCurv,ET1);
2665         DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);      
2666       }
2667     }
2668
2669     Degene = V3.Point().IsEqual(V4.Point(), 0);
2670
2671     // Processing of degenerated case     
2672     if (Degene) {
2673       // Queue de Billard
2674       Standard_Boolean Vertex = (V3.IsVertex()) && (V4.IsVertex());
2675       if (!Vertex) {
2676
2677       }
2678       else {
2679         // The edge of the spine starting on this vertex is removed.
2680         Standard_Boolean Trouve = Standard_False;
2681         TopoDS_Edge Arcspine;
2682         TopAbs_Orientation OVtx = TopAbs_FORWARD;
2683         BoutdeVtx = V3.Vertex();
2684
2685         while (NumEdge<= spine->NbEdges() && !Trouve) { 
2686           Arcspine = spine->Edges(NumEdge);
2687           for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); 
2688             ex.More() && (!Trouve); ex.Next()) {
2689               if(BoutdeVtx.IsSame(ex.Current())) {
2690                 OVtx = ex.Current().Orientation();
2691                 if (Closed &&  (NumEdge == 1)) 
2692                   Trouve = (spine->NbEdges() == 1);
2693                 else Trouve = Standard_True;
2694               }
2695           }
2696           if (!Trouve) NumEdge++; // Go to the next edge
2697         }
2698         Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2699         Standard_Integer IVtx;
2700         if  (j == SeqFil.Length()) {
2701           IVtx = CorDat->IndexLastPointOnS1();
2702         }
2703         else { IVtx = DStr.AddShape(BoutdeVtx); }
2704         OVtx = TopAbs::Reverse(OVtx);
2705         Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2706         Handle(TopOpeBRepDS_CurvePointInterference) 
2707           interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2708         DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2709       }
2710     } // end of degenerated case
2711     else if (!(Closed && j == SeqFil.Length())) {
2712       // Processing of interference Point / Edges
2713       if (V3.IsOnArc()) {
2714         if(!(V3.IsVertex() && Fd->IsOnCurve1())) {
2715           Iarc1 = DStr.AddShape(V3.Arc());
2716           if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1,V3.IsVertex(),Standard_True) ) {
2717             Handle(TopOpeBRepDS_CurvePointInterference) Interfpp = 
2718               ChFi3d_FilPointInDS(V3.TransitionOnArc(),
2719               Iarc1,Ipoin1,V3.ParameterOnArc(), V3.IsVertex());
2720             DStr.ChangeShapeInterferences(V3.Arc()).Append(Interfpp);
2721           }
2722         }
2723       }
2724
2725       if (V4.IsOnArc()) {
2726         if(!(V4.IsVertex() && Fd->IsOnCurve2())) {
2727           Iarc2 = DStr.AddShape(V4.Arc());
2728           if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2,V4.IsVertex(),Standard_True) ) {
2729             Handle(TopOpeBRepDS_CurvePointInterference) Intfpp=
2730               ChFi3d_FilPointInDS(V4.TransitionOnArc(),
2731               Iarc2,Ipoin2,V4.ParameterOnArc(), V4.IsVertex());
2732             DStr.ChangeShapeInterferences(V4.Arc()).Append(Intfpp);
2733           }
2734         }
2735       }
2736     }
2737   }
2738 }
2739 //=======================================================================
2740 //function : StripeEdgeInter
2741 //purpose  : This function examines two stripes for an intersection 
2742 //           between curves of interference with faces. If the intersection
2743 //           exists, it will cause bad result, so it's better to quit.
2744 //remark   : If someone somewhen computes the interference between stripes, 
2745 //           this function will become useless.
2746 //author   : akm, 06/02/02. Against bug OCC119.
2747 //=======================================================================
2748 void ChFi3d_StripeEdgeInter (const Handle(ChFiDS_Stripe)& theStripe1,
2749   const Handle(ChFiDS_Stripe)& theStripe2,
2750   TopOpeBRepDS_DataStructure&  /*DStr*/,
2751   const Standard_Real          tol2d)
2752 {
2753   // Do not check the stripeshaving common corner points
2754   for (Standard_Integer iSur1=1; iSur1<=2; iSur1++)
2755     for (Standard_Integer iSur2=1; iSur2<=2; iSur2++)
2756       if (theStripe1->IndexPoint(0,iSur1)==theStripe2->IndexPoint(0,iSur2) ||
2757         theStripe1->IndexPoint(0,iSur1)==theStripe2->IndexPoint(1,iSur2) ||
2758         theStripe1->IndexPoint(1,iSur1)==theStripe2->IndexPoint(0,iSur2) ||
2759         theStripe1->IndexPoint(1,iSur1)==theStripe2->IndexPoint(1,iSur2))
2760         return;
2761
2762   Handle(ChFiDS_HData) aSurDat1 = theStripe1->SetOfSurfData();
2763   Handle(ChFiDS_HData) aSurDat2 = theStripe2->SetOfSurfData();
2764
2765   Geom2dInt_GInter anIntersector;
2766   Standard_Integer iPart1, iPart2;
2767   Standard_Integer Ishape11, Ishape12, Ishape21, Ishape22;
2768   // Loop on parts of the first stripe
2769   for (iPart1=1; iPart1<=aSurDat1->Length(); iPart1++) 
2770   {
2771     Handle(ChFiDS_SurfData) aDat1 = aSurDat1->Value(iPart1);
2772     Ishape11 = aDat1->IndexOfS1();
2773     Ishape12 = aDat1->IndexOfS2();
2774     // Loop on parts of the second stripe
2775     for (iPart2=1; iPart2<=aSurDat2->Length(); iPart2++) 
2776     {
2777       Handle(ChFiDS_SurfData) aDat2 = aSurDat2->Value(iPart2);
2778       Ishape21 = aDat2->IndexOfS1();
2779       Ishape22 = aDat2->IndexOfS2();
2780
2781       // Find those FaceInterferences able to intersect
2782       ChFiDS_FaceInterference aFI1, aFI2;
2783       if (Ishape11 == Ishape21)
2784       {
2785         aFI1 = aDat1->InterferenceOnS1();
2786         aFI2 = aDat2->InterferenceOnS1();
2787       } 
2788       else if (Ishape11 == Ishape22)
2789       {
2790         aFI1 = aDat1->InterferenceOnS1();
2791         aFI2 = aDat2->InterferenceOnS2();
2792       } 
2793       else if (Ishape12 == Ishape21)
2794       {
2795         aFI1 = aDat1->InterferenceOnS2();
2796         aFI2 = aDat2->InterferenceOnS1();
2797       } 
2798       else if (Ishape12 == Ishape22)
2799       {
2800         aFI1 = aDat1->InterferenceOnS2();
2801         aFI2 = aDat2->InterferenceOnS2();
2802       }
2803       else
2804       {
2805         // No common faces
2806         continue;
2807       }
2808
2809       if (IsEqual (aFI1.FirstParameter(),aFI1.LastParameter()) ||
2810         IsEqual (aFI2.FirstParameter(),aFI2.LastParameter()) ||
2811         aFI1.PCurveOnFace().IsNull() ||
2812         aFI2.PCurveOnFace().IsNull())
2813         // Do not waste time on degenerates
2814         continue;
2815       // Examine for intersections
2816       Geom2dAdaptor_Curve aPCurve1 (aFI1.PCurveOnFace(),
2817         aFI1.FirstParameter(),
2818         aFI1.LastParameter());
2819       Geom2dAdaptor_Curve aPCurve2 (aFI2.PCurveOnFace(),
2820         aFI2.FirstParameter(),
2821         aFI2.LastParameter());
2822       anIntersector.Perform (aPCurve1,
2823         aPCurve2,
2824         tol2d,
2825         Precision::PConfusion());
2826       if (anIntersector.NbSegments() > 0 ||
2827         anIntersector.NbPoints() > 0)
2828         StdFail_NotDone::Raise ("StripeEdgeInter : fillets have too big radiuses");
2829     }
2830   }
2831 }
2832
2833 //=======================================================================
2834 //function : IndexOfSurfData
2835 //purpose  : 
2836 //=======================================================================
2837 Standard_Integer ChFi3d_IndexOfSurfData(const TopoDS_Vertex& V1,
2838   const Handle(ChFiDS_Stripe)& CD,
2839   Standard_Integer& sens)
2840 {
2841   Handle(ChFiDS_Spine) spine = CD->Spine();
2842   Standard_Integer Index = 0;
2843   sens = 1;
2844   TopoDS_Vertex Vref;
2845   const TopoDS_Edge& E = spine->Edges(1);
2846   if (E.Orientation() == TopAbs_REVERSED) Vref = TopExp::LastVertex(E);
2847   else Vref = TopExp::FirstVertex(E); 
2848   if (Vref.IsSame(V1)) Index =1;
2849   else {
2850     const TopoDS_Edge& E1 = spine->Edges(spine->NbEdges());
2851     if (E1.Orientation() == TopAbs_REVERSED) Vref = TopExp::FirstVertex(E1);
2852     else Vref = TopExp::LastVertex(E1); 
2853     sens = -1;
2854     if(CD->SetOfSurfData().IsNull()) return 0;
2855     else if (Vref.IsSame(V1)) Index = CD->SetOfSurfData()->Length();
2856     else Standard_ConstructionError::Raise("");
2857   }
2858   return Index; 
2859 }  
2860 //=======================================================================
2861 //function : EdgeFromV1
2862 //purpose  : 
2863 //=======================================================================
2864
2865 TopoDS_Edge ChFi3d_EdgeFromV1(const TopoDS_Vertex& V1,
2866   const Handle(ChFiDS_Stripe)& CD,
2867   Standard_Integer& sens)
2868 {
2869   Handle(ChFiDS_Spine) spine = CD->Spine();
2870   sens = 1;
2871   TopoDS_Vertex Vref;
2872   const TopoDS_Edge& E = spine->Edges(1);
2873   if (E.Orientation() == TopAbs_REVERSED) Vref = TopExp::LastVertex(E);
2874   else Vref = TopExp::FirstVertex(E); 
2875   if (Vref.IsSame(V1)) return E;
2876   else
2877   {
2878     const TopoDS_Edge& E1 = spine->Edges(spine->NbEdges());
2879     if (E1.Orientation() == TopAbs_REVERSED) Vref = TopExp::FirstVertex(E1);
2880     else Vref = TopExp::LastVertex(E1); 
2881     sens = -1;
2882     if (Vref.IsSame(V1)) return E1;
2883     else Standard_ConstructionError::Raise("");
2884   }
2885   return E;
2886 }
2887 //=======================================================================
2888 //function : ConvTol2dToTol3d
2889 //purpose  : Comme son nom l indique.
2890 //=======================================================================
2891
2892 Standard_Real ChFi3d_ConvTol2dToTol3d(const Handle(Adaptor3d_HSurface)& S,
2893   const Standard_Real             tol2d)
2894 {
2895   Standard_Real ures = S->UResolution(1.e-7);
2896   Standard_Real vres = S->VResolution(1.e-7);
2897   Standard_Real uresto3d = 1.e-7*tol2d/ures;
2898   Standard_Real vresto3d = 1.e-7*tol2d/vres;
2899   return Max(uresto3d,vresto3d);
2900 }
2901 //=======================================================================
2902 //function : EvalTolReached
2903 //purpose  : The function above is too hard because 
2904 //           parametrization of surfaces is not homogenous.
2905 //=======================================================================
2906
2907 Standard_Real ChFi3d_EvalTolReached(const Handle(Adaptor3d_HSurface)& S1,
2908   const Handle(Geom2d_Curve)&     pc1,
2909   const Handle(Adaptor3d_HSurface)& S2,
2910   const Handle(Geom2d_Curve)&     pc2,
2911   const Handle(Geom_Curve)&       C)
2912 {
2913   Standard_Real distmax = 0.;
2914
2915   Standard_Real f = C->FirstParameter();
2916   Standard_Real l = C->LastParameter();
2917   Standard_Integer nbp = 45;
2918   Standard_Real step = 1./(nbp -1);
2919   for(Standard_Integer i = 0; i < nbp; i++) {
2920     Standard_Real t,u,v;
2921     t = step * i;
2922     t = (1-t) * f + t * l;
2923     pc1->Value(t).Coord(u,v);
2924     gp_Pnt pS1 = S1->Value(u,v);
2925     pc2->Value(t).Coord(u,v);
2926     gp_Pnt pS2 = S2->Value(u,v);
2927     gp_Pnt pC = C->Value(t);
2928     Standard_Real d = pS1.SquareDistance(pC);
2929     if(d>distmax) distmax = d;
2930     d = pS2.SquareDistance(pC);
2931     if(d>distmax) distmax = d;
2932     d = pS1.SquareDistance(pS2);
2933     if(d>distmax) distmax = d;
2934   }
2935   distmax = 1.5*sqrt(distmax);
2936   distmax = Max(distmax, Precision::Confusion());
2937   return distmax;
2938 }
2939
2940 //=======================================================================
2941 //function : trsfsurf
2942 //purpose  : 
2943 //=======================================================================
2944 Handle(Geom_Surface) trsfsurf(const Handle(Adaptor3d_HSurface)& HS,
2945   Handle(Adaptor3d_TopolTool)&      /*dom*/)
2946 {
2947   //Pour l utilisation des domaines voir avec BUBUCH!!
2948   Handle(Geom_Surface) res;
2949   Handle(BRepAdaptor_HSurface) hbs = Handle(BRepAdaptor_HSurface)::DownCast(HS);
2950   Handle(GeomAdaptor_HSurface) hgs = Handle(GeomAdaptor_HSurface)::DownCast(HS);
2951   if(!hbs.IsNull()) {
2952     res = hbs->ChangeSurface().Surface().Surface();
2953     gp_Trsf trsf = hbs->ChangeSurface().Trsf();
2954     res = Handle(Geom_Surface)::DownCast(res->Transformed(trsf));
2955   }
2956   else if(!hgs.IsNull()) {
2957     res = hgs->ChangeSurface().Surface();
2958   }
2959   Handle(Geom_RectangularTrimmedSurface) 
2960     tr = Handle(Geom_RectangularTrimmedSurface)::DownCast(res);
2961   if(!tr.IsNull()) res = tr->BasisSurface();
2962
2963   Standard_Real U1 = HS->FirstUParameter(), U2 = HS->LastUParameter();
2964   Standard_Real V1 = HS->FirstVParameter(), V2 = HS->LastVParameter();
2965   if(!res.IsNull()) {
2966     // Protection against Construction Errors
2967     Standard_Real u1, u2, v1, v2;
2968     res->Bounds( u1, u2, v1, v2);
2969     if (!res->IsUPeriodic()) {
2970       if (U1 < u1) U1 = u1;
2971       if (U2 > u2) U2 = u2;
2972     }
2973     if (!res->IsVPeriodic()) {
2974       if (V1 < v1) V1 = v1;
2975       if (V2 > v2) V2 = v2;
2976     }
2977     res = new Geom_RectangularTrimmedSurface(res,U1,U2,V1,V2);
2978   }
2979   //  Handle(GeomAdaptor_HSurface) temp = new GeomAdaptor_HSurface(res,U1,U2,V1,V2);
2980   //  dom = new Adaptor3d_TopolTool(temp);
2981   return res;
2982 }
2983 //=======================================================================
2984 //function : CurveCleaner
2985 //purpose  : Makes a BSpline as much continued as possible
2986 //           at a given tolerance
2987 //=======================================================================
2988 static void CurveCleaner(Handle(Geom_BSplineCurve)& BS, 
2989   const Standard_Real Tol,
2990   const Standard_Integer MultMin)
2991
2992 {
2993   Standard_Real tol = Tol;
2994   Standard_Integer Mult, ii;
2995   const Standard_Integer NbK=BS->NbKnots();
2996
2997   for (Mult = BS->Degree(); Mult > MultMin; Mult--) {
2998     tol *= 0.5; // Progressive reduction
2999     for (ii=NbK; ii>1; ii--) {
3000       if (BS->Multiplicity(ii) == Mult)
3001         BS->RemoveKnot(ii, Mult-1, tol);
3002     }
3003   }
3004 }
3005 //=======================================================================
3006 //function : ComputeCurves
3007 //purpose  : Calculates intersection between two HSurfaces.
3008 //           It is necessary to know the extremities of intersection and  
3009 //           the surfaces should be processed at input 
3010 //           to fit as good as possible (neither too close nor too far) 
3011 //           the points of beginning and end of the intersection.
3012 //           The analytic intersections are processed separately.
3013 //           <wholeCurv> means that the resulting curve is restricted by
3014 //           boundaries of input surfaces (eap 30 May occ354)
3015 //=======================================================================
3016 Standard_Boolean ChFi3d_ComputeCurves(const Handle(Adaptor3d_HSurface)&   S1,
3017   const Handle(Adaptor3d_HSurface)&   S2,
3018   const TColStd_Array1OfReal& Pardeb,
3019   const TColStd_Array1OfReal& Parfin,
3020   Handle(Geom_Curve)&         C3d,
3021   Handle(Geom2d_Curve)&       Pc1,
3022   Handle(Geom2d_Curve)&       Pc2,
3023   const Standard_Real         tol3d,
3024   const Standard_Real         tol2d,
3025   Standard_Real&              tolreached,
3026   const Standard_Boolean      wholeCurv) 
3027 {
3028   Standard_Real Step = 0.1;
3029
3030   gp_Pnt pdeb1 = S1->Value(Pardeb(1),Pardeb(2));
3031   gp_Pnt pfin1 = S1->Value(Parfin(1),Parfin(2));
3032   gp_Pnt pdeb2 = S2->Value(Pardeb(3),Pardeb(4));
3033   gp_Pnt pfin2 = S2->Value(Parfin(3),Parfin(4));
3034
3035   Standard_Real distrefdeb = pdeb1.Distance(pdeb2);//checks the worthiness 
3036   Standard_Real distreffin = pfin1.Distance(pfin2);//of input data
3037   if(distrefdeb < tol3d) distrefdeb = tol3d;
3038   if(distreffin < tol3d) distreffin = tol3d;
3039
3040   gp_Pnt pdeb,pfin;
3041   pdeb.SetXYZ(0.5*(pdeb1.XYZ()+pdeb2.XYZ()));
3042   pfin.SetXYZ(0.5*(pfin1.XYZ()+pfin2.XYZ()));
3043
3044   Standard_Real distref = 0.005*pdeb.Distance(pfin);
3045   if(distref < distrefdeb) distref = distrefdeb;
3046   if(distref < distreffin) distref = distreffin;
3047
3048   //Some analytic cases are processed separately.
3049   //To reorientate the result of the analythic intersection,
3050   //it is stated that the beginning of the tangent should be
3051   //in the direction of the start/end line.
3052   gp_Vec Vint, Vref(pdeb,pfin);
3053   gp_Pnt Pbid;
3054   Standard_Real Udeb = 0.,Ufin = 0.;
3055   Standard_Real tolr1,tolr2;
3056   tolr1 = tolr2 = tolreached = tol3d;
3057   if((S1->GetType() == GeomAbs_Cylinder && S2->GetType() == GeomAbs_Plane)||
3058     (S1->GetType() == GeomAbs_Plane && S2->GetType() == GeomAbs_Cylinder)) { 
3059       gp_Pln pl;
3060       gp_Cylinder cyl;
3061       if(S1->GetType() == GeomAbs_Plane) {
3062         pl = S1->Plane();
3063         cyl = S2->Cylinder();
3064       }
3065       else{
3066         pl = S2->Plane();
3067         cyl = S1->Cylinder();
3068       }
3069       IntAna_QuadQuadGeo ImpKK(pl,cyl,Precision::Angular(),tol3d);
3070       Standard_Boolean isIntDone = ImpKK.IsDone();
3071
3072       if(ImpKK.TypeInter() == IntAna_Ellipse)
3073       {
3074         const gp_Elips anEl = ImpKK.Ellipse(1);
3075         const Standard_Real aMajorR = anEl.MajorRadius();
3076         const Standard_Real aMinorR = anEl.MinorRadius();
3077         isIntDone = (aMajorR < 100000.0 * aMinorR);
3078       }
3079
3080       if (isIntDone) {
3081         Standard_Boolean c1line = 0;
3082         switch  (ImpKK.TypeInter()) {
3083         case IntAna_Line:
3084           {
3085             c1line = 1;
3086             Standard_Integer nbsol = ImpKK.NbSolutions();
3087             gp_Lin C1;
3088             for(Standard_Integer ilin = 1; ilin <= nbsol; ilin++) {
3089               C1 = ImpKK.Line(ilin);
3090               Udeb = ElCLib::Parameter(C1,pdeb);
3091               gp_Pnt ptest = ElCLib::Value(Udeb,C1);
3092               if(ptest.Distance(pdeb) < tol3d) break;
3093             }
3094             Ufin = ElCLib::Parameter(C1,pfin);
3095             C3d = new Geom_Line(C1);
3096             ElCLib::D1(Udeb,C1,Pbid,Vint);
3097           }
3098           break;
3099         case IntAna_Circle:
3100           {
3101             gp_Circ C1 = ImpKK.Circle(1);
3102             C3d = new Geom_Circle(C1);
3103             Udeb = ElCLib::Parameter(C1,pdeb);
3104             Ufin = ElCLib::Parameter(C1,pfin);
3105             ElCLib::D1(Udeb,C1,Pbid,Vint);
3106           }
3107           break;
3108         case IntAna_Ellipse:
3109           {
3110             gp_Elips C1 = ImpKK.Ellipse(1);
3111             C3d = new Geom_Ellipse(C1);
3112             Udeb = ElCLib::Parameter(C1,pdeb);
3113             Ufin = ElCLib::Parameter(C1,pfin);
3114             ElCLib::D1(Udeb,C1,Pbid,Vint);
3115           }
3116           break;
3117         default:
3118           break;
3119         }
3120         if (Vint.Dot(Vref)<0) {
3121           C3d->Reverse();
3122           if(c1line) {
3123             Udeb = -Udeb;
3124             Ufin = -Ufin;
3125           }
3126           else{
3127             Udeb = 2*M_PI - Udeb;
3128             Ufin = 2*M_PI - Ufin;
3129           }
3130         }
3131         if(!c1line) ElCLib::AdjustPeriodic(0.,2*M_PI,Precision::Angular(),Udeb,Ufin);
3132         Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
3133         HC->ChangeCurve().Load(C3d,Udeb,Ufin);
3134         ChFi3d_ProjectPCurv(HC,S1,Pc1,tol3d,tolr1);
3135         if(S1->GetType() == GeomAbs_Cylinder) {
3136           Standard_Real x,y;
3137           Pc1->Value(Udeb).Coord(x,y);
3138           x = Pardeb(1) - x;
3139           y = Pardeb(2) - y;
3140           if(Abs(x) >= tol2d || Abs(y) >= tol2d) Pc1->Translate(gp_Vec2d(x,y));
3141         }
3142         ChFi3d_ProjectPCurv(HC,S2,Pc2,tol3d,tolr2);
3143         if(S2->GetType() == GeomAbs_Cylinder) {
3144           Standard_Real x,y;
3145           Pc2->Value(Udeb).Coord(x,y);
3146           x = Pardeb(3) - x;
3147           y = Pardeb(4) - y;
3148           if(Abs(x) >= tol2d || Abs(y) >= tol2d) Pc2->Translate(gp_Vec2d(x,y));
3149         }
3150         C3d = new Geom_TrimmedCurve(C3d,Udeb,Ufin);
3151         tolreached = 1.5*Max(tolr1,tolr2);
3152         tolreached = Min(tolreached,ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d));
3153         return Standard_True;
3154       }
3155   }    
3156   else if(S1->GetType() == GeomAbs_Plane && S2->GetType() == GeomAbs_Plane) { 
3157     IntAna_QuadQuadGeo LInt(S1->Plane(),S2->Plane(),Precision::Angular(),tol3d);
3158     if (LInt.IsDone()) {
3159       gp_Lin L = LInt.Line(1);
3160       C3d = new Geom_Line(L);
3161       Udeb = ElCLib::Parameter(L,pdeb);
3162       Ufin = ElCLib::Parameter(L,pfin);
3163       ElCLib::D1(Udeb,L,Pbid,Vint);
3164       if (Vint.Dot(Vref)<0) {
3165         C3d->Reverse();
3166         Udeb = - Udeb;
3167         Ufin = - Ufin;
3168       }
3169       Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
3170       HC->ChangeCurve().Load(C3d,Udeb,Ufin);
3171       ChFi3d_ProjectPCurv(HC,S1,Pc1,tol3d,tolr1);
3172       ChFi3d_ProjectPCurv(HC,S2,Pc2,tol3d,tolr2);
3173       C3d = new Geom_TrimmedCurve(C3d,Udeb,Ufin);
3174       return Standard_True;
3175     }
3176   }
3177   else {
3178     // here GeomInt is approached.
3179     Handle(Adaptor3d_TopolTool) dom1,dom2;
3180     Handle(Geom_Surface) gs1 = trsfsurf(S1,dom1);
3181     Handle(Geom_Surface) gs2 = trsfsurf(S2,dom2);
3182     Standard_Integer nbl ;
3183     if(!gs1.IsNull() && !gs2.IsNull()) {
3184       GeomInt_IntSS inter;
3185       //  Modified by skv - Fri Oct 24 14:24:47 2003 OCC4077 Begin
3186       //       Standard_Real tolap = 1.e-7;//car l approx de la wline est faite dans [0,1]
3187       // Set the lowest tolerance which is used in new boolean operations.
3188       Standard_Real tolap = 2.e-7;
3189       //  Modified by skv - Fri Oct 24 14:24:48 2003 OCC4077 End
3190       inter.Perform(gs1,gs2,tolap,1,1,1);
3191       if(inter.IsDone()) {
3192         nbl = inter.NbLines();   
3193 #if defined(IRIX) || defined(__sgi)
3194         if(nbl==0) {
3195
3196           //  solution of adjustment for SGI 
3197           //  if the intersection of gs1 with gs2 doesnot worke 
3198           //  then the intersection of gs2 with gs1 is attempted.
3199
3200           inter.Perform(gs2,gs1,tolap,1,1,1);
3201           //          inter.Perform(gs2,dom2,gs1,dom1,tolap,1,1,1);
3202           if(!inter.IsDone()) return Standard_False; 
3203           nbl = inter.NbLines(); 
3204
3205           //  if GeomInt does not make the intersection the solution of adjustment 
3206           //  is not attempted 
3207           if (nbl==0) return Standard_False;
3208         }
3209 #endif
3210         GeomAPI_ProjectPointOnCurve proj;
3211         for(Standard_Integer ilin = 1; ilin <= nbl; ilin++) {
3212           if(inter.HasLineOnS1(ilin) && inter.HasLineOnS2(ilin)) {
3213             C3d = inter.Line(ilin);
3214             Pc1 = inter.LineOnS1(ilin);
3215             Pc2 = inter.LineOnS2(ilin);
3216             gp_Pnt ptestdeb, ptestfin;
3217             Standard_Real Uf=0., Ul=0.;
3218             if (wholeCurv) {
3219               Uf = C3d->FirstParameter();
3220               Ul = C3d->LastParameter();
3221               ptestdeb = C3d->Value(Uf);
3222               ptestfin = C3d->Value(Ul);
3223             }
3224             else {
3225               // find end parameters
3226               Standard_Boolean failedF, failedL;
3227               failedF = failedL = Standard_False;
3228               proj.Init( pdeb1, C3d);
3229               if (proj.NbPoints()==0 && distrefdeb > Precision::Confusion())
3230                 proj.Perform( pdeb2 );
3231               if (proj.NbPoints()==0)
3232                 failedF = Standard_True;
3233               else
3234                 Uf = proj.LowerDistanceParameter();
3235               proj.Perform( pfin1 );
3236               if (proj.NbPoints()==0 && distreffin > Precision::Confusion())
3237                 proj.Perform( pfin2 );
3238               if (proj.NbPoints()==0) 
3239                 failedL = Standard_True;
3240               else
3241                 Ul = proj.LowerDistanceParameter();
3242
3243               if (failedF && failedL) {
3244                 Uf = C3d->FirstParameter();
3245                 Ul = C3d->LastParameter();
3246               }
3247               else if (failedF || failedL) {
3248                 // select right end parameter
3249                 Standard_Real Uok = failedF ? Ul : Uf;
3250                 Standard_Real U1 = C3d->FirstParameter(), U2 = C3d->LastParameter();
3251                 Uok = Abs(Uok-U1) > Abs(Uok-U2) ? U1 : U2;
3252                 if (failedF) Uf = Uok;
3253                 else         Ul = Uok;
3254               }
3255               else { // both projected, but where?
3256                 if (Uf == Ul) continue;
3257               }
3258               ptestdeb = C3d->Value(Uf);
3259               ptestfin = C3d->Value(Ul);
3260               if (C3d->IsPeriodic() && !(failedF && failedL)) {
3261                 // assure the same order of ends, otherwise TrimmedCurve will take
3262                 // the other part of C3d
3263                 gp_Pnt Ptmp;
3264                 gp_Vec DirOld, DirNew(ptestdeb,ptestfin);
3265                 C3d->D1(Uf, Ptmp, DirOld);
3266                 if (DirOld * DirNew < 0) {
3267                   Standard_Real Utmp = Uf; Uf = Ul; Ul = Utmp;
3268                   Ptmp = ptestdeb; ptestdeb = ptestfin; ptestfin = Ptmp;
3269                 }
3270               }
3271             }
3272             C3d = new Geom_TrimmedCurve(C3d,Uf,Ul);
3273             Pc1 = new Geom2d_TrimmedCurve(Pc1,Uf,Ul);
3274             Pc2 = new Geom2d_TrimmedCurve(Pc2,Uf,Ul);
3275             //is it necesary to invert ?
3276             Standard_Real distdeb = ptestdeb.Distance(pdeb);
3277             Standard_Real distfin = ptestfin.Distance(pfin);
3278             if(distdeb > distref || distfin > distref) {
3279               C3d->Reverse();
3280               Pc1->Reverse();
3281               Pc2->Reverse();
3282               ptestdeb = C3d->Value(C3d->FirstParameter());
3283               ptestfin = C3d->Value(C3d->LastParameter());
3284               distdeb = ptestdeb.Distance(pdeb);
3285               distfin = ptestfin.Distance(pfin);
3286             }
3287             if(distdeb < distref && distfin < distref) {
3288               Uf = C3d->FirstParameter();
3289               Ul = C3d->LastParameter();
3290               ChFi3d_ReparamPcurv(Uf,Ul,Pc1);
3291               ChFi3d_ReparamPcurv(Uf,Ul,Pc2);
3292               Standard_Real x,y;
3293               Pc1->Value(Uf).Coord(x,y);
3294               x = Pardeb(1) - x;
3295               y = Pardeb(2) - y;
3296               if(Abs(x) > tol2d || Abs(y) > tol2d) Pc1->Translate(gp_Vec2d(x,y));
3297               Pc2->Value(Uf).Coord(x,y);
3298               x = Pardeb(3) - x;
3299               y = Pardeb(4) - y;
3300               if(Abs(x) > tol2d || Abs(y) > tol2d) Pc2->Translate(gp_Vec2d(x,y));
3301               tolreached = ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d);
3302               return Standard_True;
3303             }
3304           }
3305         }
3306       }
3307     }
3308   }
3309
3310   // At this stage : 
3311   // classic intersections have failed, the path is approached in vain.
3312   //  Standard_Real Step = 0.1;
3313   for(;;) {
3314     //Attention the parameters of arrow for the path and
3315     //the tolerance for the approximation can't be taken as those of the  
3316     //Builder, so they are reestimated as much as possible.
3317     Standard_Real fleche = 1.e-3 * pdeb.Distance(pfin);
3318     Standard_Real tolap = 1.e-7;
3319     IntWalk_PWalking
3320       IntKK(S1,S2,tol3d,tol3d,fleche,Step);
3321
3322     //The extremities of the intersection (Pardeb,Parfin) are known,
3323     //one tries to find the start point at the 
3324     //middle to avoid obstacles on the path.
3325     Standard_Boolean depok = Standard_False;
3326     IntSurf_PntOn2S pintdep;
3327     TColStd_Array1OfReal depart(1,4);
3328     for(Standard_Integer ipdep = 2; ipdep <= 7 && !depok; ipdep++) {
3329       Standard_Real alpha = 0.1 * ipdep;
3330       Standard_Real unmoinsalpha = 1. - alpha;
3331       depart(1) = alpha*Pardeb(1) + unmoinsalpha*Parfin(1);
3332       depart(2) = alpha*Pardeb(2) + unmoinsalpha*Parfin(2);
3333       depart(3) = alpha*Pardeb(3) + unmoinsalpha*Parfin(3);
3334       depart(4) = alpha*Pardeb(4) + unmoinsalpha*Parfin(4);
3335       depok = IntKK.PerformFirstPoint(depart,pintdep);
3336     } 
3337     if(!depok) {
3338       return Standard_False;
3339     }
3340     pintdep.Parameters(depart(1),depart(2),depart(3),depart(4));
3341     IntKK.Perform(depart);
3342     if (!IntKK.IsDone()) return Standard_False;
3343     if (IntKK.NbPoints() <= 30) {
3344       Step *= 0.5;
3345       if (Step <= 0.0001) {
3346         return Standard_False;
3347       }
3348     }
3349     else{
3350       // At this stage there is a presentable LineOn2S, it is truncated  
3351       // between the points closest to known  extremites 
3352       // in fact there is a WLine and the approximation is launched.
3353       // Then the result is corrected to get proper start and end points.
3354       const Handle(IntSurf_LineOn2S)& L2S = IntKK.Line();
3355
3356       gp_Pnt codeb1 = S1->Value(Pardeb(1),Pardeb(2));
3357       gp_Pnt codeb2 = S2->Value(Pardeb(3),Pardeb(4));
3358       Standard_Real tol1 = Max(codeb1.Distance(codeb2),tol3d);
3359       Standard_Boolean bondeb = (tol1 == tol3d); 
3360       gp_Pnt pntd(0.5*(codeb1.Coord() + codeb2.Coord()));
3361
3362       gp_Pnt cofin1 = S1->Value(Parfin(1),Parfin(2));
3363       gp_Pnt cofin2 = S2->Value(Parfin(3),Parfin(4));
3364       Standard_Real tol2 = Max(cofin1.Distance(cofin2),tol3d);
3365       Standard_Boolean bonfin = (tol2 == tol3d); 
3366       gp_Pnt pntf(0.5*(cofin1.Coord() + cofin2.Coord()));
3367
3368       Standard_Integer nbp = L2S->NbPoints(), i;
3369       Standard_Real ddeb = Precision::Infinite(); 
3370       Standard_Real dfin = Precision::Infinite();
3371       Standard_Real dd;
3372       Standard_Integer indd = 0, indf = 0;
3373       for(i = 1; i <= nbp; i++) {
3374         dd = L2S->Value(i).Value().Distance(pntd);
3375         if(dd <= ddeb) { ddeb = dd; indd = i;}
3376         dd = L2S->Value(i).Value().Distance(pntf);
3377         if(dd < dfin) { dfin = dd; indf = i;}
3378       }
3379       if(indd > indf) {
3380         L2S->Reverse();
3381         indd = nbp - indd + 1;
3382         indf = nbp - indf + 1;
3383       }
3384       for (i = 1; i < indd; i++) { L2S->RemovePoint(1); nbp--; indf--; }
3385       for (i = indf + 1; i <= nbp; i++) { L2S->RemovePoint(indf + 1); }
3386       nbp = indf;
3387       if(nbp==1) return Standard_False;
3388       //The extremities are inserted in the line if the extremity points on it 
3389       //are too far and if pardeb and parfin are good.
3390       if(ddeb >= tol3d && bondeb) {
3391         IntSurf_PntOn2S p1 = L2S->Value(1);
3392         IntSurf_PntOn2S p2 = L2S->Value(2);
3393
3394         gp_Vec v1(pntd,p1.Value());
3395         gp_Vec v2(p1.Value(),p2.Value());
3396         gp_Vec v3(pntd,p2.Value());
3397         p1.SetValue(pntd,Pardeb(1),Pardeb(2),Pardeb(3),Pardeb(4));
3398         if(v1.Dot(v3) < 0) {
3399           if(v3.Magnitude() < 0.2*v2.Magnitude()) {
3400             L2S->RemovePoint(1);
3401             nbp--;
3402           }
3403           L2S->Value(1,p1);
3404         }
3405         else if(v1.Magnitude() > 0.2*v2.Magnitude()) {
3406           L2S->InsertBefore(1,p1);
3407           nbp++;
3408         }
3409         else{
3410           L2S->Value(1,p1);
3411         }
3412         ddeb = 0.;
3413       }
3414       if(dfin >= tol3d && bonfin) {
3415         IntSurf_PntOn2S p1 = L2S->Value(nbp);
3416         IntSurf_PntOn2S p2 = L2S->Value(nbp - 1);
3417         gp_Vec v1(pntf,p1.Value());
3418         gp_Vec v2(p1.Value(),p2.Value());
3419         gp_Vec v3(pntf,p2.Value());
3420         p1.SetValue(pntf,Parfin(1),Parfin(2),Parfin(3),Parfin(4));
3421         if(v1.Dot(v3) < 0) {
3422           if(v3.Magnitude() < 0.2*v2.Magnitude()) {
3423             L2S->RemovePoint(nbp);
3424             nbp--;
3425           }
3426           L2S->Value(nbp,p1);
3427         }
3428         else if(v1.Magnitude() > 0.2*v2.Magnitude()) {
3429           L2S->Add(p1);
3430           nbp++;
3431         }
3432         else{
3433           L2S->Value(nbp,p1);
3434         }
3435         dfin = 0.;
3436       }      
3437       //
3438       Handle(IntPatch_WLine)    WL = new IntPatch_WLine(L2S,Standard_False);
3439
3440       GeomInt_WLApprox approx;
3441       approx.SetParameters(tolap,tol2d,4,8,0,1);
3442       // manage here the approximations that are not useful on planes!
3443       approx.Perform(S1,S2,WL,
3444         Standard_True,Standard_True,Standard_True,
3445         1,nbp);
3446       if(!approx.IsDone()) return Standard_False;
3447       //      tolreached = approx.TolReached3d();
3448       //      Standard_Real tolr2d = approx.TolReached2d();
3449       //      tolreached = Max(tolreached,ChFi3d_ConvTol2dToTol3d(S1,tolr2d));
3450       //      tolreached = Max(tolreached,ChFi3d_ConvTol2dToTol3d(S2,tolr2d));
3451       const AppParCurves_MultiBSpCurve& mbs = approx.Value(1);
3452       Standard_Integer nbpol = mbs.NbPoles();
3453       TColgp_Array1OfPnt pol3d(1,nbpol);
3454       mbs.Curve(1,pol3d);
3455       TColgp_Array1OfPnt2d pol2d1(1,nbpol);
3456       mbs.Curve(2,pol2d1);
3457       TColgp_Array1OfPnt2d pol2d2(1,nbpol);
3458       mbs.Curve(3,pol2d2);
3459       // The extremities of the intersection are reset on known points.
3460       if(ddeb >= tol1) {
3461         pol3d(1) = pntd;
3462         pol2d1(1).SetCoord(Pardeb(1),Pardeb(2));
3463         pol2d2(1).SetCoord(Pardeb(3),Pardeb(4));
3464         //      tolreached = Max(tolreached,ddeb);
3465       }
3466
3467       if(dfin >= tol2) {
3468         pol3d(nbpol) = pntf;
3469         pol2d1(nbpol).SetCoord(Parfin(1),Parfin(2));
3470         pol2d2(nbpol).SetCoord(Parfin(3),Parfin(4));
3471         //      tolreached = Max(tolreached,dfin);
3472       }
3473       const TColStd_Array1OfReal& knots = mbs.Knots();
3474       const TColStd_Array1OfInteger& mults = mbs.Multiplicities();
3475       Standard_Integer deg = mbs.Degree();
3476       C3d = new Geom_BSplineCurve(pol3d,knots,mults,deg);
3477       Pc1 = new Geom2d_BSplineCurve(pol2d1,knots,mults,deg);
3478       Pc2 = new Geom2d_BSplineCurve(pol2d2,knots,mults,deg);
3479       tolreached = ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d);
3480       tolreached = Max(tolreached,ddeb);
3481       tolreached = Max(tolreached,dfin);
3482       return Standard_True;
3483     }
3484   }
3485 }
3486
3487 //=======================================================================
3488 //function : IntCS
3489 //purpose  : Fast calculation of the intersection curve surface.
3490 //
3491 //=======================================================================
3492
3493 Standard_Boolean ChFi3d_IntCS(const Handle(Adaptor3d_HSurface)& S,
3494                               const Handle(Adaptor3d_HCurve)& C,
3495                               gp_Pnt2d& p2dS,
3496                               Standard_Real& wc)
3497 {
3498   IntCurveSurface_HInter Intersection;
3499
3500   Standard_Real uf = C->FirstParameter(), ul = C->LastParameter();
3501   Standard_Real u1 = S->FirstUParameter(), u2 = S->LastUParameter();
3502   Standard_Real v1 = S->FirstVParameter(), v2 = S->LastVParameter();
3503   IntCurveSurface_IntersectionPoint pint;
3504   Intersection.Perform(C,S);
3505   Standard_Boolean keepfirst = (wc < -1.e100), keeplast = (wc > 1.e100);
3506   Standard_Real temp = 0.;
3507   if(keepfirst) temp = 1.e100;
3508   if(keeplast) temp = -1.e100;
3509   Standard_Real dist = 2.e100;
3510   if(Intersection.IsDone()) {
3511     Standard_Integer nbp = Intersection.NbPoints(),i,isol = 0;
3512     for (i = 1; i <= nbp; i++) {
3513       pint = Intersection.Point(i);
3514       Standard_Real up = pint.U();
3515       Standard_Real vp = pint.V();
3516       if(S->IsUPeriodic()) up = ChFi3d_InPeriod(up,u1,u1+S->UPeriod(),1.e-8);
3517       if(S->IsVPeriodic()) vp = ChFi3d_InPeriod(vp,v1,v1+S->VPeriod(),1.e-8);
3518       if(uf <= pint.W() && ul >= pint.W() &&
3519         u1 <= up && u2 >= up &&
3520         v1 <= vp && v2 >= vp) {
3521           if(keepfirst && pint.W() < temp) {
3522             temp = pint.W();
3523             isol = i;
3524           }
3525           else if(keeplast && pint.W() > temp) {
3526             temp = pint.W();
3527             isol = i;
3528           }
3529           else if(Abs(pint.W() - wc) < dist) {
3530             dist = Abs(pint.W() - wc);
3531             isol = i;
3532           }
3533       }
3534     }
3535     if(isol == 0) return Standard_False;
3536     pint = Intersection.Point(isol);
3537     Standard_Real up = pint.U();
3538     Standard_Real vp = pint.V();
3539     if(S->IsUPeriodic()) up = ChFi3d_InPeriod(up,u1,u1+S->UPeriod(),1.e-8);
3540     if(S->IsVPeriodic()) vp = ChFi3d_InPeriod(vp,v1,v1+S->VPeriod(),1.e-8);
3541     p2dS.SetCoord(up,vp);
3542     wc = pint.W();
3543     return Standard_True;
3544   }
3545   return Standard_False;
3546 }
3547
3548 //=======================================================================
3549 //function : ComputesIntPC
3550 //purpose  : Intersection of two PCurves of type FaceInterference
3551 //           the parameters of the pcurves at the solution point are 
3552 //           UInt1,UInt2
3553 //=======================================================================
3554
3555 void ChFi3d_ComputesIntPC (const ChFiDS_FaceInterference&      Fi1,
3556   const ChFiDS_FaceInterference&      Fi2,
3557   const Handle(GeomAdaptor_HSurface)& HS1,
3558   const Handle(GeomAdaptor_HSurface)& HS2,
3559   Standard_Real&                      UInt1, 
3560   Standard_Real&                      UInt2)
3561 {
3562   gp_Pnt bid;
3563   ChFi3d_ComputesIntPC(Fi1,Fi2,HS1,HS2,UInt1,UInt2,bid);
3564 }
3565
3566 //=======================================================================
3567 //function : ChFi3d_ComputesIntPC
3568 //purpose  : 
3569 //=======================================================================
3570 void ChFi3d_ComputesIntPC (const ChFiDS_FaceInterference&      Fi1,
3571   const ChFiDS_FaceInterference&      Fi2,
3572   const Handle(GeomAdaptor_HSurface)& HS1,
3573   const Handle(GeomAdaptor_HSurface)& HS2,
3574   Standard_Real&                      UInt1, 
3575   Standard_Real&                      UInt2,
3576   gp_Pnt&                             P)
3577 {    
3578   // Only one intersection to be carried out, however, the effort
3579   // is taken to check the extremities by an extrema c3d/c3d
3580   // created on pcurveonsurf of fillets.
3581
3582   Standard_Real x,y,distref2;
3583   Fi1.PCurveOnSurf()->Value(UInt1).Coord(x,y);
3584   gp_Pnt p3d1 = HS1->Value(x,y);
3585   Fi2.PCurveOnSurf()->Value(UInt2).Coord(x,y);
3586   gp_Pnt p3d2 = HS2->Value(x,y);
3587   distref2 = p3d1.SquareDistance(p3d2);
3588   P.SetXYZ(0.5*(p3d1.XYZ() + p3d2.XYZ()));
3589   // recalculation of the extremums
3590   Standard_Real delt1 = 
3591     Min(0.1,0.05*(Fi1.LastParameter() - Fi1.FirstParameter()));
3592   Handle(Geom2dAdaptor_HCurve) hc2d1 = 
3593     new Geom2dAdaptor_HCurve(Fi1.PCurveOnSurf(),UInt1-delt1,UInt1+delt1);
3594   Adaptor3d_CurveOnSurface cons1(hc2d1,HS1);
3595   Standard_Real delt2 = 
3596     Min(0.1,0.05*(Fi2.LastParameter() - Fi2.FirstParameter()));
3597   Handle(Geom2dAdaptor_HCurve) hc2d2 = 
3598     new Geom2dAdaptor_HCurve(Fi2.PCurveOnSurf(),UInt2-delt2,UInt2+delt2);
3599   Adaptor3d_CurveOnSurface cons2(hc2d2,HS2);
3600   Extrema_LocateExtCC ext(cons1,cons2,UInt1,UInt2);
3601   if(ext.IsDone()) {
3602     Standard_Real dist2 = ext.SquareDistance();
3603     if(dist2<distref2) {
3604       Extrema_POnCurv ponc1,ponc2;
3605       ext.Point(ponc1,ponc2);
3606       UInt1 = ponc1.Parameter();
3607       UInt2 = ponc2.Parameter();
3608       gp_Pnt Pnt1 = ponc1.Value();
3609       gp_Pnt Pnt2 = ponc2.Value();
3610       P.SetXYZ(0.5*(Pnt1.XYZ() + Pnt2.XYZ()));
3611     }
3612   }
3613
3614
3615 //=======================================================================
3616 //function : BoundSurf
3617 //purpose  : computes a GeomAdaptor_Surface from the surface of the 
3618 //           SurfData Fd1 and trims it to allow the intersection computation
3619
3620 //=======================================================================
3621 Handle(GeomAdaptor_HSurface) ChFi3d_BoundSurf(TopOpeBRepDS_DataStructure&    DStr,
3622   const Handle(ChFiDS_SurfData)& Fd1,
3623   const Standard_Integer&        IFaCo1,
3624   const Standard_Integer&        IFaArc1)
3625 {
3626   //rmq : as in fact 2 interferences of Fd1 serve only to set limits 
3627   //      indexes IFaCo1 and IFaArc1 are not useful.
3628   //      They are preserver here as an option in case it will be necessary to set 
3629   //      more restrictive limits (with intersection points as additional argument).
3630
3631   Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface();
3632   GeomAdaptor_Surface& S1 = HS1->ChangeSurface();
3633   S1.Load(DStr.Surface(Fd1->Surf()).Surface());
3634
3635   if ((IFaCo1 == 0)||(IFaArc1 == 0)) 
3636     return HS1;
3637
3638   const ChFiDS_FaceInterference& FiCo1 = Fd1->Interference(IFaCo1);
3639   const ChFiDS_FaceInterference& FiArc1 = Fd1->Interference(IFaArc1);
3640
3641   Standard_Real Du,Dv,mu,Mu,mv,Mv;
3642   gp_Pnt2d UVf1,UVf2,UVl1,UVl2;
3643
3644   UVf1 = FiCo1.PCurveOnSurf()->Value(FiCo1.FirstParameter());
3645   UVl1 = FiCo1.PCurveOnSurf()->Value(FiCo1.LastParameter());
3646   UVf2 = FiArc1.PCurveOnSurf()->Value(FiArc1.FirstParameter());
3647   UVl2 = FiArc1.PCurveOnSurf()->Value(FiArc1.LastParameter());
3648   ChFi3d_Boite(UVf1,UVf2,UVl1,UVl2,Du,Dv,mu,Mu,mv,Mv);
3649   GeomAbs_SurfaceType styp = S1.GetType();
3650   if (styp == GeomAbs_Cylinder) { 
3651     Dv = Max(0.5*Dv,4.*S1.Cylinder().Radius());
3652     Du = 0.;
3653     S1.Load(DStr.Surface(Fd1->Surf()).Surface(),
3654       mu,Mu,mv-Dv,Mv+Dv);
3655   }
3656   //In the case of a torus or cone, it is not necessary that the bounds create a surface with period more than 2PI. 
3657   else if (styp == GeomAbs_Torus ||
3658     styp == GeomAbs_Cone) {
3659       Du = Min(M_PI-0.5*Du,0.1*Du);
3660       Dv = 0.;
3661       S1.Load(DStr.Surface(Fd1->Surf()).Surface(),
3662         mu-Du,Mu+Du,mv,Mv);
3663   }
3664   else if (styp == GeomAbs_Plane) {
3665     Du = Max(0.5*Du,4.*Dv);
3666     Dv = 0.;
3667     S1.Load(DStr.Surface(Fd1->Surf()).Surface(),
3668       mu-Du,Mu+Du,mv,Mv);
3669   }
3670   return HS1;
3671 }
3672 //=======================================================================
3673 //function : SearchPivot
3674 //purpose  : 
3675 //=======================================================================
3676 Standard_Integer ChFi3d_SearchPivot(Standard_Integer* s,
3677   Standard_Real u[3][3],
3678   const Standard_Real t)
3679 {
3680   //           This function finds as pivot a cd the sections which of
3681   //           do not cross on the opposite face. 
3682   //         - probably there will be cases asymmetric to the point that
3683   //           none of tree fillets will match! To be SEEN.
3684   //         - in case when several fillets match the 
3685   //           first one taken is not inevitably the best 
3686   //           it should be refined by comparing the parameters on 
3687   //           guide lines and (/or) radiuses.
3688
3689   Standard_Boolean bondeb,bonfin;
3690   for(Standard_Integer i = 0; i <= 2; i++) {
3691     if(s[(i+1)%3] == 1) {bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] >= -t);}
3692     else {bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] <= t);}
3693     if(s[(i+2)%3] == 1) {bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] >= -t);}
3694     else {bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] <= t);}
3695     if (bondeb && bonfin) { return i; }
3696   }
3697   return -1;
3698 }
3699
3700
3701
3702 //=======================================================================
3703 //function : SearchFD
3704 //purpose  : 
3705 //=======================================================================
3706 Standard_Boolean ChFi3d_SearchFD(TopOpeBRepDS_DataStructure& DStr,
3707   const Handle(ChFiDS_Stripe)& cd1, 
3708   const Handle(ChFiDS_Stripe)& cd2,
3709   const Standard_Integer sens1,
3710   const Standard_Integer sens2,
3711   Standard_Integer& i1,
3712   Standard_Integer& i2,
3713   Standard_Real& p1,
3714   Standard_Real& p2,
3715   const Standard_Integer ind1,
3716   const Standard_Integer ind2,
3717   TopoDS_Face& face,
3718   Standard_Boolean& sameside,
3719   Standard_Integer& jf1,
3720   Standard_Integer& jf2)
3721 {
3722   Standard_Boolean found = Standard_False;
3723   Standard_Integer id1 = ind1, id2 = ind2;
3724   Standard_Integer if1 = ind1, if2 = ind2;
3725   Standard_Integer l1 = cd1->SetOfSurfData()->Length();
3726   Standard_Integer l2 = cd2->SetOfSurfData()->Length();
3727   Standard_Integer i;
3728   Standard_Boolean fini1 = Standard_False, fini2 = Standard_False;
3729   Standard_Boolean visavis,visavisok = Standard_False;
3730   TopoDS_Vertex Vtx;
3731   while( !found ) {
3732     for(i = id1; (i*sens1) <= (if1*sens1) && !found && !fini2; i = i+sens1 ) { 
3733       if(ChFi3d_IsInFront(DStr,cd1,cd2,i,if2,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)) {
3734         i1 = i;
3735         i2 = if2;
3736         found = Standard_True;
3737       }
3738       else if (visavis && !visavisok) {
3739         visavisok = Standard_True;
3740         i1 = i;
3741         i2 = if2;
3742       }
3743     }
3744     if(!fini1) {
3745       if1 = if1 + sens1;
3746       if(if1 < 1 || if1 > l1) { if1 = if1 - sens1; fini1 = Standard_True; }
3747     }
3748
3749     for(i = id2; (i*sens2) <= (if2*sens2) && !found && !fini1; i = i+sens2 ) { 
3750       if(ChFi3d_IsInFront(DStr,cd1,cd2,if1,i,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)) {
3751         i1 = if1;
3752         i2 = i;
3753         found = Standard_True;
3754       }
3755       else if (visavis && !visavisok) {
3756         visavisok = Standard_True;
3757         i1 = if1;
3758         i2 = i;
3759       }
3760     }
3761     if(!fini2) {
3762       if2 = if2 + sens2;
3763       if(if2 < 1 || if2 > l2) { if2 = if2 - sens2; fini2 = Standard_True; }
3764     }
3765     if(fini1 && fini2) break;
3766   }
3767   return found;
3768 }
3769
3770 //=======================================================================
3771 //function : Parameters
3772 //purpose  : compute the parameters <u> and <v> of the 3d point <p3d> 
3773 //           on the surface <S> if it's an analytic surface
3774 //=======================================================================
3775
3776 void ChFi3d_Parameters(const Handle(Geom_Surface)& S,
3777   const gp_Pnt& p3d,
3778   Standard_Real& u,
3779   Standard_Real& v)
3780 {
3781   GeomAdaptor_Surface gas(S);
3782   switch ( gas.GetType() ) {
3783   case GeomAbs_Plane :
3784     ElSLib::Parameters(gas.Plane(),p3d,u,v);
3785     break;
3786   case GeomAbs_Cylinder :
3787     ElSLib::Parameters(gas.Cylinder(),p3d,u,v);
3788     break;
3789   case GeomAbs_Cone :
3790     ElSLib::Parameters(gas.Cone(),p3d,u,v);
3791     break;
3792   case GeomAbs_Sphere :
3793     ElSLib::Parameters(gas.Sphere(),p3d,u,v);
3794     break;
3795   case GeomAbs_Torus :
3796     ElSLib::Parameters(gas.Torus(),p3d,u,v);
3797     break;
3798   case GeomAbs_BezierSurface :
3799   case GeomAbs_BSplineSurface :  
3800   default :
3801     {
3802       GeomAPI_ProjectPointOnSurf tool(p3d,S);
3803       if ( tool.NbPoints() != 1 )
3804         StdFail_NotDone::Raise("");
3805       else
3806         tool.Parameters(1,u,v);
3807     }
3808   }
3809 }
3810
3811 //=======================================================================
3812 //function : TrimCurve
3813 //purpose  : trims the curve <gc> between the points <FirstP> and
3814 //           <LastP>. The trimmed curve is <gtc>
3815 //=======================================================================
3816
3817 void ChFi3d_TrimCurve(const Handle(Geom_Curve)& gc,
3818   const gp_Pnt& FirstP,
3819   const gp_Pnt& LastP,
3820   Handle(Geom_TrimmedCurve)& gtc)
3821 {
3822   Standard_Real uf = 0.,ul = 0.;
3823   GeomAdaptor_Curve gac(gc);
3824   switch ( gac.GetType() ) {
3825   case GeomAbs_Line :
3826     {
3827       uf = ElCLib::Parameter(gac.Line(),FirstP);
3828       ul = ElCLib::Parameter(gac.Line(),LastP);
3829     }
3830     break;
3831   case GeomAbs_Circle :
3832     {
3833       uf = ElCLib::Parameter(gac.Circle(),FirstP);
3834       ul = ElCLib::Parameter(gac.Circle(),LastP);
3835     }
3836     break;
3837   case GeomAbs_Ellipse :
3838     {
3839       uf = ElCLib::Parameter(gac.Ellipse(),FirstP);
3840       ul = ElCLib::Parameter(gac.Ellipse(),LastP);
3841     }
3842     break;
3843   case GeomAbs_Hyperbola :
3844     {
3845       uf = ElCLib::Parameter(gac.Hyperbola(),FirstP);
3846       ul = ElCLib::Parameter(gac.Hyperbola(),LastP);
3847     }
3848     break;
3849   case GeomAbs_Parabola :
3850     {
3851       uf = ElCLib::Parameter(gac.Parabola(),FirstP);
3852       ul = ElCLib::Parameter(gac.Parabola(),LastP);
3853     }
3854     break;
3855   default :
3856     {
3857       GeomAPI_ProjectPointOnCurve tool(FirstP,gc);
3858       if ( tool.NbPoints() != 1 )
3859         StdFail_NotDone::Raise("");
3860       else
3861         uf = tool.Parameter(1);
3862       tool.Init(LastP,gc);
3863       if ( tool.NbPoints() != 1 )
3864         StdFail_NotDone::Raise("");
3865       else
3866         ul = tool.Parameter(1);
3867     }
3868   }
3869   gtc = new Geom_TrimmedCurve(gc,uf,ul);
3870 }
3871
3872
3873
3874 //=======================================================================
3875 //function : GoodExt
3876 //purpose  : 
3877 //=======================================================================
3878 static Standard_Boolean GoodExt(const Handle(Geom_Curve)& C,
3879   const gp_Vec&             V,
3880   const Standard_Real       f,
3881   const Standard_Real       l,
3882   const Standard_Real       a)
3883 {
3884   for(Standard_Integer i = 0; i < 6; i++) {
3885     gp_Pnt d0; gp_Vec d1;
3886     const Standard_Real t = i * 0.2;
3887     C->D1(((1-t)*f+t*l),d0,d1);
3888     const Standard_Real ang = d1.Angle(V);
3889     const Standard_Real angref = a*t + 0.002;
3890     if(ang > angref) return Standard_False;
3891   }
3892   return Standard_True;
3893 }
3894 //=======================================================================
3895 //function : PerformElSpine
3896 //purpose  : 
3897 //=======================================================================
3898 Standard_EXPORT 
3899   void ChFi3d_PerformElSpine(Handle(ChFiDS_HElSpine)& HES,
3900   Handle(ChFiDS_Spine)&    Spine,
3901   const GeomAbs_Shape      continuity,
3902   const Standard_Real      tol) 
3903 {
3904
3905   Standard_Boolean periodic, Bof, checkdeb, cepadur,bIsSmooth;
3906   Standard_Integer IEdge,IF,IL,nbed, iToApproxByC2;
3907   Standard_Real WF, WL, Wrefdeb, Wreffin,nwf,nwl,period,pared = 0.,tolpared;
3908   Standard_Real First, Last, epsV, urefdeb, tolrac;
3909   GeomAbs_Shape aContinuity;
3910   gp_Pnt PDeb, PFin, Bout;
3911   gp_Vec VrefDeb, VrefFin;
3912   Handle(Geom_Curve) Cv;
3913   Handle(Geom_BoundedCurve) TC;
3914   Handle(Geom_BSplineCurve) BS, BSpline;
3915   TopoDS_Edge E, Eold;
3916   TopoDS_Vertex V;
3917   //
3918   ChFiDS_ElSpine& ES = HES->ChangeCurve();
3919   WF = ES.FirstParameter();
3920   WL = ES.LastParameter();
3921   Wrefdeb = WF;
3922   Wreffin = WL;
3923   nwf = WF;
3924   nwl = WL;
3925   nbed = Spine->NbEdges();
3926   periodic = Spine->IsPeriodic();
3927   if(periodic) {
3928     period = Spine->Period();
3929     nwf = ElCLib::InPeriod(WF,-tol,period-tol);
3930     IF = Spine->Index(nwf,1);
3931     nwl = ElCLib::InPeriod(WL,tol,period+tol);
3932     IL = Spine->Index(nwl,0);
3933     if(nwl<nwf+tol) IL += nbed;
3934   }
3935   else{
3936     IF = Spine->Index(WF,1);
3937     IL = Spine->Index(WL,0);
3938     Wrefdeb = Max(Spine->FirstParameter(IF),WF);
3939     Wreffin = Min(Spine->LastParameter(IL),WL);
3940   }
3941   //
3942   Spine->D1(WF,PDeb,VrefDeb);
3943   Spine->D1(WL,PFin,VrefFin);
3944   VrefDeb.Normalize();
3945   VrefFin.Normalize();
3946   //
3947   TColgp_Array1OfPnt ExtrapPole(1, 5);
3948   TColgp_Array1OfPnt ExtraCoeffs(1, 5);
3949   TColgp_Array1OfXYZ Cont(1,5);
3950   // Attention on segmente eventuellement la premiere et la
3951   // derniere arete.
3952   // Traitment de la premiere arete
3953   cepadur = 0;
3954   E=Spine->Edges(IF);
3955   Bof=BRepLib::BuildCurve3d(E);
3956   const BRepAdaptor_Curve& edc = Spine->CurrentElementarySpine(IF);
3957   tolpared = edc.Resolution(tol);
3958   Cv = BRep_Tool::Curve(E, First, Last);
3959   //Add vertex with tangent
3960   if (ES.IsPeriodic())
3961   {
3962     Standard_Real ParForElSpine = (E.Orientation() == TopAbs_FORWARD)? First : Last;
3963     gp_Pnt PntForElSpine;
3964     gp_Vec DirForElSpine;
3965     Cv->D1(ParForElSpine, PntForElSpine, DirForElSpine);
3966     ES.AddVertexWithTangent(gp_Ax1(PntForElSpine, DirForElSpine));
3967   }
3968   /////////////////////////
3969   urefdeb = Spine->FirstParameter(IF);
3970   checkdeb = (nwf > urefdeb);
3971   if(checkdeb) {
3972     Spine->Parameter(IF,nwf,pared,0);
3973   }
3974   //
3975   if(E.Orientation() == TopAbs_REVERSED) {
3976     Standard_Real sov = First;
3977     First = Cv->ReversedParameter(Last);
3978     Last = Cv->ReversedParameter(sov);
3979     if(checkdeb) {
3980       pared = Cv->ReversedParameter(pared);
3981     }
3982     else{
3983       pared = First;
3984     }
3985     if(First < pared) {
3986       First = pared; 
3987     }
3988     if(IL == IF) {
3989       Standard_Real ureffin = Spine->LastParameter(IL);
3990       Standard_Boolean checkfin = (nwl < ureffin);
3991       if(checkfin) {
3992         Spine->Parameter(IL,nwl,pared,0);
3993         pared = Cv->ReversedParameter(pared);
3994       }
3995       else {
3996         pared = Last;
3997       }
3998       if(pared < Last) {
3999         Last = pared; 
4000       }
4001     }
4002     Cv = Cv->Reversed();
4003   }//if(E.Orientation() == TopAbs_REVERSED) 
4004   else {//#1
4005     if(!checkdeb) {
4006       pared = First;
4007     }
4008     if(First < pared) {
4009       First = pared; 
4010     }
4011     if(IL == IF) {
4012       Standard_Real ureffin = Spine->LastParameter(IL);
4013       Standard_Boolean checkfin = (nwl < ureffin);
4014       if(checkfin) {
4015         Spine->Parameter(IL,nwl,pared,0);
4016       }
4017       else {
4018         pared = Last;
4019       }
4020       if(pared < Last) {
4021         Last = pared; 
4022       }
4023     }
4024   }// else {//#1
4025   //
4026   if(Abs(Last-First) < tolpared) {
4027     cepadur = 1;
4028   }
4029   //
4030   //Petite veru pour les cas ou un KPart a bouffe l arete
4031   //sans parvenir a terminer. On tire une droite.
4032   if(cepadur) {
4033     Handle(Geom_Line) L;
4034     gp_Pnt ptemp; gp_Vec vtemp;
4035     if(WL < Spine->FirstParameter(1) + tol) {
4036       ES.LastPointAndTgt(ptemp,vtemp);
4037       gp_Dir d(vtemp);
4038       gp_Pnt olin;
4039       olin.ChangeCoord().SetLinearForm(-WL,d.XYZ(),PFin.XYZ());
4040       L = new Geom_Line(olin,d);
4041       ES.SetCurve(L);
4042     }
4043     else if(WF > Spine->LastParameter(nbed) - tol) {
4044       ES.FirstPointAndTgt(ptemp,vtemp);
4045       gp_Dir d(vtemp);
4046       gp_Pnt olin;
4047       olin.ChangeCoord().SetLinearForm(-WF,d.XYZ(),PDeb.XYZ());
4048       L = new Geom_Line(olin,d);
4049       ES.SetCurve(L);
4050     }
4051     return;// => 
4052   }
4053   //
4054   TC = new (Geom_TrimmedCurve)(Cv, First, Last);
4055   BS=GeomConvert::CurveToBSplineCurve(TC);
4056   CurveCleaner(BS, Abs(WL-WF)*1.e-4, 0);
4057   //
4058   //Smoothing of the curve
4059   iToApproxByC2=0;
4060   aContinuity=TC->Continuity();
4061   bIsSmooth=ChFi3d_IsSmooth(TC);
4062   if (aContinuity < GeomAbs_C2 && !bIsSmooth) {
4063     ++iToApproxByC2;
4064     BS = ChFi3d_ApproxByC2(TC);
4065     TC=BS;
4066   }
4067   //
4068   //  Concatenation des aretes suivantes
4069   GeomConvert_CompCurveToBSplineCurve Concat( TC, Convert_QuasiAngular );
4070   //
4071   Eold = E;
4072   for (IEdge=IF+1; IEdge<=IL; ++IEdge) {
4073     Standard_Integer iloc = IEdge;
4074     if(periodic) {
4075       iloc = (IEdge - 1)%nbed + 1;
4076     }
4077     //
4078     E = Spine->Edges(iloc);
4079     if (BRep_Tool::Degenerated(E)) {
4080       continue;
4081     }
4082     //  
4083     epsV = tol;
4084     Bof = TopExp::CommonVertex(Eold, E, V);
4085     if (Bof) {
4086       epsV = BRep_Tool::Tolerance(V);
4087     }
4088     //
4089     Bof = BRepLib::BuildCurve3d(E);
4090     if (!Bof) {
4091       Standard_ConstructionError::Raise("PerformElSpine : BuildCurve3d error");
4092     }
4093     //
4094     Cv = BRep_Tool::Curve(E, First, Last);
4095     //Add vertex with tangent
4096     Standard_Real ParForElSpine = (E.Orientation() == TopAbs_FORWARD)? First : Last;
4097     gp_Pnt PntForElSpine;
4098     gp_Vec DirForElSpine;
4099     Cv->D1(ParForElSpine, PntForElSpine, DirForElSpine);
4100     ES.AddVertexWithTangent(gp_Ax1(PntForElSpine, DirForElSpine));
4101     /////////////////////////
4102     if(IEdge == IL) {
4103       Standard_Real ureffin = Spine->LastParameter(iloc);
4104       Standard_Boolean checkfin = (nwl < ureffin);
4105       if(checkfin) {
4106         Spine->Parameter(iloc,nwl,pared,0);
4107       }
4108       else {
4109         pared = Last;
4110       }
4111       if(E.Orientation() == TopAbs_REVERSED) {
4112         Standard_Real sov = First;
4113         First = Cv->ReversedParameter(Last);
4114         Last = Cv->ReversedParameter(sov);
4115         if(checkfin) {
4116           pared = Cv->ReversedParameter(pared);
4117         }
4118         else{
4119           pared = Last;
4120         }
4121         Cv = Cv->Reversed();
4122       }
4123       if(pared < Last) {
4124         Last = pared; 
4125       }
4126     }
4127     //
4128     TC = new (Geom_TrimmedCurve)(Cv, First, Last);
4129     BS = GeomConvert::CurveToBSplineCurve(TC);
4130     CurveCleaner(BS, Abs(WL-WF)*1.e-4, 0);
4131     //
4132     //Smoothing of the curve
4133     aContinuity=TC->Continuity();
4134     bIsSmooth=ChFi3d_IsSmooth(TC);
4135     if (aContinuity < GeomAbs_C2 && !bIsSmooth) {
4136       ++iToApproxByC2;
4137       BS = ChFi3d_ApproxByC2( TC );
4138       TC = BS;
4139     }
4140     //
4141     tolrac = Min(tol, epsV);
4142     Bof = Concat.Add( TC, 2.*tolrac, Standard_True );
4143     // si l'ajout ne s'est pas bien passe on essai d'augmenter la tolerance
4144     if (!Bof) {
4145       Bof = Concat.Add( TC, 2.*epsV, Standard_True );
4146     }
4147     if (!Bof) {
4148       Bof = Concat.Add( TC, 200.*epsV, Standard_True );
4149       if (!Bof) {
4150         Standard_ConstructionError::Raise("PerformElSpine: spine merged error");
4151       }
4152     }
4153     Eold = E;
4154   }// for (IEdge=IF+1; IEdge<=IL; ++IEdge) {
4155   //
4156   // On a la portion d elspine calculee sans prolongements sur la partie 
4157   // valide des aretes du chemin.
4158   BSpline = Concat.BSplineCurve();
4159   // There is a reparametrisation to maximally connect the abscissas of edges.
4160   TColStd_Array1OfReal BSNoeuds (1, BSpline->NbKnots());
4161   BSpline->Knots(BSNoeuds);
4162   BSplCLib::Reparametrize (Wrefdeb, Wreffin, BSNoeuds);
4163   BSpline->SetKnots(BSNoeuds);
4164   //
4165   // Traitement des Extremites
4166   Standard_Integer caredeb, carefin;
4167   Standard_Real LocalWL, LocalWF, Angle;
4168   GeomAdaptor_Curve gacurve;
4169   Handle(Geom_BSplineCurve) newc;
4170   //
4171   caredeb = 0;
4172   carefin = 0;
4173   Angle = M_PI*0.75;
4174   LocalWL = WL;
4175   LocalWF = WF;
4176   if (!ES.IsPeriodic() && !PDeb.IsEqual(BSpline->Pole(1), tol) ) {
4177     // Prolongement C3 au debut
4178     // afin d'eviter des pts d'inflexions dans la partie utile de la
4179     // spine le prolongement se fait jusqu'a un point eloigne.
4180     if(BSpline->IsRational()) {
4181       caredeb = 1;
4182     }
4183     //
4184     Standard_Real rabdist = Wrefdeb - WF;
4185     Bout = PDeb.Translated(-20*rabdist * VrefDeb);
4186     Standard_Boolean goodext = 0;
4187     for(Standard_Integer icont = 3; icont>=1 && !goodext; icont--) {
4188   &