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