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