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