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