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