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