3fb0194a618aa18fb68797e98902e2c75e6b371e
[occt.git] / src / ChFi3d / ChFi3d_Builder_2.cxx
1 // Created on: 1993-12-15
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Adaptor2d_HCurve2d.hxx>
19 #include <Adaptor3d_HSurface.hxx>
20 #include <Adaptor3d_TopolTool.hxx>
21 #include <AppBlend_Approx.hxx>
22 #include <Blend_CurvPointFuncInv.hxx>
23 #include <Blend_FuncInv.hxx>
24 #include <Blend_Function.hxx>
25 #include <Blend_RstRstFunction.hxx>
26 #include <Blend_SurfCurvFuncInv.hxx>
27 #include <Blend_SurfPointFuncInv.hxx>
28 #include <Blend_SurfRstFunction.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRepAdaptor_Curve.hxx>
31 #include <BRepAdaptor_HCurve.hxx>
32 #include <BRepAdaptor_HCurve2d.hxx>
33 #include <BRepAdaptor_HSurface.hxx>
34 #include <BRepAdaptor_Surface.hxx>
35 #include <BRepBlend_Line.hxx>
36 #include <BRepLib_MakeFace.hxx>
37 #include <BRepLProp_SLProps.hxx>
38 #include <BRepTools.hxx>
39 #include <BRepTools_WireExplorer.hxx>
40 #include <BRepTopAdaptor_TopolTool.hxx>
41 #include <ChFi3d.hxx>
42 #include <ChFi3d_Builder.hxx>
43 #include <ChFi3d_Builder_0.hxx>
44 #include <ChFiDS_ChamfSpine.hxx>
45 #include <ChFiDS_CommonPoint.hxx>
46 #include <ChFiDS_ElSpine.hxx>
47 #include <ChFiDS_ErrorStatus.hxx>
48 #include <ChFiDS_FaceInterference.hxx>
49 #include <ChFiDS_FilSpine.hxx>
50 #include <ChFiDS_HData.hxx>
51 #include <ChFiDS_HElSpine.hxx>
52 #include <ChFiDS_ListIteratorOfListOfHElSpine.hxx>
53 #include <ChFiDS_ListOfHElSpine.hxx>
54 #include <ChFiDS_SequenceOfSurfData.hxx>
55 #include <ChFiDS_Spine.hxx>
56 #include <ChFiDS_State.hxx>
57 #include <ChFiDS_Stripe.hxx>
58 #include <ChFiDS_SurfData.hxx>
59 #include <ChFiKPart_ComputeData.hxx>
60 #include <ElCLib.hxx>
61 #include <Extrema_ExtPC.hxx>
62 #include <Extrema_ExtPS.hxx>
63 #include <Extrema_LocateExtPC.hxx>
64 #include <Extrema_POnCurv.hxx>
65 #include <Geom2d_Curve.hxx>
66 #include <Geom_BSplineCurve.hxx>
67 #include <Geom_BSplineSurface.hxx>
68 #include <Geom_Line.hxx>
69 #include <Geom_Plane.hxx>
70 #include <Geom_Surface.hxx>
71 #include <GeomAdaptor_HCurve.hxx>
72 #include <GeomAdaptor_HSurface.hxx>
73 #include <GeomAdaptor_Surface.hxx>
74 #include <GeomAPI_ProjectPointOnCurve.hxx>
75 #include <gp_Pln.hxx>
76 #include <gp_Pnt.hxx>
77 #include <gp_Pnt2d.hxx>
78 #include <gp_Vec.hxx>
79 #include <gp_XYZ.hxx>
80 #include <math_Vector.hxx>
81 #include <Precision.hxx>
82 #include <Standard_ConstructionError.hxx>
83 #include <Standard_NoSuchObject.hxx>
84 #include <Standard_NotImplemented.hxx>
85 #include <Standard_OutOfRange.hxx>
86 #include <TColgp_Array1OfPnt.hxx>
87 #include <TColgp_Array1OfVec.hxx>
88 #include <TColStd_Array1OfInteger.hxx>
89 #include <TColStd_Array1OfReal.hxx>
90 #include <TColStd_ListOfInteger.hxx>
91 #include <TopAbs.hxx>
92 #include <TopAbs_Orientation.hxx>
93 #include <TopAbs_ShapeEnum.hxx>
94 #include <TopExp.hxx>
95 #include <TopExp_Explorer.hxx>
96 #include <TopoDS.hxx>
97 #include <TopoDS_Edge.hxx>
98 #include <TopoDS_Face.hxx>
99 #include <TopoDS_Shape.hxx>
100 #include <TopoDS_Vertex.hxx>
101 #include <TopoDS_Wire.hxx>
102 #include <TopOpeBRepBuild_HBuilder.hxx>
103 #include <TopOpeBRepDS_HDataStructure.hxx>
104 #include <TopTools_ListIteratorOfListOfShape.hxx>
105
106 #ifdef OCCT_DEBUG
107 #ifdef DRAW
108 #include <DrawTrSurf.hxx>
109 #endif
110 #include <OSD_Chronometer.hxx>
111 extern Standard_Real  t_perfsetofkpart,t_perfsetofkgen,t_makextremities,t_performsurf,t_startsol;
112 extern Standard_Boolean ChFi3d_GettraceCHRON();
113 extern void ChFi3d_InitChron(OSD_Chronometer& ch);
114 extern void ChFi3d_ResultChron(OSD_Chronometer & ch, Standard_Real& time);
115 #endif
116
117
118 //===================================================================
119 //   Definition by a plane   
120 //
121 // It is considered that P1 and P2 are points associated to commonpoints compoint1 and
122 // compoint2, while E1 and E2 are edges containing P1 and P2.
123 // The plane containing three directions D12 T1 T2  ou  D12 represente la direction formee 
124 // par les points P1 et P2, T1 la tangente de E1 en P1 et T2 la tangente de 
125 // E2 en P2 is found (if exists). 
126 // Then fillet HConge is intersected by this plane 
127 // to find associated curve 3d C3d and the curve 2d. 
128 // 
129 //====================================================================
130 static void ChFi3d_CoupeParPlan (const ChFiDS_CommonPoint & compoint1,
131                           const ChFiDS_CommonPoint & compoint2,
132                           Handle(GeomAdaptor_HSurface)& HConge,
133                           const gp_Pnt2d & UV1,
134                           const gp_Pnt2d & UV2,
135                           const Standard_Real tol3d,
136                           const Standard_Real tol2d,
137                           Handle(Geom_Curve) &C3d,
138                           Handle(Geom2d_Curve) &pcurve,
139                           Standard_Real & tolreached,
140                           Standard_Real & Pardeb,
141                           Standard_Real & Parfin,
142                           Standard_Boolean & plane)
143 { plane=Standard_True;
144   if(compoint1.IsOnArc() && compoint2.IsOnArc() ) {
145     gp_Pnt P1,P2;
146     BRepAdaptor_Curve BCurv1(compoint1.Arc());
147     BRepAdaptor_Curve BCurv2(compoint2.Arc());
148     Standard_Real parE1,parE2;
149     parE1=compoint1.ParameterOnArc();
150     parE2=compoint2.ParameterOnArc();
151     gp_Vec t1,t2;
152     BCurv1.D1(parE1,P1,t1);
153     BCurv2.D1(parE2,P2,t2);
154     gp_Dir tgt1(t1);
155     gp_Dir tgt2(t2);
156     gp_Vec v12(P2.X()-P1.X(),P2.Y()-P1.Y(),P2.Z()-P1.Z());
157     gp_Dir d12(v12); 
158     gp_Dir nor =tgt1.Crossed(d12);
159     Handle (Geom_Plane) Plan=new Geom_Plane(P1,nor);
160     Standard_Real scal;
161     scal=Abs(nor.Dot(tgt2));
162     if (scal<0.01) {
163       Handle(GeomAdaptor_HSurface) HPlan=new GeomAdaptor_HSurface(Plan);
164       Handle(Geom2d_Curve) C2dint2;
165       TColStd_Array1OfReal Pdeb(1,4),Pfin(1,4);
166       GeomAdaptor_Surface AS(Plan);
167       Extrema_ExtPS ext(P1,AS,1.e-3,1.e-3);
168       Extrema_ExtPS ext1 (P2,AS,1.e-3,1.e-3);
169       Standard_Real u1,v1;
170       ext.Point(1).Parameter(u1,v1);
171       Pdeb(1)= UV1.X();Pdeb(2) = UV1.Y();
172       Pdeb(3)= u1;Pdeb(4) =v1;
173       ext1.Point(1).Parameter(u1,v1);
174       Pfin(1)= UV2.X();Pfin(2) = UV2.Y();
175       Pfin(3)= u1;Pfin(4) = v1;
176       if (ChFi3d_ComputeCurves(HConge,HPlan,Pdeb,Pfin,C3d,
177                              pcurve,C2dint2,tol3d,tol2d,tolreached)){
178         Pardeb=C3d->FirstParameter();
179         Parfin=C3d->LastParameter();
180       }
181       else  plane=Standard_False;
182     }
183     else plane=Standard_False;
184   }
185   else   plane=Standard_False;
186 }
187 //=======================================================================
188 //function : SortieTangente
189 //purpose  : 
190 //=======================================================================
191
192 static Standard_Boolean SortieTangente(const ChFiDS_CommonPoint& CP,
193                                        const TopoDS_Face& /*F*/,
194                                        const Handle(ChFiDS_SurfData)& /*SD*/,
195                                        const Standard_Integer /*OnS*/,
196                                        const Standard_Real TolAngular)
197 {
198   if(!CP.HasVector()) return Standard_False;
199   gp_Pnt P;
200   gp_Vec Darc, Dsurf;
201   Handle(Geom_Curve) C;
202   Standard_Real Uf, Ul;
203   C = BRep_Tool::Curve(CP.Arc(),Uf,Ul);
204   C->D1(CP.ParameterOnArc(), P, Darc);
205   Dsurf = CP.Vector();
206   return Dsurf.IsParallel(Darc, TolAngular);
207 }
208
209 //=======================================================================
210 //function : BonVoisin
211 //purpose  : 
212 //=======================================================================
213
214 static Standard_Boolean BonVoisin(const gp_Pnt& Point,
215                                   Handle(BRepAdaptor_HSurface)& HS,
216                                   TopoDS_Face& F,
217                                   Handle(GeomAdaptor_HSurface)& plane, 
218                                   const TopoDS_Edge& cured,
219                                   Standard_Real& XDep,
220                                   Standard_Real& YDep,
221                                   const ChFiDS_Map& EFMap,
222                                   const Standard_Real tolesp) 
223 {
224   Standard_Boolean bonvoisin = 1;
225   Standard_Real winter, Uf, Ul;
226   gp_Pnt papp = HS->Value(XDep, YDep);
227   Standard_Real dist = RealLast();
228   Handle(BRepAdaptor_HCurve) hc = new BRepAdaptor_HCurve();
229   Handle(Geom2d_Curve) PC;
230   Standard_Boolean found = 0;
231
232   TopExp_Explorer Ex;
233   for(Ex.Init(F,TopAbs_EDGE); Ex.More(); Ex.Next()){
234     const TopoDS_Edge& ecur = TopoDS::Edge(Ex.Current());
235     if(!ecur.IsSame(cured)){
236       hc->ChangeCurve().Initialize(ecur);
237       Standard_Real tolc = hc->ChangeCurve().Resolution(tolesp);
238       if(ChFi3d_InterPlaneEdge(plane,hc,winter,1,tolc)){
239         gp_Pnt np = hc->Value(winter);
240         Standard_Real ndist = np.SquareDistance(papp);
241         if(ndist<dist){
242           TopTools_ListIteratorOfListOfShape It;
243           TopoDS_Face ff;  
244           Standard_Boolean isclosed = BRep_Tool::IsClosed(ecur, F);
245           Standard_Boolean isreallyclosed = 
246             BRepTools::IsReallyClosed(ecur, F);
247           for(It.Initialize(EFMap(ecur));It.More();It.Next()){  
248             ff = TopoDS::Face(It.Value());
249             Standard_Boolean issame = ff.IsSame(F);
250 //  Modified by Sergey KHROMOV - Fri Dec 21 17:12:48 2001 Begin
251 //          Standard_Boolean istg = 
252 //            BRep_Tool::Continuity(ecur,ff,F) != GeomAbs_C0;
253             Standard_Boolean istg = ChFi3d_isTangentFaces(ecur,ff,F);
254 //  Modified by Sergey KHROMOV - Fri Dec 21 17:12:51 2001 End
255             if((!issame || (issame && isreallyclosed)) && istg) {
256               found = 1;
257               TopoDS_Edge newe = ecur;
258               newe.Orientation(TopAbs_FORWARD);
259               dist = ndist;
260               HS->ChangeSurface().Initialize(ff);
261               if(isclosed && !isreallyclosed){
262                 TopoDS_Face fff = ff;
263                 fff.Orientation(TopAbs_FORWARD);
264                 TopExp_Explorer Ex2;
265                 for(Ex2.Init(fff,TopAbs_EDGE); 
266                     Ex2.More(); Ex2.Next()){
267                   if(newe.IsSame(Ex2.Current())){
268                     newe = TopoDS::Edge(Ex2.Current());
269                     PC = BRep_Tool::CurveOnSurface(newe,fff,Uf,Ul);
270                     break;
271                   }
272                 }
273               }
274               else PC = BRep_Tool::CurveOnSurface(newe,ff,Uf,Ul);
275               PC->Value(winter).Coord(XDep,YDep);
276               if(issame){
277                 gp_Pnt spt; gp_Vec sdu,sdv,nors;
278                 HS->D1(XDep, YDep, spt, sdu, sdv);
279                 nors = sdu.Crossed(sdv);
280                 gp_Pnt cpt; gp_Vec cd;
281                 hc->D1(winter,cpt,cd);
282                 gp_Vec vref(Point, cpt);
283                 TopoDS_Face fff = ff;
284                 fff.Orientation(TopAbs_FORWARD);
285                 if(vref.Dot(nors.Crossed(cd)) < 0.){
286                   newe.Orientation(TopAbs_REVERSED);
287                 }
288                 PC = BRep_Tool::CurveOnSurface(newe,fff,Uf,Ul);
289                 PC->Value(winter).Coord(XDep, YDep);
290               }
291               break;
292             }
293           }
294         }
295       }
296     }
297   }
298   if(!found) bonvoisin = 0;
299   return bonvoisin;
300 }
301
302 //=======================================================================
303 //function : Projection
304 //purpose  : Projects a point on a curve
305 //=======================================================================
306
307 static Standard_Boolean Projection(Extrema_ExtPC&       PExt, 
308                                    const gp_Pnt&        P,
309                                    const Adaptor3d_Curve& C,
310                                    Standard_Real&       W,
311                                    Standard_Real        Tol)
312 {
313   Standard_Real Dist2, daux2;
314   Dist2 =  C.Value(W).SquareDistance(P);
315
316   // It is checked if it is not already a solution
317   if (Dist2 < Tol * Tol) 
318     return Standard_True;
319
320   Standard_Boolean Ok = Standard_False;
321
322   // On essai une resolution initialise
323   Extrema_LocateExtPC ext(P,C,W,Tol/10);
324   if(ext.IsDone()) {
325     daux2 = C.Value(ext.Point().Parameter()).SquareDistance(P);
326     if (daux2 <Dist2 ) {
327       W = ext.Point().Parameter();
328       Dist2 = daux2;
329       Ok = Standard_True;
330       if (Dist2 < Tol * Tol) 
331         return Standard_True;
332     }  
333   }
334   
335   // Global resolution
336   PExt.Perform(P);
337   if ( PExt.IsDone() ) {
338     for (Standard_Integer ii=1; ii<= PExt.NbExt(); ii++) {
339       if (PExt.SquareDistance(ii) < Dist2) {
340         Dist2 = PExt.SquareDistance(ii);
341         W  =  PExt.Point(ii).Parameter();
342         Ok = Standard_True;
343       }
344     }
345   }
346   return Ok;
347 }
348                                    
349 //=======================================================================
350 //function : TgtKP
351 //purpose  : 
352 //=======================================================================
353
354 static void TgtKP(const Handle(ChFiDS_SurfData)& CD,
355                   const Handle(ChFiDS_Spine)&    Spine,
356                   const Standard_Integer         iedge,
357                   const Standard_Boolean         isfirst,
358                   gp_Pnt&                        ped,
359                   gp_Vec&                        ded) 
360 {
361   Standard_Real wtg = CD->InterferenceOnS1().Parameter(isfirst);
362   const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(iedge);
363   if(Spine->Edges(iedge).Orientation() == TopAbs_FORWARD)
364     bc.D1(wtg+bc.FirstParameter(),ped,ded);
365   else{
366     bc.D1(-wtg+bc.LastParameter(),ped,ded);
367     ded.Reverse();
368   }
369   ded.Normalize();
370 }
371
372 //=======================================================================
373 //function : IsInput
374 //purpose  : Checks if a vector belongs to a Face
375 //=======================================================================
376
377 Standard_Boolean IsInput(const gp_Vec&          Vec,
378                          const TopoDS_Vertex&   Ve,
379                          const TopoDS_Face&     Fa)
380 {
381   TopExp_Explorer FaceExp(Fa, TopAbs_WIRE);
382   BRepTools_WireExplorer WireExp;
383   Standard_Integer Trouve = 0;
384   TopoDS_Wire  W;
385   TopoDS_Edge  E;
386   TopoDS_Vertex Vf, Vl;
387   gp_Vec Vec3d[2];
388   gp_Pnt Point;
389
390   // Find edges and compute 3D vectors
391   for ( ; (FaceExp.More() && (Trouve<2)); FaceExp.Next()) {
392     W = TopoDS::Wire(FaceExp.Current());
393     for (Trouve=0, WireExp.Init(W) ; 
394          WireExp.More() && (Trouve<2); WireExp.Next()) {
395       E = TopoDS::Edge(WireExp.Current());
396       TopExp::Vertices(E, Vf, Vl);
397       if (Vf.IsSame(Ve)) {
398         BRepAdaptor_Curve Cb(E);
399         Cb.D1(BRep_Tool::Parameter(Ve, E), Point, Vec3d[Trouve]);
400         Trouve++; 
401       }
402       else if (Vl.IsSame(Ve)) {
403         BRepAdaptor_Curve Cb(E);
404         Cb.D1(BRep_Tool::Parameter(Ve, E), Point, Vec3d[Trouve]);
405         Vec3d[Trouve].Reverse();
406         Trouve++; 
407       }
408     }
409   }
410   if (Trouve < 2) return Standard_False;
411   // Calculate the normal and the angles in the asssociated vector plane
412   gp_Vec Normal;
413   Normal = Vec3d[0] ^ Vec3d[1];
414   if (Normal.SquareMagnitude() < Precision::Confusion()) {//Colinear case
415     return (Vec.IsParallel(Vec3d[0],Precision::Confusion())); 
416   }
417
418   Standard_Real amin, amax;
419   amax = Vec3d[1].AngleWithRef(Vec3d[0], Normal);
420   if (amax <0) {
421     amin = amax;
422     amax = 0;  
423   }
424   else amin = 0;
425
426   // Projection of the vector
427   gp_Ax3 Axe(Point, Normal, Vec3d[0]);  
428   gp_Trsf Transf;
429   Transf.SetTransformation (Axe);
430   gp_XYZ coord = Vec.XYZ();
431   Transf.Transforms(coord);
432   coord.SetZ(0);
433   Transf.Invert();
434   Transf.Transforms(coord);
435   gp_Vec theProj(coord); 
436
437   // and finally...
438   Standard_Real Angle = theProj.AngleWithRef(Vec3d[0], Normal);
439   return ( (Angle >= amin) && (Angle<=amax));
440
441
442 //=======================================================================
443 //function : IsG1
444 //purpose  : Find a neighbor G1 by an edge
445 //=======================================================================
446
447 Standard_Boolean IsG1(const ChFiDS_Map&         TheMap,
448                       const TopoDS_Edge&        E,
449                       const TopoDS_Face&        FRef,
450                       TopoDS_Face&              FVoi) 
451 {
452   TopTools_ListIteratorOfListOfShape It;    
453   // Find a neighbor of E different from FRef (general case).
454   for(It.Initialize(TheMap(E));It.More();It.Next()) {
455     if (!TopoDS::Face(It.Value()).IsSame(FRef)) {
456       FVoi = TopoDS::Face(It.Value());
457 //  Modified by Sergey KHROMOV - Fri Dec 21 17:09:32 2001 Begin
458 //    if (BRep_Tool::Continuity(E,FRef,FVoi) != GeomAbs_C0) {
459       if (ChFi3d_isTangentFaces(E,FRef,FVoi)) {
460 //  Modified by Sergey KHROMOV - Fri Dec 21 17:09:33 2001 End
461         return Standard_True;
462       }
463     }
464   }
465   // If is was not found it is checked if E is a cutting edge,
466   // in which case FVoi = FRef is returned (less frequent case).
467   TopExp_Explorer Ex;
468   Standard_Boolean orset = Standard_False;
469   TopAbs_Orientation orient = TopAbs_FORWARD ;
470   TopoDS_Edge ed;
471   for(Ex.Init(FRef,TopAbs_EDGE); Ex.More(); Ex.Next()){
472     ed = TopoDS::Edge(Ex.Current());
473     if(ed.IsSame(E)){
474       if(!orset){ orient = ed.Orientation(); orset = Standard_True; }
475       else if(ed.Orientation() == TopAbs::Reverse(orient)){
476         FVoi = FRef;
477 //  Modified by Sergey KHROMOV - Fri Dec 21 17:15:12 2001 Begin
478 //      if (BRep_Tool::Continuity(E,FRef,FRef) >= GeomAbs_G1) {   
479         if (ChFi3d_isTangentFaces(E,FRef,FRef)) {
480 //  Modified by Sergey KHROMOV - Fri Dec 21 17:15:16 2001 End
481           return Standard_True;
482         }
483         return Standard_False;
484       }
485     }
486   }
487   return Standard_False;
488 }
489
490 //=======================================================================
491 //function : SearchFaceOnV
492 //purpose  : Finds the output face(s) of the path by a vertex
493 //           The following criteria should be followed
494 //         -1 : The face shares regular edges with FRef 
495 //              (too hard condition that should be reconsidered)
496 //         -2 : The vector starting in CommonPoint "belongs" to the face
497 //========================================================================
498 static Standard_Integer SearchFaceOnV(const ChFiDS_CommonPoint&    Pc,
499                                       const TopoDS_Face&           FRef,
500                                       const ChFiDS_Map&            VEMap,
501                                       const ChFiDS_Map&            EFMap,
502                                       TopoDS_Face&                 F1,
503                                       TopoDS_Face&                 F2)
504 {
505   // it is checked that it leaves the current face.
506   Standard_Boolean FindFace = IsInput(Pc.Vector(), Pc.Vertex(), FRef);
507   if (FindFace) {
508     FindFace = IsInput(Pc.Vector().Reversed(), Pc.Vertex(), FRef);
509   }
510   // If it does not leave, it is finished
511   if (FindFace) {
512     F1 = FRef;
513     return 1;
514   }
515   Standard_Integer Num = 0;
516   Standard_Boolean Trouve;
517   TopTools_ListIteratorOfListOfShape ItE, ItF;
518   TopoDS_Edge E;
519   TopoDS_Face FVoi;
520
521   for(ItE.Initialize(VEMap(Pc.Vertex()));
522       ItE.More() && (Num < 2); ItE.Next()) {
523     E = TopoDS::Edge(ItE.Value());
524     for(ItF.Initialize(EFMap(E)), Trouve=Standard_False;
525         ItF.More()&&(!Trouve); ItF.Next()) {
526       if (TopoDS::Face(ItF.Value()).IsSame(FRef)) {
527         Trouve = Standard_True;
528       }
529     }
530     if (Trouve) Trouve = IsG1(EFMap, E, FRef, FVoi);
531     if (Trouve) Trouve = IsInput(Pc.Vector(), Pc.Vertex(), FVoi);
532     if (Trouve) {
533       if (Num == 0) F1 = FVoi;
534       else F2 =  FVoi;
535       Num++;
536     }
537   }
538   return Num;
539 }
540
541 //=======================================================================
542 //function : ChangeTransition
543 //purpose  : Changes the transition of the second common Point, when the surface
544 //           does not cross the arc
545 //           As it is supposed that the support Faces are the same, it is enough
546 //           to examine the cas of cutting edges.
547 //========================================================================
548 static void ChangeTransition(const ChFiDS_CommonPoint&    Precedant,
549                              ChFiDS_CommonPoint&          Courant,
550                              Standard_Integer             FaceIndex,
551                              const Handle(TopOpeBRepDS_HDataStructure)& DS)
552 {
553   Standard_Boolean tochange = Standard_True;
554   Standard_Real f,l;
555   const TopoDS_Face& F = TopoDS::Face(DS->Shape(FaceIndex));
556   const TopoDS_Edge& Arc = Precedant.Arc();
557   Handle(Geom2d_Curve) PCurve1, PCurve2;
558   PCurve1 = BRep_Tool::CurveOnSurface(Arc, F, f, l);
559   TopoDS_Shape aLocalShape = Arc.Reversed();
560   PCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape), F, f, l);
561 //  PCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(Arc.Reversed()), F, f, l);
562   if (PCurve1 != PCurve2) { 
563     // This is a cutting edge, it is necessary to make a small Geometric test
564     gp_Vec tgarc;
565     gp_Pnt P;
566     BRepAdaptor_Curve AC(Arc);
567     AC.D1(Precedant.ParameterOnArc(), P, tgarc);
568     tochange = tgarc.IsParallel(Precedant.Vector(), Precision::Confusion());
569   }
570
571   if (tochange) 
572     Courant.SetArc(Precision::Confusion(), 
573                    Arc, 
574                    Precedant.ParameterOnArc(),
575                    TopAbs::Reverse(Precedant.TransitionOnArc()));
576
577 }
578
579 //=======================================================================
580 //function : CallPerformSurf
581 //purpose  : Encapsulates call to PerformSurf/SimulSurf
582 //========================================================================
583
584 void ChFi3d_Builder::
585 CallPerformSurf(Handle(ChFiDS_Stripe)&              Stripe,
586                 const Standard_Boolean              Simul,
587                 ChFiDS_SequenceOfSurfData&          SeqSD,
588                 Handle(ChFiDS_SurfData)&            SD,
589                 const Handle(ChFiDS_HElSpine)&      HGuide,
590                 const Handle(ChFiDS_Spine)&         Spine,
591                 const Handle(BRepAdaptor_HSurface)& HS1,
592                 const Handle(BRepAdaptor_HSurface)& HS3,
593                 const gp_Pnt2d&                     pp1,
594                 const gp_Pnt2d&                     pp3,
595                 const Handle(Adaptor3d_TopolTool)&          It1,
596                 const Handle(BRepAdaptor_HSurface)& HS2,
597                 const Handle(BRepAdaptor_HSurface)& HS4,
598                 const gp_Pnt2d&                     pp2,
599                 const gp_Pnt2d&                     pp4,
600                 const Handle(Adaptor3d_TopolTool)&          It2,
601                 const Standard_Real                 MaxStep,
602                 const Standard_Real                 Fleche,
603                 const Standard_Real                 /*TolGuide*/,
604                 Standard_Real&                      First,
605                 Standard_Real&                      Last,
606                 const Standard_Boolean              Inside,
607                 const Standard_Boolean              /*Appro*/,
608                 const Standard_Boolean              forward,
609                 const Standard_Boolean              RecOnS1,
610                 const Standard_Boolean              RecOnS2,
611                 math_Vector&                        Soldep,
612                 Standard_Integer&                   intf,
613                 Standard_Integer&                   intl,
614                 Handle(BRepAdaptor_HSurface)&       Surf1,
615                 Handle(BRepAdaptor_HSurface)&       Surf2) 
616 {
617 #ifdef OCCT_DEBUG
618   OSD_Chronometer ch1;
619 #endif 
620   Handle(BRepAdaptor_HSurface) HSon1, HSon2;
621   HSon1 = HS1;
622   HSon2 = HS2;
623   // Definition of the domain of path It1, It2
624   It1->Initialize((const Handle(Adaptor3d_HSurface)&)HSon1);
625   It2->Initialize((const Handle(Adaptor3d_HSurface)&)HSon2);
626
627
628   TopAbs_Orientation Or1 = HS1->ChangeSurface().Face().Orientation();
629   TopAbs_Orientation Or2 = HS2->ChangeSurface().Face().Orientation();
630   Standard_Integer Choix = 
631     ChFi3d::NextSide(Or1,Or2,
632                      Stripe->OrientationOnFace1(),
633                      Stripe->OrientationOnFace2(),
634                      Stripe->Choix());
635   Soldep(1) = pp1.X(); Soldep(2) = pp1.Y();
636   Soldep(3) = pp2.X(); Soldep(4) = pp2.Y();
637       
638   Standard_Real thef = First, thel = Last;
639   Standard_Boolean isdone;
640
641   if(Simul){
642     isdone = SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,HS2,It2,tolesp,First,Last,
643                        Inside,Inside,forward,RecOnS1,RecOnS2,Soldep,intf,intl);
644   }
645   else{
646         
647 #ifdef OCCT_DEBUG
648     ChFi3d_InitChron(ch1);//initial perform for PerformSurf
649 #endif
650         
651     isdone = PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,HS2,It2,
652                          MaxStep,Fleche,tolesp,
653                          First,Last,Inside,Inside,forward,
654                          RecOnS1,RecOnS2,Soldep,intf,intl);
655 #ifdef OCCT_DEBUG
656     ChFi3d_ResultChron(ch1,t_performsurf);// result perf for PerformSurf   
657 #endif
658   }
659
660  // Case of error
661  if (!isdone) {
662    First = thef;
663    Last = thel;
664    Standard_Boolean reprise = Standard_False;
665    if (! HS3.IsNull()) {
666      HSon1 = HS3;
667      It1->Initialize((const Handle(Adaptor3d_HSurface)&)HS3); 
668      Or1 = HS3->ChangeSurface().Face().Orientation();
669      Soldep(1) = pp3.X(); Soldep(2) = pp3.Y();
670      reprise = Standard_True;
671    }
672    else if (! HS4.IsNull()) {
673      HSon2 = HS4;
674      It2->Initialize((const Handle(Adaptor3d_HSurface)&)HS4); 
675      Or2 = HS4->ChangeSurface().Face().Orientation();
676      Soldep(3) = pp4.X(); Soldep(4) = pp4.Y();
677      reprise = Standard_True;
678    }
679
680    if (reprise) {
681      Choix = ChFi3d::NextSide(Or1,Or2,
682                               Stripe->OrientationOnFace1(),
683                               Stripe->OrientationOnFace2(),
684                               Stripe->Choix());
685      if(Simul){
686        isdone = SimulSurf(SD,HGuide,Spine,Choix,HSon1,It1,HSon2,It2,
687                           tolesp,First,Last,
688                           Inside,Inside,forward,RecOnS1,RecOnS2,
689                           Soldep,intf,intl);
690      }
691      else{
692         
693 #ifdef OCCT_DEBUG
694        ChFi3d_InitChron(ch1);//init perf for PerformSurf
695 #endif
696         
697        isdone = PerformSurf(SeqSD,HGuide,Spine,Choix,HSon1,It1,HSon2,It2,
698                             MaxStep,Fleche,tolesp,
699                             First,Last,Inside,Inside,forward,
700                             RecOnS1,RecOnS2,Soldep,intf,intl);
701 #ifdef OCCT_DEBUG
702        ChFi3d_ResultChron(ch1,t_performsurf);// result perf for PerformSurf   
703 #endif
704      }
705    }
706  }  
707   Surf1 = HSon1;
708   Surf2 = HSon2;
709 }
710
711 //=======================================================================
712 //function : StripeOrientation
713 //purpose  : Calculates the reference orientation determining the
714 //           concave face for construction of the fillet.
715 //=======================================================================
716
717 Standard_Boolean ChFi3d_Builder::StripeOrientations
718 (const Handle(ChFiDS_Spine)& Spine,
719  TopAbs_Orientation&         Or1,
720  TopAbs_Orientation&         Or2,
721  Standard_Integer&           ChoixConge) const 
722 {
723   //TopTools_ListIteratorOfListOfShape It;
724   BRepAdaptor_Surface Sb1,Sb2;
725   TopAbs_Orientation Of1,Of2;
726   TopoDS_Face ff1,ff2;
727   ChFi3d_conexfaces(Spine->Edges(1),ff1,ff2,myEFMap);
728   Of1 = ff1.Orientation();
729   ff1.Orientation(TopAbs_FORWARD);
730   Sb1.Initialize(ff1);
731   Of2 = ff2.Orientation();
732   ff2.Orientation(TopAbs_FORWARD);
733   Sb2.Initialize(ff2);
734
735   ChoixConge = ChFi3d::ConcaveSide(Sb1,Sb2,Spine->Edges(1),
736                                    Or1,Or2);
737   Or1 = TopAbs::Compose(Or1,Of1);
738   Or2 = TopAbs::Compose(Or2,Of2);
739   return Standard_True;
740 }
741
742
743 //=======================================================================
744 //function : ConexFaces
745 //purpose  : 
746 //=======================================================================
747
748 void ChFi3d_Builder::ConexFaces (const Handle(ChFiDS_Spine)&   Spine,
749                                  const Standard_Integer        IEdge,
750                                  const Standard_Integer        RC,      
751                                  Handle(BRepAdaptor_HSurface)& HS1,
752                                  Handle(BRepAdaptor_HSurface)& HS2) const
753 {
754   if(HS1.IsNull()) HS1 = new BRepAdaptor_HSurface ();
755   if(HS2.IsNull()) HS2 = new BRepAdaptor_HSurface ();
756   BRepAdaptor_Surface& Sb1 = HS1->ChangeSurface();
757   BRepAdaptor_Surface& Sb2 = HS2->ChangeSurface();
758
759   TopoDS_Face ff1,ff2;  
760   ChFi3d_conexfaces(Spine->Edges(IEdge),ff1,ff2,myEFMap);
761
762   Sb1.Initialize(ff1);
763   Sb2.Initialize(ff2);
764   
765   TopAbs_Orientation Or1,Or2;
766   Standard_Integer Choix = ChFi3d::ConcaveSide(Sb1,Sb2,Spine->Edges(IEdge),
767                                                Or1,Or2);  
768   if (RC%2 != Choix%2) {
769     Sb1.Initialize(ff2);
770     Sb2.Initialize(ff1);
771   }
772 }
773
774 //=======================================================================
775 //function : StartSol
776 //purpose  : Calculates a starting solution :
777 //           - one starts by parsing about ten points on the spine,
778 //           - in case of fail one finds the solution on neighbor faces;
779 //             section plane of edges of the adjacent face 
780 //             and identication of the face by connection to that edge.
781 //=======================================================================
782
783 void ChFi3d_Builder::StartSol(const Handle(ChFiDS_Stripe)&      Stripe,
784                               const Handle(ChFiDS_HElSpine)&    HGuide,
785                               Handle(BRepAdaptor_HSurface)&     HS1,
786                               Handle(BRepAdaptor_HSurface)&     HS2,
787                               Handle(BRepTopAdaptor_TopolTool)& I1,
788                               Handle(BRepTopAdaptor_TopolTool)& I2,
789                               gp_Pnt2d&                         P1,
790                               gp_Pnt2d&                         P2,
791                               Standard_Real&                    First) const 
792 {
793   Handle(ChFiDS_Spine)& Spine = Stripe->ChangeSpine();
794   ChFiDS_ElSpine& els = HGuide->ChangeCurve();
795   Standard_Integer nbed = Spine->NbEdges();
796   Standard_Integer nbessaimax = 3*nbed;
797   if (nbessaimax < 10) nbessaimax = 10;
798   Standard_Real unsurnbessaimax = 1./nbessaimax;
799   Standard_Real wf = 0.9981 * Spine->FirstParameter(1) +
800     0.0019 * Spine->LastParameter(1);
801   Standard_Real wl = 0.9973 * Spine->LastParameter(nbed) +
802     0.0027 * Spine->FirstParameter(nbed);
803
804   Standard_Real TolE = 1.0e-7;
805   BRepAdaptor_Surface AS;  
806
807   Standard_Integer nbessai;
808   Standard_Integer iedge = 0;
809   Standard_Integer RC = Stripe->Choix();
810   gp_Vec2d derive;
811   gp_Pnt2d P2d;
812   TopoDS_Edge cured;
813   TopoDS_Face f1,f2;
814   TopAbs_Orientation Or1,Or2;
815   Standard_Integer Choix = 0;
816   math_Vector SolDep(1,4);
817   Handle(Geom2d_Curve) PC;
818   Extrema_ExtPC PExt;
819   PExt.Initialize(els, 
820                   Spine->FirstParameter(1),
821                   Spine->LastParameter(nbed),
822                   Precision::Confusion());
823   TopAbs_State Pos1,Pos2;
824   for(nbessai = 0; nbessai <= nbessaimax; nbessai++){
825     Standard_Real t = nbessai*unsurnbessaimax;
826     Standard_Real w = wf * (1. -t) + wl * t;
827     Standard_Integer ie = Spine->Index(w);
828     if(iedge != ie){
829       iedge = ie;
830       cured = Spine->Edges(iedge);
831       TolE = BRep_Tool::Tolerance(cured);
832       ConexFaces(Spine,iedge,RC,HS1,HS2);
833       f1 = HS1->ChangeSurface().Face();
834       f2 = HS2->ChangeSurface().Face();
835       Or1 = f1.Orientation();
836       Or2 = f2.Orientation();
837       Choix = ChFi3d::NextSide(Or1,Or2,
838                                Stripe->OrientationOnFace1(),
839                                Stripe->OrientationOnFace2(),
840                                RC);
841     }
842
843     Standard_Real woned,Uf,Ul, ResU, ResV;
844     Spine->Parameter(iedge,w,woned,Standard_True);
845     cured.Orientation(TopAbs_FORWARD);
846     TopoDS_Face f1forward = f1, f2forward = f2;
847     f1forward.Orientation(TopAbs_FORWARD);
848     f2forward.Orientation(TopAbs_FORWARD);
849     PC = BRep_Tool::CurveOnSurface(cured,f1forward,Uf,Ul);
850     I1->Initialize((const Handle(Adaptor3d_HSurface)&)HS1);
851     PC->D1(woned, P1, derive);
852     // There are ponts on the border, and internal points are found
853     if (derive.Magnitude() > Precision::PConfusion()) {
854       derive.Normalized();
855       derive.Rotate(M_PI/2);
856       AS.Initialize(f1);
857       ResU = AS.UResolution(TolE);
858       ResV = AS.VResolution(TolE);
859       derive *= 2*(Abs(derive.X())*ResU + Abs(derive.Y())*ResV);
860       P2d = P1.Translated(derive);
861       if (I1->Classify(P2d, Min(ResU, ResV), 0)== TopAbs_IN) {
862         P1 = P2d;
863       }
864       else {
865          P2d = P1.Translated(-derive);
866          if (I1->Classify(P2d, Min(ResU, ResV), 0)== TopAbs_IN) {
867            P1 = P2d;
868          }
869       }
870     }
871     if(f1.IsSame(f2)) cured.Orientation(TopAbs_REVERSED);
872     PC = BRep_Tool::CurveOnSurface(cured,f2forward,Uf,Ul);
873     P2 = PC->Value(woned);
874     const Handle(Adaptor3d_HSurface)& HSon2 = HS2; // to avoid ambiguity
875     I2->Initialize(HSon2);
876
877     SolDep(1) = P1.X(); SolDep(2) = P1.Y();
878     SolDep(3) = P2.X(); SolDep(4) = P2.Y();
879     const BRepAdaptor_Curve& Ced = Spine->CurrentElementarySpine(iedge);
880     gp_Pnt pnt = Ced.Value(woned);
881   
882     if (Projection(PExt, pnt, els, w, tolesp) &&
883         PerformFirstSection(Spine,HGuide,Choix,HS1,HS2,
884                             I1,I2,w,SolDep,Pos1,Pos2)) {
885       P1.SetCoord(SolDep(1),SolDep(2));
886       P2.SetCoord(SolDep(3),SolDep(4));
887       First = w;
888       return;
889     }
890   }
891   // No solution was found for the faces adjacent to the trajectory.
892   // Now one tries the neighbor faces.
893   iedge = 0;
894   for(nbessai = 0; nbessai <= nbessaimax; nbessai++){
895     Standard_Real t = nbessai*unsurnbessaimax;
896     Standard_Real w = wf * (1. -t) + wl * t;
897     iedge = Spine->Index(w);
898     cured = Spine->Edges(iedge);
899     ConexFaces(Spine,iedge,RC,HS1,HS2);
900     f1 = HS1->ChangeSurface().Face();
901     f2 = HS2->ChangeSurface().Face();
902     Or1 = f1.Orientation();
903     Or2 = f2.Orientation();
904     Choix = ChFi3d::NextSide(Or1,Or2,
905                              Stripe->OrientationOnFace1(),
906                              Stripe->OrientationOnFace2(),
907                              RC);
908     Standard_Real woned,Uf,Ul;
909     Spine->Parameter(iedge,w,woned,Standard_True);
910     TopoDS_Face f1forward = f1, f2forward = f2;
911     f1forward.Orientation(TopAbs_FORWARD);
912     f2forward.Orientation(TopAbs_FORWARD);
913     PC = BRep_Tool::CurveOnSurface(cured,f1forward,Uf,Ul);
914     P1 = PC->Value(woned);
915     PC = BRep_Tool::CurveOnSurface(cured,f2forward,Uf,Ul);
916     P2 = PC->Value(woned);
917     const Handle(Adaptor3d_HSurface)& HSon1 = HS1; // to avoid ambiguity
918     const Handle(Adaptor3d_HSurface)& HSon2 = HS2; // to avoid ambiguity
919     I1->Initialize(HSon1);
920     I2->Initialize(HSon2);
921     SolDep(1) = P1.X(); SolDep(2) = P1.Y();
922     SolDep(3) = P2.X(); SolDep(4) = P2.Y();
923     const BRepAdaptor_Curve& Ced = Spine->CurrentElementarySpine(iedge);
924     gp_Pnt pnt = Ced.Value(woned);
925 //    Extrema_LocateExtPC ext(pnt,els,w,1.e-8);
926 //    if(ext.IsDone()){
927 //      w = ext.Point().Parameter(); 
928     if (Projection(PExt, pnt, els, w, tolesp)) {
929       PerformFirstSection(Spine,HGuide,Choix,HS1,HS2,
930                           I1,I2,w,SolDep,Pos1,Pos2);
931       gp_Pnt P;
932       gp_Vec V;
933       HGuide->D1(w,P,V);
934       Handle(Geom_Plane) pl = new Geom_Plane(P,V);
935       Handle(GeomAdaptor_HSurface) plane = new GeomAdaptor_HSurface(pl);
936
937       Standard_Boolean bonvoisin = 1, found = 0;
938       Standard_Integer NbChangement;
939       for (NbChangement = 1; bonvoisin && (!found) && (NbChangement < 5);
940            NbChangement++) {
941         if(Pos1 != TopAbs_IN){
942           bonvoisin = BonVoisin(P, HS1, f1, plane, cured, 
943                                 SolDep(1),SolDep(2), myEFMap, tolesp); 
944         }
945         if(Pos2 != TopAbs_IN && bonvoisin){
946           bonvoisin = BonVoisin(P, HS2, f2, plane, cured, 
947                                 SolDep(3),SolDep(4), myEFMap, tolesp);
948         } 
949         if(bonvoisin){
950           f1 = HS1->ChangeSurface().Face();
951           f2 = HS2->ChangeSurface().Face();
952           Or1 = f1.Orientation();
953           Or2 = f2.Orientation();
954           Choix = ChFi3d::NextSide(Or1,Or2,
955                                    Stripe->OrientationOnFace1(),
956                                    Stripe->OrientationOnFace2(),
957                                    RC);
958           const Handle(Adaptor3d_HSurface)& HSon1new = HS1; // to avoid ambiguity
959           const Handle(Adaptor3d_HSurface)& HSon2new = HS2; // to avoid ambiguity
960           I1->Initialize(HSon1new);
961           I2->Initialize(HSon2new);
962           if(PerformFirstSection(Spine,HGuide,Choix,HS1,HS2,
963                                  I1,I2,w,SolDep,Pos1,Pos2)){
964             P1.SetCoord(SolDep(1),SolDep(2));
965             P2.SetCoord(SolDep(3),SolDep(4));
966             First = w;
967             found = Standard_True;
968           }
969         }
970       }
971       if (found) return;
972     }
973   }
974   Spine->SetErrorStatus(ChFiDS_StartsolFailure);
975   Standard_Failure::Raise("StartSol echec");
976 }
977
978 //=======================================================================
979 //function : ChFi3d_BuildPlane
980 //purpose  : 
981 //=======================================================================
982
983 static void  ChFi3d_BuildPlane (TopOpeBRepDS_DataStructure&    DStr,
984                                 Handle(BRepAdaptor_HSurface)&  HS,
985                                 gp_Pnt2d&                      pons,
986                                 const Handle(ChFiDS_SurfData)& SD,
987                                 const Standard_Boolean         isfirst,
988                                 const Standard_Integer         ons)
989 {
990   Handle(Geom2d_Curve) Hc;      
991   TopoDS_Face F = TopoDS::Face(DStr.Shape(SD->Index(ons)));
992   Standard_Real u,v;
993   gp_Pnt P;
994   //gp_Vec V1,V2;
995   
996   if (SD->Vertex(isfirst,ons).IsOnArc()){
997     Hc = BRep_Tool::CurveOnSurface
998       (SD->Vertex(isfirst,ons).Arc(),F,u,v);
999     Hc->Value(SD->Vertex(isfirst,ons).ParameterOnArc()).Coord(u,v);
1000     BRepLProp_SLProps theProp(HS->ChangeSurface(), u, v, 1, 1.e-12);
1001     if  (theProp.IsNormalDefined()) {
1002       P =  theProp.Value();
1003       Handle(Geom_Plane) Pln  = new Geom_Plane(P, theProp.Normal());
1004       TopoDS_Face        NewF = BRepLib_MakeFace(Pln, Precision::Confusion());
1005       NewF.Orientation(F.Orientation());
1006       pons.SetCoord(0.,0.);
1007       HS->ChangeSurface().Initialize(NewF);
1008       return; // everything is good !
1009     }
1010   }
1011   Standard_Failure::Raise("ChFi3d_BuildPlane : echec .");
1012 }
1013
1014 //=======================================================================
1015 //function : StartSol
1016 //purpose  : If the commonpoint is not OnArc the input face
1017 //           is returned and 2D point is updated,
1018 //           if it is OnArc
1019 //              if it is detached  the input face
1020 //              is returned and 2D point is updated,
1021 //              otherwise
1022 //                 either there is a neighbor tangent face and it is returned
1023 //                         with recalculated 2D point
1024 //                 or if there is no face 
1025 //                         if the reference arc is Vref (extremity of the spine)
1026 //                            this is the end and the input face is returned 
1027 //                         otherwise this is an obstacle and HC is updated.
1028 //=======================================================================
1029
1030 Standard_Boolean  
1031 ChFi3d_Builder::StartSol(const Handle(ChFiDS_Spine)&    Spine,
1032                          Handle(BRepAdaptor_HSurface)&  HS, // New face
1033                          gp_Pnt2d&                      pons,// " Localization
1034                          Handle(BRepAdaptor_HCurve2d)&  HC, // Representation of the obstacle
1035                          Standard_Real&                 W,
1036                          const Handle(ChFiDS_SurfData)& SD,
1037                          const Standard_Boolean         isfirst,
1038                          const Standard_Integer         ons,
1039                          Handle(BRepAdaptor_HSurface)&  HSref, // The other representation
1040                          Handle(BRepAdaptor_HCurve2d)&  HCref, // of the obstacle          
1041                          Standard_Boolean&              RecP,
1042                          Standard_Boolean&              RecS,
1043                          Standard_Boolean&              RecRst,
1044                          Standard_Boolean&              c1obstacle,
1045                          Handle(BRepAdaptor_HSurface)&  HSBis, // Face of support       
1046                          gp_Pnt2d&                      PBis,  // and its point
1047                          const Standard_Boolean         decroch,
1048                          const TopoDS_Vertex&           Vref) const 
1049 {
1050   RecRst = RecS = RecP = c1obstacle = 0;
1051   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
1052   TopoDS_Face Fv,Fref;
1053   //gp_Pnt2d  pp1,pp2;
1054   Handle(Geom2d_Curve) pc;      
1055   Standard_Real Uf,Ul;
1056   
1057   TopoDS_Face F = TopoDS::Face(DStr.Shape(SD->Index(ons)));
1058   if(!HSref.IsNull()) Fref = HSref->ChangeSurface().Face();
1059   const ChFiDS_CommonPoint& CP = SD->Vertex(isfirst,ons);
1060   HSBis.Nullify();
1061
1062   if (CP.IsOnArc()) {
1063     Standard_Integer notons;
1064     if (ons == 1)  notons = 2;
1065     else           notons = 1;
1066     const ChFiDS_CommonPoint& CPbis = SD->Vertex(isfirst,notons);
1067     if (CPbis.IsOnArc()) { // It is checked if it is not the extension zone 
1068                   // In case CP is not at the end of surfdata and it is not necesary to take it into account
1069                   // except for separate cases (ie pointus) ...
1070       //ts and tns were earlier CP.Parameter() and CPbis.Parameter, but sometimes they had no values.
1071       Standard_Real ts=SD->Interference(ons).Parameter(isfirst), tns=SD->Interference(notons).Parameter(isfirst);
1072       Standard_Boolean isExtend;
1073       // Arbitrary test (to precise)
1074       if (isfirst) isExtend = (ts-tns > 100*tolesp); 
1075       else         isExtend = (tns-ts > 100*tolesp);
1076       if (isExtend && !CP.Point().IsEqual(CPbis.Point(), 0) ) {
1077         //  the state is preserved and False is returned (extension by the expected plane).
1078         HS->ChangeSurface().Initialize(F);
1079         pc = SD->Interference(ons).PCurveOnFace();
1080         // The 2nd point is given by its trace on the support surface
1081         RecS = Standard_False;
1082         pons = pc->Value(tns);
1083         return Standard_False;
1084       }
1085     }
1086   }  
1087   
1088   if (CP.IsVertex() && !HC.IsNull() && !decroch){
1089     //The edge is changed, the parameter is updated and
1090     //eventually the support face and(or) the reference face.
1091     TopoDS_Vertex VCP = CP.Vertex();
1092     TopoDS_Edge EHC = HC->ChangeCurve2d().Edge();
1093     //One starts by searching in Fref another edge referencing VCP.
1094     TopExp_Explorer ex1,ex2;
1095     TopoDS_Edge newedge, edgereg;
1096     TopoDS_Face bidface = Fref, facereg;
1097     bidface.Orientation(TopAbs_FORWARD);
1098     for(ex1.Init(bidface,TopAbs_EDGE); ex1.More(); ex1.Next()){
1099       const TopoDS_Edge& cured = TopoDS::Edge(ex1.Current());
1100       Standard_Boolean found = 0;
1101       if(!cured.IsSame(EHC)){
1102         for(ex2.Init(cured,TopAbs_VERTEX); ex2.More() && !found; ex2.Next()){
1103           if(ex2.Current().IsSame(VCP)){
1104             if(IsG1(myEFMap,cured,Fref,Fv)){
1105               edgereg = cured;
1106               facereg = Fv;
1107             }
1108             else found = 1;
1109           }
1110         }
1111       }
1112       if(found) {
1113         newedge = cured;
1114         break;
1115       }
1116     }
1117     if(newedge.IsNull()){
1118       //It is checked if EHC is not a closed edge.
1119       TopoDS_Vertex V1,V2;
1120       TopExp::Vertices(EHC,V1,V2);
1121       if(V1.IsSame(V2)){
1122         newedge = EHC;
1123         Standard_Real w1 = BRep_Tool::Parameter(V1,EHC);
1124         Standard_Real w2 = BRep_Tool::Parameter(V2,EHC);
1125         const ChFiDS_FaceInterference& fi = SD->Interference(ons);
1126         const Handle(Geom2d_Curve)& pcf = fi.PCurveOnFace();
1127         Standard_Real ww = fi.Parameter(isfirst);
1128         
1129         gp_Pnt2d pww;
1130         if(!pcf.IsNull()) pww = pcf->Value(ww);
1131         else pww = SD->Get2dPoints(isfirst,ons);
1132         gp_Pnt2d p1 = HC->Value(w1);
1133         gp_Pnt2d p2 = HC->Value(w2);
1134         
1135         if(p1.Distance(pww) >  p2.Distance(pww)){
1136           W = w1;
1137           pons = p1;
1138         }
1139         else {
1140           W = w2;
1141           pons = p2;
1142         }
1143         RecP = c1obstacle = 1;
1144         return 1;
1145       }
1146       else if(!edgereg.IsNull()){
1147         // the reference edge and face are changed.
1148         Fref = facereg;
1149         HSref->ChangeSurface().Initialize(Fref);
1150         for(ex1.Init(facereg,TopAbs_EDGE); ex1.More() && newedge.IsNull(); ex1.Next()){
1151           const TopoDS_Edge& cured = TopoDS::Edge(ex1.Current());
1152           if(!cured.IsSame(edgereg)){
1153             for(ex2.Init(cured,TopAbs_VERTEX); ex2.More(); ex2.Next()){
1154               if(ex2.Current().IsSame(VCP)){
1155                 if(!IsG1(myEFMap,cured,Fref,Fv)){
1156                   newedge = cured;
1157                 }
1158               }
1159             }
1160           }
1161         }
1162       }
1163     }
1164     // it is necessary to find the new support face of the fillet : 
1165     // connected to FRef along the newedge.
1166     if(newedge.IsNull()) {
1167       Standard_Failure::Raise
1168         ("StartSol : chain is not possible, new obstacle not found");
1169     }
1170     if(IsG1(myEFMap,newedge,Fref,Fv)){
1171       Standard_Failure::Raise
1172         ("StartSol : chain is not possible, config non processed");
1173     }
1174     else if(Fv.IsNull()){
1175       Standard_Failure::Raise
1176         ("StartSol : chain is not possible, new obstacle not found");
1177     }
1178     else{
1179       HS->ChangeSurface().Initialize(Fv);
1180       W = BRep_Tool::Parameter(VCP,newedge);
1181       HCref->ChangeCurve2d().Initialize(newedge,Fref);
1182       TopoDS_Face newface = Fv;
1183       newface.Orientation(TopAbs_FORWARD);
1184       TopExp_Explorer ex;
1185       for(ex.Init(newface,TopAbs_EDGE); ex.More(); ex.Next()){
1186         if(ex.Current().IsSame(newedge)){
1187           newedge = TopoDS::Edge(ex.Current());
1188           break;
1189         }
1190       }
1191       HC->ChangeCurve2d().Initialize(newedge,Fv);
1192       pons = HC->Value(W);
1193     }
1194     RecP = c1obstacle = 1;
1195     return 1;
1196   } // End of Case Vertex && Obstacle 
1197
1198   else if (CP.IsOnArc() && !HC.IsNull() && !decroch){
1199     //Nothing is changed, the parameter is only updated.
1200     W = CP.ParameterOnArc();
1201     c1obstacle = 1;
1202     return 1;
1203   }
1204   
1205   HC.Nullify();
1206   
1207   if (CP.IsOnArc()){
1208     const TopoDS_Edge& E = CP.Arc();
1209     if(decroch){
1210       HS->ChangeSurface().Initialize(Fref);
1211       W = CP.ParameterOnArc();
1212       pc = BRep_Tool::CurveOnSurface(E,Fref,Uf,Ul);
1213       pons = pc->Value(W);
1214       RecS = 1;
1215       return 1;
1216     }
1217     if (SearchFace(Spine,CP,F,Fv)){
1218       HS->ChangeSurface().Initialize(Fv);
1219       RecS = 1;
1220       if (CP.IsVertex()) { 
1221         // One goes directly by the Vertex
1222         Standard_Integer Nb;
1223         TopoDS_Face aux;
1224         // And it is checked that there are no other candidates
1225         Nb = SearchFaceOnV(CP, F, myVEMap, myEFMap, Fv, aux);
1226
1227         pons = BRep_Tool::Parameters(CP.Vertex(), Fv);
1228         HS->ChangeSurface().Initialize(Fv);
1229         if (Nb >=2) {
1230           HSBis = new (BRepAdaptor_HSurface)(aux);
1231           PBis = BRep_Tool::Parameters(CP.Vertex(), aux);
1232         }
1233         return 1;
1234       }
1235       // otherwise one passes by the arc...
1236       if(!Fv.IsSame(F)){
1237         Fv.Orientation(TopAbs_FORWARD);
1238         TopoDS_Edge newedge;
1239         TopExp_Explorer ex;
1240         for(ex.Init(Fv,TopAbs_EDGE); ex.More(); ex.Next()){
1241           if(ex.Current().IsSame(E)){
1242             newedge = TopoDS::Edge(ex.Current());
1243             break;
1244           }
1245         }
1246         //gp_Vec Varc, VSurf;
1247         // In cas of Tangent output, the current face becomes the support face
1248         if (SortieTangente(CP, F, SD, ons, 0.1)) { 
1249           pc = BRep_Tool::CurveOnSurface(CP.Arc(),F,Uf,Ul);
1250           HSBis = new (BRepAdaptor_HSurface)(F);
1251           PBis = pc->Value(CP.ParameterOnArc());
1252         }
1253         
1254
1255         pc = BRep_Tool::CurveOnSurface(newedge,Fv,Uf,Ul);
1256       }
1257       else{
1258         TopoDS_Edge newedge = E;
1259         newedge.Reverse();
1260         Fv.Orientation(TopAbs_FORWARD);
1261         pc = BRep_Tool::CurveOnSurface(newedge,Fv,Uf,Ul);
1262       }
1263       pons = pc->Value(CP.ParameterOnArc());
1264       return 1;
1265     }
1266     else if(!Fv.IsNull()){    
1267       c1obstacle = 1;
1268       if(!Vref.IsNull()){
1269         TopExp_Explorer ex;
1270         for(ex.Init(E,TopAbs_VERTEX); ex.More(); ex.Next()){
1271           if(ex.Current().IsSame(Vref)){
1272             c1obstacle = 0;
1273             break;
1274           }
1275         }
1276       }
1277       if(c1obstacle){
1278         HS->ChangeSurface().Initialize(Fv);
1279         HSref->ChangeSurface().Initialize(F);
1280         W = CP.ParameterOnArc();
1281         HC = new BRepAdaptor_HCurve2d();
1282         TopoDS_Edge newedge;
1283         TopoDS_Face newface = Fv;
1284         newface.Orientation(TopAbs_FORWARD);
1285         TopExp_Explorer ex;
1286         for(ex.Init(newface,TopAbs_EDGE); ex.More(); ex.Next()){
1287           if(ex.Current().IsSame(E)){
1288             newedge = TopoDS::Edge(ex.Current());
1289             break;
1290           }
1291         }
1292         HC->ChangeCurve2d().Initialize(newedge,Fv);
1293         pons = HC->Value(W);
1294         HCref->ChangeCurve2d().Initialize(E,F);
1295         if(CP.IsVertex()) RecP = 1;
1296         else RecRst = 1;
1297         return 1;
1298       }
1299       else{
1300         HS->ChangeSurface().Initialize(F);
1301         W = CP.ParameterOnArc();
1302         pc = BRep_Tool::CurveOnSurface(E,F,Uf,Ul);
1303         pons = pc->Value(W);
1304         return Standard_False;
1305       }
1306     }
1307     else{ // there is no neighbor face, the state is preserved and False is returned.
1308       HS->ChangeSurface().Initialize(F);
1309       W = CP.ParameterOnArc();
1310       pc = BRep_Tool::CurveOnSurface(E,F,Uf,Ul);
1311       pons = pc->Value(W);
1312       return Standard_False;
1313     }
1314   }
1315   else{
1316     HS->ChangeSurface().Initialize(F);
1317     const ChFiDS_FaceInterference& FI = SD->Interference(ons);
1318     if(FI.PCurveOnFace().IsNull()) pons = SD->Get2dPoints(isfirst,ons);
1319     else pons = FI.PCurveOnFace()->Value(FI.Parameter(isfirst));
1320   }
1321   return Standard_True;
1322 }
1323
1324 //=======================================================================
1325 //function : SearchFace
1326 //purpose  : 
1327 //=======================================================================
1328
1329 Standard_Boolean  ChFi3d_Builder::SearchFace
1330                  (const Handle(ChFiDS_Spine)&  Spine,
1331                   const ChFiDS_CommonPoint&    Pc,
1332                   const TopoDS_Face&           FRef,
1333                   TopoDS_Face&                 FVoi) const
1334 {
1335   Standard_Boolean Trouve = Standard_False;
1336   if (! Pc.IsOnArc()) return Standard_False;
1337   FVoi.Nullify();
1338   TopoDS_Edge E;
1339   if (Pc.IsVertex()){
1340     // attention it is necessary to analyze all faces that turn around of the vertex
1341 #ifdef OCCT_DEBUG
1342     cout<<"Commonpoint on vertex, the process hangs up"<<endl;
1343 #endif
1344     if (Pc.HasVector()) { //General processing
1345       TopoDS_Face Fbis;
1346       Standard_Integer nb_faces;
1347       nb_faces = SearchFaceOnV(Pc,  FRef, myVEMap, myEFMap, FVoi, Fbis);
1348       return ( nb_faces > 0);
1349     }
1350     else { // Processing using the spine
1351       Standard_Boolean  FindFace=Standard_False;
1352       gp_Pnt Point;
1353       gp_Vec VecSpine;
1354       Spine->D1(Pc.Parameter(), Point, VecSpine);
1355     
1356       // It is checked if one leaves from the current face.
1357       FindFace = IsInput(VecSpine, Pc.Vertex(), FRef);
1358       if (FindFace) {
1359         VecSpine.Reverse();
1360         FindFace = IsInput(VecSpine, Pc.Vertex(), FRef);
1361       }
1362       // If one does not leave, it is ended
1363       if (FindFace) {
1364         FVoi = FRef;
1365         return Standard_True;
1366       }
1367     
1368       // Otherwise one finds the next among shared Faces 
1369       // by a common edge G1
1370       TopTools_ListIteratorOfListOfShape ItE, ItF;
1371       for(ItE.Initialize(myVEMap(Pc.Vertex()));
1372           ItE.More() && (!FindFace); ItE.Next()) {
1373         E = TopoDS::Edge(ItE.Value());
1374         Trouve=Standard_False;
1375         for(ItF.Initialize(myEFMap(E));//, Trouve=Standard_False;           15.11.99 SVV
1376             ItF.More()&&(!Trouve); ItF.Next()) {
1377           if (TopoDS::Face(ItF.Value()).IsSame(FRef)) {
1378             Trouve = Standard_True;
1379           }
1380         }
1381         if (Trouve) FindFace = IsG1(myEFMap, E, FRef, FVoi);
1382         if (FindFace) { 
1383           FindFace = Standard_False;
1384           if (Spine.IsNull()) {
1385             //La Spine peut etre nulle (ThreeCorner)
1386 #ifdef OCCT_DEBUG
1387             cout << "FindFace sur vertex avec spine nulle! QUEZAKO ?" << endl;
1388 #endif
1389             return Standard_False;
1390           }
1391         
1392           // It is checked if the selected face actually possesses edges of the spine
1393           // containing the vertex on its front
1394           // This processing should go only if the Vertex belongs to the spine
1395           // This is a single case, for other vertexes it is required to do other things
1396           Trouve=Standard_False;
1397           for (Standard_Integer IE=1;//, Trouve=Standard_False;                   15.11.99  SVV
1398                (IE<=Spine->NbEdges()) && (!Trouve); IE++) {
1399             E = Spine->Edges(IE);
1400             if (  (TopExp::FirstVertex(E).IsSame(Pc.Vertex())) 
1401                 ||(TopExp::LastVertex(E) .IsSame(Pc.Vertex())) ) {
1402               for(ItF.Initialize(myEFMap(E)), Trouve=Standard_False;
1403                   ItF.More()&&(!Trouve); ItF.Next()) {
1404                 if (TopoDS::Face(ItF.Value()).IsSame(FVoi)) {
1405                   Trouve = Standard_True;
1406                 }
1407               }
1408             }
1409           } 
1410           FindFace = Trouve;
1411         }
1412       }
1413     }
1414   }
1415   else {
1416     return IsG1(myEFMap, Pc.Arc(), FRef, FVoi);
1417   }
1418   return Standard_False;
1419 }
1420
1421
1422 //=======================================================================
1423 //function : ChFi3d_SingularExtremity
1424 //purpose  : load the vertex in the DS and calculate the pcurve 
1425 //           for an extremity in case of singular freeboundary 
1426 //           or periodic and singular at the cut.
1427 //=======================================================================
1428 static void ChFi3d_SingularExtremity( Handle(ChFiDS_Stripe)&     stripe,
1429                                      TopOpeBRepDS_DataStructure& DStr,
1430                                      const TopoDS_Vertex&        Vtx,      
1431                                      const Standard_Real         tol3d,
1432                                      const Standard_Real         tol2d)
1433 {
1434   Handle(ChFiDS_SurfData) Fd;
1435   Standard_Real tolreached;
1436   Standard_Real Pardeb, Parfin; 
1437   gp_Pnt2d VOnS1, VOnS2;
1438   Handle(Geom_Curve) C3d;
1439   Handle(Geom2d_Curve) PCurv;
1440   TopOpeBRepDS_Curve Crv;
1441   // SurfData and its CommonPoints,
1442   Standard_Integer Ivtx, Icurv;
1443   Standard_Boolean isfirst;
1444   
1445   if  (stripe->Spine()->IsPeriodic()) {
1446      isfirst = Standard_True;
1447      Fd = stripe->SetOfSurfData()->Sequence().First();
1448    }
1449   else {
1450     Standard_Integer sens;
1451     Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens);
1452     Fd =  stripe->SetOfSurfData()->Sequence().Value(num);
1453     isfirst = (sens == 1);
1454   }
1455  
1456   const ChFiDS_CommonPoint& CV1 = Fd->Vertex(isfirst,1);
1457   const ChFiDS_CommonPoint& CV2 = Fd->Vertex(isfirst,2);
1458   // Is it always degenerated ?
1459   if ( CV1.Point().IsEqual( CV2.Point(), 0) ) { 
1460     Ivtx = ChFi3d_IndexPointInDS(CV1, DStr);
1461     if (isfirst) {
1462       VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()->
1463                    Value(Fd->InterferenceOnS1().FirstParameter());
1464       VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()->
1465                      Value(Fd->InterferenceOnS2().FirstParameter());
1466     }
1467     else {
1468       VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()->
1469                     Value(Fd->InterferenceOnS1().LastParameter());
1470       VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()->
1471                     Value(Fd->InterferenceOnS2().LastParameter());
1472     }
1473       
1474     ChFi3d_ComputeArete(CV1, VOnS1,
1475                         CV2, VOnS2,
1476                         DStr.Surface(Fd->Surf()).Surface(),
1477                         C3d, PCurv,
1478                         Pardeb,Parfin, tol3d, tol2d, tolreached,0);
1479     Crv = TopOpeBRepDS_Curve(C3d,tolreached);
1480     Icurv = DStr.AddCurve(Crv);
1481
1482     stripe->SetCurve(Icurv, isfirst);
1483     stripe->SetParameters(isfirst, Pardeb,Parfin);
1484     stripe->ChangePCurve(isfirst) = PCurv;
1485     stripe->SetIndexPoint(Ivtx, isfirst, 1);
1486     stripe->SetIndexPoint(Ivtx, isfirst, 2);
1487
1488     if (stripe->Spine()->IsPeriodic()) { 
1489       // periodic case : The operation is renewed
1490       // the curve 3d is not shared.
1491       // 2 degenerated edges coinciding in 3d
1492       isfirst = Standard_False;
1493       Fd = stripe->SetOfSurfData()->Sequence().Last();
1494       VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()->
1495               Value(Fd->InterferenceOnS1().LastParameter());
1496       VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()->
1497               Value(Fd->InterferenceOnS2().LastParameter());
1498
1499       ChFi3d_ComputeArete(CV1, VOnS1,
1500                           CV2, VOnS2,
1501                           DStr.Surface(Fd->Surf()).Surface(),
1502                           C3d, PCurv,
1503                           Pardeb,Parfin, tol3d, tol2d, tolreached,0);
1504       Crv = TopOpeBRepDS_Curve(C3d,tolreached);
1505       Icurv = DStr.AddCurve(Crv);
1506
1507       stripe->SetCurve(Icurv, isfirst);
1508       stripe->SetParameters(isfirst, Pardeb,Parfin);
1509       stripe->ChangePCurve(isfirst) = PCurv;
1510       stripe->SetIndexPoint(Ivtx, isfirst, 1);
1511       stripe->SetIndexPoint(Ivtx, isfirst, 2);    
1512     }
1513   }
1514 }
1515
1516 //=======================================================================
1517 //function : ChFi3d_MakeExtremities
1518 //purpose  : calculate Curves3d and pcurves of extremities in
1519 //           periodic and freeboundary cases.
1520 //=======================================================================
1521 static Standard_Boolean IsFree(const TopoDS_Shape& E,
1522                                const ChFiDS_Map&   EFMap)
1523 {
1524   if(!EFMap.Contains(E)) return 0;
1525   TopTools_ListIteratorOfListOfShape It;
1526   TopoDS_Shape Fref;
1527   for(It.Initialize(EFMap(E)); It.More(); It.Next()){
1528     if(Fref.IsNull()) Fref = It.Value();
1529     else if(!Fref.IsSame(It.Value())) return 0;
1530   }
1531   return 1;
1532 }
1533
1534 static void ChFi3d_MakeExtremities(Handle(ChFiDS_Stripe)&      Stripe,
1535                                    TopOpeBRepDS_DataStructure& DStr,
1536                                    const ChFiDS_Map&           EFMap,
1537                                    const Standard_Real         tol3d,
1538                                    const Standard_Real         tol2d)
1539 {
1540   Handle(ChFiDS_Spine)& sp = Stripe->ChangeSpine();
1541   Standard_Real Pardeb,Parfin;
1542   Handle(Geom_Curve) C3d;
1543   Standard_Real tolreached;
1544   if(sp->IsPeriodic()){
1545     Bnd_Box b1,b2;
1546     const Handle(ChFiDS_SurfData)& 
1547       SDF = Stripe->SetOfSurfData()->Sequence().First();
1548     const ChFiDS_CommonPoint& CV1 = SDF->VertexFirstOnS1();
1549     const ChFiDS_CommonPoint& CV2 = SDF->VertexFirstOnS2();
1550     if ( !CV1.Point().IsEqual(CV2.Point(), 0) ) { 
1551       ChFi3d_ComputeArete(CV1,
1552                           SDF->InterferenceOnS1().PCurveOnSurf()->
1553                           Value(SDF->InterferenceOnS1().FirstParameter()),
1554                           CV2,
1555                           SDF->InterferenceOnS2().PCurveOnSurf()-> 
1556                           Value(SDF->InterferenceOnS2().FirstParameter()),
1557                           DStr.Surface(SDF->Surf()).Surface(),C3d,
1558                           Stripe->ChangeFirstPCurve(),Pardeb,Parfin,
1559                           tol3d,tol2d,tolreached,0);
1560       TopOpeBRepDS_Curve Crv(C3d,tolreached);
1561       Stripe->ChangeFirstCurve(DStr.AddCurve(Crv));
1562       Stripe->ChangeFirstParameters(Pardeb,Parfin);
1563       Stripe->ChangeIndexFirstPointOnS1
1564         (ChFi3d_IndexPointInDS(SDF->VertexFirstOnS1(),DStr));
1565       Stripe->ChangeIndexFirstPointOnS2
1566         (ChFi3d_IndexPointInDS(SDF->VertexFirstOnS2(),DStr));
1567       Standard_Integer ICurv = Stripe->FirstCurve();
1568       Stripe->ChangeLastParameters(Pardeb,Parfin);
1569       Stripe->ChangeLastCurve(ICurv);
1570       Stripe->ChangeIndexLastPointOnS1(Stripe->IndexFirstPointOnS1());
1571       Stripe->ChangeIndexLastPointOnS2(Stripe->IndexFirstPointOnS2());
1572       
1573       const Handle(ChFiDS_SurfData)& 
1574         SDL = Stripe->SetOfSurfData()->Sequence().Last();
1575       
1576       
1577       ChFi3d_ComputePCurv(C3d,
1578                           SDL->InterferenceOnS1().PCurveOnSurf()->
1579                           Value(SDL->InterferenceOnS1().LastParameter()),
1580                           SDL->InterferenceOnS2().PCurveOnSurf()->
1581                           Value(SDL->InterferenceOnS2().LastParameter()),
1582                           Stripe->ChangeLastPCurve(),
1583                           DStr.Surface(SDL->Surf()).Surface(),
1584                           Pardeb,Parfin,tol3d,tolreached);
1585       Standard_Real oldtol = DStr.ChangeCurve(ICurv).Tolerance();
1586       DStr.ChangeCurve(ICurv).Tolerance(Max(oldtol,tolreached));
1587       if(CV1.IsOnArc()){
1588         ChFi3d_EnlargeBox(CV1.Arc(),EFMap(CV1.Arc()),CV1.ParameterOnArc(),b1);
1589       }
1590       
1591       if(CV2.IsOnArc()){
1592         ChFi3d_EnlargeBox(CV2.Arc(),EFMap(CV2.Arc()),CV2.ParameterOnArc(),b2);
1593       }
1594       ChFi3d_EnlargeBox(DStr,Stripe,SDF,b1,b2,1);
1595       ChFi3d_EnlargeBox(DStr,Stripe,SDL,b1,b2,0);
1596       if (!CV1.IsVertex())
1597         ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexFirstPointOnS1());
1598       if (!CV2.IsVertex())
1599         ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexFirstPointOnS2());
1600     }
1601     else {
1602       // Case of the single extremity
1603       if (CV1.IsVertex()) { 
1604         ChFi3d_SingularExtremity(Stripe, DStr, CV1.Vertex(), tol3d, tol2d);
1605       }
1606 # if CHFI3D_DEB
1607       else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; }
1608 # endif
1609     }
1610     return;
1611   }  
1612   
1613   const Handle(ChFiDS_SurfData)& 
1614     SDdeb = Stripe->SetOfSurfData()->Sequence().First();
1615     
1616   const ChFiDS_CommonPoint& cpdeb1 = SDdeb->VertexFirstOnS1();
1617   const ChFiDS_CommonPoint& cpdeb2 = SDdeb->VertexFirstOnS2();
1618   Standard_Boolean freedeb = sp->FirstStatus() == ChFiDS_FreeBoundary;
1619   if(!freedeb && cpdeb1.IsOnArc() && cpdeb2.IsOnArc()){
1620     freedeb = (IsFree(cpdeb1.Arc(),EFMap) && IsFree(cpdeb2.Arc(),EFMap));
1621   }
1622   if(freedeb){
1623     sp->SetFirstStatus(ChFiDS_FreeBoundary);
1624     Bnd_Box b1,b2;
1625     if ( !cpdeb1.Point().IsEqual(cpdeb2.Point(), 0) ) { 
1626       Standard_Boolean plane;  
1627       gp_Pnt2d UV1,UV2;
1628       UV1=SDdeb->InterferenceOnS1().PCurveOnSurf()->
1629                           Value(SDdeb->InterferenceOnS1().FirstParameter());     
1630       UV2=SDdeb->InterferenceOnS2().PCurveOnSurf()->
1631                           Value(SDdeb->InterferenceOnS2().FirstParameter());
1632 // The intersection of the fillet by a plane is attempted
1633
1634       Handle(GeomAdaptor_HSurface) HConge=ChFi3d_BoundSurf(DStr,SDdeb,1,2);
1635       ChFi3d_CoupeParPlan(cpdeb1,cpdeb2,HConge,UV1,UV2,
1636                           tol3d,tol2d,C3d,Stripe->ChangeFirstPCurve(),tolreached,
1637                           Pardeb,Parfin,plane);  
1638       if (!plane) 
1639       ChFi3d_ComputeArete(cpdeb1,
1640                           SDdeb->InterferenceOnS1().PCurveOnSurf()->
1641                           Value(SDdeb->InterferenceOnS1().FirstParameter()),
1642                           cpdeb2,
1643                           SDdeb->InterferenceOnS2().PCurveOnSurf()-> 
1644                           Value(SDdeb->InterferenceOnS2().FirstParameter()),
1645                           DStr.Surface(SDdeb->Surf()).Surface(),C3d,
1646                           Stripe->ChangeFirstPCurve(),Pardeb,Parfin,
1647                           tol3d,tol2d,tolreached,0);
1648       TopOpeBRepDS_Curve Crv(C3d,tolreached);
1649       Stripe->ChangeFirstCurve(DStr.AddCurve(Crv));
1650       Stripe->ChangeFirstParameters(Pardeb,Parfin);
1651       Stripe->ChangeIndexFirstPointOnS1
1652         (ChFi3d_IndexPointInDS(SDdeb->VertexFirstOnS1(),DStr));
1653       Stripe->ChangeIndexFirstPointOnS2
1654         (ChFi3d_IndexPointInDS(SDdeb->VertexFirstOnS2(),DStr));
1655       if(cpdeb1.IsOnArc()){
1656         ChFi3d_EnlargeBox(cpdeb1.Arc(),EFMap(cpdeb1.Arc()),cpdeb1.ParameterOnArc(),b1);
1657       }
1658       if(cpdeb2.IsOnArc()){
1659         ChFi3d_EnlargeBox(cpdeb2.Arc(),EFMap(cpdeb2.Arc()),cpdeb2.ParameterOnArc(),b2);
1660       }
1661       ChFi3d_EnlargeBox(DStr,Stripe,SDdeb,b1,b2,1);
1662       if (!cpdeb1.IsVertex())
1663         ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexFirstPointOnS1());
1664       if (!cpdeb2.IsVertex())
1665         ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexFirstPointOnS2());
1666     }
1667     else { // Case of a singular extremity
1668       if (cpdeb1.IsVertex()) { 
1669         ChFi3d_SingularExtremity(Stripe, DStr, cpdeb1.Vertex(), tol3d, tol2d);
1670       }
1671 # if CHFI3D_DEB
1672       else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; }
1673 # endif
1674     }
1675   }
1676   const Handle(ChFiDS_SurfData)& 
1677     SDfin = Stripe->SetOfSurfData()->Sequence().Last();
1678   const ChFiDS_CommonPoint& cpfin1 = SDfin->VertexLastOnS1();
1679   const ChFiDS_CommonPoint& cpfin2 = SDfin->VertexLastOnS2();
1680   Standard_Boolean freefin = sp->LastStatus() == ChFiDS_FreeBoundary;
1681   if(!freefin && cpfin1.IsOnArc() && cpfin2.IsOnArc()){
1682     freefin = (IsFree(cpfin1.Arc(),EFMap) && IsFree(cpfin2.Arc(),EFMap));
1683   }
1684   if(freefin){
1685     sp->SetLastStatus(ChFiDS_FreeBoundary);
1686     Bnd_Box b1,b2;
1687     if ( !cpfin1.Point().IsEqual(cpfin2.Point(), 0) ) { 
1688       Standard_Boolean plane;
1689       gp_Pnt2d UV1,UV2;
1690       UV1=SDfin->InterferenceOnS1().PCurveOnSurf()->
1691                           Value(SDfin->InterferenceOnS1().LastParameter());     
1692       UV2=SDfin->InterferenceOnS2().PCurveOnSurf()->
1693                           Value(SDfin->InterferenceOnS2().LastParameter());
1694 // Intersection of the fillet by a plane is attempted
1695
1696       Handle(GeomAdaptor_HSurface) HConge=ChFi3d_BoundSurf(DStr,SDfin,1,2);
1697       ChFi3d_CoupeParPlan(cpfin1,cpfin2,HConge,UV1,UV2,
1698                           tol3d,tol2d,C3d,Stripe->ChangeLastPCurve(),tolreached,
1699                           Pardeb,Parfin,plane);      
1700       if (!plane)   
1701       ChFi3d_ComputeArete(cpfin1,
1702                           SDfin->InterferenceOnS1().PCurveOnSurf()->
1703                           Value(SDfin->InterferenceOnS1().LastParameter()),
1704                           cpfin2,
1705                           SDfin->InterferenceOnS2().PCurveOnSurf()-> 
1706                           Value(SDfin->InterferenceOnS2().LastParameter()),
1707                           DStr.Surface(SDfin->Surf()).Surface(),C3d,
1708                           Stripe->ChangeLastPCurve(),Pardeb,Parfin,
1709                           tol3d,tol2d,tolreached,0);
1710       TopOpeBRepDS_Curve Crv(C3d,tolreached);
1711       Stripe->ChangeLastCurve(DStr.AddCurve(Crv));
1712       Stripe->ChangeLastParameters(Pardeb,Parfin);
1713       Stripe->ChangeIndexLastPointOnS1
1714         (ChFi3d_IndexPointInDS(SDfin->VertexLastOnS1(),DStr));
1715       Stripe->ChangeIndexLastPointOnS2
1716         (ChFi3d_IndexPointInDS(SDfin->VertexLastOnS2(),DStr));
1717       if(cpfin1.IsOnArc()){
1718         ChFi3d_EnlargeBox(cpfin1.Arc(),EFMap(cpfin1.Arc()),cpfin1.ParameterOnArc(),b1);
1719       }
1720       if(cpfin2.IsOnArc()){
1721         ChFi3d_EnlargeBox(cpfin2.Arc(),EFMap(cpfin2.Arc()),cpfin2.ParameterOnArc(),b2);
1722       }
1723       ChFi3d_EnlargeBox(DStr,Stripe,SDfin,b1,b2,0);
1724       if (!cpfin1.IsVertex())
1725         ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexLastPointOnS1());
1726       if (!cpfin2.IsVertex())
1727         ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexLastPointOnS2());
1728     }
1729     else { // Case of the single extremity
1730       if (cpfin1.IsVertex()) { 
1731         ChFi3d_SingularExtremity(Stripe, DStr, cpfin1.Vertex(), tol3d, tol2d);
1732       }
1733 # if CHFI3D_DEB
1734       else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; }
1735 # endif
1736     }
1737   }
1738 }
1739
1740 //=======================================================================
1741 //function : ChFi3d_Purge
1742 //purpose  : 
1743 //=======================================================================
1744
1745 static void ChFi3d_Purge (Handle(ChFiDS_Stripe)&    Stripe,
1746                           Handle(ChFiDS_SurfData)&  SD,
1747                           const ChFiDS_CommonPoint& VRef,
1748                           const Standard_Boolean    isfirst,
1749                           const Standard_Integer    ons,
1750                           Standard_Integer&         intf,
1751                           Standard_Integer&         intl)
1752 {
1753   if (isfirst) intf = 1; else intl = 1; // End.
1754   Standard_Integer opp = 3-ons;
1755   if (!SD->Vertex(isfirst,opp).IsOnArc() || 
1756       SD->TwistOnS1() || SD->TwistOnS2() ) {
1757 #ifdef OCCT_DEBUG
1758     cout<<"ChFi3d_Purge : No output on extension."<<endl;
1759 #endif
1760     ChFiDS_SequenceOfSurfData& Seq = 
1761       Stripe->ChangeSetOfSurfData()->ChangeSequence();
1762     if(isfirst) Seq.Remove(1);
1763     else Seq.Remove(Seq.Length());
1764     return;
1765   }
1766   if (ons == 1) SD->ChangeIndexOfS1(0);
1767   else          SD->ChangeIndexOfS2(0);
1768   
1769   SD->ChangeVertex(!isfirst,ons) = VRef;
1770   SD->ChangeVertex(isfirst,ons)  = VRef;
1771   
1772   ChFiDS_FaceInterference& fi = SD->ChangeInterference(ons);
1773   if(isfirst) fi.SetFirstParameter(fi.LastParameter());
1774   else fi.SetLastParameter(fi.FirstParameter());
1775   fi.SetLineIndex(0);
1776 }
1777
1778 //=======================================================================
1779 //function : InsertAfter
1780 //purpose  : insert Item after ref in Seq. If ref is null, the item is
1781 //           inserted at the beginning.
1782 //=======================================================================
1783
1784 static void InsertAfter (Handle(ChFiDS_Stripe)&   Stripe,
1785                          Handle(ChFiDS_SurfData)& Ref,
1786                          Handle(ChFiDS_SurfData)& Item)
1787 {
1788   if (Ref == Item) 
1789     Standard_Failure::Raise("InsertAfter : twice the same surfdata.");
1790   
1791   ChFiDS_SequenceOfSurfData& Seq = 
1792     Stripe->ChangeSetOfSurfData()->ChangeSequence();
1793   
1794   if (Seq.IsEmpty() || Ref.IsNull()) {
1795     Seq.Prepend(Item);
1796   }
1797   for (Standard_Integer i = 1; i <= Seq.Length(); i++) {
1798     if (Seq.Value(i) == Ref) {
1799       Seq.InsertAfter(i,Item);
1800       break;
1801     }
1802   }
1803 }
1804
1805 //=======================================================================
1806 //function : RemoveSD
1807 //purpose  : 
1808 //=======================================================================
1809
1810 static void RemoveSD (Handle(ChFiDS_Stripe)&   Stripe,
1811                       Handle(ChFiDS_SurfData)& Prev,
1812                       Handle(ChFiDS_SurfData)& Next)
1813 {
1814   ChFiDS_SequenceOfSurfData& Seq = 
1815     Stripe->ChangeSetOfSurfData()->ChangeSequence();
1816   if(Seq.IsEmpty()) return;
1817   Standard_Integer iprev = 0, inext = 0;
1818   for (Standard_Integer i = 1; i <= Seq.Length(); i++) {
1819     if (Seq.Value(i) == Prev) iprev = i + 1;
1820     if (Seq.Value(i) == Next) { inext = i - 1; break; }
1821   }
1822   if(Prev.IsNull()) iprev = 1;
1823   if(Next.IsNull()) inext = Seq.Length();
1824   if(iprev <= inext) Seq.Remove(iprev,inext);
1825 }
1826
1827 //=======================================================================
1828 //function : InsertBefore
1829 //purpose  : Insert item before ref in Seq. If ref is null, the item is
1830 //           inserted in the queue.
1831 //=======================================================================
1832
1833 static void InsertBefore (Handle(ChFiDS_Stripe)&   Stripe,
1834                           Handle(ChFiDS_SurfData)& Ref,
1835                           Handle(ChFiDS_SurfData)& Item)
1836 {
1837   if (Ref == Item) 
1838     Standard_Failure::Raise("InsertBefore : twice the same surfdata.");
1839   
1840   ChFiDS_SequenceOfSurfData& Seq = 
1841     Stripe->ChangeSetOfSurfData()->ChangeSequence();
1842   
1843   if (Seq.IsEmpty() || Ref.IsNull()) {
1844     Seq.Append(Item);
1845   }
1846   for (Standard_Integer i = 1; i <= Seq.Length(); i++) {
1847     if (Seq.Value(i) == Ref) {
1848       Seq.InsertBefore(i,Item);
1849       break;
1850     }
1851   }
1852 }
1853
1854
1855 //=======================================================================
1856 //function : PerformSetOfSurfOnElSpine
1857 //purpose  : 
1858 //=======================================================================
1859
1860 void ChFi3d_Builder::PerformSetOfSurfOnElSpine
1861 (const Handle(ChFiDS_HElSpine)&    HGuide,
1862  Handle(ChFiDS_Stripe)&            Stripe,
1863  Handle(BRepTopAdaptor_TopolTool)& It1,
1864  Handle(BRepTopAdaptor_TopolTool)& It2,
1865  const Standard_Boolean            Simul)
1866
1867 #ifdef OCCT_DEBUG
1868   OSD_Chronometer ch1;
1869 #endif 
1870   
1871   ChFiDS_ElSpine& Guide = HGuide->ChangeCurve();
1872   Standard_Real wf = Guide.FirstParameter();
1873   Standard_Real wl = Guide.LastParameter();
1874   Standard_Real locfleche = (wl - wf) * fleche;
1875   Standard_Real wfsav = wf, wlsav = wl;
1876   if (!Guide.IsPeriodic())
1877   {
1878     //Now the ElSpine is artificially extended to help rsnld.
1879     Standard_Real prab = 0.01;
1880     Guide.FirstParameter(wf-prab*(wl-wf));
1881     Guide.LastParameter (wl+prab*(wl-wf));
1882   }
1883   Handle(ChFiDS_Spine)&  Spine = Stripe->ChangeSpine();
1884   Standard_Integer ii, nbed = Spine->NbEdges();
1885   Standard_Real lastedlastp = Spine->LastParameter(nbed);
1886   
1887   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
1888   
1889   Handle(ChFiDS_SurfData) ref = Guide.Previous();
1890   Handle(ChFiDS_SurfData) refbis, SD;
1891   Handle(ChFiDS_SurfData) raf = Guide.Next();
1892   RemoveSD(Stripe,ref,raf);
1893   
1894   Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface();
1895   Handle(BRepAdaptor_HSurface) HS2 = new BRepAdaptor_HSurface();
1896   Handle(BRepAdaptor_HSurface) HS3, HS4;
1897   Handle(BRepAdaptor_HSurface) HSref1 = new BRepAdaptor_HSurface();
1898   Handle(BRepAdaptor_HSurface) HSref2 = new BRepAdaptor_HSurface();
1899   Handle(BRepAdaptor_HCurve2d) HC1,HC2;
1900   Handle(BRepAdaptor_HCurve2d) HCref1 = new BRepAdaptor_HCurve2d();
1901   Handle(BRepAdaptor_HCurve2d) HCref2 = new BRepAdaptor_HCurve2d();
1902   Standard_Boolean decroch1 = Standard_False, decroch2 = Standard_False;
1903   Standard_Boolean RecP1 = Standard_False, RecS1 = Standard_False, RecRst1 = Standard_False, obstacleon1 = Standard_False;
1904   Standard_Boolean RecP2 = Standard_False, RecS2 = Standard_False, RecRst2 = Standard_False, obstacleon2 = Standard_False;
1905   gp_Pnt2d pp1,pp2,pp3,pp4;
1906   Standard_Real w1 = 0.,w2 = 0.;
1907   math_Vector Soldep(1,4);
1908   math_Vector SoldepCS(1,3);
1909   math_Vector SoldepCC(1,2);
1910   
1911   // Restore a neighboring KPart.
1912   // If no neighbor calculation start point. 
1913   Standard_Boolean forward = Standard_True;
1914   Standard_Boolean Inside  = Standard_False;
1915   Standard_Real    First   = wf;
1916   Standard_Real    Last    = wl;
1917   Standard_Boolean Ok1 = 1,Ok2 = 1;
1918   // Restore the next KPart if it exists
1919   TopoDS_Vertex Vref;
1920   if(ref.IsNull() && raf.IsNull()){
1921     //sinon solution approchee.
1922     Inside = Standard_True;
1923     
1924 #ifdef OCCT_DEBUG
1925     ChFi3d_InitChron(ch1);// init perf for StartSol 
1926 #endif
1927     
1928     StartSol(Stripe,HGuide,HS1,HS2,It1,It2,pp1,pp2,First);
1929     
1930 #ifdef OCCT_DEBUG
1931     ChFi3d_ResultChron(ch1,t_startsol); // result perf for StartSol  
1932 #endif 
1933     
1934     Last = wf;
1935     if(Guide.IsPeriodic()) {
1936       Last = First - Guide.Period();
1937       Guide.SaveFirstParameter();
1938       Guide.FirstParameter(Last);
1939       Guide.SaveLastParameter();
1940       Guide.LastParameter (First * 1.1);//Extension to help rsnld.
1941     }
1942   }
1943   else{
1944     if(!Spine->IsPeriodic() && (wl - lastedlastp > -tolesp)){ 
1945       Vref = Spine->LastVertex(); 
1946     }
1947     if (ref.IsNull()) {
1948       if(!Spine->IsPeriodic() && (wf < tolesp)){ 
1949         Vref = Spine->FirstVertex(); 
1950       }
1951       ref = raf;
1952       forward = Standard_False;
1953       First = wl; Last = Guide.FirstParameter();
1954     }
1955     
1956 #ifdef OCCT_DEBUG
1957     ChFi3d_InitChron(ch1);// init perf for startsol 
1958 #endif
1959     
1960     
1961     Ok1 = StartSol(Spine,HS1,pp1,HC1,w1,ref,!forward,1,
1962                    HSref1,HCref1,RecP1,RecS1,RecRst1,obstacleon1,
1963                    HS3,pp3,decroch1,Vref);
1964     Ok2 = StartSol(Spine,HS2,pp2,HC2,w2,ref,!forward,2,
1965                    HSref2,HCref2, RecP2,RecS2,RecRst2,obstacleon2,
1966                    HS4,pp4,decroch2,Vref);
1967     HC1.Nullify(); 
1968     HC2.Nullify();
1969     
1970 #ifdef OCCT_DEBUG
1971     ChFi3d_ResultChron(ch1,t_startsol); // result perf for startsol  
1972 #endif
1973     
1974     
1975     if(Ok1 == 1 && Ok2 == 1) {
1976       if(forward) Guide.FirstParameter(wf);
1977       else Guide.LastParameter(wl);
1978     }
1979   }
1980   Standard_Boolean      fini     = Standard_False;
1981   Standard_Boolean      complete = Inside;
1982   if(!Guide.IsPeriodic()){
1983     Standard_Integer indf = Spine->Index(wf);
1984     Standard_Integer indl = Spine->Index(wl,0);
1985     if(Spine->IsPeriodic() && (indl < indf)) indl += nbed;
1986     nbed = indl-indf+1;
1987   }
1988   // No Max at the touch : 20 points by edge at average without  
1989   // counting the extensions.
1990
1991   Standard_Real bidf = wf, bidl = wl;
1992   if(!Spine->IsPeriodic()) {
1993     bidf = Max(0.,wf);
1994     bidl = Min(wl,Spine->LastParameter(Spine->NbEdges()));
1995     // PMN 20/07/98 : Attention in case if there is only extension
1996     if  ((bidl-bidf) < 0.01 * Spine->LastParameter(Spine->NbEdges())) {
1997        bidf = wf;
1998        bidl = wl;
1999     }   
2000   }
2001   Standard_Real         MaxStep  = (bidl-bidf)*0.05/nbed;
2002   Standard_Real         Firstsov = 0.;
2003   Standard_Integer      intf = 0, intl = 0;
2004   while(!fini){
2005     // are these the ends (no extension on periodic).
2006     Ok1 = 1,Ok2 = 1;
2007     if(!Spine->IsPeriodic()){
2008       if(wf < tolesp && (complete == Inside)){
2009         if(Spine->FirstStatus() == ChFiDS_OnSame) intf = 2;
2010         else intf = 1;
2011       }
2012       if(Spine->IsTangencyExtremity(Standard_True)){
2013         intf = 4;
2014         Guide.FirstParameter(wfsav);
2015       }
2016       if(wl - lastedlastp > -tolesp){
2017         if(Spine->LastStatus() == ChFiDS_OnSame) intl = 2;
2018         else intl = 1;
2019       }
2020       if(Spine->IsTangencyExtremity(Standard_False)){
2021         intl = 4;
2022         Guide.LastParameter(wlsav);
2023       }
2024     }
2025     if(intf && !forward) Vref = Spine->FirstVertex();
2026     if(intl && forward) Vref = Spine->LastVertex();
2027     if(!ref.IsNull()){
2028       
2029 #ifdef OCCT_DEBUG
2030       ChFi3d_InitChron(ch1);// init perf for StartSol 
2031 #endif
2032       
2033       Ok1 = StartSol(Spine,HS1,pp1,HC1,w1,ref,!forward,1,
2034                      HSref1,HCref1, RecP1,RecS1,RecRst1,obstacleon1,
2035                      HS3,pp3,decroch1,Vref);
2036       Ok2 = StartSol(Spine,HS2,pp2,HC2,w2,ref,!forward,2,
2037                      HSref2,HCref2, RecP2,RecS2,RecRst2,obstacleon2,
2038                      HS4,pp4,decroch2,Vref);
2039       
2040 #ifdef OCCT_DEBUG
2041       ChFi3d_ResultChron(ch1,t_startsol); // result perf for StartSol  
2042 #endif 
2043       
2044     }
2045     
2046     // No more connected faces. Construction of the tangent plane to continue the path 
2047     // till the output on the other face.
2048     if ((!Ok1 && HC1.IsNull()) || (!Ok2 && HC2.IsNull())) {
2049       if ((intf && !forward) || (intl && forward)) {
2050         if (!Ok1) ChFi3d_BuildPlane (DStr,HS1,pp1,ref,!forward,1);
2051         if (!Ok2) ChFi3d_BuildPlane (DStr,HS2,pp2,ref,!forward,2);      
2052         if(intf) intf = 5;
2053         else if(intl) intl = 5;
2054         if(forward) Guide.FirstParameter(wf);
2055         else Guide.LastParameter(wl);
2056       }
2057       else Standard_Failure::Raise("PerformSetOfSurfOnElSpine : Chaining is impossible.");
2058     }
2059     
2060     // Definition of the domain of patch It1, It2
2061     const Handle(Adaptor3d_HSurface)& HSon1 = HS1; // to avoid ambiguity
2062     const Handle(Adaptor3d_HSurface)& HSon2 = HS2; // to avoid ambiguity
2063     It1->Initialize(HSon1);
2064     It2->Initialize(HSon2);
2065     
2066     // Calculate one (several if singularity) SurfaData
2067     SD = new ChFiDS_SurfData();
2068     ChFiDS_SequenceOfSurfData SeqSD;
2069     SeqSD.Append(SD);
2070     
2071     if(obstacleon1 && obstacleon2){
2072       TopAbs_Orientation Or1 = HSref1->ChangeSurface().Face().Orientation();
2073       TopAbs_Orientation Or2 = HSref2->ChangeSurface().Face().Orientation();
2074       Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2,
2075                                                 Stripe->OrientationOnFace1(),
2076                                                 Stripe->OrientationOnFace2(),
2077                                                 Stripe->Choix());
2078
2079
2080       // Calculate the criterion of Choice edge / edge
2081       if (Choix%2 == 0) Choix = 4;
2082       else Choix = 1;
2083
2084       SoldepCC(1) = w1; SoldepCC(2) = w2;
2085       if(Simul){
2086         SimulSurf(SD,HGuide,Spine,Choix,
2087                   HS1,It1,HC1,HSref1,HCref1,decroch1,Or1,
2088                   HS2,It2,HC2,HSref2,HCref2,decroch2,Or2,
2089                   locfleche,tolesp,First,Last,Inside,Inside,forward,
2090                   RecP1,RecRst1,RecP2,RecRst2,SoldepCC);
2091       }
2092       else{
2093 #ifdef OCCT_DEBUG
2094         ChFi3d_InitChron(ch1); // init perf for PerformSurf 
2095 #endif
2096         PerformSurf(SeqSD,HGuide,Spine,Choix,
2097                     HS1,It1,HC1,HSref1,HCref1,decroch1,Or1,
2098                     HS2,It2,HC2,HSref2,HCref2,decroch2,Or2,
2099                     MaxStep,locfleche,tolesp,First,Last,Inside,Inside,forward,
2100                     RecP1,RecRst1,RecP2,RecRst2,SoldepCC);
2101 #ifdef OCCT_DEBUG
2102         ChFi3d_ResultChron(ch1,t_performsurf); //result  perf for PerformSurf 
2103 #endif 
2104       }
2105       SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2106       SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2107     }
2108     else if (obstacleon1){
2109       TopAbs_Orientation Or1 = HSref1->ChangeSurface().Face().Orientation();
2110       TopAbs_Orientation Or2 = HS2->ChangeSurface().Face().Orientation();
2111       Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2,
2112                                                 Stripe->OrientationOnFace1(),
2113                                                 Stripe->OrientationOnFace2(),
2114                                                 -Stripe->Choix());
2115       if(Choix%2 == 1) Choix++;
2116       else Choix--;
2117       SoldepCS(3) = w1; SoldepCS(1) =  pp2.X(); SoldepCS(2) =  pp2.Y();
2118       if(Simul){
2119         SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,HC1,HSref1,HCref1,decroch1,
2120                   HS2,It2,Or2,locfleche,tolesp,First,Last,
2121                   Inside,Inside,forward,RecP1,RecS2,RecRst1,SoldepCS);
2122       }
2123       else{
2124 #ifdef OCCT_DEBUG
2125         ChFi3d_InitChron(ch1); // init perf for PerformSurf
2126 #endif
2127         PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,HC1,HSref1,HCref1,decroch1,
2128                     HS2,It2,Or2,MaxStep,locfleche,tolesp,First,Last,
2129                     Inside,Inside,forward,RecP1,RecS2,RecRst1,SoldepCS);
2130 #ifdef OCCT_DEBUG
2131         ChFi3d_ResultChron(ch1,t_performsurf);//result  perf for PerformSurf  
2132 #endif 
2133       }
2134       SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2135       SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2136       decroch2 = 0;
2137     }
2138     else if (obstacleon2){
2139       TopAbs_Orientation Or1 = HS1->ChangeSurface().Face().Orientation();
2140       TopAbs_Orientation Or2 = HSref2->ChangeSurface().Face().Orientation();
2141       Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2,
2142                                                 Stripe->OrientationOnFace1(),
2143                                                 Stripe->OrientationOnFace2(),
2144                                                 Stripe->Choix());
2145       SoldepCS(3) = w2; SoldepCS(1) =  pp1.X(); SoldepCS(2) =  pp1.Y();
2146       if(Simul){
2147         SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,Or1,
2148                   HS2,It2,HC2,HSref2,HCref2,decroch2,locfleche,tolesp,
2149                   First,Last,Inside,Inside,forward,RecP2,RecS1,RecRst2,SoldepCS);
2150       }
2151       else{
2152 #ifdef OCCT_DEBUG
2153         ChFi3d_InitChron(ch1); // init perf for PerformSurf 
2154 #endif
2155         PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,Or1,
2156                     HS2,It2,HC2,HSref2,HCref2,decroch2,MaxStep,locfleche,tolesp,
2157                     First,Last,Inside,Inside,forward,RecP2,RecS1,RecRst2,SoldepCS);
2158 #ifdef OCCT_DEBUG
2159         ChFi3d_ResultChron(ch1,t_performsurf); //result  perf for PerformSurf 
2160 #endif 
2161       }
2162       SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2163       SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2164       decroch1 = 0;
2165     }
2166     else{ 
2167       const Handle(Adaptor3d_TopolTool)& aTT1 = It1; // to avoid ambiguity
2168       const Handle(Adaptor3d_TopolTool)& aTT2 = It2; // to avoid ambiguity
2169       CallPerformSurf(Stripe, Simul, SeqSD, SD,
2170                       HGuide,Spine,
2171                       HS1, HS3, pp1, pp3, aTT1,
2172                       HS2, HS4, pp2, pp4, aTT2, 
2173                       MaxStep,locfleche,tolesp,
2174                       First,Last,Inside,Inside,forward,
2175                       RecS1,RecS2,Soldep,intf,intl, 
2176                       HS1, HS2);
2177       decroch1 = decroch2 = 0;
2178     }
2179
2180     if(!done) { // Case of fail
2181       if ((!Ok1 && !obstacleon1) || (!Ok2 && !obstacleon2)) {
2182         //Fail in a part of extension is not serious
2183         //Here one stops.
2184         done = Standard_True;
2185         Inside = Standard_False;
2186         if (forward) intl = 1;
2187         else         intf = 1;
2188       }
2189       else { // Otherwise invalidation of the stripe.
2190         Spine->SetErrorStatus(ChFiDS_WalkingFailure);
2191         Standard_Failure::Raise("CallPerformSurf : Path failed!");
2192       }
2193     }
2194     
2195     else {
2196       refbis = ref;
2197       if(forward) {
2198         for (ii=1; ii<=SeqSD.Length(); ii++) {
2199           SD = SeqSD(ii);
2200           SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2201           if(obstacleon1) SD->SetIndexOfC1(DStr.AddShape(HC1->ChangeCurve2d().Edge()));
2202           SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2203           if(obstacleon2) SD->SetIndexOfC2(DStr.AddShape(HC2->ChangeCurve2d().Edge()));
2204           InsertAfter (Stripe, refbis, SD);
2205           refbis = SD;
2206         }
2207       }
2208       else {
2209         for (ii=SeqSD.Length(); ii>=1; ii--) {
2210           SD = SeqSD(ii);
2211           SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2212           if(obstacleon1) SD->SetIndexOfC1(DStr.AddShape(HC1->ChangeCurve2d().Edge()));
2213           SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2214           if(obstacleon2) SD->SetIndexOfC2(DStr.AddShape(HC2->ChangeCurve2d().Edge()));
2215           InsertBefore(Stripe,refbis,SD);
2216           refbis = SD;
2217         }
2218       } 
2219     
2220       if (!Ok1 && !obstacleon1) 
2221         // clean infos on the plane of extension.
2222         ChFi3d_Purge (Stripe,SD,ref->Vertex(!forward,1),!forward,1,intf,intl);
2223       
2224       if (!Ok2 && !obstacleon2) 
2225         // clean infos on the plane of extension.
2226         ChFi3d_Purge (Stripe,SD,ref->Vertex(!forward,2),!forward,2,intf,intl);
2227     
2228       // The end. The reference is changed.      
2229       ref = refbis;  
2230     }  
2231     
2232     if(Inside){// There are starting solutions for the next.
2233       Inside = Standard_False;
2234       Firstsov = First;
2235       if(Guide.IsPeriodic()) {
2236         complete = Standard_False;
2237         wf  = Guide.FirstParameter();
2238         wl  = Guide.LastParameter();
2239       }
2240     }
2241     if(forward){
2242       fini = ((wl - Last) <= 10.*tolesp || 
2243               (intl && !(obstacleon1 || obstacleon2))); //General case
2244
2245       if (!fini && Guide.IsPeriodic() && 
2246           ((wl - Last)< Guide.Period()*1.e-3)) {
2247         // It is tested if reframing of extremes is done at the same edge
2248         // Loop Condition
2249         Handle(ChFiDS_SurfData) thefirst, thelast;
2250         thefirst = Stripe->SetOfSurfData()->Sequence().First();
2251         thelast =  Stripe->SetOfSurfData()->Sequence().Last();
2252         
2253         if (thefirst->VertexFirstOnS1().IsOnArc() && 
2254             thelast->VertexLastOnS1().IsOnArc())
2255           fini = thefirst->VertexFirstOnS1().Arc().IsSame
2256             (thelast->VertexLastOnS1().Arc());
2257         if (!fini &&
2258             thefirst->VertexFirstOnS2().IsOnArc() && 
2259             thelast->VertexLastOnS2().IsOnArc())
2260           fini = thefirst->VertexFirstOnS2().Arc().IsSame
2261             (thelast->VertexLastOnS2().Arc());
2262
2263         if (fini) 
2264           return; //It is ended!
2265       }
2266
2267       if(fini && complete) {
2268         // restart in the opposite direction.
2269         ref  = Stripe->SetOfSurfData()->Sequence().First();
2270         forward = Standard_False;
2271         fini = Standard_False;
2272         First = Firstsov;
2273       }
2274       else {
2275         First = Last;
2276         Last  = wl;
2277       }
2278     }
2279     if(!forward){
2280       fini = ((First - wf) <= 10.*tolesp || 
2281               (intf && !(obstacleon1 || obstacleon2)));
2282       complete = Standard_False;
2283       Last = wf;
2284     }
2285   }
2286   // The initial state is restored
2287   if(!Guide.IsPeriodic()){
2288     Guide.FirstParameter(wfsav);
2289     Guide.LastParameter (wlsav);
2290   }
2291
2292 }
2293
2294 //=======================================================================
2295 //function : PerformSetOfKPart
2296 //purpose  : 
2297 //=======================================================================
2298
2299 void ChFi3d_Builder::PerformSetOfKPart(Handle(ChFiDS_Stripe)& Stripe,
2300                                        const Standard_Boolean Simul) 
2301 {
2302   TopOpeBRepDS_DataStructure&  DStr = myDS->ChangeDS();
2303   Handle(ChFiDS_Spine)&        Spine = Stripe->ChangeSpine();
2304   Handle(BRepAdaptor_HSurface) HS1,HS2;
2305   TopAbs_Orientation           Or1,Or2,RefOr1,RefOr2;
2306   Standard_Integer             RefChoix;
2307   
2308   // initialization of the stripe.
2309   Stripe->Reset();
2310   Handle(ChFiDS_HData)&  HData  = Stripe->ChangeSetOfSurfData();
2311   HData =  new ChFiDS_HData();
2312   ChFiDS_SequenceOfSurfData& SeqSurf = HData->ChangeSequence();
2313   
2314   StripeOrientations(Spine,RefOr1,RefOr2,RefChoix);
2315   Stripe->OrientationOnFace1(RefOr1);
2316   Stripe->OrientationOnFace2(RefOr2);
2317   Stripe->Choix(RefChoix);
2318   
2319   Handle(BRepTopAdaptor_TopolTool) It1 = new BRepTopAdaptor_TopolTool();
2320   Handle(BRepTopAdaptor_TopolTool) It2 = new BRepTopAdaptor_TopolTool();
2321   
2322   Standard_Real WFirst,WLast = 0.;
2323   gp_Vec TFirst,TLast,TEndPeriodic;
2324   gp_Pnt PFirst,PLast,PEndPeriodic;
2325   Standard_Boolean intf = Standard_False, intl = Standard_False;
2326   
2327   Handle(ChFiDS_HElSpine) CurrentHE = new ChFiDS_HElSpine();
2328   Spine->D1(Spine->FirstParameter(),PFirst,TFirst);
2329   CurrentHE->ChangeCurve().FirstParameter(Spine->FirstParameter());
2330   CurrentHE->ChangeCurve().SetFirstPointAndTgt(PFirst,TFirst);
2331   
2332   Standard_Boolean YaKPart = Standard_False;
2333   Standard_Integer iedgelastkpart = 0;
2334   
2335   Standard_Real WStartPeriodic = 0.;
2336   Standard_Real WEndPeriodic = Spine->LastParameter(Spine->NbEdges());
2337   Spine->D1(WEndPeriodic,PEndPeriodic,TEndPeriodic);
2338   
2339   // Construction of particular cases.
2340   
2341   for (Standard_Integer iedge = 1; iedge <= Spine->NbEdges(); iedge++){
2342     
2343     ConexFaces(Spine,iedge,RefChoix,HS1,HS2);
2344     
2345     if (ChFi3d_KParticular(Spine,iedge,HS1->ChangeSurface(),HS2->ChangeSurface())) {
2346       intf = ((iedge == 1) && !Spine->IsPeriodic());
2347       intl = ((iedge == Spine->NbEdges()) && !Spine->IsPeriodic());
2348       Or1   = HS1->ChangeSurface().Face().Orientation();
2349       Or2   = HS2->ChangeSurface().Face().Orientation();
2350       ChFi3d::NextSide(Or1,Or2,RefOr1,RefOr2,RefChoix);      
2351       const Handle(Adaptor3d_HSurface)& HSon1 = HS1; // to avoid ambiguity
2352       const Handle(Adaptor3d_HSurface)& HSon2 = HS2; // to avoid ambiguity
2353       It1->Initialize(HSon1);
2354       It2->Initialize(HSon2);
2355       
2356       Handle(ChFiDS_SurfData)   SD = new ChFiDS_SurfData();
2357       ChFiDS_SequenceOfSurfData LSD;
2358       
2359       if(!ChFiKPart_ComputeData::Compute(DStr,SD,HS1,HS2,Or1,Or2,Spine,iedge)){
2360 #ifdef OCCT_DEBUG
2361         cout<<"failed calculation KPart"<<endl;
2362 #endif
2363       }
2364       else if(!SplitKPart(SD,LSD,Spine,iedge,HS1,It1,HS2,It2,intf,intl)){
2365 #ifdef OCCT_DEBUG
2366         cout<<"failed calculation KPart"<<endl;
2367 #endif
2368         LSD.Clear();
2369       }
2370       else iedgelastkpart = iedge;
2371       if(Spine->IsPeriodic()){//debug provisory for SD that arrive in desorder.
2372         Standard_Integer nbsd = LSD.Length();
2373         Standard_Real period = Spine->Period();
2374         Standard_Real wfp = WStartPeriodic, wlp = WEndPeriodic;
2375 //  modified by NIZHNY-EAP Thu Nov 25 12:57:53 1999 ___BEGIN___
2376         if(!YaKPart && nbsd>0){
2377 //      if(!YaKPart){
2378 //  modified by NIZHNY-EAP Thu Nov 25 12:57:57 1999 ___END___
2379           Handle(ChFiDS_SurfData) firstSD = LSD.ChangeValue(1);
2380           Standard_Real wwf = firstSD->FirstSpineParam();
2381           Standard_Real wwl = firstSD->LastSpineParam();
2382           wwf = ChFi3d_InPeriod(wwf,wfp,wlp,tolesp);
2383           wwl = ChFi3d_InPeriod(wwl,wfp,wlp,tolesp);
2384           if (wwl <= wwf + tolesp) wwl += period;
2385           wfp = wwf;
2386           wlp = wfp + period;
2387         }
2388         for(Standard_Integer j = 1; j < nbsd; j++){
2389           Handle(ChFiDS_SurfData) jSD = LSD.Value(j);
2390           for(Standard_Integer k = j+1; k <= nbsd; k++){
2391             Handle(ChFiDS_SurfData) kSD = LSD.Value(k);
2392             Standard_Real jwf = jSD->FirstSpineParam();
2393             jwf = ChFi3d_InPeriod(jwf,wfp,wlp,tolesp);
2394             Standard_Real kwf = kSD->FirstSpineParam();
2395             kwf = ChFi3d_InPeriod(kwf,wfp,wlp,tolesp);
2396             if(kwf < jwf){
2397               LSD.SetValue(j,kSD);
2398               LSD.SetValue(k,jSD);
2399             }
2400           }
2401         }
2402       }
2403       TColStd_ListOfInteger li;
2404       for(Standard_Integer j = 1; j <= LSD.Length(); j++){
2405         Handle(ChFiDS_SurfData)& curSD = LSD.ChangeValue(j);
2406         if(Simul) SimulKPart(curSD);
2407         SeqSurf.Append(curSD);
2408         if(!Simul) li.Append(curSD->Surf());
2409         WFirst = LSD.Value(j)->FirstSpineParam();
2410         WLast  = LSD.Value(j)->LastSpineParam();
2411         if(Spine->IsPeriodic()){
2412           WFirst = ChFi3d_InPeriod(WFirst,WStartPeriodic,WEndPeriodic,tolesp);
2413           WLast  = ChFi3d_InPeriod(WLast ,WStartPeriodic,WEndPeriodic,tolesp);
2414           if (WLast <= WFirst + tolesp) WLast+= Spine->Period();
2415         }
2416         TgtKP(LSD.Value(j),Spine,iedge,1,PFirst,TFirst);
2417         TgtKP(LSD.Value(j),Spine,iedge,0,PLast,TLast);
2418         
2419         // Determine the sections to approximate
2420         if(!YaKPart){
2421           if(Spine->IsPeriodic()){
2422             WStartPeriodic = WFirst;
2423             WEndPeriodic = WStartPeriodic + Spine->Period();
2424             WLast = ElCLib::InPeriod(WLast,WStartPeriodic,WEndPeriodic);
2425             if (WLast <= WFirst + tolesp) WLast+= Spine->Period();
2426             PEndPeriodic = PFirst;
2427             TEndPeriodic = TFirst;
2428             Spine->SetFirstParameter(WStartPeriodic);
2429             Spine->SetLastParameter(WEndPeriodic);
2430           }
2431           else if(!intf || (iedge > 1)){
2432             // start section -> first KPart
2433             // update of extension.
2434             Spine->SetFirstTgt(Min(0.,WFirst));
2435             CurrentHE->ChangeCurve().LastParameter (WFirst);
2436             CurrentHE->ChangeCurve().SetLastPointAndTgt(PFirst,TFirst);
2437             Spine->AppendElSpine(CurrentHE);
2438             CurrentHE->ChangeCurve().ChangeNext() = LSD.Value(j);
2439             CurrentHE =  new ChFiDS_HElSpine();
2440           }
2441           CurrentHE->ChangeCurve().FirstParameter(WLast);
2442           CurrentHE->ChangeCurve().SetFirstPointAndTgt(PLast,TLast);
2443           CurrentHE->ChangeCurve().ChangePrevious() = LSD.Value(j);
2444           YaKPart = Standard_True;
2445         }
2446         else {
2447           if (WFirst - CurrentHE->FirstParameter() > tolesp) {
2448             // section between two KPart
2449             CurrentHE->ChangeCurve().LastParameter(WFirst);
2450             CurrentHE->ChangeCurve().SetLastPointAndTgt(PFirst,TFirst);
2451             Spine->AppendElSpine(CurrentHE);
2452             CurrentHE->ChangeCurve().ChangeNext() = LSD.Value(j);
2453             CurrentHE = new ChFiDS_HElSpine();
2454           }
2455           CurrentHE->ChangeCurve().FirstParameter(WLast);
2456           CurrentHE->ChangeCurve().SetFirstPointAndTgt(PLast,TLast);
2457           CurrentHE->ChangeCurve().ChangePrevious() = LSD.Value(j);
2458         }
2459       }
2460       if(!li.IsEmpty()) myEVIMap.Bind(Spine->Edges(iedge),li);
2461     }
2462   }
2463   
2464   if (!intl || (iedgelastkpart < Spine->NbEdges())) {
2465     // section last KPart(or start of the spine) -> End of the spine.
2466     // update of the extension.
2467     
2468     if(Spine->IsPeriodic()){
2469       if(WEndPeriodic - WLast > tolesp){
2470         CurrentHE->ChangeCurve().LastParameter(WEndPeriodic);
2471         CurrentHE->ChangeCurve().SetLastPointAndTgt(PEndPeriodic,TEndPeriodic);
2472         if(!YaKPart) CurrentHE->ChangeCurve().SetPeriodic(Standard_True);
2473         Spine->AppendElSpine(CurrentHE);
2474       }
2475     }
2476     else{
2477       Spine->D1(Spine->LastParameter(),PLast,TLast);
2478       Spine->SetLastTgt(Max(Spine->LastParameter(Spine->NbEdges()),
2479                             WLast));
2480       if (Spine->LastParameter() - WLast > tolesp) {
2481         CurrentHE->ChangeCurve().LastParameter(Spine->LastParameter());
2482         CurrentHE->ChangeCurve().SetLastPointAndTgt(PLast,TLast);
2483         Spine->AppendElSpine(CurrentHE);
2484       }
2485     }
2486   }
2487   
2488   ChFiDS_ListOfHElSpine& ll = Spine->ChangeElSpines();
2489   ChFiDS_ListIteratorOfListOfHElSpine ILES(ll);
2490   for ( ; ILES.More(); ILES.Next()) {
2491 #ifdef OCCT_DEBUG
2492     if(ChFi3d_GettraceCHRON()) elspine.Start();
2493 #endif
2494     ChFi3d_PerformElSpine(ILES.Value(),Spine,myConti,tolesp);
2495 #ifdef OCCT_DEBUG
2496     if(ChFi3d_GettraceCHRON()) { elspine.Stop(); }
2497 #endif
2498   }
2499   Spine->SplitDone(Standard_True);
2500 }
2501
2502 static Standard_Real ChFi3d_BoxDiag(const Bnd_Box& box)
2503 {
2504   Standard_Real a,b,c,d,e,f;
2505   box.Get(a,b,c,d,e,f); 
2506   d-=a; e-=b; f-=c; 
2507   d*=d; e*=e; f*=f;
2508   Standard_Real diag = sqrt(d + e + f);
2509   return diag;
2510 }
2511
2512 //=======================================================================
2513 //function : PerformSetOfKGen
2514 //purpose  : 
2515 //=======================================================================
2516
2517 void ChFi3d_Builder::PerformSetOfKGen(Handle(ChFiDS_Stripe)& Stripe,
2518                                       const Standard_Boolean Simul) 
2519 {
2520   Handle(BRepTopAdaptor_TopolTool) It1 = new BRepTopAdaptor_TopolTool();
2521   Handle(BRepTopAdaptor_TopolTool) It2 = new BRepTopAdaptor_TopolTool();
2522   Handle(ChFiDS_Spine)& Spine = Stripe->ChangeSpine();
2523   ChFiDS_ListOfHElSpine& ll = Spine->ChangeElSpines();
2524   ChFiDS_ListIteratorOfListOfHElSpine ILES(ll);
2525   for ( ; ILES.More(); ILES.Next()) {
2526 #ifdef OCCT_DEBUG
2527     if(ChFi3d_GettraceCHRON()) { chemine.Start(); }
2528 #endif
2529     PerformSetOfSurfOnElSpine(ILES.Value(),Stripe,It1,It2,Simul);
2530 #ifdef OCCT_DEBUG
2531     if(ChFi3d_GettraceCHRON()) chemine.Stop();
2532 #endif
2533   }
2534   if(!Simul){
2535     TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
2536     Handle(ChFiDS_HData)&  HData  = Stripe->ChangeSetOfSurfData();
2537     ChFiDS_SequenceOfSurfData& SeqSurf = HData->ChangeSequence();
2538     Standard_Integer len = SeqSurf.Length();
2539     Standard_Integer last = len, i;
2540     Standard_Boolean periodic = Spine->IsPeriodic();
2541     if(periodic) last++;
2542     // It is attempted to reprocess the squares that bore.
2543     for(i = 1; i <= len; i++){
2544       Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i);
2545       Standard_Boolean tw1 = cursd->TwistOnS1();
2546       Standard_Boolean tw2 = cursd->TwistOnS2();
2547       Handle(ChFiDS_SurfData) prevsd, nextsd;
2548       Standard_Integer iprev = i-1;
2549       if(iprev == 0) {
2550         if(periodic) iprev = len;
2551       }
2552       Standard_Integer inext = i + 1;
2553       if(inext > len) {
2554         if(periodic) inext = 1;
2555         else inext = 0;
2556       }
2557
2558       // For the moment only the surfaces where the twist is 
2559       // detected at the path are corrected, it is necessary to control  
2560       // more subtly the ugly traces (size, curvature, inflexion... ) 
2561       if(!tw1 && !tw2) continue;
2562       
2563       // It is decided (fairly at random) if the extended surface is ready for the filling.
2564       ChFiDS_FaceInterference& intf1 = cursd->ChangeInterferenceOnS1();
2565       ChFiDS_FaceInterference& intf2 = cursd->ChangeInterferenceOnS2();
2566       Standard_Integer cursurf1 = cursd->IndexOfS1();
2567       Standard_Integer cursurf2 = cursd->IndexOfS2();
2568       ChFiDS_CommonPoint& cpd1 = cursd->ChangeVertexFirstOnS1();
2569       ChFiDS_CommonPoint& cpd2 = cursd->ChangeVertexFirstOnS2();
2570       ChFiDS_CommonPoint& cpf1 = cursd->ChangeVertexLastOnS1();
2571       ChFiDS_CommonPoint& cpf2 = cursd->ChangeVertexLastOnS2();
2572       const gp_Pnt& pd1 = cpd1.Point();
2573       const gp_Pnt& pd2 = cpd2.Point();
2574       const gp_Pnt& pf1 = cpf1.Point();
2575       const gp_Pnt& pf2 = cpf2.Point();
2576       Standard_Real ddeb = pd1.Distance(pd2);
2577       Standard_Real dfin = pf1.Distance(pf2);
2578       Standard_Real don1 = pd1.Distance(pf1);
2579       Standard_Real don2 = pd2.Distance(pf2);
2580       Standard_Boolean possibleon1 = (don1 < 2*(ddeb + dfin));
2581       Standard_Boolean possibleon2 = (don2 < 2*(ddeb + dfin));
2582       if((tw1 && !possibleon1) || (tw2 && !possibleon2)) {
2583         Spine->SetErrorStatus(ChFiDS_TwistedSurface);
2584         Standard_Failure::Raise("adjustment by reprocessing the non-written points");
2585       }
2586       
2587       // It is checked if there are presentable neighbors
2588       Standard_Boolean yaprevon1 = 0, yaprevon2 = 0;
2589       Standard_Boolean samesurfon1 = 0, samesurfon2 = 0;
2590       if(iprev){
2591         prevsd = SeqSurf.ChangeValue(iprev);
2592         yaprevon1 = !prevsd->TwistOnS1();
2593         samesurfon1 = (prevsd->IndexOfS1() == cursurf1);
2594         yaprevon2 = !prevsd->TwistOnS2();
2595         samesurfon2 = (prevsd->IndexOfS2() == cursurf2);
2596       }
2597       Standard_Boolean yanexton1 = 0, yanexton2 = 0;
2598       if(inext){
2599         nextsd = SeqSurf.ChangeValue(inext);
2600         yanexton1 = !nextsd->TwistOnS1();
2601         if(samesurfon1) samesurfon1 = (nextsd->IndexOfS1() == cursurf1);
2602         yanexton2 = !nextsd->TwistOnS2();
2603         if(samesurfon2) samesurfon2 = (nextsd->IndexOfS2() == cursurf2);
2604       }
2605       // A contour of filling is constructed
2606       Handle(Geom2d_Curve) PC1 = intf1.PCurveOnFace();
2607       Handle(Geom2d_Curve) PC2 = intf2.PCurveOnFace();
2608       Handle(BRepAdaptor_HSurface) S1 = new BRepAdaptor_HSurface();
2609       TopoDS_Face F1 = TopoDS::Face(DStr.Shape(cursurf1));
2610       S1->ChangeSurface().Initialize(F1);
2611       Handle(BRepAdaptor_HSurface) S2 = new BRepAdaptor_HSurface();
2612       TopoDS_Face F2 = TopoDS::Face(DStr.Shape(cursurf2));
2613       S2->ChangeSurface().Initialize(F2);
2614       Handle(GeomFill_Boundary) Bdeb,Bfin,Bon1,Bon2;
2615       Standard_Boolean pointuon1 = 0, pointuon2 = 0;
2616       if(tw1){
2617         if(!yaprevon1 || !yanexton1){
2618           Spine->SetErrorStatus(ChFiDS_TwistedSurface);
2619           Standard_Failure::Raise
2620             ("adjustment by reprocessing the non-written points: no neighbor");
2621         }
2622         ChFiDS_FaceInterference& previntf1 = prevsd->ChangeInterferenceOnS1();
2623         ChFiDS_FaceInterference& nextintf1 = nextsd->ChangeInterferenceOnS1();
2624         Standard_Real prevpar1 = previntf1.LastParameter();
2625         Standard_Real nextpar1 = nextintf1.FirstParameter();
2626         if(samesurfon1){
2627           // It is checked if it is possible to intersect traces of neighbors
2628           // to create a sharp end.
2629           Handle(Geom2d_Curve) pcprev1 = previntf1.PCurveOnFace();
2630           Handle(Geom2d_Curve) pcnext1 = nextintf1.PCurveOnFace();
2631           Standard_Real nprevpar1,nnextpar1;
2632           gp_Pnt2d p2d;
2633 //  Modified by Sergey KHROMOV - Wed Feb  5 12:03:17 2003 Begin
2634 //        if(ChFi3d_IntTraces(prevsd,prevpar1,nprevpar1,1,1,
2635 //                            nextsd,nextpar1,nnextpar1,1,-1,p2d)){
2636           if(ChFi3d_IntTraces(prevsd,prevpar1,nprevpar1,1,1,
2637                               nextsd,nextpar1,nnextpar1,1,-1,p2d,
2638                               Standard_False, Standard_True)){
2639 //  Modified by Sergey KHROMOV - Wed Feb  5 12:03:17 2003 End
2640             previntf1.SetLastParameter(nprevpar1);
2641             nextintf1.SetFirstParameter(nnextpar1);
2642             pointuon1 = 1;
2643             PC1.Nullify();
2644           }
2645           else{
2646             gp_Pnt2d pdeb1,pfin1;
2647             gp_Vec2d vdeb1,vfin1;
2648             pcprev1->D1(prevpar1,pdeb1,vdeb1);
2649             pcnext1->D1(nextpar1,pfin1,vfin1);
2650             Bon1 = ChFi3d_mkbound(S1,PC1,-1,pdeb1,vdeb1,1,
2651                                   pfin1,vfin1,tolesp,2.e-4);
2652           }
2653         }
2654         else{
2655           //here the base is on 3D tangents of neighbors.
2656           const Handle(Geom_Curve)& c3dprev1 = 
2657             DStr.Curve(previntf1.LineIndex()).Curve();
2658           const Handle(Geom_Curve)& c3dnext1 = 
2659             DStr.Curve(nextintf1.LineIndex()).Curve();
2660           gp_Pnt Pdeb1, Pfin1;
2661           gp_Vec Vdeb1, Vfin1;
2662           c3dprev1->D1(prevpar1,Pdeb1,Vdeb1);
2663           c3dnext1->D1(nextpar1,Pfin1,Vfin1);
2664           gp_Pnt2d pdeb1,pfin1;
2665           Standard_Real pardeb1 = intf1.FirstParameter();
2666           Standard_Real parfin1 = intf1.LastParameter();
2667           pdeb1 = PC1->Value(pardeb1);
2668           pfin1 = PC1->Value(parfin1);
2669           Bon1 = ChFi3d_mkbound(S1,PC1,-1,pdeb1,Vdeb1,1,
2670                                 pfin1,Vfin1,tolesp,2.e-4);
2671         }
2672       }
2673       else{
2674         Bon1 = ChFi3d_mkbound(S1,PC1,tolesp,2.e-4);
2675       }
2676       if(tw2){
2677         if(!yaprevon2 || !yanexton2){
2678           Standard_Failure::Raise
2679             ("adjustment by reprocessing the non-written points: no neighbor");
2680         }
2681         ChFiDS_FaceInterference& previntf2 = prevsd->ChangeInterferenceOnS2();
2682         ChFiDS_FaceInterference& nextintf2 = nextsd->ChangeInterferenceOnS2();
2683         Standard_Real prevpar2 = previntf2.LastParameter();
2684         Standard_Real nextpar2 = nextintf2.FirstParameter();
2685         if(samesurfon2){
2686           // It is checked if it is possible to intersect traces of neighbors
2687           // to create a sharp end.
2688           Handle(Geom2d_Curve) pcprev2 = previntf2.PCurveOnFace();
2689           Handle(Geom2d_Curve) pcnext2 = nextintf2.PCurveOnFace();
2690           Standard_Real nprevpar2,nnextpar2;
2691           gp_Pnt2d p2d;
2692 //  Modified by Sergey KHROMOV - Wed Feb  5 12:03:17 2003 Begin
2693 //        if(ChFi3d_IntTraces(prevsd,prevpar2,nprevpar2,2,1,
2694 //                            nextsd,nextpar2,nnextpar2,2,-1,p2d)){
2695           if(ChFi3d_IntTraces(prevsd,prevpar2,nprevpar2,2,1,
2696                               nextsd,nextpar2,nnextpar2,2,-1,p2d,
2697                               Standard_False, Standard_True)){
2698 //  Modified by Sergey KHROMOV - Wed Feb  5 12:03:17 2003 End
2699             previntf2.SetLastParameter(nprevpar2);
2700             nextintf2.SetFirstParameter(nnextpar2);
2701             pointuon2 = 1;
2702             PC2.Nullify();
2703           }
2704           else{
2705             gp_Pnt2d pdeb2,pfin2;
2706             gp_Vec2d vdeb2,vfin2;
2707             pcprev2->D1(prevpar2,pdeb2,vdeb2);
2708             pcnext2->D1(nextpar2,pfin2,vfin2);
2709             Bon2 = ChFi3d_mkbound(S2,PC2,-1,pdeb2,vdeb2,1,
2710                                   pfin2,vfin2,tolesp,2.e-4);
2711           }
2712         }
2713         else{
2714          //here the base is on 3D tangents of neighbors.
2715           const Handle(Geom_Curve)& c3dprev2 = 
2716             DStr.Curve(previntf2.LineIndex()).Curve();
2717           const Handle(Geom_Curve)& c3dnext2 = 
2718             DStr.Curve(nextintf2.LineIndex()).Curve();
2719           gp_Pnt Pdeb2, Pfin2;
2720           gp_Vec Vdeb2, Vfin2;
2721           c3dprev2->D1(prevpar2,Pdeb2,Vdeb2);
2722           c3dnext2->D1(nextpar2,Pfin2,Vfin2);
2723           gp_Pnt2d pdeb2,pfin2;
2724           Standard_Real pardeb2 = intf2.FirstParameter();
2725           Standard_Real parfin2 = intf2.LastParameter();
2726           pdeb2 = PC2->Value(pardeb2);
2727           pfin2 = PC2->Value(parfin2);
2728           Bon2 = ChFi3d_mkbound(S2,PC2,-1,pdeb2,Vdeb2,1,
2729                                 pfin2,Vfin2,tolesp,2.e-4);
2730         }
2731       }
2732       else{
2733         Bon2 = ChFi3d_mkbound(S2,PC2,tolesp,2.e-4);
2734       }
2735       // The parameters of neighbor traces are updated, so 
2736       // straight lines uv are pulled.
2737       const Handle(Geom_Surface)& 
2738         sprev = DStr.Surface(prevsd->Surf()).Surface();
2739       const Handle(Geom_Surface)& 
2740         snext = DStr.Surface(nextsd->Surf()).Surface();
2741       ChFiDS_FaceInterference& previntf1 = prevsd->ChangeInterferenceOnS1();
2742       ChFiDS_FaceInterference& nextintf1 = nextsd->ChangeInterferenceOnS1();
2743       ChFiDS_FaceInterference& previntf2 = prevsd->ChangeInterferenceOnS2();
2744       ChFiDS_FaceInterference& nextintf2 = nextsd->ChangeInterferenceOnS2();
2745       Handle(Geom2d_Curve) pcsprev1 = previntf1.PCurveOnSurf();
2746       Handle(Geom2d_Curve) pcsnext1 = nextintf1.PCurveOnSurf();
2747       Standard_Real prevpar1 = previntf1.LastParameter();
2748       Standard_Real nextpar1 = nextintf1.FirstParameter();
2749       Handle(Geom2d_Curve) pcsprev2 = previntf2.PCurveOnSurf();
2750       Handle(Geom2d_Curve) pcsnext2 = nextintf2.PCurveOnSurf();
2751       Standard_Real prevpar2 = previntf2.LastParameter();
2752       Standard_Real nextpar2 = nextintf2.FirstParameter();
2753       gp_Pnt2d pdebs1 = pcsprev1->Value(prevpar1);
2754       gp_Pnt2d pdebs2 = pcsprev2->Value(prevpar2);
2755       gp_Pnt2d pfins1 = pcsnext1->Value(nextpar1);
2756       gp_Pnt2d pfins2 = pcsnext2->Value(nextpar2);
2757       Bdeb = ChFi3d_mkbound(sprev,pdebs1,pdebs2,tolesp,2.e-4);
2758       Bfin = ChFi3d_mkbound(snext,pfins1,pfins2,tolesp,2.e-4);
2759
2760       GeomFill_ConstrainedFilling fil(11,20);
2761       if(pointuon1) fil.Init(Bon2,Bfin,Bdeb,1);
2762       else if(pointuon2) fil.Init(Bon1,Bfin,Bdeb,1);
2763       else fil.Init(Bon1,Bfin,Bon2,Bdeb,1);
2764       
2765       ChFi3d_ReparamPcurv(0.,1.,PC1);
2766       ChFi3d_ReparamPcurv(0.,1.,PC2);
2767       Handle(Geom_Surface) newsurf = fil.Surface();
2768 #ifdef OCCT_DEBUG
2769 #ifdef DRAW
2770       //POP for NT
2771       char* pops = "newsurf";
2772       DrawTrSurf::Set(pops,newsurf);
2773 #endif
2774 #endif
2775       if(pointuon1) {
2776         newsurf->VReverse(); // we return to direction 1 from  2;
2777         done = CompleteData(cursd,newsurf,S1,PC1,S2,PC2,
2778                             F2.Orientation(),0,0,0,0,0);
2779         cursd->ChangeIndexOfS1(0);
2780       }
2781       else{
2782         done = CompleteData(cursd,newsurf,S1,PC1,S2,PC2,
2783                             F1.Orientation(),1,0,0,0,0);
2784         if(pointuon2) cursd->ChangeIndexOfS2(0);
2785       }
2786       if(tw1){
2787         prevsd->ChangeVertexLastOnS1().SetPoint(cpd1.Point());
2788         nextsd->ChangeVertexFirstOnS1().SetPoint(cpf1.Point());
2789       }
2790       if(tw2){
2791         prevsd->ChangeVertexLastOnS2().SetPoint(cpd2.Point());
2792         nextsd->ChangeVertexFirstOnS2().SetPoint(cpf2.Point());
2793       }
2794     }
2795     // The tolerance of points is updated.
2796     for(i = 1; i < last; i++){
2797       Standard_Integer j = i%len + 1;
2798       Standard_Integer curs1, curs2;
2799       Standard_Integer nexts1, nexts2;
2800       Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i);
2801       Handle(ChFiDS_SurfData)& nextsd = SeqSurf.ChangeValue(j);
2802       ChFiDS_CommonPoint& curp1 = cursd->ChangeVertexLastOnS1();
2803       ChFiDS_CommonPoint& nextp1 = nextsd->ChangeVertexFirstOnS1();
2804       if (cursd->IsOnCurve1()) curs1 = cursd->IndexOfC1();
2805       else                     curs1 = cursd->IndexOfS1();
2806       if (cursd->IsOnCurve2()) curs2 = cursd->IndexOfC2();
2807       else                     curs2 = cursd->IndexOfS2();
2808       Standard_Real tol1 = Max(curp1.Tolerance(),nextp1.Tolerance());
2809       ChFiDS_CommonPoint& curp2 = cursd->ChangeVertexLastOnS2();
2810       ChFiDS_CommonPoint& nextp2 = nextsd->ChangeVertexFirstOnS2();
2811       Standard_Real tol2 = Max(curp2.Tolerance(),nextp2.Tolerance());
2812       if (nextsd->IsOnCurve1()) nexts1 = nextsd->IndexOfC1();
2813       else                     nexts1 = nextsd->IndexOfS1();
2814       if (nextsd->IsOnCurve2()) nexts2 = nextsd->IndexOfC2();
2815       else                     nexts2 = nextsd->IndexOfS2();
2816
2817       if(!curp1.IsOnArc() && nextp1.IsOnArc()){ 
2818         curp1 = nextp1;
2819         if ( (curs1 == nexts1) && !nextsd->IsOnCurve1()) 
2820           // Case when it is not possible to pass along the border without leaving
2821           ChangeTransition(nextp1, curp1, nexts1, myDS);
2822       }
2823       else if(curp1.IsOnArc() && !nextp1.IsOnArc()) { 
2824         nextp1 = curp1;
2825         if ( (curs1 == nexts1) && !cursd->IsOnCurve1())
2826           ChangeTransition(curp1, nextp1, curs1, myDS);
2827       }
2828         
2829       if(!curp2.IsOnArc() && nextp2.IsOnArc()) {
2830         curp2 = nextp2;
2831         if ( (curs2 == nexts2) && !nextsd->IsOnCurve2()) 
2832           ChangeTransition(nextp2, curp2, curs2, myDS);
2833       }
2834       else if(curp2.IsOnArc() && !nextp2.IsOnArc()){
2835         nextp2 = curp2;
2836         if ( (curs2 == nexts2) && !cursd->IsOnCurve2()) 
2837           ChangeTransition(curp2, nextp2, curs2, myDS);
2838       }
2839
2840       curp1.SetTolerance(tol1); nextp1.SetTolerance(tol1); 
2841       curp2.SetTolerance(tol2); nextp2.SetTolerance(tol2); 
2842       
2843       Bnd_Box b1,b2;
2844       if(curp1.IsOnArc()){
2845         ChFi3d_EnlargeBox(curp1.Arc(),myEFMap(curp1.Arc()),curp1.ParameterOnArc(),b1);
2846       }
2847       if(curp2.IsOnArc()){
2848         ChFi3d_EnlargeBox(curp2.Arc(),myEFMap(curp2.Arc()),curp2.ParameterOnArc(),b2);
2849       }
2850       Handle(ChFiDS_Stripe) bidst;
2851       ChFi3d_EnlargeBox(DStr,bidst,cursd,b1,b2,0);
2852       ChFi3d_EnlargeBox(DStr,bidst,nextsd,b1,b2,1);
2853       tol1 = ChFi3d_BoxDiag(b1);
2854       tol2 = ChFi3d_BoxDiag(b2);
2855       curp1.SetTolerance(tol1); nextp1.SetTolerance(tol1); 
2856       curp2.SetTolerance(tol2); nextp2.SetTolerance(tol2); 
2857     }
2858     // The connections edge/new faces are updated.
2859     for (ILES.Initialize(ll) ; ILES.More(); ILES.Next()) {
2860       const Handle(ChFiDS_HElSpine)& curhels = ILES.Value();
2861       const ChFiDS_ElSpine& curels = curhels->ChangeCurve();
2862       Standard_Real WF = curels.FirstParameter();
2863       Standard_Real WL = curels.LastParameter();
2864       Standard_Integer IF,IL;
2865       Standard_Real nwf = WF, nwl = WL;
2866       Standard_Real period = 0.;
2867       Standard_Integer nbed = Spine->NbEdges();
2868       if(periodic){
2869         period = Spine->Period();
2870         nwf = ElCLib::InPeriod(WF,-tolesp,period-tolesp);
2871         IF = Spine->Index(nwf,1);
2872         nwl = ElCLib::InPeriod(WL,tolesp,period+tolesp);
2873         IL = Spine->Index(nwl,0);
2874         if(nwl<nwf+tolesp) IL += nbed;
2875       }
2876       else{
2877         IF = Spine->Index(WF,1);
2878         IL = Spine->Index(WL,0);
2879       }
2880       if(IF == IL) {
2881         //fast processing
2882         Standard_Integer IFloc = IF;
2883         if(periodic) IFloc = (IF - 1)%nbed + 1;
2884         const TopoDS_Edge& Ej = Spine->Edges(IFloc);
2885         for(i = 1; i <= len; i++){
2886           Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i);
2887           Standard_Real fp = cursd->FirstSpineParam();
2888           Standard_Real lp = cursd->LastSpineParam();
2889           if(lp < WF+tolesp || fp > WL-tolesp) continue;
2890           if(!myEVIMap.IsBound(Ej)) {
2891             TColStd_ListOfInteger li;
2892             myEVIMap.Bind(Ej,li);
2893           }
2894           myEVIMap.ChangeFind(Ej).Append(cursd->Surf());
2895         }
2896       }
2897       else if(IF < IL){
2898         TColStd_Array1OfReal wv(IF,IL - 1);
2899 #ifdef OCCT_DEBUG
2900         cout<<"length of the trajectory : "<<(WL-WF)<<endl;
2901 #endif
2902         for(i = IF; i < IL; i++){
2903           Standard_Integer iloc = i;
2904           if(periodic) iloc = (i - 1)%nbed + 1;
2905           Standard_Real wi = Spine->LastParameter(iloc);
2906           if(periodic) wi = ElCLib::InPeriod(wi,WF,WF+period);
2907           gp_Pnt pv = Spine->Value(wi);
2908 #ifdef OCCT_DEBUG
2909           gp_Pnt pelsapp = curels.Value(wi);
2910           Standard_Real distinit = pv.Distance(pelsapp);
2911           cout<<"distance psp/papp : "<<distinit<<endl;
2912 #endif
2913           Extrema_LocateExtPC ext(pv,curels,wi,1.e-8);
2914           wv(i) = wi;
2915           if(ext.IsDone()){
2916             wv(i) = ext.Point().Parameter(); 
2917           }
2918           else {
2919 #ifdef OCCT_DEBUG
2920             cout<<"fail of projection vertex ElSpine!!!"<<endl;
2921 #endif
2922           }
2923         }
2924         for(i = 1; i <= len; i++){
2925           Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i);
2926           Standard_Real fp = cursd->FirstSpineParam();
2927           Standard_Real lp = cursd->LastSpineParam();
2928           Standard_Integer j;
2929           Standard_Integer jf = 0, jl = 0;
2930           if(lp < WF+tolesp || fp > WL-tolesp) continue;
2931           for(j = IF; j < IL; j++){
2932             jf = j;
2933             if(fp < wv(j) - tolesp) break;
2934           }
2935           for(j = IF; j < IL; j++){
2936             jl = j;
2937             if(lp < wv(j) + tolesp) break;
2938           }
2939           for(j = jf; j <= jl; j++){
2940             Standard_Integer jloc = j;
2941             if(periodic) jloc = (j - 1)%nbed + 1;
2942             const TopoDS_Edge& Ej = Spine->Edges(jloc);
2943             if(!myEVIMap.IsBound(Ej)) {
2944               TColStd_ListOfInteger li;
2945               myEVIMap.Bind(Ej,li);
2946             }
2947             myEVIMap.ChangeFind(Ej).Append(cursd->Surf());
2948           }
2949         }
2950       }
2951     }
2952   }
2953 }
2954
2955 //=======================================================================
2956 //function : PerformSetOfSurf
2957 //purpose  : 
2958 //=======================================================================
2959
2960 void ChFi3d_Builder::PerformSetOfSurf(Handle(ChFiDS_Stripe)& Stripe,
2961                                       const Standard_Boolean Simul) 
2962 {
2963   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
2964   
2965 #ifdef OCCT_DEBUG
2966   OSD_Chronometer ch;
2967   ChFi3d_InitChron(ch);// init perf for PerformSetOfKPart
2968 #endif
2969   
2970   const Handle(ChFiDS_Spine)& sp = Stripe->Spine();
2971   Standard_Integer SI = ChFi3d_SolidIndex(sp,DStr,myESoMap,myEShMap);
2972   Stripe->SetSolidIndex(SI);
2973   if(!sp->SplitDone()) PerformSetOfKPart(Stripe,Simul);
2974   
2975 #ifdef OCCT_DEBUG
2976   ChFi3d_ResultChron(ch ,t_perfsetofkpart); // result perf PerformSetOfKPart(
2977   ChFi3d_InitChron(ch); // init perf for  PerformSetOfKGen
2978 #endif
2979   
2980   PerformSetOfKGen(Stripe,Simul);
2981   
2982 #ifdef OCCT_DEBUG
2983   ChFi3d_ResultChron(ch, t_perfsetofkgen);//result perf PerformSetOfKGen 
2984   ChFi3d_InitChron(ch); // init perf for ChFi3d_MakeExtremities
2985 #endif
2986   
2987   if(!Simul) ChFi3d_MakeExtremities(Stripe,DStr,myEFMap,tolesp,tol2d);
2988   
2989 #ifdef OCCT_DEBUG
2990   ChFi3d_ResultChron(ch, t_makextremities); // result perf t_makextremities
2991 #endif
2992 }