0026937: Eliminate NO_CXX_EXCEPTION macro support
[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   throw Standard_Failure("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   throw Standard_Failure("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       throw Standard_Failure("StartSol : chain is not possible, new obstacle not found");
1168     }
1169     if(IsG1(myEFMap,newedge,Fref,Fv)){
1170       throw Standard_Failure("StartSol : chain is not possible, config non processed");
1171     }
1172     else if(Fv.IsNull()){
1173       throw Standard_Failure("StartSol : chain is not possible, new obstacle not found");
1174     }
1175     else{
1176       HS->ChangeSurface().Initialize(Fv);
1177       W = BRep_Tool::Parameter(VCP,newedge);
1178       HCref->ChangeCurve2d().Initialize(newedge,Fref);
1179       TopoDS_Face newface = Fv;
1180       newface.Orientation(TopAbs_FORWARD);
1181       TopExp_Explorer ex;
1182       for(ex.Init(newface,TopAbs_EDGE); ex.More(); ex.Next()){
1183         if(ex.Current().IsSame(newedge)){
1184           newedge = TopoDS::Edge(ex.Current());
1185           break;
1186         }
1187       }
1188       HC->ChangeCurve2d().Initialize(newedge,Fv);
1189       pons = HC->Value(W);
1190     }
1191     RecP = c1obstacle = 1;
1192     return 1;
1193   } // End of Case Vertex && Obstacle 
1194
1195   else if (CP.IsOnArc() && !HC.IsNull() && !decroch){
1196     //Nothing is changed, the parameter is only updated.
1197     W = CP.ParameterOnArc();
1198     c1obstacle = 1;
1199     return 1;
1200   }
1201   
1202   HC.Nullify();
1203   
1204   if (CP.IsOnArc()){
1205     const TopoDS_Edge& E = CP.Arc();
1206     if(decroch){
1207       HS->ChangeSurface().Initialize(Fref);
1208       W = CP.ParameterOnArc();
1209       pc = BRep_Tool::CurveOnSurface(E,Fref,Uf,Ul);
1210       pons = pc->Value(W);
1211       RecS = 1;
1212       return 1;
1213     }
1214     if (SearchFace(Spine,CP,F,Fv)){
1215       HS->ChangeSurface().Initialize(Fv);
1216       RecS = 1;
1217       if (CP.IsVertex()) { 
1218         // One goes directly by the Vertex
1219         Standard_Integer Nb;
1220         TopoDS_Face aux;
1221         // And it is checked that there are no other candidates
1222         Nb = SearchFaceOnV(CP, F, myVEMap, myEFMap, Fv, aux);
1223
1224         pons = BRep_Tool::Parameters(CP.Vertex(), Fv);
1225         HS->ChangeSurface().Initialize(Fv);
1226         if (Nb >=2) {
1227           HSBis = new (BRepAdaptor_HSurface)(aux);
1228           PBis = BRep_Tool::Parameters(CP.Vertex(), aux);
1229         }
1230         return 1;
1231       }
1232       // otherwise one passes by the arc...
1233       if(!Fv.IsSame(F)){
1234         Fv.Orientation(TopAbs_FORWARD);
1235         TopoDS_Edge newedge;
1236         TopExp_Explorer ex;
1237         for(ex.Init(Fv,TopAbs_EDGE); ex.More(); ex.Next()){
1238           if(ex.Current().IsSame(E)){
1239             newedge = TopoDS::Edge(ex.Current());
1240             break;
1241           }
1242         }
1243         //gp_Vec Varc, VSurf;
1244         // In cas of Tangent output, the current face becomes the support face
1245         if (SortieTangente(CP, F, SD, ons, 0.1)) { 
1246           pc = BRep_Tool::CurveOnSurface(CP.Arc(),F,Uf,Ul);
1247           HSBis = new (BRepAdaptor_HSurface)(F);
1248           PBis = pc->Value(CP.ParameterOnArc());
1249         }
1250         
1251
1252         pc = BRep_Tool::CurveOnSurface(newedge,Fv,Uf,Ul);
1253       }
1254       else{
1255         TopoDS_Edge newedge = E;
1256         newedge.Reverse();
1257         Fv.Orientation(TopAbs_FORWARD);
1258         pc = BRep_Tool::CurveOnSurface(newedge,Fv,Uf,Ul);
1259       }
1260       pons = pc->Value(CP.ParameterOnArc());
1261       return 1;
1262     }
1263     else if(!Fv.IsNull()){    
1264       c1obstacle = 1;
1265       if(!Vref.IsNull()){
1266         TopExp_Explorer ex;
1267         for(ex.Init(E,TopAbs_VERTEX); ex.More(); ex.Next()){
1268           if(ex.Current().IsSame(Vref)){
1269             c1obstacle = 0;
1270             break;
1271           }
1272         }
1273       }
1274       if(c1obstacle){
1275         HS->ChangeSurface().Initialize(Fv);
1276         HSref->ChangeSurface().Initialize(F);
1277         W = CP.ParameterOnArc();
1278         HC = new BRepAdaptor_HCurve2d();
1279         TopoDS_Edge newedge;
1280         TopoDS_Face newface = Fv;
1281         newface.Orientation(TopAbs_FORWARD);
1282         TopExp_Explorer ex;
1283         for(ex.Init(newface,TopAbs_EDGE); ex.More(); ex.Next()){
1284           if(ex.Current().IsSame(E)){
1285             newedge = TopoDS::Edge(ex.Current());
1286             break;
1287           }
1288         }
1289         HC->ChangeCurve2d().Initialize(newedge,Fv);
1290         pons = HC->Value(W);
1291         HCref->ChangeCurve2d().Initialize(E,F);
1292         if(CP.IsVertex()) RecP = 1;
1293         else RecRst = 1;
1294         return 1;
1295       }
1296       else{
1297         HS->ChangeSurface().Initialize(F);
1298         W = CP.ParameterOnArc();
1299         pc = BRep_Tool::CurveOnSurface(E,F,Uf,Ul);
1300         pons = pc->Value(W);
1301         return Standard_False;
1302       }
1303     }
1304     else{ // there is no neighbor face, the state is preserved and False is returned.
1305       HS->ChangeSurface().Initialize(F);
1306       W = CP.ParameterOnArc();
1307       pc = BRep_Tool::CurveOnSurface(E,F,Uf,Ul);
1308       pons = pc->Value(W);
1309       return Standard_False;
1310     }
1311   }
1312   else{
1313     HS->ChangeSurface().Initialize(F);
1314     const ChFiDS_FaceInterference& FI = SD->Interference(ons);
1315     if(FI.PCurveOnFace().IsNull()) pons = SD->Get2dPoints(isfirst,ons);
1316     else pons = FI.PCurveOnFace()->Value(FI.Parameter(isfirst));
1317   }
1318   return Standard_True;
1319 }
1320
1321 //=======================================================================
1322 //function : SearchFace
1323 //purpose  : 
1324 //=======================================================================
1325
1326 Standard_Boolean  ChFi3d_Builder::SearchFace
1327                  (const Handle(ChFiDS_Spine)&  Spine,
1328                   const ChFiDS_CommonPoint&    Pc,
1329                   const TopoDS_Face&           FRef,
1330                   TopoDS_Face&                 FVoi) const
1331 {
1332   Standard_Boolean Trouve = Standard_False;
1333   if (! Pc.IsOnArc()) return Standard_False;
1334   FVoi.Nullify();
1335   TopoDS_Edge E;
1336   if (Pc.IsVertex()){
1337     // attention it is necessary to analyze all faces that turn around of the vertex
1338 #ifdef OCCT_DEBUG
1339     cout<<"Commonpoint on vertex, the process hangs up"<<endl;
1340 #endif
1341     if (Pc.HasVector()) { //General processing
1342       TopoDS_Face Fbis;
1343       Standard_Integer nb_faces;
1344       nb_faces = SearchFaceOnV(Pc,  FRef, myVEMap, myEFMap, FVoi, Fbis);
1345       return ( nb_faces > 0);
1346     }
1347     else { // Processing using the spine
1348       Standard_Boolean  FindFace=Standard_False;
1349       gp_Pnt Point;
1350       gp_Vec VecSpine;
1351       Spine->D1(Pc.Parameter(), Point, VecSpine);
1352     
1353       // It is checked if one leaves from the current face.
1354       FindFace = IsInput(VecSpine, Pc.Vertex(), FRef);
1355       if (FindFace) {
1356         VecSpine.Reverse();
1357         FindFace = IsInput(VecSpine, Pc.Vertex(), FRef);
1358       }
1359       // If one does not leave, it is ended
1360       if (FindFace) {
1361         FVoi = FRef;
1362         return Standard_True;
1363       }
1364     
1365       // Otherwise one finds the next among shared Faces 
1366       // by a common edge G1
1367       TopTools_ListIteratorOfListOfShape ItE, ItF;
1368       for(ItE.Initialize(myVEMap(Pc.Vertex()));
1369           ItE.More() && (!FindFace); ItE.Next()) {
1370         E = TopoDS::Edge(ItE.Value());
1371         Trouve=Standard_False;
1372         for(ItF.Initialize(myEFMap(E));//, Trouve=Standard_False;           15.11.99 SVV
1373             ItF.More()&&(!Trouve); ItF.Next()) {
1374           if (TopoDS::Face(ItF.Value()).IsSame(FRef)) {
1375             Trouve = Standard_True;
1376           }
1377         }
1378         if (Trouve) FindFace = IsG1(myEFMap, E, FRef, FVoi);
1379         if (FindFace) { 
1380           FindFace = Standard_False;
1381           if (Spine.IsNull()) {
1382             //La Spine peut etre nulle (ThreeCorner)
1383 #ifdef OCCT_DEBUG
1384             cout << "FindFace sur vertex avec spine nulle! QUEZAKO ?" << endl;
1385 #endif
1386             return Standard_False;
1387           }
1388         
1389           // It is checked if the selected face actually possesses edges of the spine
1390           // containing the vertex on its front
1391           // This processing should go only if the Vertex belongs to the spine
1392           // This is a single case, for other vertexes it is required to do other things
1393           Trouve=Standard_False;
1394           for (Standard_Integer IE=1;//, Trouve=Standard_False;                   15.11.99  SVV
1395                (IE<=Spine->NbEdges()) && (!Trouve); IE++) {
1396             E = Spine->Edges(IE);
1397             if (  (TopExp::FirstVertex(E).IsSame(Pc.Vertex())) 
1398                 ||(TopExp::LastVertex(E) .IsSame(Pc.Vertex())) ) {
1399               for(ItF.Initialize(myEFMap(E)), Trouve=Standard_False;
1400                   ItF.More()&&(!Trouve); ItF.Next()) {
1401                 if (TopoDS::Face(ItF.Value()).IsSame(FVoi)) {
1402                   Trouve = Standard_True;
1403                 }
1404               }
1405             }
1406           } 
1407           FindFace = Trouve;
1408         }
1409       }
1410     }
1411   }
1412   else {
1413     return IsG1(myEFMap, Pc.Arc(), FRef, FVoi);
1414   }
1415   return Standard_False;
1416 }
1417
1418
1419 //=======================================================================
1420 //function : ChFi3d_SingularExtremity
1421 //purpose  : load the vertex in the DS and calculate the pcurve 
1422 //           for an extremity in case of singular freeboundary 
1423 //           or periodic and singular at the cut.
1424 //=======================================================================
1425 static void ChFi3d_SingularExtremity( Handle(ChFiDS_Stripe)&     stripe,
1426                                      TopOpeBRepDS_DataStructure& DStr,
1427                                      const TopoDS_Vertex&        Vtx,      
1428                                      const Standard_Real         tol3d,
1429                                      const Standard_Real         tol2d)
1430 {
1431   Handle(ChFiDS_SurfData) Fd;
1432   Standard_Real tolreached;
1433   Standard_Real Pardeb, Parfin; 
1434   gp_Pnt2d VOnS1, VOnS2;
1435   Handle(Geom_Curve) C3d;
1436   Handle(Geom2d_Curve) PCurv;
1437   TopOpeBRepDS_Curve Crv;
1438   // SurfData and its CommonPoints,
1439   Standard_Integer Ivtx, Icurv;
1440   Standard_Boolean isfirst;
1441   
1442   if  (stripe->Spine()->IsPeriodic()) {
1443      isfirst = Standard_True;
1444      Fd = stripe->SetOfSurfData()->Sequence().First();
1445    }
1446   else {
1447     Standard_Integer sens;
1448     Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens);
1449     Fd =  stripe->SetOfSurfData()->Sequence().Value(num);
1450     isfirst = (sens == 1);
1451   }
1452  
1453   const ChFiDS_CommonPoint& CV1 = Fd->Vertex(isfirst,1);
1454   const ChFiDS_CommonPoint& CV2 = Fd->Vertex(isfirst,2);
1455   // Is it always degenerated ?
1456   if ( CV1.Point().IsEqual( CV2.Point(), 0) ) { 
1457     Ivtx = ChFi3d_IndexPointInDS(CV1, DStr);
1458     if (isfirst) {
1459       VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()->
1460                    Value(Fd->InterferenceOnS1().FirstParameter());
1461       VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()->
1462                      Value(Fd->InterferenceOnS2().FirstParameter());
1463     }
1464     else {
1465       VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()->
1466                     Value(Fd->InterferenceOnS1().LastParameter());
1467       VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()->
1468                     Value(Fd->InterferenceOnS2().LastParameter());
1469     }
1470       
1471     ChFi3d_ComputeArete(CV1, VOnS1,
1472                         CV2, VOnS2,
1473                         DStr.Surface(Fd->Surf()).Surface(),
1474                         C3d, PCurv,
1475                         Pardeb,Parfin, tol3d, tol2d, tolreached,0);
1476     Crv = TopOpeBRepDS_Curve(C3d,tolreached);
1477     Icurv = DStr.AddCurve(Crv);
1478
1479     stripe->SetCurve(Icurv, isfirst);
1480     stripe->SetParameters(isfirst, Pardeb,Parfin);
1481     stripe->ChangePCurve(isfirst) = PCurv;
1482     stripe->SetIndexPoint(Ivtx, isfirst, 1);
1483     stripe->SetIndexPoint(Ivtx, isfirst, 2);
1484
1485     if (stripe->Spine()->IsPeriodic()) { 
1486       // periodic case : The operation is renewed
1487       // the curve 3d is not shared.
1488       // 2 degenerated edges coinciding in 3d
1489       isfirst = Standard_False;
1490       Fd = stripe->SetOfSurfData()->Sequence().Last();
1491       VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()->
1492               Value(Fd->InterferenceOnS1().LastParameter());
1493       VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()->
1494               Value(Fd->InterferenceOnS2().LastParameter());
1495
1496       ChFi3d_ComputeArete(CV1, VOnS1,
1497                           CV2, VOnS2,
1498                           DStr.Surface(Fd->Surf()).Surface(),
1499                           C3d, PCurv,
1500                           Pardeb,Parfin, tol3d, tol2d, tolreached,0);
1501       Crv = TopOpeBRepDS_Curve(C3d,tolreached);
1502       Icurv = DStr.AddCurve(Crv);
1503
1504       stripe->SetCurve(Icurv, isfirst);
1505       stripe->SetParameters(isfirst, Pardeb,Parfin);
1506       stripe->ChangePCurve(isfirst) = PCurv;
1507       stripe->SetIndexPoint(Ivtx, isfirst, 1);
1508       stripe->SetIndexPoint(Ivtx, isfirst, 2);    
1509     }
1510   }
1511 }
1512
1513 //=======================================================================
1514 //function : ChFi3d_MakeExtremities
1515 //purpose  : calculate Curves3d and pcurves of extremities in
1516 //           periodic and freeboundary cases.
1517 //=======================================================================
1518 static Standard_Boolean IsFree(const TopoDS_Shape& E,
1519                                const ChFiDS_Map&   EFMap)
1520 {
1521   if(!EFMap.Contains(E)) return 0;
1522   TopTools_ListIteratorOfListOfShape It;
1523   TopoDS_Shape Fref;
1524   for(It.Initialize(EFMap(E)); It.More(); It.Next()){
1525     if(Fref.IsNull()) Fref = It.Value();
1526     else if(!Fref.IsSame(It.Value())) return 0;
1527   }
1528   return 1;
1529 }
1530
1531 static void ChFi3d_MakeExtremities(Handle(ChFiDS_Stripe)&      Stripe,
1532                                    TopOpeBRepDS_DataStructure& DStr,
1533                                    const ChFiDS_Map&           EFMap,
1534                                    const Standard_Real         tol3d,
1535                                    const Standard_Real         tol2d)
1536 {
1537   Handle(ChFiDS_Spine)& sp = Stripe->ChangeSpine();
1538   Standard_Real Pardeb,Parfin;
1539   Handle(Geom_Curve) C3d;
1540   Standard_Real tolreached;
1541   if(sp->IsPeriodic()){
1542     Bnd_Box b1,b2;
1543     const Handle(ChFiDS_SurfData)& 
1544       SDF = Stripe->SetOfSurfData()->Sequence().First();
1545     const ChFiDS_CommonPoint& CV1 = SDF->VertexFirstOnS1();
1546     const ChFiDS_CommonPoint& CV2 = SDF->VertexFirstOnS2();
1547     if ( !CV1.Point().IsEqual(CV2.Point(), 0) ) { 
1548       ChFi3d_ComputeArete(CV1,
1549                           SDF->InterferenceOnS1().PCurveOnSurf()->
1550                           Value(SDF->InterferenceOnS1().FirstParameter()),
1551                           CV2,
1552                           SDF->InterferenceOnS2().PCurveOnSurf()-> 
1553                           Value(SDF->InterferenceOnS2().FirstParameter()),
1554                           DStr.Surface(SDF->Surf()).Surface(),C3d,
1555                           Stripe->ChangeFirstPCurve(),Pardeb,Parfin,
1556                           tol3d,tol2d,tolreached,0);
1557       TopOpeBRepDS_Curve Crv(C3d,tolreached);
1558       Stripe->ChangeFirstCurve(DStr.AddCurve(Crv));
1559       Stripe->ChangeFirstParameters(Pardeb,Parfin);
1560       Stripe->ChangeIndexFirstPointOnS1
1561         (ChFi3d_IndexPointInDS(SDF->VertexFirstOnS1(),DStr));
1562       Stripe->ChangeIndexFirstPointOnS2
1563         (ChFi3d_IndexPointInDS(SDF->VertexFirstOnS2(),DStr));
1564       Standard_Integer ICurv = Stripe->FirstCurve();
1565       Stripe->ChangeLastParameters(Pardeb,Parfin);
1566       Stripe->ChangeLastCurve(ICurv);
1567       Stripe->ChangeIndexLastPointOnS1(Stripe->IndexFirstPointOnS1());
1568       Stripe->ChangeIndexLastPointOnS2(Stripe->IndexFirstPointOnS2());
1569       
1570       const Handle(ChFiDS_SurfData)& 
1571         SDL = Stripe->SetOfSurfData()->Sequence().Last();
1572       
1573       
1574       ChFi3d_ComputePCurv(C3d,
1575                           SDL->InterferenceOnS1().PCurveOnSurf()->
1576                           Value(SDL->InterferenceOnS1().LastParameter()),
1577                           SDL->InterferenceOnS2().PCurveOnSurf()->
1578                           Value(SDL->InterferenceOnS2().LastParameter()),
1579                           Stripe->ChangeLastPCurve(),
1580                           DStr.Surface(SDL->Surf()).Surface(),
1581                           Pardeb,Parfin,tol3d,tolreached);
1582       Standard_Real oldtol = DStr.ChangeCurve(ICurv).Tolerance();
1583       DStr.ChangeCurve(ICurv).Tolerance(Max(oldtol,tolreached));
1584       if(CV1.IsOnArc()){
1585         ChFi3d_EnlargeBox(CV1.Arc(),EFMap(CV1.Arc()),CV1.ParameterOnArc(),b1);
1586       }
1587       
1588       if(CV2.IsOnArc()){
1589         ChFi3d_EnlargeBox(CV2.Arc(),EFMap(CV2.Arc()),CV2.ParameterOnArc(),b2);
1590       }
1591       ChFi3d_EnlargeBox(DStr,Stripe,SDF,b1,b2,1);
1592       ChFi3d_EnlargeBox(DStr,Stripe,SDL,b1,b2,0);
1593       if (!CV1.IsVertex())
1594         ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexFirstPointOnS1());
1595       if (!CV2.IsVertex())
1596         ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexFirstPointOnS2());
1597     }
1598     else {
1599       // Case of the single extremity
1600       if (CV1.IsVertex()) { 
1601         ChFi3d_SingularExtremity(Stripe, DStr, CV1.Vertex(), tol3d, tol2d);
1602       }
1603 # if CHFI3D_DEB
1604       else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; }
1605 # endif
1606     }
1607     return;
1608   }  
1609   
1610   const Handle(ChFiDS_SurfData)& 
1611     SDdeb = Stripe->SetOfSurfData()->Sequence().First();
1612     
1613   const ChFiDS_CommonPoint& cpdeb1 = SDdeb->VertexFirstOnS1();
1614   const ChFiDS_CommonPoint& cpdeb2 = SDdeb->VertexFirstOnS2();
1615   Standard_Boolean freedeb = sp->FirstStatus() == ChFiDS_FreeBoundary;
1616   if(!freedeb && cpdeb1.IsOnArc() && cpdeb2.IsOnArc()){
1617     freedeb = (IsFree(cpdeb1.Arc(),EFMap) && IsFree(cpdeb2.Arc(),EFMap));
1618   }
1619   if(freedeb){
1620     sp->SetFirstStatus(ChFiDS_FreeBoundary);
1621     Bnd_Box b1,b2;
1622     if ( !cpdeb1.Point().IsEqual(cpdeb2.Point(), 0) ) { 
1623       Standard_Boolean plane;  
1624       gp_Pnt2d UV1,UV2;
1625       UV1=SDdeb->InterferenceOnS1().PCurveOnSurf()->
1626                           Value(SDdeb->InterferenceOnS1().FirstParameter());     
1627       UV2=SDdeb->InterferenceOnS2().PCurveOnSurf()->
1628                           Value(SDdeb->InterferenceOnS2().FirstParameter());
1629 // The intersection of the fillet by a plane is attempted
1630
1631       Handle(GeomAdaptor_HSurface) HConge=ChFi3d_BoundSurf(DStr,SDdeb,1,2);
1632       ChFi3d_CoupeParPlan(cpdeb1,cpdeb2,HConge,UV1,UV2,
1633                           tol3d,tol2d,C3d,Stripe->ChangeFirstPCurve(),tolreached,
1634                           Pardeb,Parfin,plane);  
1635       if (!plane) 
1636       ChFi3d_ComputeArete(cpdeb1,
1637                           SDdeb->InterferenceOnS1().PCurveOnSurf()->
1638                           Value(SDdeb->InterferenceOnS1().FirstParameter()),
1639                           cpdeb2,
1640                           SDdeb->InterferenceOnS2().PCurveOnSurf()-> 
1641                           Value(SDdeb->InterferenceOnS2().FirstParameter()),
1642                           DStr.Surface(SDdeb->Surf()).Surface(),C3d,
1643                           Stripe->ChangeFirstPCurve(),Pardeb,Parfin,
1644                           tol3d,tol2d,tolreached,0);
1645       TopOpeBRepDS_Curve Crv(C3d,tolreached);
1646       Stripe->ChangeFirstCurve(DStr.AddCurve(Crv));
1647       Stripe->ChangeFirstParameters(Pardeb,Parfin);
1648       Stripe->ChangeIndexFirstPointOnS1
1649         (ChFi3d_IndexPointInDS(SDdeb->VertexFirstOnS1(),DStr));
1650       Stripe->ChangeIndexFirstPointOnS2
1651         (ChFi3d_IndexPointInDS(SDdeb->VertexFirstOnS2(),DStr));
1652       if(cpdeb1.IsOnArc()){
1653         ChFi3d_EnlargeBox(cpdeb1.Arc(),EFMap(cpdeb1.Arc()),cpdeb1.ParameterOnArc(),b1);
1654       }
1655       if(cpdeb2.IsOnArc()){
1656         ChFi3d_EnlargeBox(cpdeb2.Arc(),EFMap(cpdeb2.Arc()),cpdeb2.ParameterOnArc(),b2);
1657       }
1658       ChFi3d_EnlargeBox(DStr,Stripe,SDdeb,b1,b2,1);
1659       if (!cpdeb1.IsVertex())
1660         ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexFirstPointOnS1());
1661       if (!cpdeb2.IsVertex())
1662         ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexFirstPointOnS2());
1663     }
1664     else { // Case of a singular extremity
1665       if (cpdeb1.IsVertex()) { 
1666         ChFi3d_SingularExtremity(Stripe, DStr, cpdeb1.Vertex(), tol3d, tol2d);
1667       }
1668 # if CHFI3D_DEB
1669       else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; }
1670 # endif
1671     }
1672   }
1673   const Handle(ChFiDS_SurfData)& 
1674     SDfin = Stripe->SetOfSurfData()->Sequence().Last();
1675   const ChFiDS_CommonPoint& cpfin1 = SDfin->VertexLastOnS1();
1676   const ChFiDS_CommonPoint& cpfin2 = SDfin->VertexLastOnS2();
1677   Standard_Boolean freefin = sp->LastStatus() == ChFiDS_FreeBoundary;
1678   if(!freefin && cpfin1.IsOnArc() && cpfin2.IsOnArc()){
1679     freefin = (IsFree(cpfin1.Arc(),EFMap) && IsFree(cpfin2.Arc(),EFMap));
1680   }
1681   if(freefin){
1682     sp->SetLastStatus(ChFiDS_FreeBoundary);
1683     Bnd_Box b1,b2;
1684     if ( !cpfin1.Point().IsEqual(cpfin2.Point(), 0) ) { 
1685       Standard_Boolean plane;
1686       gp_Pnt2d UV1,UV2;
1687       UV1=SDfin->InterferenceOnS1().PCurveOnSurf()->
1688                           Value(SDfin->InterferenceOnS1().LastParameter());     
1689       UV2=SDfin->InterferenceOnS2().PCurveOnSurf()->
1690                           Value(SDfin->InterferenceOnS2().LastParameter());
1691 // Intersection of the fillet by a plane is attempted
1692
1693       Handle(GeomAdaptor_HSurface) HConge=ChFi3d_BoundSurf(DStr,SDfin,1,2);
1694       ChFi3d_CoupeParPlan(cpfin1,cpfin2,HConge,UV1,UV2,
1695                           tol3d,tol2d,C3d,Stripe->ChangeLastPCurve(),tolreached,
1696                           Pardeb,Parfin,plane);      
1697       if (!plane)   
1698       ChFi3d_ComputeArete(cpfin1,
1699                           SDfin->InterferenceOnS1().PCurveOnSurf()->
1700                           Value(SDfin->InterferenceOnS1().LastParameter()),
1701                           cpfin2,
1702                           SDfin->InterferenceOnS2().PCurveOnSurf()-> 
1703                           Value(SDfin->InterferenceOnS2().LastParameter()),
1704                           DStr.Surface(SDfin->Surf()).Surface(),C3d,
1705                           Stripe->ChangeLastPCurve(),Pardeb,Parfin,
1706                           tol3d,tol2d,tolreached,0);
1707       TopOpeBRepDS_Curve Crv(C3d,tolreached);
1708       Stripe->ChangeLastCurve(DStr.AddCurve(Crv));
1709       Stripe->ChangeLastParameters(Pardeb,Parfin);
1710       Stripe->ChangeIndexLastPointOnS1
1711         (ChFi3d_IndexPointInDS(SDfin->VertexLastOnS1(),DStr));
1712       Stripe->ChangeIndexLastPointOnS2
1713         (ChFi3d_IndexPointInDS(SDfin->VertexLastOnS2(),DStr));
1714       if(cpfin1.IsOnArc()){
1715         ChFi3d_EnlargeBox(cpfin1.Arc(),EFMap(cpfin1.Arc()),cpfin1.ParameterOnArc(),b1);
1716       }
1717       if(cpfin2.IsOnArc()){
1718         ChFi3d_EnlargeBox(cpfin2.Arc(),EFMap(cpfin2.Arc()),cpfin2.ParameterOnArc(),b2);
1719       }
1720       ChFi3d_EnlargeBox(DStr,Stripe,SDfin,b1,b2,0);
1721       if (!cpfin1.IsVertex())
1722         ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexLastPointOnS1());
1723       if (!cpfin2.IsVertex())
1724         ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexLastPointOnS2());
1725     }
1726     else { // Case of the single extremity
1727       if (cpfin1.IsVertex()) { 
1728         ChFi3d_SingularExtremity(Stripe, DStr, cpfin1.Vertex(), tol3d, tol2d);
1729       }
1730 # if CHFI3D_DEB
1731       else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; }
1732 # endif
1733     }
1734   }
1735 }
1736
1737 //=======================================================================
1738 //function : ChFi3d_Purge
1739 //purpose  : 
1740 //=======================================================================
1741
1742 static void ChFi3d_Purge (Handle(ChFiDS_Stripe)&    Stripe,
1743                           Handle(ChFiDS_SurfData)&  SD,
1744                           const ChFiDS_CommonPoint& VRef,
1745                           const Standard_Boolean    isfirst,
1746                           const Standard_Integer    ons,
1747                           Standard_Integer&         intf,
1748                           Standard_Integer&         intl)
1749 {
1750   if (isfirst) intf = 1; else intl = 1; // End.
1751   Standard_Integer opp = 3-ons;
1752   if (!SD->Vertex(isfirst,opp).IsOnArc() || 
1753       SD->TwistOnS1() || SD->TwistOnS2() ) {
1754 #ifdef OCCT_DEBUG
1755     cout<<"ChFi3d_Purge : No output on extension."<<endl;
1756 #endif
1757     ChFiDS_SequenceOfSurfData& Seq = 
1758       Stripe->ChangeSetOfSurfData()->ChangeSequence();
1759     if(isfirst) Seq.Remove(1);
1760     else Seq.Remove(Seq.Length());
1761     return;
1762   }
1763   if (ons == 1) SD->ChangeIndexOfS1(0);
1764   else          SD->ChangeIndexOfS2(0);
1765   
1766   SD->ChangeVertex(!isfirst,ons) = VRef;
1767   SD->ChangeVertex(isfirst,ons)  = VRef;
1768   
1769   ChFiDS_FaceInterference& fi = SD->ChangeInterference(ons);
1770   if(isfirst) fi.SetFirstParameter(fi.LastParameter());
1771   else fi.SetLastParameter(fi.FirstParameter());
1772   fi.SetLineIndex(0);
1773 }
1774
1775 //=======================================================================
1776 //function : InsertAfter
1777 //purpose  : insert Item after ref in Seq. If ref is null, the item is
1778 //           inserted at the beginning.
1779 //=======================================================================
1780
1781 static void InsertAfter (Handle(ChFiDS_Stripe)&   Stripe,
1782                          Handle(ChFiDS_SurfData)& Ref,
1783                          Handle(ChFiDS_SurfData)& Item)
1784 {
1785   if (Ref == Item) 
1786     throw Standard_Failure("InsertAfter : twice the same surfdata.");
1787   
1788   ChFiDS_SequenceOfSurfData& Seq = 
1789     Stripe->ChangeSetOfSurfData()->ChangeSequence();
1790   
1791   if (Seq.IsEmpty() || Ref.IsNull()) {
1792     Seq.Prepend(Item);
1793   }
1794   for (Standard_Integer i = 1; i <= Seq.Length(); i++) {
1795     if (Seq.Value(i) == Ref) {
1796       Seq.InsertAfter(i,Item);
1797       break;
1798     }
1799   }
1800 }
1801
1802 //=======================================================================
1803 //function : RemoveSD
1804 //purpose  : 
1805 //=======================================================================
1806
1807 static void RemoveSD (Handle(ChFiDS_Stripe)&   Stripe,
1808                       Handle(ChFiDS_SurfData)& Prev,
1809                       Handle(ChFiDS_SurfData)& Next)
1810 {
1811   ChFiDS_SequenceOfSurfData& Seq = 
1812     Stripe->ChangeSetOfSurfData()->ChangeSequence();
1813   if(Seq.IsEmpty()) return;
1814   Standard_Integer iprev = 0, inext = 0;
1815   for (Standard_Integer i = 1; i <= Seq.Length(); i++) {
1816     if (Seq.Value(i) == Prev) iprev = i + 1;
1817     if (Seq.Value(i) == Next) { inext = i - 1; break; }
1818   }
1819   if(Prev.IsNull()) iprev = 1;
1820   if(Next.IsNull()) inext = Seq.Length();
1821   if(iprev <= inext) Seq.Remove(iprev,inext);
1822 }
1823
1824 //=======================================================================
1825 //function : InsertBefore
1826 //purpose  : Insert item before ref in Seq. If ref is null, the item is
1827 //           inserted in the queue.
1828 //=======================================================================
1829
1830 static void InsertBefore (Handle(ChFiDS_Stripe)&   Stripe,
1831                           Handle(ChFiDS_SurfData)& Ref,
1832                           Handle(ChFiDS_SurfData)& Item)
1833 {
1834   if (Ref == Item) 
1835     throw Standard_Failure("InsertBefore : twice the same surfdata.");
1836   
1837   ChFiDS_SequenceOfSurfData& Seq = 
1838     Stripe->ChangeSetOfSurfData()->ChangeSequence();
1839   
1840   if (Seq.IsEmpty() || Ref.IsNull()) {
1841     Seq.Append(Item);
1842   }
1843   for (Standard_Integer i = 1; i <= Seq.Length(); i++) {
1844     if (Seq.Value(i) == Ref) {
1845       Seq.InsertBefore(i,Item);
1846       break;
1847     }
1848   }
1849 }
1850
1851
1852 //=======================================================================
1853 //function : PerformSetOfSurfOnElSpine
1854 //purpose  : 
1855 //=======================================================================
1856
1857 void ChFi3d_Builder::PerformSetOfSurfOnElSpine
1858 (const Handle(ChFiDS_HElSpine)&    HGuide,
1859  Handle(ChFiDS_Stripe)&            Stripe,
1860  Handle(BRepTopAdaptor_TopolTool)& It1,
1861  Handle(BRepTopAdaptor_TopolTool)& It2,
1862  const Standard_Boolean            Simul)
1863
1864 #ifdef OCCT_DEBUG
1865   OSD_Chronometer ch1;
1866 #endif 
1867   
1868   ChFiDS_ElSpine& Guide = HGuide->ChangeCurve();
1869   Standard_Real wf = Guide.FirstParameter();
1870   Standard_Real wl = Guide.LastParameter();
1871   Standard_Real locfleche = (wl - wf) * fleche;
1872   Standard_Real wfsav = wf, wlsav = wl;
1873   if (!Guide.IsPeriodic())
1874   {
1875     //Now the ElSpine is artificially extended to help rsnld.
1876     Standard_Real prab = 0.01;
1877     Guide.FirstParameter(wf-prab*(wl-wf));
1878     Guide.LastParameter (wl+prab*(wl-wf));
1879   }
1880   Handle(ChFiDS_Spine)&  Spine = Stripe->ChangeSpine();
1881   Standard_Integer ii, nbed = Spine->NbEdges();
1882   Standard_Real lastedlastp = Spine->LastParameter(nbed);
1883   
1884   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
1885   
1886   Handle(ChFiDS_SurfData) ref = Guide.Previous();
1887   Handle(ChFiDS_SurfData) refbis, SD;
1888   Handle(ChFiDS_SurfData) raf = Guide.Next();
1889   RemoveSD(Stripe,ref,raf);
1890   
1891   Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface();
1892   Handle(BRepAdaptor_HSurface) HS2 = new BRepAdaptor_HSurface();
1893   Handle(BRepAdaptor_HSurface) HS3, HS4;
1894   Handle(BRepAdaptor_HSurface) HSref1 = new BRepAdaptor_HSurface();
1895   Handle(BRepAdaptor_HSurface) HSref2 = new BRepAdaptor_HSurface();
1896   Handle(BRepAdaptor_HCurve2d) HC1,HC2;
1897   Handle(BRepAdaptor_HCurve2d) HCref1 = new BRepAdaptor_HCurve2d();
1898   Handle(BRepAdaptor_HCurve2d) HCref2 = new BRepAdaptor_HCurve2d();
1899   Standard_Boolean decroch1 = Standard_False, decroch2 = Standard_False;
1900   Standard_Boolean RecP1 = Standard_False, RecS1 = Standard_False, RecRst1 = Standard_False, obstacleon1 = Standard_False;
1901   Standard_Boolean RecP2 = Standard_False, RecS2 = Standard_False, RecRst2 = Standard_False, obstacleon2 = Standard_False;
1902   gp_Pnt2d pp1,pp2,pp3,pp4;
1903   Standard_Real w1 = 0.,w2 = 0.;
1904   math_Vector Soldep(1,4);
1905   math_Vector SoldepCS(1,3);
1906   math_Vector SoldepCC(1,2);
1907   
1908   // Restore a neighboring KPart.
1909   // If no neighbor calculation start point. 
1910   Standard_Boolean forward = Standard_True;
1911   Standard_Boolean Inside  = Standard_False;
1912   Standard_Real    First   = wf;
1913   Standard_Real    Last    = wl;
1914   Standard_Boolean Ok1 = 1,Ok2 = 1;
1915   // Restore the next KPart if it exists
1916   TopoDS_Vertex Vref;
1917   if(ref.IsNull() && raf.IsNull()){
1918     //sinon solution approchee.
1919     Inside = Standard_True;
1920     
1921 #ifdef OCCT_DEBUG
1922     ChFi3d_InitChron(ch1);// init perf for StartSol 
1923 #endif
1924     
1925     StartSol(Stripe,HGuide,HS1,HS2,It1,It2,pp1,pp2,First);
1926     
1927 #ifdef OCCT_DEBUG
1928     ChFi3d_ResultChron(ch1,t_startsol); // result perf for StartSol  
1929 #endif 
1930     
1931     Last = wf;
1932     if(Guide.IsPeriodic()) {
1933       Last = First - Guide.Period();
1934       Guide.SaveFirstParameter();
1935       Guide.FirstParameter(Last);
1936       Guide.SaveLastParameter();
1937       Guide.LastParameter (First * 1.1);//Extension to help rsnld.
1938     }
1939   }
1940   else{
1941     if(!Spine->IsPeriodic() && (wl - lastedlastp > -tolesp)){ 
1942       Vref = Spine->LastVertex(); 
1943     }
1944     if (ref.IsNull()) {
1945       if(!Spine->IsPeriodic() && (wf < tolesp)){ 
1946         Vref = Spine->FirstVertex(); 
1947       }
1948       ref = raf;
1949       forward = Standard_False;
1950       First = wl; Last = Guide.FirstParameter();
1951     }
1952     
1953 #ifdef OCCT_DEBUG
1954     ChFi3d_InitChron(ch1);// init perf for startsol 
1955 #endif
1956     
1957     
1958     Ok1 = StartSol(Spine,HS1,pp1,HC1,w1,ref,!forward,1,
1959                    HSref1,HCref1,RecP1,RecS1,RecRst1,obstacleon1,
1960                    HS3,pp3,decroch1,Vref);
1961     Ok2 = StartSol(Spine,HS2,pp2,HC2,w2,ref,!forward,2,
1962                    HSref2,HCref2, RecP2,RecS2,RecRst2,obstacleon2,
1963                    HS4,pp4,decroch2,Vref);
1964     HC1.Nullify(); 
1965     HC2.Nullify();
1966     
1967 #ifdef OCCT_DEBUG
1968     ChFi3d_ResultChron(ch1,t_startsol); // result perf for startsol  
1969 #endif
1970     
1971     
1972     if(Ok1 == 1 && Ok2 == 1) {
1973       if(forward) Guide.FirstParameter(wf);
1974       else Guide.LastParameter(wl);
1975     }
1976   }
1977   Standard_Boolean      fini     = Standard_False;
1978   Standard_Boolean      complete = Inside;
1979   if(!Guide.IsPeriodic()){
1980     Standard_Integer indf = Spine->Index(wf);
1981     Standard_Integer indl = Spine->Index(wl,0);
1982     if(Spine->IsPeriodic() && (indl < indf)) indl += nbed;
1983     nbed = indl-indf+1;
1984   }
1985   // No Max at the touch : 20 points by edge at average without  
1986   // counting the extensions.
1987
1988   Standard_Real bidf = wf, bidl = wl;
1989   if(!Spine->IsPeriodic()) {
1990     bidf = Max(0.,wf);
1991     bidl = Min(wl,Spine->LastParameter(Spine->NbEdges()));
1992     // PMN 20/07/98 : Attention in case if there is only extension
1993     if  ((bidl-bidf) < 0.01 * Spine->LastParameter(Spine->NbEdges())) {
1994        bidf = wf;
1995        bidl = wl;
1996     }   
1997   }
1998   Standard_Real         MaxStep  = (bidl-bidf)*0.05/nbed;
1999   Standard_Real         Firstsov = 0.;
2000   Standard_Integer      intf = 0, intl = 0;
2001   while(!fini){
2002     // are these the ends (no extension on periodic).
2003     Ok1 = 1,Ok2 = 1;
2004     if(!Spine->IsPeriodic()){
2005       if(wf < tolesp && (complete == Inside)){
2006         if(Spine->FirstStatus() == ChFiDS_OnSame) intf = 2;
2007         else intf = 1;
2008       }
2009       if(Spine->IsTangencyExtremity(Standard_True)){
2010         intf = 4;
2011         Guide.FirstParameter(wfsav);
2012       }
2013       if(wl - lastedlastp > -tolesp){
2014         if(Spine->LastStatus() == ChFiDS_OnSame) intl = 2;
2015         else intl = 1;
2016       }
2017       if(Spine->IsTangencyExtremity(Standard_False)){
2018         intl = 4;
2019         Guide.LastParameter(wlsav);
2020       }
2021     }
2022     if(intf && !forward) Vref = Spine->FirstVertex();
2023     if(intl && forward) Vref = Spine->LastVertex();
2024     if(!ref.IsNull()){
2025       
2026 #ifdef OCCT_DEBUG
2027       ChFi3d_InitChron(ch1);// init perf for StartSol 
2028 #endif
2029       
2030       Ok1 = StartSol(Spine,HS1,pp1,HC1,w1,ref,!forward,1,
2031                      HSref1,HCref1, RecP1,RecS1,RecRst1,obstacleon1,
2032                      HS3,pp3,decroch1,Vref);
2033       Ok2 = StartSol(Spine,HS2,pp2,HC2,w2,ref,!forward,2,
2034                      HSref2,HCref2, RecP2,RecS2,RecRst2,obstacleon2,
2035                      HS4,pp4,decroch2,Vref);
2036       
2037 #ifdef OCCT_DEBUG
2038       ChFi3d_ResultChron(ch1,t_startsol); // result perf for StartSol  
2039 #endif 
2040       
2041     }
2042     
2043     // No more connected faces. Construction of the tangent plane to continue the path 
2044     // till the output on the other face.
2045     if ((!Ok1 && HC1.IsNull()) || (!Ok2 && HC2.IsNull())) {
2046       if ((intf && !forward) || (intl && forward)) {
2047         if (!Ok1) ChFi3d_BuildPlane (DStr,HS1,pp1,ref,!forward,1);
2048         if (!Ok2) ChFi3d_BuildPlane (DStr,HS2,pp2,ref,!forward,2);      
2049         if(intf) intf = 5;
2050         else if(intl) intl = 5;
2051         if(forward) Guide.FirstParameter(wf);
2052         else Guide.LastParameter(wl);
2053       }
2054       else throw Standard_Failure("PerformSetOfSurfOnElSpine : Chaining is impossible.");
2055     }
2056     
2057     // Definition of the domain of patch It1, It2
2058     const Handle(Adaptor3d_HSurface)& HSon1 = HS1; // to avoid ambiguity
2059     const Handle(Adaptor3d_HSurface)& HSon2 = HS2; // to avoid ambiguity
2060     It1->Initialize(HSon1);
2061     It2->Initialize(HSon2);
2062     
2063     // Calculate one (several if singularity) SurfaData
2064     SD = new ChFiDS_SurfData();
2065     ChFiDS_SequenceOfSurfData SeqSD;
2066     SeqSD.Append(SD);
2067     
2068     if(obstacleon1 && obstacleon2){
2069       TopAbs_Orientation Or1 = HSref1->ChangeSurface().Face().Orientation();
2070       TopAbs_Orientation Or2 = HSref2->ChangeSurface().Face().Orientation();
2071       Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2,
2072                                                 Stripe->OrientationOnFace1(),
2073                                                 Stripe->OrientationOnFace2(),
2074                                                 Stripe->Choix());
2075
2076
2077       // Calculate the criterion of Choice edge / edge
2078       if (Choix%2 == 0) Choix = 4;
2079       else Choix = 1;
2080
2081       SoldepCC(1) = w1; SoldepCC(2) = w2;
2082       if(Simul){
2083         SimulSurf(SD,HGuide,Spine,Choix,
2084                   HS1,It1,HC1,HSref1,HCref1,decroch1,Or1,
2085                   HS2,It2,HC2,HSref2,HCref2,decroch2,Or2,
2086                   locfleche,tolesp,First,Last,Inside,Inside,forward,
2087                   RecP1,RecRst1,RecP2,RecRst2,SoldepCC);
2088       }
2089       else{
2090 #ifdef OCCT_DEBUG
2091         ChFi3d_InitChron(ch1); // init perf for PerformSurf 
2092 #endif
2093         PerformSurf(SeqSD,HGuide,Spine,Choix,
2094                     HS1,It1,HC1,HSref1,HCref1,decroch1,Or1,
2095                     HS2,It2,HC2,HSref2,HCref2,decroch2,Or2,
2096                     MaxStep,locfleche,tolesp,First,Last,Inside,Inside,forward,
2097                     RecP1,RecRst1,RecP2,RecRst2,SoldepCC);
2098 #ifdef OCCT_DEBUG
2099         ChFi3d_ResultChron(ch1,t_performsurf); //result  perf for PerformSurf 
2100 #endif 
2101       }
2102       SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2103       SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2104     }
2105     else if (obstacleon1){
2106       TopAbs_Orientation Or1 = HSref1->ChangeSurface().Face().Orientation();
2107       TopAbs_Orientation Or2 = HS2->ChangeSurface().Face().Orientation();
2108       Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2,
2109                                                 Stripe->OrientationOnFace1(),
2110                                                 Stripe->OrientationOnFace2(),
2111                                                 -Stripe->Choix());
2112       if(Choix%2 == 1) Choix++;
2113       else Choix--;
2114       SoldepCS(3) = w1; SoldepCS(1) =  pp2.X(); SoldepCS(2) =  pp2.Y();
2115       if(Simul){
2116         SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,HC1,HSref1,HCref1,decroch1,
2117                   HS2,It2,Or2,locfleche,tolesp,First,Last,
2118                   Inside,Inside,forward,RecP1,RecS2,RecRst1,SoldepCS);
2119       }
2120       else{
2121 #ifdef OCCT_DEBUG
2122         ChFi3d_InitChron(ch1); // init perf for PerformSurf
2123 #endif
2124         PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,HC1,HSref1,HCref1,decroch1,
2125                     HS2,It2,Or2,MaxStep,locfleche,tolesp,First,Last,
2126                     Inside,Inside,forward,RecP1,RecS2,RecRst1,SoldepCS);
2127 #ifdef OCCT_DEBUG
2128         ChFi3d_ResultChron(ch1,t_performsurf);//result  perf for PerformSurf  
2129 #endif 
2130       }
2131       SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2132       SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2133       decroch2 = 0;
2134     }
2135     else if (obstacleon2){
2136       TopAbs_Orientation Or1 = HS1->ChangeSurface().Face().Orientation();
2137       TopAbs_Orientation Or2 = HSref2->ChangeSurface().Face().Orientation();
2138       Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2,
2139                                                 Stripe->OrientationOnFace1(),
2140                                                 Stripe->OrientationOnFace2(),
2141                                                 Stripe->Choix());
2142       SoldepCS(3) = w2; SoldepCS(1) =  pp1.X(); SoldepCS(2) =  pp1.Y();
2143       if(Simul){
2144         SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,Or1,
2145                   HS2,It2,HC2,HSref2,HCref2,decroch2,locfleche,tolesp,
2146                   First,Last,Inside,Inside,forward,RecP2,RecS1,RecRst2,SoldepCS);
2147       }
2148       else{
2149 #ifdef OCCT_DEBUG
2150         ChFi3d_InitChron(ch1); // init perf for PerformSurf 
2151 #endif
2152         PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,Or1,
2153                     HS2,It2,HC2,HSref2,HCref2,decroch2,MaxStep,locfleche,tolesp,
2154                     First,Last,Inside,Inside,forward,RecP2,RecS1,RecRst2,SoldepCS);
2155 #ifdef OCCT_DEBUG
2156         ChFi3d_ResultChron(ch1,t_performsurf); //result  perf for PerformSurf 
2157 #endif 
2158       }
2159       SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2160       SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2161       decroch1 = 0;
2162     }
2163     else{ 
2164       const Handle(Adaptor3d_TopolTool)& aTT1 = It1; // to avoid ambiguity
2165       const Handle(Adaptor3d_TopolTool)& aTT2 = It2; // to avoid ambiguity
2166       CallPerformSurf(Stripe, Simul, SeqSD, SD,
2167                       HGuide,Spine,
2168                       HS1, HS3, pp1, pp3, aTT1,
2169                       HS2, HS4, pp2, pp4, aTT2, 
2170                       MaxStep,locfleche,tolesp,
2171                       First,Last,Inside,Inside,forward,
2172                       RecS1,RecS2,Soldep,intf,intl, 
2173                       HS1, HS2);
2174       decroch1 = decroch2 = 0;
2175     }
2176
2177     if(!done) { // Case of fail
2178       if ((!Ok1 && !obstacleon1) || (!Ok2 && !obstacleon2)) {
2179         //Fail in a part of extension is not serious
2180         //Here one stops.
2181         done = Standard_True;
2182         Inside = Standard_False;
2183         if (forward) intl = 1;
2184         else         intf = 1;
2185       }
2186       else { // Otherwise invalidation of the stripe.
2187         Spine->SetErrorStatus(ChFiDS_WalkingFailure);
2188         throw Standard_Failure("CallPerformSurf : Path failed!");
2189       }
2190     }
2191     
2192     else {
2193       refbis = ref;
2194       if(forward) {
2195         for (ii=1; ii<=SeqSD.Length(); ii++) {
2196           SD = SeqSD(ii);
2197           SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2198           if(obstacleon1) SD->SetIndexOfC1(DStr.AddShape(HC1->ChangeCurve2d().Edge()));
2199           SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2200           if(obstacleon2) SD->SetIndexOfC2(DStr.AddShape(HC2->ChangeCurve2d().Edge()));
2201           InsertAfter (Stripe, refbis, SD);
2202           refbis = SD;
2203         }
2204       }
2205       else {
2206         for (ii=SeqSD.Length(); ii>=1; ii--) {
2207           SD = SeqSD(ii);
2208           SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2209           if(obstacleon1) SD->SetIndexOfC1(DStr.AddShape(HC1->ChangeCurve2d().Edge()));
2210           SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2211           if(obstacleon2) SD->SetIndexOfC2(DStr.AddShape(HC2->ChangeCurve2d().Edge()));
2212           InsertBefore(Stripe,refbis,SD);
2213           refbis = SD;
2214         }
2215       } 
2216     
2217       if (!Ok1 && !obstacleon1) 
2218         // clean infos on the plane of extension.
2219         ChFi3d_Purge (Stripe,SD,ref->Vertex(!forward,1),!forward,1,intf,intl);
2220       
2221       if (!Ok2 && !obstacleon2) 
2222         // clean infos on the plane of extension.
2223         ChFi3d_Purge (Stripe,SD,ref->Vertex(!forward,2),!forward,2,intf,intl);
2224     
2225       // The end. The reference is changed.      
2226       ref = refbis;  
2227     }  
2228     
2229     if(Inside){// There are starting solutions for the next.
2230       Inside = Standard_False;
2231       Firstsov = First;
2232       if(Guide.IsPeriodic()) {
2233         complete = Standard_False;
2234         wf  = Guide.FirstParameter();
2235         wl  = Guide.LastParameter();
2236       }
2237     }
2238     if(forward){
2239       fini = ((wl - Last) <= 10.*tolesp || 
2240               (intl && !(obstacleon1 || obstacleon2))); //General case
2241
2242       if (!fini && Guide.IsPeriodic() && 
2243           ((wl - Last)< Guide.Period()*1.e-3)) {
2244         // It is tested if reframing of extremes is done at the same edge
2245         // Loop Condition
2246         Handle(ChFiDS_SurfData) thefirst, thelast;
2247         thefirst = Stripe->SetOfSurfData()->Sequence().First();
2248         thelast =  Stripe->SetOfSurfData()->Sequence().Last();
2249         
2250         if (thefirst->VertexFirstOnS1().IsOnArc() && 
2251             thelast->VertexLastOnS1().IsOnArc())
2252           fini = thefirst->VertexFirstOnS1().Arc().IsSame
2253             (thelast->VertexLastOnS1().Arc());
2254         if (!fini &&
2255             thefirst->VertexFirstOnS2().IsOnArc() && 
2256             thelast->VertexLastOnS2().IsOnArc())
2257           fini = thefirst->VertexFirstOnS2().Arc().IsSame
2258             (thelast->VertexLastOnS2().Arc());
2259
2260         if (fini) 
2261           return; //It is ended!
2262       }
2263
2264       if(fini && complete) {
2265         // restart in the opposite direction.
2266         ref  = Stripe->SetOfSurfData()->Sequence().First();
2267         forward = Standard_False;
2268         fini = Standard_False;
2269         First = Firstsov;
2270       }
2271       else {
2272         First = Last;
2273         Last  = wl;
2274       }
2275     }
2276     if(!forward){
2277       fini = ((First - wf) <= 10.*tolesp || 
2278               (intf && !(obstacleon1 || obstacleon2)));
2279       complete = Standard_False;
2280       Last = wf;
2281     }
2282   }
2283   // The initial state is restored
2284   if(!Guide.IsPeriodic()){
2285     Guide.FirstParameter(wfsav);
2286     Guide.LastParameter (wlsav);
2287   }
2288
2289 }
2290
2291 //=======================================================================
2292 //function : PerformSetOfKPart
2293 //purpose  : 
2294 //=======================================================================
2295
2296 void ChFi3d_Builder::PerformSetOfKPart(Handle(ChFiDS_Stripe)& Stripe,
2297                                        const Standard_Boolean Simul) 
2298 {
2299   TopOpeBRepDS_DataStructure&  DStr = myDS->ChangeDS();
2300   Handle(ChFiDS_Spine)&        Spine = Stripe->ChangeSpine();
2301   Handle(BRepAdaptor_HSurface) HS1,HS2;
2302   TopAbs_Orientation           Or1,Or2,RefOr1,RefOr2;
2303   Standard_Integer             RefChoix;
2304   
2305   // initialization of the stripe.
2306   Stripe->Reset();
2307   Handle(ChFiDS_HData)&  HData  = Stripe->ChangeSetOfSurfData();
2308   HData =  new ChFiDS_HData();
2309   ChFiDS_SequenceOfSurfData& SeqSurf = HData->ChangeSequence();
2310   
2311   StripeOrientations(Spine,RefOr1,RefOr2,RefChoix);
2312   Stripe->OrientationOnFace1(RefOr1);
2313   Stripe->OrientationOnFace2(RefOr2);
2314   Stripe->Choix(RefChoix);
2315   
2316   Handle(BRepTopAdaptor_TopolTool) It1 = new BRepTopAdaptor_TopolTool();
2317   Handle(BRepTopAdaptor_TopolTool) It2 = new BRepTopAdaptor_TopolTool();
2318   
2319   Standard_Real WFirst,WLast = 0.;
2320   gp_Vec TFirst,TLast,TEndPeriodic;
2321   gp_Pnt PFirst,PLast,PEndPeriodic;
2322   Standard_Boolean intf = Standard_False, intl = Standard_False;
2323   
2324   Handle(ChFiDS_HElSpine) CurrentHE = new ChFiDS_HElSpine();
2325   Spine->D1(Spine->FirstParameter(),PFirst,TFirst);
2326   CurrentHE->ChangeCurve().FirstParameter(Spine->FirstParameter());
2327   CurrentHE->ChangeCurve().SetFirstPointAndTgt(PFirst,TFirst);
2328   
2329   Standard_Boolean YaKPart = Standard_False;
2330   Standard_Integer iedgelastkpart = 0;
2331   
2332   Standard_Real WStartPeriodic = 0.;
2333   Standard_Real WEndPeriodic = Spine->LastParameter(Spine->NbEdges());
2334   Spine->D1(WEndPeriodic,PEndPeriodic,TEndPeriodic);
2335   
2336   // Construction of particular cases.
2337   
2338   for (Standard_Integer iedge = 1; iedge <= Spine->NbEdges(); iedge++){
2339     
2340     ConexFaces(Spine,iedge,RefChoix,HS1,HS2);
2341     
2342     if (ChFi3d_KParticular(Spine,iedge,HS1->ChangeSurface(),HS2->ChangeSurface())) {
2343       intf = ((iedge == 1) && !Spine->IsPeriodic());
2344       intl = ((iedge == Spine->NbEdges()) && !Spine->IsPeriodic());
2345       Or1   = HS1->ChangeSurface().Face().Orientation();
2346       Or2   = HS2->ChangeSurface().Face().Orientation();
2347       ChFi3d::NextSide(Or1,Or2,RefOr1,RefOr2,RefChoix);      
2348       const Handle(Adaptor3d_HSurface)& HSon1 = HS1; // to avoid ambiguity
2349       const Handle(Adaptor3d_HSurface)& HSon2 = HS2; // to avoid ambiguity
2350       It1->Initialize(HSon1);
2351       It2->Initialize(HSon2);
2352       
2353       Handle(ChFiDS_SurfData)   SD = new ChFiDS_SurfData();
2354       ChFiDS_SequenceOfSurfData LSD;
2355       
2356       if(!ChFiKPart_ComputeData::Compute(DStr,SD,HS1,HS2,Or1,Or2,Spine,iedge)){
2357 #ifdef OCCT_DEBUG
2358         cout<<"failed calculation KPart"<<endl;
2359 #endif
2360       }
2361       else if(!SplitKPart(SD,LSD,Spine,iedge,HS1,It1,HS2,It2,intf,intl)){
2362 #ifdef OCCT_DEBUG
2363         cout<<"failed calculation KPart"<<endl;
2364 #endif
2365         LSD.Clear();
2366       }
2367       else iedgelastkpart = iedge;
2368       if(Spine->IsPeriodic()){//debug provisory for SD that arrive in desorder.
2369         Standard_Integer nbsd = LSD.Length();
2370         Standard_Real period = Spine->Period();
2371         Standard_Real wfp = WStartPeriodic, wlp = WEndPeriodic;
2372 //  modified by NIZHNY-EAP Thu Nov 25 12:57:53 1999 ___BEGIN___
2373         if(!YaKPart && nbsd>0){
2374 //      if(!YaKPart){
2375 //  modified by NIZHNY-EAP Thu Nov 25 12:57:57 1999 ___END___
2376           Handle(ChFiDS_SurfData) firstSD = LSD.ChangeValue(1);
2377           Standard_Real wwf = firstSD->FirstSpineParam();
2378           Standard_Real wwl = firstSD->LastSpineParam();
2379           wwf = ChFi3d_InPeriod(wwf,wfp,wlp,tolesp);
2380           wwl = ChFi3d_InPeriod(wwl,wfp,wlp,tolesp);
2381           if (wwl <= wwf + tolesp) wwl += period;
2382           wfp = wwf;
2383           wlp = wfp + period;
2384         }
2385         for(Standard_Integer j = 1; j < nbsd; j++){
2386           Handle(ChFiDS_SurfData) jSD = LSD.Value(j);
2387           for(Standard_Integer k = j+1; k <= nbsd; k++){
2388             Handle(ChFiDS_SurfData) kSD = LSD.Value(k);
2389             Standard_Real jwf = jSD->FirstSpineParam();
2390             jwf = ChFi3d_InPeriod(jwf,wfp,wlp,tolesp);
2391             Standard_Real kwf = kSD->FirstSpineParam();
2392             kwf = ChFi3d_InPeriod(kwf,wfp,wlp,tolesp);
2393             if(kwf < jwf){
2394               LSD.SetValue(j,kSD);
2395               LSD.SetValue(k,jSD);
2396             }
2397           }
2398         }
2399       }
2400       TColStd_ListOfInteger li;
2401       for(Standard_Integer j = 1; j <= LSD.Length(); j++){
2402         Handle(ChFiDS_SurfData)& curSD = LSD.ChangeValue(j);
2403         if(Simul) SimulKPart(curSD);
2404         SeqSurf.Append(curSD);
2405         if(!Simul) li.Append(curSD->Surf());
2406         WFirst = LSD.Value(j)->FirstSpineParam();
2407         WLast  = LSD.Value(j)->LastSpineParam();
2408         if(Spine->IsPeriodic()){
2409           WFirst = ChFi3d_InPeriod(WFirst,WStartPeriodic,WEndPeriodic,tolesp);
2410           WLast  = ChFi3d_InPeriod(WLast ,WStartPeriodic,WEndPeriodic,tolesp);
2411           if (WLast <= WFirst + tolesp) WLast+= Spine->Period();
2412         }
2413         TgtKP(LSD.Value(j),Spine,iedge,1,PFirst,TFirst);
2414         TgtKP(LSD.Value(j),Spine,iedge,0,PLast,TLast);
2415         
2416         // Determine the sections to approximate
2417         if(!YaKPart){
2418           if(Spine->IsPeriodic()){
2419             WStartPeriodic = WFirst;
2420             WEndPeriodic = WStartPeriodic + Spine->Period();
2421             WLast = ElCLib::InPeriod(WLast,WStartPeriodic,WEndPeriodic);
2422             if (WLast <= WFirst + tolesp) WLast+= Spine->Period();
2423             PEndPeriodic = PFirst;
2424             TEndPeriodic = TFirst;
2425             Spine->SetFirstParameter(WStartPeriodic);
2426             Spine->SetLastParameter(WEndPeriodic);
2427           }
2428           else if(!intf || (iedge > 1)){
2429             // start section -> first KPart
2430             // update of extension.
2431             Spine->SetFirstTgt(Min(0.,WFirst));
2432             CurrentHE->ChangeCurve().LastParameter (WFirst);
2433             CurrentHE->ChangeCurve().SetLastPointAndTgt(PFirst,TFirst);
2434             Spine->AppendElSpine(CurrentHE);
2435             CurrentHE->ChangeCurve().ChangeNext() = LSD.Value(j);
2436             CurrentHE =  new ChFiDS_HElSpine();
2437           }
2438           CurrentHE->ChangeCurve().FirstParameter(WLast);
2439           CurrentHE->ChangeCurve().SetFirstPointAndTgt(PLast,TLast);
2440           CurrentHE->ChangeCurve().ChangePrevious() = LSD.Value(j);
2441           YaKPart = Standard_True;
2442         }
2443         else {
2444           if (WFirst - CurrentHE->FirstParameter() > tolesp) {
2445             // section between two KPart
2446             CurrentHE->ChangeCurve().LastParameter(WFirst);
2447             CurrentHE->ChangeCurve().SetLastPointAndTgt(PFirst,TFirst);
2448             Spine->AppendElSpine(CurrentHE);
2449             CurrentHE->ChangeCurve().ChangeNext() = LSD.Value(j);
2450             CurrentHE = new ChFiDS_HElSpine();
2451           }
2452           CurrentHE->ChangeCurve().FirstParameter(WLast);
2453           CurrentHE->ChangeCurve().SetFirstPointAndTgt(PLast,TLast);
2454           CurrentHE->ChangeCurve().ChangePrevious() = LSD.Value(j);
2455         }
2456       }
2457       if(!li.IsEmpty()) myEVIMap.Bind(Spine->Edges(iedge),li);
2458     }
2459   }
2460   
2461   if (!intl || (iedgelastkpart < Spine->NbEdges())) {
2462     // section last KPart(or start of the spine) -> End of the spine.
2463     // update of the extension.
2464     
2465     if(Spine->IsPeriodic()){
2466       if(WEndPeriodic - WLast > tolesp){
2467         CurrentHE->ChangeCurve().LastParameter(WEndPeriodic);
2468         CurrentHE->ChangeCurve().SetLastPointAndTgt(PEndPeriodic,TEndPeriodic);
2469         if(!YaKPart) CurrentHE->ChangeCurve().SetPeriodic(Standard_True);
2470         Spine->AppendElSpine(CurrentHE);
2471       }
2472     }
2473     else{
2474       Spine->D1(Spine->LastParameter(),PLast,TLast);
2475       Spine->SetLastTgt(Max(Spine->LastParameter(Spine->NbEdges()),
2476                             WLast));
2477       if (Spine->LastParameter() - WLast > tolesp) {
2478         CurrentHE->ChangeCurve().LastParameter(Spine->LastParameter());
2479         CurrentHE->ChangeCurve().SetLastPointAndTgt(PLast,TLast);
2480         Spine->AppendElSpine(CurrentHE);
2481       }
2482     }
2483   }
2484   
2485   ChFiDS_ListOfHElSpine& ll = Spine->ChangeElSpines();
2486   ChFiDS_ListIteratorOfListOfHElSpine ILES(ll);
2487   for ( ; ILES.More(); ILES.Next()) {
2488 #ifdef OCCT_DEBUG
2489     if(ChFi3d_GettraceCHRON()) elspine.Start();
2490 #endif
2491     ChFi3d_PerformElSpine(ILES.Value(),Spine,myConti,tolesp);
2492 #ifdef OCCT_DEBUG
2493     if(ChFi3d_GettraceCHRON()) { elspine.Stop(); }
2494 #endif
2495   }
2496   Spine->SplitDone(Standard_True);
2497 }
2498
2499 static Standard_Real ChFi3d_BoxDiag(const Bnd_Box& box)
2500 {
2501   Standard_Real a,b,c,d,e,f;
2502   box.Get(a,b,c,d,e,f); 
2503   d-=a; e-=b; f-=c; 
2504   d*=d; e*=e; f*=f;
2505   Standard_Real diag = sqrt(d + e + f);
2506   return diag;
2507 }
2508
2509 //=======================================================================
2510 //function : PerformSetOfKGen
2511 //purpose  : 
2512 //=======================================================================
2513
2514 void ChFi3d_Builder::PerformSetOfKGen(Handle(ChFiDS_Stripe)& Stripe,
2515                                       const Standard_Boolean Simul) 
2516 {
2517   Handle(BRepTopAdaptor_TopolTool) It1 = new BRepTopAdaptor_TopolTool();
2518   Handle(BRepTopAdaptor_TopolTool) It2 = new BRepTopAdaptor_TopolTool();
2519   Handle(ChFiDS_Spine)& Spine = Stripe->ChangeSpine();
2520   ChFiDS_ListOfHElSpine& ll = Spine->ChangeElSpines();
2521   ChFiDS_ListIteratorOfListOfHElSpine ILES(ll);
2522   for ( ; ILES.More(); ILES.Next()) {
2523 #ifdef OCCT_DEBUG
2524     if(ChFi3d_GettraceCHRON()) { chemine.Start(); }
2525 #endif
2526     PerformSetOfSurfOnElSpine(ILES.Value(),Stripe,It1,It2,Simul);
2527 #ifdef OCCT_DEBUG
2528     if(ChFi3d_GettraceCHRON()) chemine.Stop();
2529 #endif
2530   }
2531   if(!Simul){
2532     TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
2533     Handle(ChFiDS_HData)&  HData  = Stripe->ChangeSetOfSurfData();
2534     ChFiDS_SequenceOfSurfData& SeqSurf = HData->ChangeSequence();
2535     Standard_Integer len = SeqSurf.Length();
2536     Standard_Integer last = len, i;
2537     Standard_Boolean periodic = Spine->IsPeriodic();
2538     if(periodic) last++;
2539     // It is attempted to reprocess the squares that bore.
2540     for(i = 1; i <= len; i++){
2541       Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i);
2542       Standard_Boolean tw1 = cursd->TwistOnS1();
2543       Standard_Boolean tw2 = cursd->TwistOnS2();
2544       Handle(ChFiDS_SurfData) prevsd, nextsd;
2545       Standard_Integer iprev = i-1;
2546       if(iprev == 0) {
2547         if(periodic) iprev = len;
2548       }
2549       Standard_Integer inext = i + 1;
2550       if(inext > len) {
2551         if(periodic) inext = 1;
2552         else inext = 0;
2553       }
2554
2555       // For the moment only the surfaces where the twist is 
2556       // detected at the path are corrected, it is necessary to control  
2557       // more subtly the ugly traces (size, curvature, inflexion... ) 
2558       if(!tw1 && !tw2) continue;
2559       
2560       // It is decided (fairly at random) if the extended surface is ready for the filling.
2561       ChFiDS_FaceInterference& intf1 = cursd->ChangeInterferenceOnS1();
2562       ChFiDS_FaceInterference& intf2 = cursd->ChangeInterferenceOnS2();
2563       Standard_Integer cursurf1 = cursd->IndexOfS1();
2564       Standard_Integer cursurf2 = cursd->IndexOfS2();
2565       ChFiDS_CommonPoint& cpd1 = cursd->ChangeVertexFirstOnS1();
2566       ChFiDS_CommonPoint& cpd2 = cursd->ChangeVertexFirstOnS2();
2567       ChFiDS_CommonPoint& cpf1 = cursd->ChangeVertexLastOnS1();
2568       ChFiDS_CommonPoint& cpf2 = cursd->ChangeVertexLastOnS2();
2569       const gp_Pnt& pd1 = cpd1.Point();
2570       const gp_Pnt& pd2 = cpd2.Point();
2571       const gp_Pnt& pf1 = cpf1.Point();
2572       const gp_Pnt& pf2 = cpf2.Point();
2573       Standard_Real ddeb = pd1.Distance(pd2);
2574       Standard_Real dfin = pf1.Distance(pf2);
2575       Standard_Real don1 = pd1.Distance(pf1);
2576       Standard_Real don2 = pd2.Distance(pf2);
2577       Standard_Boolean possibleon1 = (don1 < 2*(ddeb + dfin));
2578       Standard_Boolean possibleon2 = (don2 < 2*(ddeb + dfin));
2579       if((tw1 && !possibleon1) || (tw2 && !possibleon2)) {
2580         Spine->SetErrorStatus(ChFiDS_TwistedSurface);
2581         throw Standard_Failure("adjustment by reprocessing the non-written points");
2582       }
2583       
2584       // It is checked if there are presentable neighbors
2585       Standard_Boolean yaprevon1 = 0, yaprevon2 = 0;
2586       Standard_Boolean samesurfon1 = 0, samesurfon2 = 0;
2587       if(iprev){
2588         prevsd = SeqSurf.ChangeValue(iprev);
2589         yaprevon1 = !prevsd->TwistOnS1();
2590         samesurfon1 = (prevsd->IndexOfS1() == cursurf1);
2591         yaprevon2 = !prevsd->TwistOnS2();
2592         samesurfon2 = (prevsd->IndexOfS2() == cursurf2);
2593       }
2594       Standard_Boolean yanexton1 = 0, yanexton2 = 0;
2595       if(inext){
2596         nextsd = SeqSurf.ChangeValue(inext);
2597         yanexton1 = !nextsd->TwistOnS1();
2598         if(samesurfon1) samesurfon1 = (nextsd->IndexOfS1() == cursurf1);
2599         yanexton2 = !nextsd->TwistOnS2();
2600         if(samesurfon2) samesurfon2 = (nextsd->IndexOfS2() == cursurf2);
2601       }
2602       // A contour of filling is constructed
2603       Handle(Geom2d_Curve) PC1 = intf1.PCurveOnFace();
2604       Handle(Geom2d_Curve) PC2 = intf2.PCurveOnFace();
2605       Handle(BRepAdaptor_HSurface) S1 = new BRepAdaptor_HSurface();
2606       TopoDS_Face F1 = TopoDS::Face(DStr.Shape(cursurf1));
2607       S1->ChangeSurface().Initialize(F1);
2608       Handle(BRepAdaptor_HSurface) S2 = new BRepAdaptor_HSurface();
2609       TopoDS_Face F2 = TopoDS::Face(DStr.Shape(cursurf2));
2610       S2->ChangeSurface().Initialize(F2);
2611       Handle(GeomFill_Boundary) Bdeb,Bfin,Bon1,Bon2;
2612       Standard_Boolean pointuon1 = 0, pointuon2 = 0;
2613       if(tw1){
2614         if(!yaprevon1 || !yanexton1){
2615           Spine->SetErrorStatus(ChFiDS_TwistedSurface);
2616           throw Standard_Failure("adjustment by reprocessing the non-written points: no neighbor");
2617         }
2618         ChFiDS_FaceInterference& previntf1 = prevsd->ChangeInterferenceOnS1();
2619         ChFiDS_FaceInterference& nextintf1 = nextsd->ChangeInterferenceOnS1();
2620         Standard_Real prevpar1 = previntf1.LastParameter();
2621         Standard_Real nextpar1 = nextintf1.FirstParameter();
2622         if(samesurfon1){
2623           // It is checked if it is possible to intersect traces of neighbors
2624           // to create a sharp end.
2625           Handle(Geom2d_Curve) pcprev1 = previntf1.PCurveOnFace();
2626           Handle(Geom2d_Curve) pcnext1 = nextintf1.PCurveOnFace();
2627           Standard_Real nprevpar1,nnextpar1;
2628           gp_Pnt2d p2d;
2629 //  Modified by Sergey KHROMOV - Wed Feb  5 12:03:17 2003 Begin
2630 //        if(ChFi3d_IntTraces(prevsd,prevpar1,nprevpar1,1,1,
2631 //                            nextsd,nextpar1,nnextpar1,1,-1,p2d)){
2632           if(ChFi3d_IntTraces(prevsd,prevpar1,nprevpar1,1,1,
2633                               nextsd,nextpar1,nnextpar1,1,-1,p2d,
2634                               Standard_False, Standard_True)){
2635 //  Modified by Sergey KHROMOV - Wed Feb  5 12:03:17 2003 End
2636             previntf1.SetLastParameter(nprevpar1);
2637             nextintf1.SetFirstParameter(nnextpar1);
2638             pointuon1 = 1;
2639             PC1.Nullify();
2640           }
2641           else{
2642             gp_Pnt2d pdeb1,pfin1;
2643             gp_Vec2d vdeb1,vfin1;
2644             pcprev1->D1(prevpar1,pdeb1,vdeb1);
2645             pcnext1->D1(nextpar1,pfin1,vfin1);
2646             Bon1 = ChFi3d_mkbound(S1,PC1,-1,pdeb1,vdeb1,1,
2647                                   pfin1,vfin1,tolesp,2.e-4);
2648           }
2649         }
2650         else{
2651           //here the base is on 3D tangents of neighbors.
2652           const Handle(Geom_Curve)& c3dprev1 = 
2653             DStr.Curve(previntf1.LineIndex()).Curve();
2654           const Handle(Geom_Curve)& c3dnext1 = 
2655             DStr.Curve(nextintf1.LineIndex()).Curve();
2656           gp_Pnt Pdeb1, Pfin1;
2657           gp_Vec Vdeb1, Vfin1;
2658           c3dprev1->D1(prevpar1,Pdeb1,Vdeb1);
2659           c3dnext1->D1(nextpar1,Pfin1,Vfin1);
2660           gp_Pnt2d pdeb1,pfin1;
2661           Standard_Real pardeb1 = intf1.FirstParameter();
2662           Standard_Real parfin1 = intf1.LastParameter();
2663           pdeb1 = PC1->Value(pardeb1);
2664           pfin1 = PC1->Value(parfin1);
2665           Bon1 = ChFi3d_mkbound(S1,PC1,-1,pdeb1,Vdeb1,1,
2666                                 pfin1,Vfin1,tolesp,2.e-4);
2667         }
2668       }
2669       else{
2670         Bon1 = ChFi3d_mkbound(S1,PC1,tolesp,2.e-4);
2671       }
2672       if(tw2){
2673         if(!yaprevon2 || !yanexton2){
2674           throw Standard_Failure("adjustment by reprocessing the non-written points: no neighbor");
2675         }
2676         ChFiDS_FaceInterference& previntf2 = prevsd->ChangeInterferenceOnS2();
2677         ChFiDS_FaceInterference& nextintf2 = nextsd->ChangeInterferenceOnS2();
2678         Standard_Real prevpar2 = previntf2.LastParameter();
2679         Standard_Real nextpar2 = nextintf2.FirstParameter();
2680         if(samesurfon2){
2681           // It is checked if it is possible to intersect traces of neighbors
2682           // to create a sharp end.
2683           Handle(Geom2d_Curve) pcprev2 = previntf2.PCurveOnFace();
2684           Handle(Geom2d_Curve) pcnext2 = nextintf2.PCurveOnFace();
2685           Standard_Real nprevpar2,nnextpar2;
2686           gp_Pnt2d p2d;
2687 //  Modified by Sergey KHROMOV - Wed Feb  5 12:03:17 2003 Begin
2688 //        if(ChFi3d_IntTraces(prevsd,prevpar2,nprevpar2,2,1,
2689 //                            nextsd,nextpar2,nnextpar2,2,-1,p2d)){
2690           if(ChFi3d_IntTraces(prevsd,prevpar2,nprevpar2,2,1,
2691                               nextsd,nextpar2,nnextpar2,2,-1,p2d,
2692                               Standard_False, Standard_True)){
2693 //  Modified by Sergey KHROMOV - Wed Feb  5 12:03:17 2003 End
2694             previntf2.SetLastParameter(nprevpar2);
2695             nextintf2.SetFirstParameter(nnextpar2);
2696             pointuon2 = 1;
2697             PC2.Nullify();
2698           }
2699           else{
2700             gp_Pnt2d pdeb2,pfin2;
2701             gp_Vec2d vdeb2,vfin2;
2702             pcprev2->D1(prevpar2,pdeb2,vdeb2);
2703             pcnext2->D1(nextpar2,pfin2,vfin2);
2704             Bon2 = ChFi3d_mkbound(S2,PC2,-1,pdeb2,vdeb2,1,
2705                                   pfin2,vfin2,tolesp,2.e-4);
2706           }
2707         }
2708         else{
2709          //here the base is on 3D tangents of neighbors.
2710           const Handle(Geom_Curve)& c3dprev2 = 
2711             DStr.Curve(previntf2.LineIndex()).Curve();
2712           const Handle(Geom_Curve)& c3dnext2 = 
2713             DStr.Curve(nextintf2.LineIndex()).Curve();
2714           gp_Pnt Pdeb2, Pfin2;
2715           gp_Vec Vdeb2, Vfin2;
2716           c3dprev2->D1(prevpar2,Pdeb2,Vdeb2);
2717           c3dnext2->D1(nextpar2,Pfin2,Vfin2);
2718           gp_Pnt2d pdeb2,pfin2;
2719           Standard_Real pardeb2 = intf2.FirstParameter();
2720           Standard_Real parfin2 = intf2.LastParameter();
2721           pdeb2 = PC2->Value(pardeb2);
2722           pfin2 = PC2->Value(parfin2);
2723           Bon2 = ChFi3d_mkbound(S2,PC2,-1,pdeb2,Vdeb2,1,
2724                                 pfin2,Vfin2,tolesp,2.e-4);
2725         }
2726       }
2727       else{
2728         Bon2 = ChFi3d_mkbound(S2,PC2,tolesp,2.e-4);
2729       }
2730       // The parameters of neighbor traces are updated, so 
2731       // straight lines uv are pulled.
2732       const Handle(Geom_Surface)& 
2733         sprev = DStr.Surface(prevsd->Surf()).Surface();
2734       const Handle(Geom_Surface)& 
2735         snext = DStr.Surface(nextsd->Surf()).Surface();
2736       ChFiDS_FaceInterference& previntf1 = prevsd->ChangeInterferenceOnS1();
2737       ChFiDS_FaceInterference& nextintf1 = nextsd->ChangeInterferenceOnS1();
2738       ChFiDS_FaceInterference& previntf2 = prevsd->ChangeInterferenceOnS2();
2739       ChFiDS_FaceInterference& nextintf2 = nextsd->ChangeInterferenceOnS2();
2740       Handle(Geom2d_Curve) pcsprev1 = previntf1.PCurveOnSurf();
2741       Handle(Geom2d_Curve) pcsnext1 = nextintf1.PCurveOnSurf();
2742       Standard_Real prevpar1 = previntf1.LastParameter();
2743       Standard_Real nextpar1 = nextintf1.FirstParameter();
2744       Handle(Geom2d_Curve) pcsprev2 = previntf2.PCurveOnSurf();
2745       Handle(Geom2d_Curve) pcsnext2 = nextintf2.PCurveOnSurf();
2746       Standard_Real prevpar2 = previntf2.LastParameter();
2747       Standard_Real nextpar2 = nextintf2.FirstParameter();
2748       gp_Pnt2d pdebs1 = pcsprev1->Value(prevpar1);
2749       gp_Pnt2d pdebs2 = pcsprev2->Value(prevpar2);
2750       gp_Pnt2d pfins1 = pcsnext1->Value(nextpar1);
2751       gp_Pnt2d pfins2 = pcsnext2->Value(nextpar2);
2752       Bdeb = ChFi3d_mkbound(sprev,pdebs1,pdebs2,tolesp,2.e-4);
2753       Bfin = ChFi3d_mkbound(snext,pfins1,pfins2,tolesp,2.e-4);
2754
2755       GeomFill_ConstrainedFilling fil(11,20);
2756       if(pointuon1) fil.Init(Bon2,Bfin,Bdeb,1);
2757       else if(pointuon2) fil.Init(Bon1,Bfin,Bdeb,1);
2758       else fil.Init(Bon1,Bfin,Bon2,Bdeb,1);
2759       
2760       ChFi3d_ReparamPcurv(0.,1.,PC1);
2761       ChFi3d_ReparamPcurv(0.,1.,PC2);
2762       Handle(Geom_Surface) newsurf = fil.Surface();
2763 #ifdef OCCT_DEBUG
2764 #ifdef DRAW
2765       //POP for NT
2766       char* pops = "newsurf";
2767       DrawTrSurf::Set(pops,newsurf);
2768 #endif
2769 #endif
2770       if(pointuon1) {
2771         newsurf->VReverse(); // we return to direction 1 from  2;
2772         done = CompleteData(cursd,newsurf,S1,PC1,S2,PC2,
2773                             F2.Orientation(),0,0,0,0,0);
2774         cursd->ChangeIndexOfS1(0);
2775       }
2776       else{
2777         done = CompleteData(cursd,newsurf,S1,PC1,S2,PC2,
2778                             F1.Orientation(),1,0,0,0,0);
2779         if(pointuon2) cursd->ChangeIndexOfS2(0);
2780       }
2781       if(tw1){
2782         prevsd->ChangeVertexLastOnS1().SetPoint(cpd1.Point());
2783         nextsd->ChangeVertexFirstOnS1().SetPoint(cpf1.Point());
2784       }
2785       if(tw2){
2786         prevsd->ChangeVertexLastOnS2().SetPoint(cpd2.Point());
2787         nextsd->ChangeVertexFirstOnS2().SetPoint(cpf2.Point());
2788       }
2789     }
2790     // The tolerance of points is updated.
2791     for(i = 1; i < last; i++){
2792       Standard_Integer j = i%len + 1;
2793       Standard_Integer curs1, curs2;
2794       Standard_Integer nexts1, nexts2;
2795       Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i);
2796       Handle(ChFiDS_SurfData)& nextsd = SeqSurf.ChangeValue(j);
2797       ChFiDS_CommonPoint& curp1 = cursd->ChangeVertexLastOnS1();
2798       ChFiDS_CommonPoint& nextp1 = nextsd->ChangeVertexFirstOnS1();
2799       if (cursd->IsOnCurve1()) curs1 = cursd->IndexOfC1();
2800       else                     curs1 = cursd->IndexOfS1();
2801       if (cursd->IsOnCurve2()) curs2 = cursd->IndexOfC2();
2802       else                     curs2 = cursd->IndexOfS2();
2803       Standard_Real tol1 = Max(curp1.Tolerance(),nextp1.Tolerance());
2804       ChFiDS_CommonPoint& curp2 = cursd->ChangeVertexLastOnS2();
2805       ChFiDS_CommonPoint& nextp2 = nextsd->ChangeVertexFirstOnS2();
2806       Standard_Real tol2 = Max(curp2.Tolerance(),nextp2.Tolerance());
2807       if (nextsd->IsOnCurve1()) nexts1 = nextsd->IndexOfC1();
2808       else                     nexts1 = nextsd->IndexOfS1();
2809       if (nextsd->IsOnCurve2()) nexts2 = nextsd->IndexOfC2();
2810       else                     nexts2 = nextsd->IndexOfS2();
2811
2812       if(!curp1.IsOnArc() && nextp1.IsOnArc()){ 
2813         curp1 = nextp1;
2814         if ( (curs1 == nexts1) && !nextsd->IsOnCurve1()) 
2815           // Case when it is not possible to pass along the border without leaving
2816           ChangeTransition(nextp1, curp1, nexts1, myDS);
2817       }
2818       else if(curp1.IsOnArc() && !nextp1.IsOnArc()) { 
2819         nextp1 = curp1;
2820         if ( (curs1 == nexts1) && !cursd->IsOnCurve1())
2821           ChangeTransition(curp1, nextp1, curs1, myDS);
2822       }
2823         
2824       if(!curp2.IsOnArc() && nextp2.IsOnArc()) {
2825         curp2 = nextp2;
2826         if ( (curs2 == nexts2) && !nextsd->IsOnCurve2()) 
2827           ChangeTransition(nextp2, curp2, curs2, myDS);
2828       }
2829       else if(curp2.IsOnArc() && !nextp2.IsOnArc()){
2830         nextp2 = curp2;
2831         if ( (curs2 == nexts2) && !cursd->IsOnCurve2()) 
2832           ChangeTransition(curp2, nextp2, curs2, myDS);
2833       }
2834
2835       curp1.SetTolerance(tol1); nextp1.SetTolerance(tol1); 
2836       curp2.SetTolerance(tol2); nextp2.SetTolerance(tol2); 
2837       
2838       Bnd_Box b1,b2;
2839       if(curp1.IsOnArc()){
2840         ChFi3d_EnlargeBox(curp1.Arc(),myEFMap(curp1.Arc()),curp1.ParameterOnArc(),b1);
2841       }
2842       if(curp2.IsOnArc()){
2843         ChFi3d_EnlargeBox(curp2.Arc(),myEFMap(curp2.Arc()),curp2.ParameterOnArc(),b2);
2844       }
2845       Handle(ChFiDS_Stripe) bidst;
2846       ChFi3d_EnlargeBox(DStr,bidst,cursd,b1,b2,0);
2847       ChFi3d_EnlargeBox(DStr,bidst,nextsd,b1,b2,1);
2848       tol1 = ChFi3d_BoxDiag(b1);
2849       tol2 = ChFi3d_BoxDiag(b2);
2850       curp1.SetTolerance(tol1); nextp1.SetTolerance(tol1); 
2851       curp2.SetTolerance(tol2); nextp2.SetTolerance(tol2); 
2852     }
2853     // The connections edge/new faces are updated.
2854     for (ILES.Initialize(ll) ; ILES.More(); ILES.Next()) {
2855       const Handle(ChFiDS_HElSpine)& curhels = ILES.Value();
2856       const ChFiDS_ElSpine& curels = curhels->ChangeCurve();
2857       Standard_Real WF = curels.FirstParameter();
2858       Standard_Real WL = curels.LastParameter();
2859       Standard_Integer IF,IL;
2860       Standard_Real nwf = WF, nwl = WL;
2861       Standard_Real period = 0.;
2862       Standard_Integer nbed = Spine->NbEdges();
2863       if(periodic){
2864         period = Spine->Period();
2865         nwf = ElCLib::InPeriod(WF,-tolesp,period-tolesp);
2866         IF = Spine->Index(nwf,1);
2867         nwl = ElCLib::InPeriod(WL,tolesp,period+tolesp);
2868         IL = Spine->Index(nwl,0);
2869         if(nwl<nwf+tolesp) IL += nbed;
2870       }
2871       else{
2872         IF = Spine->Index(WF,1);
2873         IL = Spine->Index(WL,0);
2874       }
2875       if(IF == IL) {
2876         //fast processing
2877         Standard_Integer IFloc = IF;
2878         if(periodic) IFloc = (IF - 1)%nbed + 1;
2879         const TopoDS_Edge& Ej = Spine->Edges(IFloc);
2880         for(i = 1; i <= len; i++){
2881           Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i);
2882           Standard_Real fp = cursd->FirstSpineParam();
2883           Standard_Real lp = cursd->LastSpineParam();
2884           if(lp < WF+tolesp || fp > WL-tolesp) continue;
2885           if(!myEVIMap.IsBound(Ej)) {
2886             TColStd_ListOfInteger li;
2887             myEVIMap.Bind(Ej,li);
2888           }
2889           myEVIMap.ChangeFind(Ej).Append(cursd->Surf());
2890         }
2891       }
2892       else if(IF < IL){
2893         TColStd_Array1OfReal wv(IF,IL - 1);
2894 #ifdef OCCT_DEBUG
2895         cout<<"length of the trajectory : "<<(WL-WF)<<endl;
2896 #endif
2897         for(i = IF; i < IL; i++){
2898           Standard_Integer iloc = i;
2899           if(periodic) iloc = (i - 1)%nbed + 1;
2900           Standard_Real wi = Spine->LastParameter(iloc);
2901           if(periodic) wi = ElCLib::InPeriod(wi,WF,WF+period);
2902           gp_Pnt pv = Spine->Value(wi);
2903 #ifdef OCCT_DEBUG
2904           gp_Pnt pelsapp = curels.Value(wi);
2905           Standard_Real distinit = pv.Distance(pelsapp);
2906           cout<<"distance psp/papp : "<<distinit<<endl;
2907 #endif
2908           Extrema_LocateExtPC ext(pv,curels,wi,1.e-8);
2909           wv(i) = wi;
2910           if(ext.IsDone()){
2911             wv(i) = ext.Point().Parameter(); 
2912           }
2913           else {
2914 #ifdef OCCT_DEBUG
2915             cout<<"fail of projection vertex ElSpine!!!"<<endl;
2916 #endif
2917           }
2918         }
2919         for(i = 1; i <= len; i++){
2920           Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i);
2921           Standard_Real fp = cursd->FirstSpineParam();
2922           Standard_Real lp = cursd->LastSpineParam();
2923           Standard_Integer j;
2924           Standard_Integer jf = 0, jl = 0;
2925           if(lp < WF+tolesp || fp > WL-tolesp) continue;
2926           for(j = IF; j < IL; j++){
2927             jf = j;
2928             if(fp < wv(j) - tolesp) break;
2929           }
2930           for(j = IF; j < IL; j++){
2931             jl = j;
2932             if(lp < wv(j) + tolesp) break;
2933           }
2934           for(j = jf; j <= jl; j++){
2935             Standard_Integer jloc = j;
2936             if(periodic) jloc = (j - 1)%nbed + 1;
2937             const TopoDS_Edge& Ej = Spine->Edges(jloc);
2938             if(!myEVIMap.IsBound(Ej)) {
2939               TColStd_ListOfInteger li;
2940               myEVIMap.Bind(Ej,li);
2941             }
2942             myEVIMap.ChangeFind(Ej).Append(cursd->Surf());
2943           }
2944         }
2945       }
2946     }
2947   }
2948 }
2949
2950 //=======================================================================
2951 //function : PerformSetOfSurf
2952 //purpose  : 
2953 //=======================================================================
2954
2955 void ChFi3d_Builder::PerformSetOfSurf(Handle(ChFiDS_Stripe)& Stripe,
2956                                       const Standard_Boolean Simul) 
2957 {
2958   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
2959   
2960 #ifdef OCCT_DEBUG
2961   OSD_Chronometer ch;
2962   ChFi3d_InitChron(ch);// init perf for PerformSetOfKPart
2963 #endif
2964   
2965   const Handle(ChFiDS_Spine)& sp = Stripe->Spine();
2966   Standard_Integer SI = ChFi3d_SolidIndex(sp,DStr,myESoMap,myEShMap);
2967   Stripe->SetSolidIndex(SI);
2968   if(!sp->SplitDone()) PerformSetOfKPart(Stripe,Simul);
2969   
2970 #ifdef OCCT_DEBUG
2971   ChFi3d_ResultChron(ch ,t_perfsetofkpart); // result perf PerformSetOfKPart(
2972   ChFi3d_InitChron(ch); // init perf for  PerformSetOfKGen
2973 #endif
2974   
2975   PerformSetOfKGen(Stripe,Simul);
2976   
2977 #ifdef OCCT_DEBUG
2978   ChFi3d_ResultChron(ch, t_perfsetofkgen);//result perf PerformSetOfKGen 
2979   ChFi3d_InitChron(ch); // init perf for ChFi3d_MakeExtremities
2980 #endif
2981   
2982   if(!Simul) ChFi3d_MakeExtremities(Stripe,DStr,myEFMap,tolesp,tol2d);
2983   
2984 #ifdef OCCT_DEBUG
2985   ChFi3d_ResultChron(ch, t_makextremities); // result perf t_makextremities
2986 #endif
2987 }