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