a15dd4ed6ee74b3cfb7d8c1716290256e5d4d19d
[occt.git] / src / ChFi3d / ChFi3d_Builder_2.cxx
1 // Created on: 1993-12-15
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Adaptor2d_HCurve2d.hxx>
19 #include <Adaptor3d_HSurface.hxx>
20 #include <Adaptor3d_TopolTool.hxx>
21 #include <AppBlend_Approx.hxx>
22 #include <Blend_CurvPointFuncInv.hxx>
23 #include <Blend_FuncInv.hxx>
24 #include <Blend_Function.hxx>
25 #include <Blend_RstRstFunction.hxx>
26 #include <Blend_SurfCurvFuncInv.hxx>
27 #include <Blend_SurfPointFuncInv.hxx>
28 #include <Blend_SurfRstFunction.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRepAdaptor_Curve.hxx>
31 #include <BRepAdaptor_HCurve.hxx>
32 #include <BRepAdaptor_HCurve2d.hxx>
33 #include <BRepAdaptor_HSurface.hxx>
34 #include <BRepAdaptor_Surface.hxx>
35 #include <BRepBlend_Line.hxx>
36 #include <BRepLib_MakeFace.hxx>
37 #include <BRepLProp_SLProps.hxx>
38 #include <BRepTools.hxx>
39 #include <BRepTools_WireExplorer.hxx>
40 #include <BRepTopAdaptor_TopolTool.hxx>
41 #include <ChFi3d.hxx>
42 #include <ChFi3d_Builder.hxx>
43 #include <ChFi3d_Builder_0.hxx>
44 #include <ChFiDS_ChamfSpine.hxx>
45 #include <ChFiDS_CommonPoint.hxx>
46 #include <ChFiDS_ElSpine.hxx>
47 #include <ChFiDS_ErrorStatus.hxx>
48 #include <ChFiDS_FaceInterference.hxx>
49 #include <ChFiDS_FilSpine.hxx>
50 #include <ChFiDS_HData.hxx>
51 #include <ChFiDS_HElSpine.hxx>
52 #include <ChFiDS_ListIteratorOfListOfHElSpine.hxx>
53 #include <ChFiDS_ListOfHElSpine.hxx>
54 #include <ChFiDS_SequenceOfSurfData.hxx>
55 #include <ChFiDS_Spine.hxx>
56 #include <ChFiDS_State.hxx>
57 #include <ChFiDS_Stripe.hxx>
58 #include <ChFiDS_SurfData.hxx>
59 #include <ChFiKPart_ComputeData.hxx>
60 #include <ElCLib.hxx>
61 #include <Extrema_ExtPC.hxx>
62 #include <Extrema_ExtPS.hxx>
63 #include <Extrema_LocateExtPC.hxx>
64 #include <Extrema_POnCurv.hxx>
65 #include <Geom2d_Curve.hxx>
66 #include <Geom_BSplineCurve.hxx>
67 #include <Geom_BSplineSurface.hxx>
68 #include <Geom_Line.hxx>
69 #include <Geom_Plane.hxx>
70 #include <Geom_Surface.hxx>
71 #include <GeomAdaptor_HCurve.hxx>
72 #include <GeomAdaptor_HSurface.hxx>
73 #include <GeomAdaptor_Surface.hxx>
74 #include <GeomAPI_ProjectPointOnCurve.hxx>
75 #include <gp_Pln.hxx>
76 #include <gp_Pnt.hxx>
77 #include <gp_Pnt2d.hxx>
78 #include <gp_Vec.hxx>
79 #include <gp_XYZ.hxx>
80 #include <math_Vector.hxx>
81 #include <Precision.hxx>
82 #include <Standard_ConstructionError.hxx>
83 #include <Standard_NoSuchObject.hxx>
84 #include <Standard_NotImplemented.hxx>
85 #include <Standard_OutOfRange.hxx>
86 #include <TColgp_Array1OfPnt.hxx>
87 #include <TColgp_Array1OfVec.hxx>
88 #include <TColStd_Array1OfInteger.hxx>
89 #include <TColStd_Array1OfReal.hxx>
90 #include <TColStd_ListOfInteger.hxx>
91 #include <TopAbs.hxx>
92 #include <TopAbs_Orientation.hxx>
93 #include <TopAbs_ShapeEnum.hxx>
94 #include <TopExp.hxx>
95 #include <TopExp_Explorer.hxx>
96 #include <TopoDS.hxx>
97 #include <TopoDS_Edge.hxx>
98 #include <TopoDS_Face.hxx>
99 #include <TopoDS_Shape.hxx>
100 #include <TopoDS_Vertex.hxx>
101 #include <TopoDS_Wire.hxx>
102 #include <TopOpeBRepBuild_HBuilder.hxx>
103 #include <TopOpeBRepDS_HDataStructure.hxx>
104 #include <TopTools_ListIteratorOfListOfShape.hxx>
105
106 #ifdef OCCT_DEBUG
107 #ifdef DRAW
108 #include <DrawTrSurf.hxx>
109 #endif
110 #include <OSD_Chronometer.hxx>
111 extern Standard_Real  t_perfsetofkpart,t_perfsetofkgen,t_makextremities,t_performsurf,t_startsol;
112 extern Standard_Boolean ChFi3d_GettraceCHRON();
113 extern void ChFi3d_InitChron(OSD_Chronometer& ch);
114 extern void ChFi3d_ResultChron(OSD_Chronometer & ch, Standard_Real& time);
115 #endif
116
117 //  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   TopAbs_Orientation orient = TopAbs_FORWARD ;
475   TopoDS_Edge ed;
476   for(Ex.Init(FRef,TopAbs_EDGE); Ex.More(); Ex.Next()){
477     ed = TopoDS::Edge(Ex.Current());
478     if(ed.IsSame(E)){
479       if(!orset){ orient = ed.Orientation(); orset = Standard_True; }
480       else if(ed.Orientation() == TopAbs::Reverse(orient)){
481         FVoi = FRef;
482 //  Modified by Sergey KHROMOV - Fri Dec 21 17:15:12 2001 Begin
483 //      if (BRep_Tool::Continuity(E,FRef,FRef) >= GeomAbs_G1) {   
484         if (isTangentFaces(E,FRef,FRef)) {
485 //  Modified by Sergey KHROMOV - Fri Dec 21 17:15:16 2001 End
486           return Standard_True;
487         }
488         return Standard_False;
489       }
490     }
491   }
492   return Standard_False;
493 }
494
495 //=======================================================================
496 //function : SearchFaceOnV
497 //purpose  : Finds the output face(s) of the path by a vertex
498 //           The following criteria should be followed
499 //         -1 : The face shares regular edges with FRef 
500 //              (too hard condition that should be reconsidered)
501 //         -2 : The vector starting in CommonPoint "belongs" to the face
502 //========================================================================
503 static Standard_Integer SearchFaceOnV(const ChFiDS_CommonPoint&    Pc,
504                                       const TopoDS_Face&           FRef,
505                                       const ChFiDS_Map&            VEMap,
506                                       const ChFiDS_Map&            EFMap,
507                                       TopoDS_Face&                 F1,
508                                       TopoDS_Face&                 F2)
509 {
510   // it is checked that it leaves the current face.
511   Standard_Boolean FindFace = IsInput(Pc.Vector(), Pc.Vertex(), FRef);
512   if (FindFace) {
513     FindFace = IsInput(Pc.Vector().Reversed(), Pc.Vertex(), FRef);
514   }
515   // If it does not leave, it is finished
516   if (FindFace) {
517     F1 = FRef;
518     return 1;
519   }
520   Standard_Integer Num = 0;
521   Standard_Boolean Trouve;
522   TopTools_ListIteratorOfListOfShape ItE, ItF;
523   TopoDS_Edge E;
524   TopoDS_Face FVoi;
525
526   for(ItE.Initialize(VEMap(Pc.Vertex()));
527       ItE.More() && (Num < 2); ItE.Next()) {
528     E = TopoDS::Edge(ItE.Value());
529     for(ItF.Initialize(EFMap(E)), Trouve=Standard_False;
530         ItF.More()&&(!Trouve); ItF.Next()) {
531       if (TopoDS::Face(ItF.Value()).IsSame(FRef)) {
532         Trouve = Standard_True;
533       }
534     }
535     if (Trouve) Trouve = IsG1(EFMap, E, FRef, FVoi);
536     if (Trouve) Trouve = IsInput(Pc.Vector(), Pc.Vertex(), FVoi);
537     if (Trouve) {
538       if (Num == 0) F1 = FVoi;
539       else F2 =  FVoi;
540       Num++;
541     }
542   }
543   return Num;
544 }
545
546 //=======================================================================
547 //function : ChangeTransition
548 //purpose  : Changes the transition of the second common Point, when the surface
549 //           does not cross the arc
550 //           As it is supposed that the support Faces are the same, it is enough
551 //           to examine the cas of cutting edges.
552 //========================================================================
553 static void ChangeTransition(const ChFiDS_CommonPoint&    Precedant,
554                              ChFiDS_CommonPoint&          Courant,
555                              Standard_Integer             FaceIndex,
556                              const Handle(TopOpeBRepDS_HDataStructure)& DS)
557 {
558   Standard_Boolean tochange = Standard_True;
559   Standard_Real f,l;
560   const TopoDS_Face& F = TopoDS::Face(DS->Shape(FaceIndex));
561   const TopoDS_Edge& Arc = Precedant.Arc();
562   Handle(Geom2d_Curve) PCurve1, PCurve2;
563   PCurve1 = BRep_Tool::CurveOnSurface(Arc, F, f, l);
564   TopoDS_Shape aLocalShape = Arc.Reversed();
565   PCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape), F, f, l);
566 //  PCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(Arc.Reversed()), F, f, l);
567   if (PCurve1 != PCurve2) { 
568     // This is a cutting edge, it is necessary to make a small Geometric test
569     gp_Vec tgarc;
570     gp_Pnt P;
571     BRepAdaptor_Curve AC(Arc);
572     AC.D1(Precedant.ParameterOnArc(), P, tgarc);
573     tochange = tgarc.IsParallel(Precedant.Vector(), Precision::Confusion());
574   }
575
576   if (tochange) 
577     Courant.SetArc(Precision::Confusion(), 
578                    Arc, 
579                    Precedant.ParameterOnArc(),
580                    TopAbs::Reverse(Precedant.TransitionOnArc()));
581
582 }
583
584 //=======================================================================
585 //function : CallPerformSurf
586 //purpose  : Encapsulates call to PerformSurf/SimulSurf
587 //========================================================================
588
589 void ChFi3d_Builder::
590 CallPerformSurf(Handle(ChFiDS_Stripe)&              Stripe,
591                 const Standard_Boolean              Simul,
592                 ChFiDS_SequenceOfSurfData&          SeqSD,
593                 Handle(ChFiDS_SurfData)&            SD,
594                 const Handle(ChFiDS_HElSpine)&      HGuide,
595                 const Handle(ChFiDS_Spine)&         Spine,
596                 const Handle(BRepAdaptor_HSurface)& HS1,
597                 const Handle(BRepAdaptor_HSurface)& HS3,
598                 const gp_Pnt2d&                     pp1,
599                 const gp_Pnt2d&                     pp3,
600                 const Handle(Adaptor3d_TopolTool)&          It1,
601                 const Handle(BRepAdaptor_HSurface)& HS2,
602                 const Handle(BRepAdaptor_HSurface)& HS4,
603                 const gp_Pnt2d&                     pp2,
604                 const gp_Pnt2d&                     pp4,
605                 const Handle(Adaptor3d_TopolTool)&          It2,
606                 const Standard_Real                 MaxStep,
607                 const Standard_Real                 Fleche,
608                 const Standard_Real                 /*TolGuide*/,
609                 Standard_Real&                      First,
610                 Standard_Real&                      Last,
611                 const Standard_Boolean              Inside,
612                 const Standard_Boolean              /*Appro*/,
613                 const Standard_Boolean              forward,
614                 const Standard_Boolean              RecOnS1,
615                 const Standard_Boolean              RecOnS2,
616                 math_Vector&                        Soldep,
617                 Standard_Boolean&                   intf,
618                 Standard_Boolean&                   intl,
619                 Handle(BRepAdaptor_HSurface)&       Surf1,
620                 Handle(BRepAdaptor_HSurface)&       Surf2) 
621 {
622 #ifdef OCCT_DEBUG
623   OSD_Chronometer ch1;
624 #endif 
625   Handle(BRepAdaptor_HSurface) HSon1, HSon2;
626   HSon1 = HS1;
627   HSon2 = HS2;
628   // Definition of the domain of path It1, It2
629   It1->Initialize((const Handle(Adaptor3d_HSurface)&)HSon1);
630   It2->Initialize((const Handle(Adaptor3d_HSurface)&)HSon2);
631
632
633   TopAbs_Orientation Or1 = HS1->ChangeSurface().Face().Orientation();
634   TopAbs_Orientation Or2 = HS2->ChangeSurface().Face().Orientation();
635   Standard_Integer Choix = 
636     ChFi3d::NextSide(Or1,Or2,
637                      Stripe->OrientationOnFace1(),
638                      Stripe->OrientationOnFace2(),
639                      Stripe->Choix());
640   Soldep(1) = pp1.X(); Soldep(2) = pp1.Y();
641   Soldep(3) = pp2.X(); Soldep(4) = pp2.Y();
642       
643   Standard_Real thef = First, thel = Last;
644   Standard_Boolean isdone;
645
646   if(Simul){
647     isdone = SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,HS2,It2,tolesp,First,Last,
648                        Inside,Inside,forward,RecOnS1,RecOnS2,Soldep,intf,intl);
649   }
650   else{
651         
652 #ifdef OCCT_DEBUG
653     ChFi3d_InitChron(ch1);//initial perform for PerformSurf
654 #endif
655         
656     isdone = PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,HS2,It2,
657                          MaxStep,Fleche,tolesp,
658                          First,Last,Inside,Inside,forward,
659                          RecOnS1,RecOnS2,Soldep,intf,intl);
660 #ifdef OCCT_DEBUG
661     ChFi3d_ResultChron(ch1,t_performsurf);// result perf for PerformSurf   
662 #endif
663   }
664
665  // Case of error
666  if (!isdone) {
667    First = thef;
668    Last = thel;
669    Standard_Boolean reprise = Standard_False;
670    if (! HS3.IsNull()) {
671      HSon1 = HS3;
672      It1->Initialize((const Handle(Adaptor3d_HSurface)&)HS3); 
673      Or1 = HS3->ChangeSurface().Face().Orientation();
674      Soldep(1) = pp3.X(); Soldep(2) = pp3.Y();
675      reprise = Standard_True;
676    }
677    else if (! HS4.IsNull()) {
678      HSon2 = HS4;
679      It2->Initialize((const Handle(Adaptor3d_HSurface)&)HS4); 
680      Or2 = HS4->ChangeSurface().Face().Orientation();
681      Soldep(3) = pp4.X(); Soldep(4) = pp4.Y();
682      reprise = Standard_True;
683    }
684
685    if (reprise) {
686      Choix = ChFi3d::NextSide(Or1,Or2,
687                               Stripe->OrientationOnFace1(),
688                               Stripe->OrientationOnFace2(),
689                               Stripe->Choix());
690      if(Simul){
691        isdone = SimulSurf(SD,HGuide,Spine,Choix,HSon1,It1,HSon2,It2,
692                           tolesp,First,Last,
693                           Inside,Inside,forward,RecOnS1,RecOnS2,
694                           Soldep,intf,intl);
695      }
696      else{
697         
698 #ifdef OCCT_DEBUG
699        ChFi3d_InitChron(ch1);//init perf for PerformSurf
700 #endif
701         
702        isdone = PerformSurf(SeqSD,HGuide,Spine,Choix,HSon1,It1,HSon2,It2,
703                             MaxStep,Fleche,tolesp,
704                             First,Last,Inside,Inside,forward,
705                             RecOnS1,RecOnS2,Soldep,intf,intl);
706 #ifdef OCCT_DEBUG
707        ChFi3d_ResultChron(ch1,t_performsurf);// result perf for PerformSurf   
708 #endif
709      }
710    }
711  }  
712   Surf1 = HSon1;
713   Surf2 = HSon2;
714 }
715
716 //=======================================================================
717 //function : StripeOrientation
718 //purpose  : Calculates the reference orientation determining the
719 //           concave face for construction of the fillet.
720 //=======================================================================
721
722 Standard_Boolean ChFi3d_Builder::StripeOrientations
723 (const Handle(ChFiDS_Spine)& Spine,
724  TopAbs_Orientation&         Or1,
725  TopAbs_Orientation&         Or2,
726  Standard_Integer&           ChoixConge) const 
727 {
728   //TopTools_ListIteratorOfListOfShape It;
729   BRepAdaptor_Surface Sb1,Sb2;
730   TopAbs_Orientation Of1,Of2;
731   TopoDS_Face ff1,ff2;
732   ChFi3d_conexfaces(Spine->Edges(1),ff1,ff2,myEFMap);
733   Of1 = ff1.Orientation();
734   ff1.Orientation(TopAbs_FORWARD);
735   Sb1.Initialize(ff1);
736   Of2 = ff2.Orientation();
737   ff2.Orientation(TopAbs_FORWARD);
738   Sb2.Initialize(ff2);
739
740   ChoixConge = ChFi3d::ConcaveSide(Sb1,Sb2,Spine->Edges(1),
741                                    Or1,Or2);
742   Or1 = TopAbs::Compose(Or1,Of1);
743   Or2 = TopAbs::Compose(Or2,Of2);
744   return Standard_True;
745 }
746
747
748 //=======================================================================
749 //function : ConexFaces
750 //purpose  : 
751 //=======================================================================
752
753 void ChFi3d_Builder::ConexFaces (const Handle(ChFiDS_Spine)&   Spine,
754                                  const Standard_Integer        IEdge,
755                                  const Standard_Integer        RC,      
756                                  Handle(BRepAdaptor_HSurface)& HS1,
757                                  Handle(BRepAdaptor_HSurface)& HS2) const
758 {
759   if(HS1.IsNull()) HS1 = new BRepAdaptor_HSurface ();
760   if(HS2.IsNull()) HS2 = new BRepAdaptor_HSurface ();
761   BRepAdaptor_Surface& Sb1 = HS1->ChangeSurface();
762   BRepAdaptor_Surface& Sb2 = HS2->ChangeSurface();
763
764   TopoDS_Face ff1,ff2;  
765   ChFi3d_conexfaces(Spine->Edges(IEdge),ff1,ff2,myEFMap);
766
767   Sb1.Initialize(ff1);
768   Sb2.Initialize(ff2);
769   
770   TopAbs_Orientation Or1,Or2;
771   Standard_Integer Choix = ChFi3d::ConcaveSide(Sb1,Sb2,Spine->Edges(IEdge),
772                                                Or1,Or2);  
773   if (RC%2 != Choix%2) {
774     Sb1.Initialize(ff2);
775     Sb2.Initialize(ff1);
776   }
777 }
778
779 //=======================================================================
780 //function : StartSol
781 //purpose  : Calculates a starting solution :
782 //           - one starts by parsing about ten points on the spine,
783 //           - in case of fail one finds the solution on neighbor faces;
784 //             section plane of edges of the adjacent face 
785 //             and identication of the face by connection to that edge.
786 //=======================================================================
787
788 void ChFi3d_Builder::StartSol(const Handle(ChFiDS_Stripe)&      Stripe,
789                               const Handle(ChFiDS_HElSpine)&    HGuide,
790                               Handle(BRepAdaptor_HSurface)&     HS1,
791                               Handle(BRepAdaptor_HSurface)&     HS2,
792                               Handle(BRepTopAdaptor_TopolTool)& I1,
793                               Handle(BRepTopAdaptor_TopolTool)& I2,
794                               gp_Pnt2d&                         P1,
795                               gp_Pnt2d&                         P2,
796                               Standard_Real&                    First) const 
797 {
798   Handle(ChFiDS_Spine)& Spine = Stripe->ChangeSpine();
799   ChFiDS_ElSpine& els = HGuide->ChangeCurve();
800   Standard_Integer nbed = Spine->NbEdges();
801   Standard_Integer nbessaimax = 3*nbed;
802   if (nbessaimax < 10) nbessaimax = 10;
803   Standard_Real unsurnbessaimax = 1./nbessaimax;
804   Standard_Real wf = 0.9981 * Spine->FirstParameter(1) +
805     0.0019 * Spine->LastParameter(1);
806   Standard_Real wl = 0.9973 * Spine->LastParameter(nbed) +
807     0.0027 * Spine->FirstParameter(nbed);
808
809   Standard_Real TolE = 1.0e-7;
810   BRepAdaptor_Surface AS;  
811
812   Standard_Integer nbessai;
813   Standard_Integer iedge = 0;
814   Standard_Integer RC = Stripe->Choix();
815   gp_Vec2d derive;
816   gp_Pnt2d P2d;
817   TopoDS_Edge cured;
818   TopoDS_Face f1,f2;
819   TopAbs_Orientation Or1,Or2;
820   Standard_Integer Choix = 0;
821   math_Vector SolDep(1,4);
822   Handle(Geom2d_Curve) PC;
823   Extrema_ExtPC PExt;
824   PExt.Initialize(els, 
825                   Spine->FirstParameter(1),
826                   Spine->LastParameter(nbed),
827                   Precision::Confusion());
828   TopAbs_State Pos1,Pos2;
829   for(nbessai = 0; nbessai <= nbessaimax; nbessai++){
830     Standard_Real t = nbessai*unsurnbessaimax;
831     Standard_Real w = wf * (1. -t) + wl * t;
832     Standard_Integer ie = Spine->Index(w);
833     if(iedge != ie){
834       iedge = ie;
835       cured = Spine->Edges(iedge);
836       TolE = BRep_Tool::Tolerance(cured);
837       ConexFaces(Spine,iedge,RC,HS1,HS2);
838       f1 = HS1->ChangeSurface().Face();
839       f2 = HS2->ChangeSurface().Face();
840       Or1 = f1.Orientation();
841       Or2 = f2.Orientation();
842       Choix = ChFi3d::NextSide(Or1,Or2,
843                                Stripe->OrientationOnFace1(),
844                                Stripe->OrientationOnFace2(),
845                                RC);
846     }
847
848     Standard_Real woned,Uf,Ul, ResU, ResV;
849     Spine->Parameter(iedge,w,woned,Standard_True);
850     cured.Orientation(TopAbs_FORWARD);
851     TopoDS_Face f1forward = f1, f2forward = f2;
852     f1forward.Orientation(TopAbs_FORWARD);
853     f2forward.Orientation(TopAbs_FORWARD);
854     PC = BRep_Tool::CurveOnSurface(cured,f1forward,Uf,Ul);
855     I1->Initialize((const Handle(Adaptor3d_HSurface)&)HS1);
856     PC->D1(woned, P1, derive);
857     // There are ponts on the border, and internal points are found
858     if (derive.Magnitude() > Precision::PConfusion()) {
859       derive.Normalized();
860       derive.Rotate(M_PI/2);
861       AS.Initialize(f1);
862       ResU = AS.UResolution(TolE);
863       ResV = AS.VResolution(TolE);
864       derive *= 2*(Abs(derive.X())*ResU + Abs(derive.Y())*ResV);
865       P2d = P1.Translated(derive);
866       if (I1->Classify(P2d, Min(ResU, ResV), 0)== TopAbs_IN) {
867         P1 = P2d;
868       }
869       else {
870          P2d = P1.Translated(-derive);
871          if (I1->Classify(P2d, Min(ResU, ResV), 0)== TopAbs_IN) {
872            P1 = P2d;
873          }
874       }
875     }
876     if(f1.IsSame(f2)) cured.Orientation(TopAbs_REVERSED);
877     PC = BRep_Tool::CurveOnSurface(cured,f2forward,Uf,Ul);
878     P2 = PC->Value(woned);
879     const Handle(Adaptor3d_HSurface)& HSon2 = HS2; // to avoid ambiguity
880     I2->Initialize(HSon2);
881
882     SolDep(1) = P1.X(); SolDep(2) = P1.Y();
883     SolDep(3) = P2.X(); SolDep(4) = P2.Y();
884     const BRepAdaptor_Curve& Ced = Spine->CurrentElementarySpine(iedge);
885     gp_Pnt pnt = Ced.Value(woned);
886   
887     if (Projection(PExt, pnt, els, w, tolesp) &&
888         PerformFirstSection(Spine,HGuide,Choix,HS1,HS2,
889                             I1,I2,w,SolDep,Pos1,Pos2)) {
890       P1.SetCoord(SolDep(1),SolDep(2));
891       P2.SetCoord(SolDep(3),SolDep(4));
892       First = w;
893       return;
894     }
895   }
896   // No solution was found for the faces adjacent to the trajectory.
897   // Now one tries the neighbor faces.
898   iedge = 0;
899   for(nbessai = 0; nbessai <= nbessaimax; nbessai++){
900     Standard_Real t = nbessai*unsurnbessaimax;
901     Standard_Real w = wf * (1. -t) + wl * t;
902     iedge = Spine->Index(w);
903     cured = Spine->Edges(iedge);
904     ConexFaces(Spine,iedge,RC,HS1,HS2);
905     f1 = HS1->ChangeSurface().Face();
906     f2 = HS2->ChangeSurface().Face();
907     Or1 = f1.Orientation();
908     Or2 = f2.Orientation();
909     Choix = ChFi3d::NextSide(Or1,Or2,
910                              Stripe->OrientationOnFace1(),
911                              Stripe->OrientationOnFace2(),
912                              RC);
913     Standard_Real woned,Uf,Ul;
914     Spine->Parameter(iedge,w,woned,Standard_True);
915     TopoDS_Face f1forward = f1, f2forward = f2;
916     f1forward.Orientation(TopAbs_FORWARD);
917     f2forward.Orientation(TopAbs_FORWARD);
918     PC = BRep_Tool::CurveOnSurface(cured,f1forward,Uf,Ul);
919     P1 = PC->Value(woned);
920     PC = BRep_Tool::CurveOnSurface(cured,f2forward,Uf,Ul);
921     P2 = PC->Value(woned);
922     const Handle(Adaptor3d_HSurface)& HSon1 = HS1; // to avoid ambiguity
923     const Handle(Adaptor3d_HSurface)& HSon2 = HS2; // to avoid ambiguity
924     I1->Initialize(HSon1);
925     I2->Initialize(HSon2);
926     SolDep(1) = P1.X(); SolDep(2) = P1.Y();
927     SolDep(3) = P2.X(); SolDep(4) = P2.Y();
928     const BRepAdaptor_Curve& Ced = Spine->CurrentElementarySpine(iedge);
929     gp_Pnt pnt = Ced.Value(woned);
930 //    Extrema_LocateExtPC ext(pnt,els,w,1.e-8);
931 //    if(ext.IsDone()){
932 //      w = ext.Point().Parameter(); 
933     if (Projection(PExt, pnt, els, w, tolesp)) {
934       PerformFirstSection(Spine,HGuide,Choix,HS1,HS2,
935                           I1,I2,w,SolDep,Pos1,Pos2);
936       gp_Pnt P;
937       gp_Vec V;
938       HGuide->D1(w,P,V);
939       Handle(Geom_Plane) pl = new Geom_Plane(P,V);
940       Handle(GeomAdaptor_HSurface) plane = new GeomAdaptor_HSurface(pl);
941
942       Standard_Boolean bonvoisin = 1, found = 0;
943       Standard_Integer NbChangement;
944       for (NbChangement = 1; bonvoisin && (!found) && (NbChangement < 5);
945            NbChangement++) {
946         if(Pos1 != TopAbs_IN){
947           bonvoisin = BonVoisin(P, HS1, f1, plane, cured, 
948                                 SolDep(1),SolDep(2), myEFMap, tolesp); 
949         }
950         if(Pos2 != TopAbs_IN && bonvoisin){
951           bonvoisin = BonVoisin(P, HS2, f2, plane, cured, 
952                                 SolDep(3),SolDep(4), myEFMap, tolesp);
953         } 
954         if(bonvoisin){
955           f1 = HS1->ChangeSurface().Face();
956           f2 = HS2->ChangeSurface().Face();
957           Or1 = f1.Orientation();
958           Or2 = f2.Orientation();
959           Choix = ChFi3d::NextSide(Or1,Or2,
960                                    Stripe->OrientationOnFace1(),
961                                    Stripe->OrientationOnFace2(),
962                                    RC);
963           const Handle(Adaptor3d_HSurface)& HSon1 = HS1; // to avoid ambiguity
964           const Handle(Adaptor3d_HSurface)& HSon2 = HS2; // to avoid ambiguity
965           I1->Initialize(HSon1);
966           I2->Initialize(HSon2);
967           if(PerformFirstSection(Spine,HGuide,Choix,HS1,HS2,
968                                  I1,I2,w,SolDep,Pos1,Pos2)){
969             P1.SetCoord(SolDep(1),SolDep(2));
970             P2.SetCoord(SolDep(3),SolDep(4));
971             First = w;
972             found = Standard_True;
973           }
974         }
975       }
976       if (found) return;
977     }
978   }
979   Spine->SetErrorStatus(ChFiDS_StartsolFailure);
980   Standard_Failure::Raise("StartSol echec");
981 }
982
983 //=======================================================================
984 //function : ChFi3d_BuildPlane
985 //purpose  : 
986 //=======================================================================
987
988 static void  ChFi3d_BuildPlane (TopOpeBRepDS_DataStructure&    DStr,
989                                 Handle(BRepAdaptor_HSurface)&  HS,
990                                 gp_Pnt2d&                      pons,
991                                 const Handle(ChFiDS_SurfData)& SD,
992                                 const Standard_Boolean         isfirst,
993                                 const Standard_Integer         ons)
994 {
995   Handle(Geom2d_Curve) Hc;      
996   TopoDS_Face F = TopoDS::Face(DStr.Shape(SD->Index(ons)));
997   Standard_Real u,v;
998   gp_Pnt P;
999   //gp_Vec V1,V2;
1000   
1001   if (SD->Vertex(isfirst,ons).IsOnArc()){
1002     Hc = BRep_Tool::CurveOnSurface
1003       (SD->Vertex(isfirst,ons).Arc(),F,u,v);
1004     Hc->Value(SD->Vertex(isfirst,ons).ParameterOnArc()).Coord(u,v);
1005     BRepLProp_SLProps theProp(HS->ChangeSurface(), u, v, 1, 1.e-12);
1006     if  (theProp.IsNormalDefined()) {
1007       P =  theProp.Value();
1008       Handle(Geom_Plane) Pln  = new Geom_Plane(P, theProp.Normal());
1009       TopoDS_Face        NewF = BRepLib_MakeFace(Pln, Precision::Confusion());
1010       NewF.Orientation(F.Orientation());
1011       pons.SetCoord(0.,0.);
1012       HS->ChangeSurface().Initialize(NewF);
1013       return; // everything is good !
1014     }
1015   }
1016   Standard_Failure::Raise("ChFi3d_BuildPlane : echec .");
1017 }
1018
1019 //=======================================================================
1020 //function : StartSol
1021 //purpose  : If the commonpoint is not OnArc the input face
1022 //           is returned and 2D point is updated,
1023 //           if it is OnArc
1024 //              if it is detached  the input face
1025 //              is returned and 2D point is updated,
1026 //              otherwise
1027 //                 either there is a neighbor tangent face and it is returned
1028 //                         with recalculated 2D point
1029 //                 or if there is no face 
1030 //                         if the reference arc is Vref (extremity of the spine)
1031 //                            this is the end and the input face is returned 
1032 //                         otherwise this is an obstacle and HC is updated.
1033 //=======================================================================
1034
1035 Standard_Boolean  
1036 ChFi3d_Builder::StartSol(const Handle(ChFiDS_Spine)&    Spine,
1037                          Handle(BRepAdaptor_HSurface)&  HS, // New face
1038                          gp_Pnt2d&                      pons,// " Localization
1039                          Handle(BRepAdaptor_HCurve2d)&  HC, // Representation of the obstacle
1040                          Standard_Real&                 W,
1041                          const Handle(ChFiDS_SurfData)& SD,
1042                          const Standard_Boolean         isfirst,
1043                          const Standard_Integer         ons,
1044                          Handle(BRepAdaptor_HSurface)&  HSref, // The other representation
1045                          Handle(BRepAdaptor_HCurve2d)&  HCref, // of the obstacle          
1046                          Standard_Boolean&              RecP,
1047                          Standard_Boolean&              RecS,
1048                          Standard_Boolean&              RecRst,
1049                          Standard_Boolean&              c1obstacle,
1050                          Handle(BRepAdaptor_HSurface)&  HSBis, // Face of support       
1051                          gp_Pnt2d&                      PBis,  // and its point
1052                          const Standard_Boolean         decroch,
1053                          const TopoDS_Vertex&           Vref) const 
1054 {
1055   RecRst = RecS = RecP = c1obstacle = 0;
1056   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
1057   TopoDS_Face Fv,Fref;
1058   //gp_Pnt2d  pp1,pp2;
1059   Handle(Geom2d_Curve) pc;      
1060   Standard_Real Uf,Ul;
1061   
1062   TopoDS_Face F = TopoDS::Face(DStr.Shape(SD->Index(ons)));
1063   if(!HSref.IsNull()) Fref = HSref->ChangeSurface().Face();
1064   const ChFiDS_CommonPoint& CP = SD->Vertex(isfirst,ons);
1065   HSBis.Nullify();
1066
1067   if (CP.IsOnArc()) {
1068     Standard_Integer notons;
1069     if (ons == 1)  notons = 2;
1070     else           notons = 1;
1071     const ChFiDS_CommonPoint& CPbis = SD->Vertex(isfirst,notons);
1072     if (CPbis.IsOnArc()) { // It is checked if it is not the extension zone 
1073                   // In case CP is not at the end of surfdata and it is not necesary to take it into account
1074                   // except for separate cases (ie pointus) ...
1075       //ts and tns were earlier CP.Parameter() and CPbis.Parameter, but sometimes they had no values.
1076       Standard_Real ts=SD->Interference(ons).Parameter(isfirst), tns=SD->Interference(notons).Parameter(isfirst);
1077       Standard_Boolean isExtend;
1078       // Arbitrary test (to precise)
1079       if (isfirst) isExtend = (ts-tns > 100*tolesp); 
1080       else         isExtend = (tns-ts > 100*tolesp);
1081       if (isExtend && !CP.Point().IsEqual(CPbis.Point(), 0) ) {
1082         //  the state is preserved and False is returned (extension by the expected plane).
1083         HS->ChangeSurface().Initialize(F);
1084         pc = SD->Interference(ons).PCurveOnFace();
1085         // The 2nd point is given by its trace on the support surface
1086         RecS = Standard_False;
1087         pons = pc->Value(tns);
1088         return Standard_False;
1089       }
1090     }
1091   }  
1092   
1093   if (CP.IsVertex() && !HC.IsNull() && !decroch){
1094     //The edge is changed, the parameter is updated and
1095     //eventually the support face and(or) the reference face.
1096     TopoDS_Vertex VCP = CP.Vertex();
1097     TopoDS_Edge EHC = HC->ChangeCurve2d().Edge();
1098     //One starts by searching in Fref another edge referencing VCP.
1099     TopExp_Explorer ex1,ex2;
1100     TopoDS_Edge newedge, edgereg;
1101     TopoDS_Face bidface = Fref, facereg;
1102     bidface.Orientation(TopAbs_FORWARD);
1103     for(ex1.Init(bidface,TopAbs_EDGE); ex1.More(); ex1.Next()){
1104       const TopoDS_Edge& cured = TopoDS::Edge(ex1.Current());
1105       Standard_Boolean found = 0;
1106       if(!cured.IsSame(EHC)){
1107         for(ex2.Init(cured,TopAbs_VERTEX); ex2.More() && !found; ex2.Next()){
1108           if(ex2.Current().IsSame(VCP)){
1109             if(IsG1(myEFMap,cured,Fref,Fv)){
1110               edgereg = cured;
1111               facereg = Fv;
1112             }
1113             else found = 1;
1114           }
1115         }
1116       }
1117       if(found) {
1118         newedge = cured;
1119         break;
1120       }
1121     }
1122     if(newedge.IsNull()){
1123       //It is checked if EHC is not a closed edge.
1124       TopoDS_Vertex V1,V2;
1125       TopExp::Vertices(EHC,V1,V2);
1126       if(V1.IsSame(V2)){
1127         newedge = EHC;
1128         Standard_Real w1 = BRep_Tool::Parameter(V1,EHC);
1129         Standard_Real w2 = BRep_Tool::Parameter(V2,EHC);
1130         const ChFiDS_FaceInterference& fi = SD->Interference(ons);
1131         const Handle(Geom2d_Curve)& pcf = fi.PCurveOnFace();
1132         Standard_Real ww = fi.Parameter(isfirst);
1133         
1134         gp_Pnt2d pww;
1135         if(!pcf.IsNull()) pww = pcf->Value(ww);
1136         else pww = SD->Get2dPoints(isfirst,ons);
1137         gp_Pnt2d p1 = HC->Value(w1);
1138         gp_Pnt2d p2 = HC->Value(w2);
1139         
1140         if(p1.Distance(pww) >  p2.Distance(pww)){
1141           W = w1;
1142           pons = p1;
1143         }
1144         else {
1145           W = w2;
1146           pons = p2;
1147         }
1148         RecP = c1obstacle = 1;
1149         return 1;
1150       }
1151       else if(!edgereg.IsNull()){
1152         // the reference edge and face are changed.
1153         Fref = facereg;
1154         HSref->ChangeSurface().Initialize(Fref);
1155         for(ex1.Init(facereg,TopAbs_EDGE); ex1.More() && newedge.IsNull(); ex1.Next()){
1156           const TopoDS_Edge& cured = TopoDS::Edge(ex1.Current());
1157           if(!cured.IsSame(edgereg)){
1158             for(ex2.Init(cured,TopAbs_VERTEX); ex2.More(); ex2.Next()){
1159               if(ex2.Current().IsSame(VCP)){
1160                 if(!IsG1(myEFMap,cured,Fref,Fv)){
1161                   newedge = cured;
1162                 }
1163               }
1164             }
1165           }
1166         }
1167       }
1168     }
1169     // it is necessary to find the new support face of the fillet : 
1170     // connected to FRef along the newedge.
1171     if(newedge.IsNull()) {
1172       Standard_Failure::Raise
1173         ("StartSol : chain is not possible, new obstacle not found");
1174     }
1175     if(IsG1(myEFMap,newedge,Fref,Fv)){
1176       Standard_Failure::Raise
1177         ("StartSol : chain is not possible, config non processed");
1178     }
1179     else if(Fv.IsNull()){
1180       Standard_Failure::Raise
1181         ("StartSol : chain is not possible, new obstacle not found");
1182     }
1183     else{
1184       HS->ChangeSurface().Initialize(Fv);
1185       W = BRep_Tool::Parameter(VCP,newedge);
1186       HCref->ChangeCurve2d().Initialize(newedge,Fref);
1187       TopoDS_Face newface = Fv;
1188       newface.Orientation(TopAbs_FORWARD);
1189       TopExp_Explorer ex;
1190       for(ex.Init(newface,TopAbs_EDGE); ex.More(); ex.Next()){
1191         if(ex.Current().IsSame(newedge)){
1192           newedge = TopoDS::Edge(ex.Current());
1193           break;
1194         }
1195       }
1196       HC->ChangeCurve2d().Initialize(newedge,Fv);
1197       pons = HC->Value(W);
1198     }
1199     RecP = c1obstacle = 1;
1200     return 1;
1201   } // End of Case Vertex && Obstacle 
1202
1203   else if (CP.IsOnArc() && !HC.IsNull() && !decroch){
1204     //Nothing is changed, the parameter is only updated.
1205     W = CP.ParameterOnArc();
1206     c1obstacle = 1;
1207     return 1;
1208   }
1209   
1210   HC.Nullify();
1211   
1212   if (CP.IsOnArc()){
1213     const TopoDS_Edge& E = CP.Arc();
1214     if(decroch){
1215       HS->ChangeSurface().Initialize(Fref);
1216       W = CP.ParameterOnArc();
1217       pc = BRep_Tool::CurveOnSurface(E,Fref,Uf,Ul);
1218       pons = pc->Value(W);
1219       RecS = 1;
1220       return 1;
1221     }
1222     if (SearchFace(Spine,CP,F,Fv)){
1223       HS->ChangeSurface().Initialize(Fv);
1224       RecS = 1;
1225       if (CP.IsVertex()) { 
1226         // One goes directly by the Vertex
1227         Standard_Integer Nb;
1228         TopoDS_Face aux;
1229         // And it is checked that there are no other candidates
1230         Nb = SearchFaceOnV(CP, F, myVEMap, myEFMap, Fv, aux);
1231
1232         pons = BRep_Tool::Parameters(CP.Vertex(), Fv);
1233         HS->ChangeSurface().Initialize(Fv);
1234         if (Nb >=2) {
1235           HSBis = new (BRepAdaptor_HSurface)(aux);
1236           PBis = BRep_Tool::Parameters(CP.Vertex(), aux);
1237         }
1238         return 1;
1239       }
1240       // otherwise one passes by the arc...
1241       if(!Fv.IsSame(F)){
1242         Fv.Orientation(TopAbs_FORWARD);
1243         TopoDS_Edge newedge;
1244         TopExp_Explorer ex;
1245         for(ex.Init(Fv,TopAbs_EDGE); ex.More(); ex.Next()){
1246           if(ex.Current().IsSame(E)){
1247             newedge = TopoDS::Edge(ex.Current());
1248             break;
1249           }
1250         }
1251         //gp_Vec Varc, VSurf;
1252         // In cas of Tangent output, the current face becomes the support face
1253         if (SortieTangente(CP, F, SD, ons, 0.1)) { 
1254           pc = BRep_Tool::CurveOnSurface(CP.Arc(),F,Uf,Ul);
1255           HSBis = new (BRepAdaptor_HSurface)(F);
1256           PBis = pc->Value(CP.ParameterOnArc());
1257         }
1258         
1259
1260         pc = BRep_Tool::CurveOnSurface(newedge,Fv,Uf,Ul);
1261       }
1262       else{
1263         TopoDS_Edge newedge = E;
1264         newedge.Reverse();
1265         Fv.Orientation(TopAbs_FORWARD);
1266         pc = BRep_Tool::CurveOnSurface(newedge,Fv,Uf,Ul);
1267       }
1268       pons = pc->Value(CP.ParameterOnArc());
1269       return 1;
1270     }
1271     else if(!Fv.IsNull()){    
1272       c1obstacle = 1;
1273       if(!Vref.IsNull()){
1274         TopExp_Explorer ex;
1275         for(ex.Init(E,TopAbs_VERTEX); ex.More(); ex.Next()){
1276           if(ex.Current().IsSame(Vref)){
1277             c1obstacle = 0;
1278             break;
1279           }
1280         }
1281       }
1282       if(c1obstacle){
1283         HS->ChangeSurface().Initialize(Fv);
1284         HSref->ChangeSurface().Initialize(F);
1285         W = CP.ParameterOnArc();
1286         HC = new BRepAdaptor_HCurve2d();
1287         TopoDS_Edge newedge;
1288         TopoDS_Face newface = Fv;
1289         newface.Orientation(TopAbs_FORWARD);
1290         TopExp_Explorer ex;
1291         for(ex.Init(newface,TopAbs_EDGE); ex.More(); ex.Next()){
1292           if(ex.Current().IsSame(E)){
1293             newedge = TopoDS::Edge(ex.Current());
1294             break;
1295           }
1296         }
1297         HC->ChangeCurve2d().Initialize(newedge,Fv);
1298         pons = HC->Value(W);
1299         HCref->ChangeCurve2d().Initialize(E,F);
1300         if(CP.IsVertex()) RecP = 1;
1301         else RecRst = 1;
1302         return 1;
1303       }
1304       else{
1305         HS->ChangeSurface().Initialize(F);
1306         W = CP.ParameterOnArc();
1307         pc = BRep_Tool::CurveOnSurface(E,F,Uf,Ul);
1308         pons = pc->Value(W);
1309         return Standard_False;
1310       }
1311     }
1312     else{ // there is no neighbor face, the state is preserved and False is returned.
1313       HS->ChangeSurface().Initialize(F);
1314       W = CP.ParameterOnArc();
1315       pc = BRep_Tool::CurveOnSurface(E,F,Uf,Ul);
1316       pons = pc->Value(W);
1317       return Standard_False;
1318     }
1319   }
1320   else{
1321     HS->ChangeSurface().Initialize(F);
1322     const ChFiDS_FaceInterference& FI = SD->Interference(ons);
1323     if(FI.PCurveOnFace().IsNull()) pons = SD->Get2dPoints(isfirst,ons);
1324     else pons = FI.PCurveOnFace()->Value(FI.Parameter(isfirst));
1325   }
1326   return Standard_True;
1327 }
1328
1329 //=======================================================================
1330 //function : SearchFace
1331 //purpose  : 
1332 //=======================================================================
1333
1334 Standard_Boolean  ChFi3d_Builder::SearchFace
1335                  (const Handle(ChFiDS_Spine)&  Spine,
1336                   const ChFiDS_CommonPoint&    Pc,
1337                   const TopoDS_Face&           FRef,
1338                   TopoDS_Face&                 FVoi) const
1339 {
1340   Standard_Boolean Trouve = Standard_False;
1341   if (! Pc.IsOnArc()) return Standard_False;
1342   FVoi.Nullify();
1343   TopoDS_Edge E;
1344   if (Pc.IsVertex()){
1345     // attention it is necessary to analyze all faces that turn around of the vertex
1346 #ifdef OCCT_DEBUG
1347     cout<<"Commonpoint on vertex, the process hangs up"<<endl;
1348 #endif
1349     if (Pc.HasVector()) { //General processing
1350       TopoDS_Face Fbis;
1351       Standard_Integer nb_faces;
1352       nb_faces = SearchFaceOnV(Pc,  FRef, myVEMap, myEFMap, FVoi, Fbis);
1353       return ( nb_faces > 0);
1354     }
1355     else { // Processing using the spine
1356       Standard_Boolean  FindFace=Standard_False;
1357       gp_Pnt Point;
1358       gp_Vec VecSpine;
1359       Spine->D1(Pc.Parameter(), Point, VecSpine);
1360     
1361       // It is checked if one leaves from the current face.
1362       FindFace = IsInput(VecSpine, Pc.Vertex(), FRef);
1363       if (FindFace) {
1364         VecSpine.Reverse();
1365         FindFace = IsInput(VecSpine, Pc.Vertex(), FRef);
1366       }
1367       // If one does not leave, it is ended
1368       if (FindFace) {
1369         FVoi = FRef;
1370         return Standard_True;
1371       }
1372     
1373       // Otherwise one finds the next among shared Faces 
1374       // by a common edge G1
1375       TopTools_ListIteratorOfListOfShape ItE, ItF;
1376       for(ItE.Initialize(myVEMap(Pc.Vertex()));
1377           ItE.More() && (!FindFace); ItE.Next()) {
1378         E = TopoDS::Edge(ItE.Value());
1379         Trouve=Standard_False;
1380         for(ItF.Initialize(myEFMap(E));//, Trouve=Standard_False;           15.11.99 SVV
1381             ItF.More()&&(!Trouve); ItF.Next()) {
1382           if (TopoDS::Face(ItF.Value()).IsSame(FRef)) {
1383             Trouve = Standard_True;
1384           }
1385         }
1386         if (Trouve) FindFace = IsG1(myEFMap, E, FRef, FVoi);
1387         if (FindFace) { 
1388           FindFace = Standard_False;
1389           if (Spine.IsNull()) {
1390             //La Spine peut etre nulle (ThreeCorner)
1391 #ifdef OCCT_DEBUG
1392             cout << "FindFace sur vertex avec spine nulle! QUEZAKO ?" << endl;
1393 #endif
1394             return Standard_False;
1395           }
1396         
1397           // It is checked if the selected face actually possesses edges of the spine
1398           // containing the vertex on its front
1399           // This processing should go only if the Vertex belongs to the spine
1400           // This is a single case, for other vertexes it is required to do other things
1401           Trouve=Standard_False;
1402           for (Standard_Integer IE=1;//, Trouve=Standard_False;                   15.11.99  SVV
1403                (IE<=Spine->NbEdges()) && (!Trouve); IE++) {
1404             E = Spine->Edges(IE);
1405             if (  (TopExp::FirstVertex(E).IsSame(Pc.Vertex())) 
1406                 ||(TopExp::LastVertex(E) .IsSame(Pc.Vertex())) ) {
1407               for(ItF.Initialize(myEFMap(E)), Trouve=Standard_False;
1408                   ItF.More()&&(!Trouve); ItF.Next()) {
1409                 if (TopoDS::Face(ItF.Value()).IsSame(FVoi)) {
1410                   Trouve = Standard_True;
1411                 }
1412               }
1413             }
1414           } 
1415           FindFace = Trouve;
1416         }
1417       }
1418     }
1419   }
1420   else {
1421     return IsG1(myEFMap, Pc.Arc(), FRef, FVoi);
1422   }
1423   return Standard_False;
1424 }
1425
1426
1427 //=======================================================================
1428 //function : ChFi3d_SingularExtremity
1429 //purpose  : load the vertex in the DS and calculate the pcurve 
1430 //           for an extremity in case of singular freeboundary 
1431 //           or periodic and singular at the cut.
1432 //=======================================================================
1433 static void ChFi3d_SingularExtremity( Handle(ChFiDS_Stripe)&     stripe,
1434                                      TopOpeBRepDS_DataStructure& DStr,
1435                                      const TopoDS_Vertex&        Vtx,      
1436                                      const Standard_Real         tol3d,
1437                                      const Standard_Real         tol2d)
1438 {
1439   Handle(ChFiDS_SurfData) Fd;
1440   Standard_Real tolreached;
1441   Standard_Real Pardeb, Parfin; 
1442   gp_Pnt2d VOnS1, VOnS2;
1443   Handle(Geom_Curve) C3d;
1444   Handle(Geom2d_Curve) PCurv;
1445   TopOpeBRepDS_Curve Crv;
1446   // SurfData and its CommonPoints,
1447   Standard_Integer Ivtx, Icurv;
1448   Standard_Boolean isfirst;
1449   
1450   if  (stripe->Spine()->IsPeriodic()) {
1451      isfirst = Standard_True;
1452      Fd = stripe->SetOfSurfData()->Sequence().First();
1453    }
1454   else {
1455     Standard_Integer sens;
1456     Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens);
1457     Fd =  stripe->SetOfSurfData()->Sequence().Value(num);
1458     isfirst = (sens == 1);
1459   }
1460  
1461   const ChFiDS_CommonPoint& CV1 = Fd->Vertex(isfirst,1);
1462   const ChFiDS_CommonPoint& CV2 = Fd->Vertex(isfirst,2);
1463   // Is it always degenerated ?
1464   if ( CV1.Point().IsEqual( CV2.Point(), 0) ) { 
1465     Ivtx = ChFi3d_IndexPointInDS(CV1, DStr);
1466     if (isfirst) {
1467       VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()->
1468                    Value(Fd->InterferenceOnS1().FirstParameter());
1469       VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()->
1470                      Value(Fd->InterferenceOnS2().FirstParameter());
1471     }
1472     else {
1473       VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()->
1474                     Value(Fd->InterferenceOnS1().LastParameter());
1475       VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()->
1476                     Value(Fd->InterferenceOnS2().LastParameter());
1477     }
1478       
1479     ChFi3d_ComputeArete(CV1, VOnS1,
1480                         CV2, VOnS2,
1481                         DStr.Surface(Fd->Surf()).Surface(),
1482                         C3d, PCurv,
1483                         Pardeb,Parfin, tol3d, tol2d, tolreached,0);
1484     Crv = TopOpeBRepDS_Curve(C3d,tolreached);
1485     Icurv = DStr.AddCurve(Crv);
1486
1487     stripe->SetCurve(Icurv, isfirst);
1488     stripe->SetParameters(isfirst, Pardeb,Parfin);
1489     stripe->ChangePCurve(isfirst) = PCurv;
1490     stripe->SetIndexPoint(Ivtx, isfirst, 1);
1491     stripe->SetIndexPoint(Ivtx, isfirst, 2);
1492
1493     if (stripe->Spine()->IsPeriodic()) { 
1494       // periodic case : The operation is renewed
1495       // the curve 3d is not shared.
1496       // 2 degenerated edges coinciding in 3d
1497       isfirst = Standard_False;
1498       Fd = stripe->SetOfSurfData()->Sequence().Last();
1499       VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()->
1500               Value(Fd->InterferenceOnS1().LastParameter());
1501       VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()->
1502               Value(Fd->InterferenceOnS2().LastParameter());
1503
1504       ChFi3d_ComputeArete(CV1, VOnS1,
1505                           CV2, VOnS2,
1506                           DStr.Surface(Fd->Surf()).Surface(),
1507                           C3d, PCurv,
1508                           Pardeb,Parfin, tol3d, tol2d, tolreached,0);
1509       Crv = TopOpeBRepDS_Curve(C3d,tolreached);
1510       Icurv = DStr.AddCurve(Crv);
1511
1512       stripe->SetCurve(Icurv, isfirst);
1513       stripe->SetParameters(isfirst, Pardeb,Parfin);
1514       stripe->ChangePCurve(isfirst) = PCurv;
1515       stripe->SetIndexPoint(Ivtx, isfirst, 1);
1516       stripe->SetIndexPoint(Ivtx, isfirst, 2);    
1517     }
1518   }
1519 }
1520
1521 //=======================================================================
1522 //function : ChFi3d_MakeExtremities
1523 //purpose  : calculate Curves3d and pcurves of extremities in
1524 //           periodic and freeboundary cases.
1525 //=======================================================================
1526 static Standard_Boolean IsFree(const TopoDS_Shape& E,
1527                                const ChFiDS_Map&   EFMap)
1528 {
1529   if(!EFMap.Contains(E)) return 0;
1530   TopTools_ListIteratorOfListOfShape It;
1531   TopoDS_Shape Fref;
1532   for(It.Initialize(EFMap(E)); It.More(); It.Next()){
1533     if(Fref.IsNull()) Fref = It.Value();
1534     else if(!Fref.IsSame(It.Value())) return 0;
1535   }
1536   return 1;
1537 }
1538
1539 static void ChFi3d_MakeExtremities(Handle(ChFiDS_Stripe)&      Stripe,
1540                                    TopOpeBRepDS_DataStructure& DStr,
1541                                    const ChFiDS_Map&           EFMap,
1542                                    const Standard_Real         tol3d,
1543                                    const Standard_Real         tol2d)
1544 {
1545   Handle(ChFiDS_Spine)& sp = Stripe->ChangeSpine();
1546   Standard_Real Pardeb,Parfin;
1547   Handle(Geom_Curve) C3d;
1548   Standard_Real tolreached;
1549   if(sp->IsPeriodic()){
1550     Bnd_Box b1,b2;
1551     const Handle(ChFiDS_SurfData)& 
1552       SDF = Stripe->SetOfSurfData()->Sequence().First();
1553     const ChFiDS_CommonPoint& CV1 = SDF->VertexFirstOnS1();
1554     const ChFiDS_CommonPoint& CV2 = SDF->VertexFirstOnS2();
1555     if ( !CV1.Point().IsEqual(CV2.Point(), 0) ) { 
1556       ChFi3d_ComputeArete(CV1,
1557                           SDF->InterferenceOnS1().PCurveOnSurf()->
1558                           Value(SDF->InterferenceOnS1().FirstParameter()),
1559                           CV2,
1560                           SDF->InterferenceOnS2().PCurveOnSurf()-> 
1561                           Value(SDF->InterferenceOnS2().FirstParameter()),
1562                           DStr.Surface(SDF->Surf()).Surface(),C3d,
1563                           Stripe->ChangeFirstPCurve(),Pardeb,Parfin,
1564                           tol3d,tol2d,tolreached,0);
1565       TopOpeBRepDS_Curve Crv(C3d,tolreached);
1566       Stripe->ChangeFirstCurve(DStr.AddCurve(Crv));
1567       Stripe->ChangeFirstParameters(Pardeb,Parfin);
1568       Stripe->ChangeIndexFirstPointOnS1
1569         (ChFi3d_IndexPointInDS(SDF->VertexFirstOnS1(),DStr));
1570       Stripe->ChangeIndexFirstPointOnS2
1571         (ChFi3d_IndexPointInDS(SDF->VertexFirstOnS2(),DStr));
1572       Standard_Integer ICurv = Stripe->FirstCurve();
1573       Stripe->ChangeLastParameters(Pardeb,Parfin);
1574       Stripe->ChangeLastCurve(ICurv);
1575       Stripe->ChangeIndexLastPointOnS1(Stripe->IndexFirstPointOnS1());
1576       Stripe->ChangeIndexLastPointOnS2(Stripe->IndexFirstPointOnS2());
1577       
1578       const Handle(ChFiDS_SurfData)& 
1579         SDL = Stripe->SetOfSurfData()->Sequence().Last();
1580       
1581       
1582       ChFi3d_ComputePCurv(C3d,
1583                           SDL->InterferenceOnS1().PCurveOnSurf()->
1584                           Value(SDL->InterferenceOnS1().LastParameter()),
1585                           SDL->InterferenceOnS2().PCurveOnSurf()->
1586                           Value(SDL->InterferenceOnS2().LastParameter()),
1587                           Stripe->ChangeLastPCurve(),
1588                           DStr.Surface(SDL->Surf()).Surface(),
1589                           Pardeb,Parfin,tol3d,tolreached);
1590       Standard_Real oldtol = DStr.ChangeCurve(ICurv).Tolerance();
1591       DStr.ChangeCurve(ICurv).Tolerance(Max(oldtol,tolreached));
1592       if(CV1.IsOnArc()){
1593         ChFi3d_EnlargeBox(CV1.Arc(),EFMap(CV1.Arc()),CV1.ParameterOnArc(),b1);
1594       }
1595       
1596       if(CV2.IsOnArc()){
1597         ChFi3d_EnlargeBox(CV2.Arc(),EFMap(CV2.Arc()),CV2.ParameterOnArc(),b2);
1598       }
1599       ChFi3d_EnlargeBox(DStr,Stripe,SDF,b1,b2,1);
1600       ChFi3d_EnlargeBox(DStr,Stripe,SDL,b1,b2,0);
1601       if (!CV1.IsVertex())
1602         ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexFirstPointOnS1());
1603       if (!CV2.IsVertex())
1604         ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexFirstPointOnS2());
1605     }
1606     else {
1607       // Case of the single extremity
1608       if (CV1.IsVertex()) { 
1609         ChFi3d_SingularExtremity(Stripe, DStr, CV1.Vertex(), tol3d, tol2d);
1610       }
1611 # if CHFI3D_DEB
1612       else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; }
1613 # endif
1614     }
1615     return;
1616   }  
1617   
1618   const Handle(ChFiDS_SurfData)& 
1619     SDdeb = Stripe->SetOfSurfData()->Sequence().First();
1620     
1621   const ChFiDS_CommonPoint& cpdeb1 = SDdeb->VertexFirstOnS1();
1622   const ChFiDS_CommonPoint& cpdeb2 = SDdeb->VertexFirstOnS2();
1623   Standard_Boolean freedeb = sp->FirstStatus() == ChFiDS_FreeBoundary;
1624   if(!freedeb && cpdeb1.IsOnArc() && cpdeb2.IsOnArc()){
1625     freedeb = (IsFree(cpdeb1.Arc(),EFMap) && IsFree(cpdeb2.Arc(),EFMap));
1626   }
1627   if(freedeb){
1628     sp->SetFirstStatus(ChFiDS_FreeBoundary);
1629     Bnd_Box b1,b2;
1630     if ( !cpdeb1.Point().IsEqual(cpdeb2.Point(), 0) ) { 
1631       Standard_Boolean plane;  
1632       gp_Pnt2d UV1,UV2;
1633       UV1=SDdeb->InterferenceOnS1().PCurveOnSurf()->
1634                           Value(SDdeb->InterferenceOnS1().FirstParameter());     
1635       UV2=SDdeb->InterferenceOnS2().PCurveOnSurf()->
1636                           Value(SDdeb->InterferenceOnS2().FirstParameter());
1637 // The intersection of the fillet by a plane is attempted
1638
1639       Handle(GeomAdaptor_HSurface) HConge=ChFi3d_BoundSurf(DStr,SDdeb,1,2);
1640       ChFi3d_CoupeParPlan(cpdeb1,cpdeb2,HConge,UV1,UV2,
1641                           tol3d,tol2d,C3d,Stripe->ChangeFirstPCurve(),tolreached,
1642                           Pardeb,Parfin,plane);  
1643       if (!plane) 
1644       ChFi3d_ComputeArete(cpdeb1,
1645                           SDdeb->InterferenceOnS1().PCurveOnSurf()->
1646                           Value(SDdeb->InterferenceOnS1().FirstParameter()),
1647                           cpdeb2,
1648                           SDdeb->InterferenceOnS2().PCurveOnSurf()-> 
1649                           Value(SDdeb->InterferenceOnS2().FirstParameter()),
1650                           DStr.Surface(SDdeb->Surf()).Surface(),C3d,
1651                           Stripe->ChangeFirstPCurve(),Pardeb,Parfin,
1652                           tol3d,tol2d,tolreached,0);
1653       TopOpeBRepDS_Curve Crv(C3d,tolreached);
1654       Stripe->ChangeFirstCurve(DStr.AddCurve(Crv));
1655       Stripe->ChangeFirstParameters(Pardeb,Parfin);
1656       Stripe->ChangeIndexFirstPointOnS1
1657         (ChFi3d_IndexPointInDS(SDdeb->VertexFirstOnS1(),DStr));
1658       Stripe->ChangeIndexFirstPointOnS2
1659         (ChFi3d_IndexPointInDS(SDdeb->VertexFirstOnS2(),DStr));
1660       if(cpdeb1.IsOnArc()){
1661         ChFi3d_EnlargeBox(cpdeb1.Arc(),EFMap(cpdeb1.Arc()),cpdeb1.ParameterOnArc(),b1);
1662       }
1663       if(cpdeb2.IsOnArc()){
1664         ChFi3d_EnlargeBox(cpdeb2.Arc(),EFMap(cpdeb2.Arc()),cpdeb2.ParameterOnArc(),b2);
1665       }
1666       ChFi3d_EnlargeBox(DStr,Stripe,SDdeb,b1,b2,1);
1667       if (!cpdeb1.IsVertex())
1668         ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexFirstPointOnS1());
1669       if (!cpdeb2.IsVertex())
1670         ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexFirstPointOnS2());
1671     }
1672     else { // Case of a singular extremity
1673       if (cpdeb1.IsVertex()) { 
1674         ChFi3d_SingularExtremity(Stripe, DStr, cpdeb1.Vertex(), tol3d, tol2d);
1675       }
1676 # if CHFI3D_DEB
1677       else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; }
1678 # endif
1679     }
1680   }
1681   const Handle(ChFiDS_SurfData)& 
1682     SDfin = Stripe->SetOfSurfData()->Sequence().Last();
1683   const ChFiDS_CommonPoint& cpfin1 = SDfin->VertexLastOnS1();
1684   const ChFiDS_CommonPoint& cpfin2 = SDfin->VertexLastOnS2();
1685   Standard_Boolean freefin = sp->LastStatus() == ChFiDS_FreeBoundary;
1686   if(!freefin && cpfin1.IsOnArc() && cpfin2.IsOnArc()){
1687     freefin = (IsFree(cpfin1.Arc(),EFMap) && IsFree(cpfin2.Arc(),EFMap));
1688   }
1689   if(freefin){
1690     sp->SetLastStatus(ChFiDS_FreeBoundary);
1691     Bnd_Box b1,b2;
1692     if ( !cpfin1.Point().IsEqual(cpfin2.Point(), 0) ) { 
1693       Standard_Boolean plane;
1694       gp_Pnt2d UV1,UV2;
1695       UV1=SDfin->InterferenceOnS1().PCurveOnSurf()->
1696                           Value(SDfin->InterferenceOnS1().LastParameter());     
1697       UV2=SDfin->InterferenceOnS2().PCurveOnSurf()->
1698                           Value(SDfin->InterferenceOnS2().LastParameter());
1699 // Intersection of the fillet by a plane is attempted
1700
1701       Handle(GeomAdaptor_HSurface) HConge=ChFi3d_BoundSurf(DStr,SDfin,1,2);
1702       ChFi3d_CoupeParPlan(cpfin1,cpfin2,HConge,UV1,UV2,
1703                           tol3d,tol2d,C3d,Stripe->ChangeLastPCurve(),tolreached,
1704                           Pardeb,Parfin,plane);      
1705       if (!plane)   
1706       ChFi3d_ComputeArete(cpfin1,
1707                           SDfin->InterferenceOnS1().PCurveOnSurf()->
1708                           Value(SDfin->InterferenceOnS1().LastParameter()),
1709                           cpfin2,
1710                           SDfin->InterferenceOnS2().PCurveOnSurf()-> 
1711                           Value(SDfin->InterferenceOnS2().LastParameter()),
1712                           DStr.Surface(SDfin->Surf()).Surface(),C3d,
1713                           Stripe->ChangeLastPCurve(),Pardeb,Parfin,
1714                           tol3d,tol2d,tolreached,0);
1715       TopOpeBRepDS_Curve Crv(C3d,tolreached);
1716       Stripe->ChangeLastCurve(DStr.AddCurve(Crv));
1717       Stripe->ChangeLastParameters(Pardeb,Parfin);
1718       Stripe->ChangeIndexLastPointOnS1
1719         (ChFi3d_IndexPointInDS(SDfin->VertexLastOnS1(),DStr));
1720       Stripe->ChangeIndexLastPointOnS2
1721         (ChFi3d_IndexPointInDS(SDfin->VertexLastOnS2(),DStr));
1722       if(cpfin1.IsOnArc()){
1723         ChFi3d_EnlargeBox(cpfin1.Arc(),EFMap(cpfin1.Arc()),cpfin1.ParameterOnArc(),b1);
1724       }
1725       if(cpfin2.IsOnArc()){
1726         ChFi3d_EnlargeBox(cpfin2.Arc(),EFMap(cpfin2.Arc()),cpfin2.ParameterOnArc(),b2);
1727       }
1728       ChFi3d_EnlargeBox(DStr,Stripe,SDfin,b1,b2,0);
1729       if (!cpfin1.IsVertex())
1730         ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexLastPointOnS1());
1731       if (!cpfin2.IsVertex())
1732         ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexLastPointOnS2());
1733     }
1734     else { // Case of the single extremity
1735       if (cpfin1.IsVertex()) { 
1736         ChFi3d_SingularExtremity(Stripe, DStr, cpfin1.Vertex(), tol3d, tol2d);
1737       }
1738 # if CHFI3D_DEB
1739       else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; }
1740 # endif
1741     }
1742   }
1743 }
1744
1745 //=======================================================================
1746 //function : ChFi3d_Purge
1747 //purpose  : 
1748 //=======================================================================
1749
1750 static void ChFi3d_Purge (Handle(ChFiDS_Stripe)&    Stripe,
1751                           Handle(ChFiDS_SurfData)&  SD,
1752                           const ChFiDS_CommonPoint& VRef,
1753                           const Standard_Boolean    isfirst,
1754                           const Standard_Integer    ons,
1755                           Standard_Boolean&         intf,
1756                           Standard_Boolean&         intl)
1757 {
1758   if (isfirst) intf = 1; else intl = 1; // End.
1759   Standard_Integer opp = 3-ons;
1760   if (!SD->Vertex(isfirst,opp).IsOnArc() || 
1761       SD->TwistOnS1() || SD->TwistOnS2() ) {
1762 #ifdef OCCT_DEBUG
1763     cout<<"ChFi3d_Purge : No output on extension."<<endl;
1764 #endif
1765     ChFiDS_SequenceOfSurfData& Seq = 
1766       Stripe->ChangeSetOfSurfData()->ChangeSequence();
1767     if(isfirst) Seq.Remove(1);
1768     else Seq.Remove(Seq.Length());
1769     return;
1770   }
1771   if (ons == 1) SD->ChangeIndexOfS1(0);
1772   else          SD->ChangeIndexOfS2(0);
1773   
1774   SD->ChangeVertex(!isfirst,ons) = VRef;
1775   SD->ChangeVertex(isfirst,ons)  = VRef;
1776   
1777   ChFiDS_FaceInterference& fi = SD->ChangeInterference(ons);
1778   if(isfirst) fi.SetFirstParameter(fi.LastParameter());
1779   else fi.SetLastParameter(fi.FirstParameter());
1780   fi.SetLineIndex(0);
1781 }
1782
1783 //=======================================================================
1784 //function : InsertAfter
1785 //purpose  : insert Item after ref in Seq. If ref is null, the item is
1786 //           inserted at the beginning.
1787 //=======================================================================
1788
1789 static void InsertAfter (Handle(ChFiDS_Stripe)&   Stripe,
1790                          Handle(ChFiDS_SurfData)& Ref,
1791                          Handle(ChFiDS_SurfData)& Item)
1792 {
1793   if (Ref == Item) 
1794     Standard_Failure::Raise("InsertAfter : twice the same surfdata.");
1795   
1796   ChFiDS_SequenceOfSurfData& Seq = 
1797     Stripe->ChangeSetOfSurfData()->ChangeSequence();
1798   
1799   if (Seq.IsEmpty() || Ref.IsNull()) {
1800     Seq.Prepend(Item);
1801   }
1802   for (Standard_Integer i = 1; i <= Seq.Length(); i++) {
1803     if (Seq.Value(i) == Ref) {
1804       Seq.InsertAfter(i,Item);
1805       break;
1806     }
1807   }
1808 }
1809
1810 //=======================================================================
1811 //function : RemoveSD
1812 //purpose  : 
1813 //=======================================================================
1814
1815 static void RemoveSD (Handle(ChFiDS_Stripe)&   Stripe,
1816                       Handle(ChFiDS_SurfData)& Prev,
1817                       Handle(ChFiDS_SurfData)& Next)
1818 {
1819   ChFiDS_SequenceOfSurfData& Seq = 
1820     Stripe->ChangeSetOfSurfData()->ChangeSequence();
1821   if(Seq.IsEmpty()) return;
1822   Standard_Integer iprev = 0, inext = 0;
1823   for (Standard_Integer i = 1; i <= Seq.Length(); i++) {
1824     if (Seq.Value(i) == Prev) iprev = i + 1;
1825     if (Seq.Value(i) == Next) { inext = i - 1; break; }
1826   }
1827   if(Prev.IsNull()) iprev = 1;
1828   if(Next.IsNull()) inext = Seq.Length();
1829   if(iprev <= inext) Seq.Remove(iprev,inext);
1830 }
1831
1832 //=======================================================================
1833 //function : InsertBefore
1834 //purpose  : Insert item before ref in Seq. If ref is null, the item is
1835 //           inserted in the queue.
1836 //=======================================================================
1837
1838 static void InsertBefore (Handle(ChFiDS_Stripe)&   Stripe,
1839                           Handle(ChFiDS_SurfData)& Ref,
1840                           Handle(ChFiDS_SurfData)& Item)
1841 {
1842   if (Ref == Item) 
1843     Standard_Failure::Raise("InsertBefore : twice the same surfdata.");
1844   
1845   ChFiDS_SequenceOfSurfData& Seq = 
1846     Stripe->ChangeSetOfSurfData()->ChangeSequence();
1847   
1848   if (Seq.IsEmpty() || Ref.IsNull()) {
1849     Seq.Append(Item);
1850   }
1851   for (Standard_Integer i = 1; i <= Seq.Length(); i++) {
1852     if (Seq.Value(i) == Ref) {
1853       Seq.InsertBefore(i,Item);
1854       break;
1855     }
1856   }
1857 }
1858
1859
1860 //=======================================================================
1861 //function : PerformSetOfSurfOnElSpine
1862 //purpose  : 
1863 //=======================================================================
1864
1865 void ChFi3d_Builder::PerformSetOfSurfOnElSpine
1866 (const Handle(ChFiDS_HElSpine)&    HGuide,
1867  Handle(ChFiDS_Stripe)&            Stripe,
1868  Handle(BRepTopAdaptor_TopolTool)& It1,
1869  Handle(BRepTopAdaptor_TopolTool)& It2,
1870  const Standard_Boolean            Simul)
1871
1872 #ifdef OCCT_DEBUG
1873   OSD_Chronometer ch1;
1874 #endif 
1875   
1876   ChFiDS_ElSpine& Guide = HGuide->ChangeCurve();
1877   Standard_Real wf = Guide.FirstParameter();
1878   Standard_Real wl = Guide.LastParameter();
1879   Standard_Real locfleche = (wl - wf) * fleche;
1880   Standard_Real wfsav = wf, wlsav = wl;
1881   if (!Guide.IsPeriodic())
1882   {
1883     //Now the ElSpine is artificially extended to help rsnld.
1884     Standard_Real prab = 0.01;
1885     Guide.FirstParameter(wf-prab*(wl-wf));
1886     Guide.LastParameter (wl+prab*(wl-wf));
1887   }
1888   Handle(ChFiDS_Spine)&  Spine = Stripe->ChangeSpine();
1889   Standard_Integer ii, nbed = Spine->NbEdges();
1890   Standard_Real lastedlastp = Spine->LastParameter(nbed);
1891   
1892   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
1893   
1894   Handle(ChFiDS_SurfData) ref = Guide.Previous();
1895   Handle(ChFiDS_SurfData) refbis, SD;
1896   Handle(ChFiDS_SurfData) raf = Guide.Next();
1897   RemoveSD(Stripe,ref,raf);
1898   
1899   Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface();
1900   Handle(BRepAdaptor_HSurface) HS2 = new BRepAdaptor_HSurface();
1901   Handle(BRepAdaptor_HSurface) HS3, HS4;
1902   Handle(BRepAdaptor_HSurface) HSref1 = new BRepAdaptor_HSurface();
1903   Handle(BRepAdaptor_HSurface) HSref2 = new BRepAdaptor_HSurface();
1904   Handle(BRepAdaptor_HCurve2d) HC1,HC2;
1905   Handle(BRepAdaptor_HCurve2d) HCref1 = new BRepAdaptor_HCurve2d();
1906   Handle(BRepAdaptor_HCurve2d) HCref2 = new BRepAdaptor_HCurve2d();
1907   Standard_Boolean decroch1 = Standard_False, decroch2 = Standard_False;
1908   Standard_Boolean RecP1 = Standard_False, RecS1 = Standard_False, RecRst1 = Standard_False, obstacleon1 = Standard_False;
1909   Standard_Boolean RecP2 = Standard_False, RecS2 = Standard_False, RecRst2 = Standard_False, obstacleon2 = Standard_False;
1910   gp_Pnt2d pp1,pp2,pp3,pp4;
1911   Standard_Real w1 = 0.,w2 = 0.;
1912   math_Vector Soldep(1,4);
1913   math_Vector SoldepCS(1,3);
1914   math_Vector SoldepCC(1,2);
1915   
1916   // Restore a neighboring KPart.
1917   // If no neighbor calculation start point. 
1918   Standard_Boolean forward = Standard_True;
1919   Standard_Boolean Inside  = Standard_False;
1920   Standard_Real    First   = wf;
1921   Standard_Real    Last    = wl;
1922   Standard_Boolean Ok1 = 1,Ok2 = 1;
1923   // Restore the next KPart if it exists
1924   TopoDS_Vertex Vref;
1925   if(ref.IsNull() && raf.IsNull()){
1926     //sinon solution approchee.
1927     Inside = Standard_True;
1928     
1929 #ifdef OCCT_DEBUG
1930     ChFi3d_InitChron(ch1);// init perf for StartSol 
1931 #endif
1932     
1933     StartSol(Stripe,HGuide,HS1,HS2,It1,It2,pp1,pp2,First);
1934     
1935 #ifdef OCCT_DEBUG
1936     ChFi3d_ResultChron(ch1,t_startsol); // result perf for StartSol  
1937 #endif 
1938     
1939     Last = wf;
1940     if(Guide.IsPeriodic()) {
1941       Last = First - Guide.Period();
1942       Guide.SaveFirstParameter();
1943       Guide.FirstParameter(Last);
1944       Guide.SaveLastParameter();
1945       Guide.LastParameter (First * 1.1);//Extension to help rsnld.
1946     }
1947   }
1948   else{
1949     if(!Spine->IsPeriodic() && (wl - lastedlastp > -tolesp)){ 
1950       Vref = Spine->LastVertex(); 
1951     }
1952     if (ref.IsNull()) {
1953       if(!Spine->IsPeriodic() && (wf < tolesp)){ 
1954         Vref = Spine->FirstVertex(); 
1955       }
1956       ref = raf;
1957       forward = Standard_False;
1958       First = wl; Last = Guide.FirstParameter();
1959     }
1960     
1961 #ifdef OCCT_DEBUG
1962     ChFi3d_InitChron(ch1);// init perf for startsol 
1963 #endif
1964     
1965     
1966     Ok1 = StartSol(Spine,HS1,pp1,HC1,w1,ref,!forward,1,
1967                    HSref1,HCref1,RecP1,RecS1,RecRst1,obstacleon1,
1968                    HS3,pp3,decroch1,Vref);
1969     Ok2 = StartSol(Spine,HS2,pp2,HC2,w2,ref,!forward,2,
1970                    HSref2,HCref2, RecP2,RecS2,RecRst2,obstacleon2,
1971                    HS4,pp4,decroch2,Vref);
1972     HC1.Nullify(); 
1973     HC2.Nullify();
1974     
1975 #ifdef OCCT_DEBUG
1976     ChFi3d_ResultChron(ch1,t_startsol); // result perf for startsol  
1977 #endif
1978     
1979     
1980     if(Ok1 == 1 && Ok2 == 1) {
1981       if(forward) Guide.FirstParameter(wf);
1982       else Guide.LastParameter(wl);
1983     }
1984   }
1985   Standard_Boolean      fini     = Standard_False;
1986   Standard_Boolean      complete = Inside;
1987   if(!Guide.IsPeriodic()){
1988     Standard_Integer indf = Spine->Index(wf);
1989     Standard_Integer indl = Spine->Index(wl,0);
1990     if(Spine->IsPeriodic() && (indl < indf)) indl += nbed;
1991     nbed = indl-indf+1;
1992   }
1993   // No Max at the touch : 20 points by edge at average without  
1994   // counting the extensions.
1995
1996   Standard_Real bidf = wf, bidl = wl;
1997   if(!Spine->IsPeriodic()) {
1998     bidf = Max(0.,wf);
1999     bidl = Min(wl,Spine->LastParameter(Spine->NbEdges()));
2000     // PMN 20/07/98 : Attention in case if there is only extension
2001     if  ((bidl-bidf) < 0.01 * Spine->LastParameter(Spine->NbEdges())) {
2002        bidf = wf;
2003        bidl = wl;
2004     }   
2005   }
2006   Standard_Real         MaxStep  = (bidl-bidf)*0.05/nbed;
2007   Standard_Real         Firstsov = 0.;
2008   Standard_Boolean      intf = 0, intl = 0;
2009   while(!fini){
2010     // are these the ends (no extension on periodic).
2011     Ok1 = 1,Ok2 = 1;
2012     if(!Spine->IsPeriodic()){
2013       if(wf < tolesp && (complete == Inside)){
2014         if(Spine->FirstStatus() == ChFiDS_OnSame) intf = 2;
2015         else intf = 1;
2016       }
2017       if(Spine->IsTangencyExtremity(Standard_True)){
2018         intf = 4;
2019         Guide.FirstParameter(wfsav);
2020       }
2021       if(wl - lastedlastp > -tolesp){
2022         if(Spine->LastStatus() == ChFiDS_OnSame) intl = 2;
2023         else intl = 1;
2024       }
2025       if(Spine->IsTangencyExtremity(Standard_False)){
2026         intl = 4;
2027         Guide.LastParameter(wlsav);
2028       }
2029     }
2030     if(intf && !forward) Vref = Spine->FirstVertex();
2031     if(intl && forward) Vref = Spine->LastVertex();
2032     if(!ref.IsNull()){
2033       
2034 #ifdef OCCT_DEBUG
2035       ChFi3d_InitChron(ch1);// init perf for StartSol 
2036 #endif
2037       
2038       Ok1 = StartSol(Spine,HS1,pp1,HC1,w1,ref,!forward,1,
2039                      HSref1,HCref1, RecP1,RecS1,RecRst1,obstacleon1,
2040                      HS3,pp3,decroch1,Vref);
2041       Ok2 = StartSol(Spine,HS2,pp2,HC2,w2,ref,!forward,2,
2042                      HSref2,HCref2, RecP2,RecS2,RecRst2,obstacleon2,
2043                      HS4,pp4,decroch2,Vref);
2044       
2045 #ifdef OCCT_DEBUG
2046       ChFi3d_ResultChron(ch1,t_startsol); // result perf for StartSol  
2047 #endif 
2048       
2049     }
2050     
2051     // No more connected faces. Construction of the tangent plane to continue the path 
2052     // till the output on the other face.
2053     if ((!Ok1 && HC1.IsNull()) || (!Ok2 && HC2.IsNull())) {
2054       if ((intf && !forward) || (intl && forward)) {
2055         if (!Ok1) ChFi3d_BuildPlane (DStr,HS1,pp1,ref,!forward,1);
2056         if (!Ok2) ChFi3d_BuildPlane (DStr,HS2,pp2,ref,!forward,2);      
2057         if(intf) intf = 5;
2058         else if(intl) intl = 5;
2059         if(forward) Guide.FirstParameter(wf);
2060         else Guide.LastParameter(wl);
2061       }
2062       else Standard_Failure::Raise("PerformSetOfSurfOnElSpine : Chaining is impossible.");
2063     }
2064     
2065     // Definition of the domain of patch It1, It2
2066     const Handle(Adaptor3d_HSurface)& HSon1 = HS1; // to avoid ambiguity
2067     const Handle(Adaptor3d_HSurface)& HSon2 = HS2; // to avoid ambiguity
2068     It1->Initialize(HSon1);
2069     It2->Initialize(HSon2);
2070     
2071     // Calculate one (several if singularity) SurfaData
2072     SD = new ChFiDS_SurfData();
2073     ChFiDS_SequenceOfSurfData SeqSD;
2074     SeqSD.Append(SD);
2075     
2076     if(obstacleon1 && obstacleon2){
2077       TopAbs_Orientation Or1 = HSref1->ChangeSurface().Face().Orientation();
2078       TopAbs_Orientation Or2 = HSref2->ChangeSurface().Face().Orientation();
2079       Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2,
2080                                                 Stripe->OrientationOnFace1(),
2081                                                 Stripe->OrientationOnFace2(),
2082                                                 Stripe->Choix());
2083
2084
2085       // Calculate the criterion of Choice edge / edge
2086       if (Choix%2 == 0) Choix = 4;
2087       else Choix = 1;
2088
2089       SoldepCC(1) = w1; SoldepCC(2) = w2;
2090       if(Simul){
2091         SimulSurf(SD,HGuide,Spine,Choix,
2092                   HS1,It1,HC1,HSref1,HCref1,decroch1,Or1,
2093                   HS2,It2,HC2,HSref2,HCref2,decroch2,Or2,
2094                   locfleche,tolesp,First,Last,Inside,Inside,forward,
2095                   RecP1,RecRst1,RecP2,RecRst2,SoldepCC);
2096       }
2097       else{
2098 #ifdef OCCT_DEBUG
2099         ChFi3d_InitChron(ch1); // init perf for PerformSurf 
2100 #endif
2101         PerformSurf(SeqSD,HGuide,Spine,Choix,
2102                     HS1,It1,HC1,HSref1,HCref1,decroch1,Or1,
2103                     HS2,It2,HC2,HSref2,HCref2,decroch2,Or2,
2104                     MaxStep,locfleche,tolesp,First,Last,Inside,Inside,forward,
2105                     RecP1,RecRst1,RecP2,RecRst2,SoldepCC);
2106 #ifdef OCCT_DEBUG
2107         ChFi3d_ResultChron(ch1,t_performsurf); //result  perf for PerformSurf 
2108 #endif 
2109       }
2110       SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2111       SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2112     }
2113     else if (obstacleon1){
2114       TopAbs_Orientation Or1 = HSref1->ChangeSurface().Face().Orientation();
2115       TopAbs_Orientation Or2 = HS2->ChangeSurface().Face().Orientation();
2116       Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2,
2117                                                 Stripe->OrientationOnFace1(),
2118                                                 Stripe->OrientationOnFace2(),
2119                                                 -Stripe->Choix());
2120       if(Choix%2 == 1) Choix++;
2121       else Choix--;
2122       SoldepCS(3) = w1; SoldepCS(1) =  pp2.X(); SoldepCS(2) =  pp2.Y();
2123       if(Simul){
2124         SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,HC1,HSref1,HCref1,decroch1,
2125                   HS2,It2,Or2,locfleche,tolesp,First,Last,
2126                   Inside,Inside,forward,RecP1,RecS2,RecRst1,SoldepCS);
2127       }
2128       else{
2129 #ifdef OCCT_DEBUG
2130         ChFi3d_InitChron(ch1); // init perf for PerformSurf
2131 #endif
2132         PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,HC1,HSref1,HCref1,decroch1,
2133                     HS2,It2,Or2,MaxStep,locfleche,tolesp,First,Last,
2134                     Inside,Inside,forward,RecP1,RecS2,RecRst1,SoldepCS);
2135 #ifdef OCCT_DEBUG
2136         ChFi3d_ResultChron(ch1,t_performsurf);//result  perf for PerformSurf  
2137 #endif 
2138       }
2139       SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2140       SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2141       decroch2 = 0;
2142     }
2143     else if (obstacleon2){
2144       TopAbs_Orientation Or1 = HS1->ChangeSurface().Face().Orientation();
2145       TopAbs_Orientation Or2 = HSref2->ChangeSurface().Face().Orientation();
2146       Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2,
2147                                                 Stripe->OrientationOnFace1(),
2148                                                 Stripe->OrientationOnFace2(),
2149                                                 Stripe->Choix());
2150       SoldepCS(3) = w2; SoldepCS(1) =  pp1.X(); SoldepCS(2) =  pp1.Y();
2151       if(Simul){
2152         SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,Or1,
2153                   HS2,It2,HC2,HSref2,HCref2,decroch2,locfleche,tolesp,
2154                   First,Last,Inside,Inside,forward,RecP2,RecS1,RecRst2,SoldepCS);
2155       }
2156       else{
2157 #ifdef OCCT_DEBUG
2158         ChFi3d_InitChron(ch1); // init perf for PerformSurf 
2159 #endif
2160         PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,Or1,
2161                     HS2,It2,HC2,HSref2,HCref2,decroch2,MaxStep,locfleche,tolesp,
2162                     First,Last,Inside,Inside,forward,RecP2,RecS1,RecRst2,SoldepCS);
2163 #ifdef OCCT_DEBUG
2164         ChFi3d_ResultChron(ch1,t_performsurf); //result  perf for PerformSurf 
2165 #endif 
2166       }
2167       SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2168       SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2169       decroch1 = 0;
2170     }
2171     else{ 
2172       const Handle(Adaptor3d_TopolTool)& aTT1 = It1; // to avoid ambiguity
2173       const Handle(Adaptor3d_TopolTool)& aTT2 = It2; // to avoid ambiguity
2174       CallPerformSurf(Stripe, Simul, SeqSD, SD,
2175                       HGuide,Spine,
2176                       HS1, HS3, pp1, pp3, aTT1,
2177                       HS2, HS4, pp2, pp4, aTT2, 
2178                       MaxStep,locfleche,tolesp,
2179                       First,Last,Inside,Inside,forward,
2180                       RecS1,RecS2,Soldep,intf,intl, 
2181                       HS1, HS2);
2182       decroch1 = decroch2 = 0;
2183     }
2184
2185     if(!done) { // Case of fail
2186       if ((!Ok1 && !obstacleon1) || (!Ok2 && !obstacleon2)) {
2187         //Fail in a part of extension is not serious
2188         //Here one stops.
2189         done = Standard_True;
2190         Inside = Standard_False;
2191         if (forward) intl = 1;
2192         else         intf = 1;
2193       }
2194       else { // Otherwise invalidation of the stripe.
2195         Spine->SetErrorStatus(ChFiDS_WalkingFailure);
2196         Standard_Failure::Raise("CallPerformSurf : Path failed!");
2197       }
2198     }
2199     
2200     else {
2201       refbis = ref;
2202       if(forward) {
2203         for (ii=1; ii<=SeqSD.Length(); ii++) {
2204           SD = SeqSD(ii);
2205           SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2206           if(obstacleon1) SD->SetIndexOfC1(DStr.AddShape(HC1->ChangeCurve2d().Edge()));
2207           SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2208           if(obstacleon2) SD->SetIndexOfC2(DStr.AddShape(HC2->ChangeCurve2d().Edge()));
2209           InsertAfter (Stripe, refbis, SD);
2210           refbis = SD;
2211         }
2212       }
2213       else {
2214         for (ii=SeqSD.Length(); ii>=1; ii--) {
2215           SD = SeqSD(ii);
2216           SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face()));
2217           if(obstacleon1) SD->SetIndexOfC1(DStr.AddShape(HC1->ChangeCurve2d().Edge()));
2218           SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face()));
2219           if(obstacleon2) SD->SetIndexOfC2(DStr.AddShape(HC2->ChangeCurve2d().Edge()));
2220           InsertBefore(Stripe,refbis,SD);
2221           refbis = SD;
2222         }
2223       } 
2224     
2225       if (!Ok1 && !obstacleon1) 
2226         // clean infos on the plane of extension.
2227         ChFi3d_Purge (Stripe,SD,ref->Vertex(!forward,1),!forward,1,intf,intl);
2228       
2229       if (!Ok2 && !obstacleon2) 
2230         // clean infos on the plane of extension.
2231         ChFi3d_Purge (Stripe,SD,ref->Vertex(!forward,2),!forward,2,intf,intl);
2232     
2233       // The end. The reference is changed.      
2234       ref = refbis;  
2235     }  
2236     
2237     if(Inside){// There are starting solutions for the next.
2238       Inside = Standard_False;
2239       Firstsov = First;
2240       if(Guide.IsPeriodic()) {
2241         complete = Standard_False;
2242         wf  = Guide.FirstParameter();
2243         wl  = Guide.LastParameter();
2244       }
2245     }
2246     if(forward){
2247       fini = ((wl - Last) <= 10.*tolesp || 
2248               (intl && !(obstacleon1 || obstacleon2))); //General case
2249
2250       if (!fini && Guide.IsPeriodic() && 
2251           ((wl - Last)< Guide.Period()*1.e-3)) {
2252         // It is tested if reframing of extremes is done at the same edge
2253         // Loop Condition
2254         Handle(ChFiDS_SurfData) thefirst, thelast;
2255         thefirst = Stripe->SetOfSurfData()->Sequence().First();
2256         thelast =  Stripe->SetOfSurfData()->Sequence().Last();
2257         
2258         if (thefirst->VertexFirstOnS1().IsOnArc() && 
2259             thelast->VertexLastOnS1().IsOnArc())
2260           fini = thefirst->VertexFirstOnS1().Arc().IsSame
2261             (thelast->VertexLastOnS1().Arc());
2262         if (!fini &&
2263             thefirst->VertexFirstOnS2().IsOnArc() && 
2264             thelast->VertexLastOnS2().IsOnArc())
2265           fini = thefirst->VertexFirstOnS2().Arc().IsSame
2266             (thelast->VertexLastOnS2().Arc());
2267
2268         if (fini) 
2269           return; //It is ended!
2270       }
2271
2272       if(fini && complete) {
2273         // restart in the opposite direction.
2274         ref  = Stripe->SetOfSurfData()->Sequence().First();
2275         forward = Standard_False;
2276         fini = Standard_False;
2277         First = Firstsov;
2278       }
2279       else {
2280         First = Last;
2281         Last  = wl;
2282       }
2283     }
2284     if(!forward){
2285       fini = ((First - wf) <= 10.*tolesp || 
2286               (intf && !(obstacleon1 || obstacleon2)));
2287       complete = Standard_False;
2288       Last = wf;
2289     }
2290   }
2291   // The initial state is restored
2292   if(!Guide.IsPeriodic()){
2293     Guide.FirstParameter(wfsav);
2294     Guide.LastParameter (wlsav);
2295   }
2296
2297 }
2298
2299 //=======================================================================
2300 //function : PerformSetOfKPart
2301 //purpose  : 
2302 //=======================================================================
2303
2304 void ChFi3d_Builder::PerformSetOfKPart(Handle(ChFiDS_Stripe)& Stripe,
2305                                        const Standard_Boolean Simul) 
2306 {
2307   TopOpeBRepDS_DataStructure&  DStr = myDS->ChangeDS();
2308   Handle(ChFiDS_Spine)&        Spine = Stripe->ChangeSpine();
2309   Handle(BRepAdaptor_HSurface) HS1,HS2;
2310   TopAbs_Orientation           Or1,Or2,RefOr1,RefOr2;
2311   Standard_Integer             RefChoix;
2312   
2313   // initialization of the stripe.
2314   Stripe->Reset();
2315   Handle(ChFiDS_HData)&  HData  = Stripe->ChangeSetOfSurfData();
2316   HData =  new ChFiDS_HData();
2317   ChFiDS_SequenceOfSurfData& SeqSurf = HData->ChangeSequence();
2318   
2319   StripeOrientations(Spine,RefOr1,RefOr2,RefChoix);
2320   Stripe->OrientationOnFace1(RefOr1);
2321   Stripe->OrientationOnFace2(RefOr2);
2322   Stripe->Choix(RefChoix);
2323   
2324   Handle(BRepTopAdaptor_TopolTool) It1 = new BRepTopAdaptor_TopolTool();
2325   Handle(BRepTopAdaptor_TopolTool) It2 = new BRepTopAdaptor_TopolTool();
2326   
2327   Standard_Real WFirst,WLast = 0.;
2328   gp_Vec TFirst,TLast,TEndPeriodic;
2329   gp_Pnt PFirst,PLast,PEndPeriodic;
2330   Standard_Boolean intf = 0, intl = 0;
2331   
2332   Handle(ChFiDS_HElSpine) CurrentHE = new ChFiDS_HElSpine();
2333   Spine->D1(Spine->FirstParameter(),PFirst,TFirst);
2334   CurrentHE->ChangeCurve().FirstParameter(Spine->FirstParameter());
2335   CurrentHE->ChangeCurve().SetFirstPointAndTgt(PFirst,TFirst);
2336   
2337   Standard_Boolean YaKPart = Standard_False;
2338   Standard_Integer iedgelastkpart = 0;
2339   
2340   Standard_Real WStartPeriodic = 0.;
2341   Standard_Real WEndPeriodic = Spine->LastParameter(Spine->NbEdges());
2342   Spine->D1(WEndPeriodic,PEndPeriodic,TEndPeriodic);
2343   
2344   // Construction of particular cases.
2345   
2346   for (Standard_Integer iedge = 1; iedge <= Spine->NbEdges(); iedge++){
2347     
2348     ConexFaces(Spine,iedge,RefChoix,HS1,HS2);
2349     
2350     if (ChFi3d_KParticular(Spine,iedge,HS1->ChangeSurface(),HS2->ChangeSurface())) {
2351       intf = ((iedge == 1) && !Spine->IsPeriodic());
2352       intl = ((iedge == Spine->NbEdges()) && !Spine->IsPeriodic());
2353       Or1   = HS1->ChangeSurface().Face().Orientation();
2354       Or2   = HS2->ChangeSurface().Face().Orientation();
2355       ChFi3d::NextSide(Or1,Or2,RefOr1,RefOr2,RefChoix);      
2356       const Handle(Adaptor3d_HSurface)& HSon1 = HS1; // to avoid ambiguity
2357       const Handle(Adaptor3d_HSurface)& HSon2 = HS2; // to avoid ambiguity
2358       It1->Initialize(HSon1);
2359       It2->Initialize(HSon2);
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
2497     if(ChFi3d_GettraceCHRON()) elspine.Start();
2498 #endif
2499     ChFi3d_PerformElSpine(ILES.Value(),Spine,myConti,tolesp);
2500 #ifdef OCCT_DEBUG
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 OCCT_DEBUG
2532     if(ChFi3d_GettraceCHRON()) { chemine.Start(); }
2533 #endif
2534     PerformSetOfSurfOnElSpine(ILES.Value(),Stripe,It1,It2,Simul);
2535 #ifdef OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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           Standard_Integer jf = 0, jl = 0;
2935           if(lp < WF+tolesp || fp > WL-tolesp) continue;
2936           for(j = IF; j < IL; j++){
2937             jf = j;
2938             if(fp < wv(j) - tolesp) break;
2939           }
2940           for(j = IF; j < IL; j++){
2941             jl = j;
2942             if(lp < wv(j) + tolesp) break;
2943           }
2944           for(j = jf; j <= jl; j++){
2945             Standard_Integer jloc = j;
2946             if(periodic) jloc = (j - 1)%nbed + 1;
2947             const TopoDS_Edge& Ej = Spine->Edges(jloc);
2948             if(!myEVIMap.IsBound(Ej)) {
2949               TColStd_ListOfInteger li;
2950               myEVIMap.Bind(Ej,li);
2951             }
2952             myEVIMap.ChangeFind(Ej).Append(cursd->Surf());
2953           }
2954         }
2955       }
2956     }
2957   }
2958 }
2959
2960 //=======================================================================
2961 //function : PerformSetOfSurf
2962 //purpose  : 
2963 //=======================================================================
2964
2965 void ChFi3d_Builder::PerformSetOfSurf(Handle(ChFiDS_Stripe)& Stripe,
2966                                       const Standard_Boolean Simul) 
2967 {
2968   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
2969   
2970 #ifdef OCCT_DEBUG
2971   OSD_Chronometer ch;
2972   ChFi3d_InitChron(ch);// init perf for PerformSetOfKPart
2973 #endif
2974   
2975   const Handle(ChFiDS_Spine)& sp = Stripe->Spine();
2976   Standard_Integer SI = ChFi3d_SolidIndex(sp,DStr,myESoMap,myEShMap);
2977   Stripe->SetSolidIndex(SI);
2978   if(!sp->SplitDone()) PerformSetOfKPart(Stripe,Simul);
2979   
2980 #ifdef OCCT_DEBUG
2981   ChFi3d_ResultChron(ch ,t_perfsetofkpart); // result perf PerformSetOfKPart(
2982   ChFi3d_InitChron(ch); // init perf for  PerformSetOfKGen
2983 #endif
2984   
2985   PerformSetOfKGen(Stripe,Simul);
2986   
2987 #ifdef OCCT_DEBUG
2988   ChFi3d_ResultChron(ch, t_perfsetofkgen);//result perf PerformSetOfKGen 
2989   ChFi3d_InitChron(ch); // init perf for ChFi3d_MakeExtremities
2990 #endif
2991   
2992   if(!Simul) ChFi3d_MakeExtremities(Stripe,DStr,myEFMap,tolesp,tol2d);
2993   
2994 #ifdef OCCT_DEBUG
2995   ChFi3d_ResultChron(ch, t_makextremities); // result perf t_makextremities
2996 #endif
2997 }