0023651: Exception on fillet construction between NURBS and surface of revolution
[occt.git] / src / ChFi3d / ChFi3d_Builder_6.cxx
CommitLineData
b311480e 1// Created on: 1994-10-25
2// Created by: Laurent BOURESCHE
3// Copyright (c) 1994-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21// modif : jlr branchement F(t) pour Edge/Face
22
23// Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898
24// modified by Edward AGAPOV (eap) Fri Feb 8 2002 (bug occ67 == BUC61052)
25// ComputeData(), case where BRepBlend_Walking::Continu() can't get up to Target
26
27#include <stdio.h>
28
29#include <ChFi3d_Builder.jxx>
30#include <ChFi3d_Builder_0.hxx>
31
32#include <Precision.hxx>
33#include <math_Vector.hxx>
34#include <BSplCLib.hxx>
35
36#include <gp_Pnt.hxx>
37#include <gp_Vec.hxx>
38#include <gp_Pnt2d.hxx>
39#include <gp_Dir2d.hxx>
40#include <gp_Vec2d.hxx>
41
42#include <Geom2d_TrimmedCurve.hxx>
43#include <Geom2d_BSplineCurve.hxx>
44#include <Geom2d_Curve.hxx>
45#include <Geom2d_Line.hxx>
46#include <Geom_Curve.hxx>
47#include <Geom_BSplineSurface.hxx>
48#include <GeomLib.hxx>
49
50#include <Adaptor3d_HSurface.hxx>
51#include <Adaptor3d_TopolTool.hxx>
52#include <GeomAdaptor_HCurve.hxx>
53#include <GeomAdaptor_HSurface.hxx>
54#include <BRepAdaptor_Surface.hxx>
55#include <BRepAdaptor_Curve2d.hxx>
56#include <BRepAdaptor_Curve.hxx>
57#include <BRepAdaptor_HCurve2d.hxx>
58#include <BRepTopAdaptor_TopolTool.hxx>
59#include <BRepTopAdaptor_HVertex.hxx>
60#include <BRep_Tool.hxx>
61
62#include <Approx_SweepFunction.hxx>
63#include <Blend_Point.hxx>
64#include <BRepBlend_Extremity.hxx>
65#include <BRepBlend_PointOnRst.hxx>
66#include <BRepBlend_Line.hxx>
67#include <BRepBlend_AppSurf.hxx>
68#include <BRepBlend_AppSurface.hxx>
69#include <BRepBlend_AppFunc.hxx>
70#include <BRepBlend_AppFuncRst.hxx>
71#include <BRepBlend_AppFuncRstRst.hxx>
72#include <BRepBlend_CSWalking.hxx>
73#include <BRepBlend_Walking.hxx>
74#include <BRepBlend_SurfRstLineBuilder.hxx>
75#include <BRepBlend_RstRstLineBuilder.hxx>
76#include <BRepBlend_ConstRad.hxx>
77#include <BRepBlend_ConstRadInv.hxx>
78
79#include <TopOpeBRepDS_DataStructure.hxx>
80#include <TopOpeBRepDS_Curve.hxx>
81#include <TopOpeBRepDS_Surface.hxx>
82
83#include <IntRes2d_IntersectionPoint.hxx>
84#include <Geom2dInt_GInter.hxx>
85#include <Geom2dAPI_ProjectPointOnCurve.hxx>
86
87#include <ChFiDS_SurfData.hxx>
88#include <ChFiDS_FaceInterference.hxx>
89#include <ChFiDS_CommonPoint.hxx>
90
91#include <TopExp.hxx>
92#include <TopTools_ListOfShape.hxx>
93#include <TopTools_ListIteratorOfListOfShape.hxx>
94
95#ifdef DEB
81bba717 96// For measurements.
7fd59977 97#include <OSD_Chronometer.hxx>
98//static OSD_Chronometer appclock;
99#endif
100
101//#define DRAW
102
103#ifdef DRAW
104#include <Draw_Appli.hxx>
105#include <Draw_Segment2D.hxx>
106#include <Draw_Marker2D.hxx>
107#include <Draw_Segment3D.hxx>
108#include <Draw_Marker3D.hxx>
109#include <Draw.hxx>
110#include <DrawTrSurf.hxx>
111static Standard_Integer IndexOfConge = 0;
112#endif
113
114#ifdef DEB
115extern Standard_Boolean ChFi3d_GettraceDRAWFIL();
116extern Standard_Boolean ChFi3d_GettraceDRAWWALK();
117extern Standard_Boolean ChFi3d_GetcontextNOOPT();
118extern void ChFi3d_SettraceDRAWFIL(const Standard_Boolean b);
119extern void ChFi3d_SettraceDRAWWALK(const Standard_Boolean b);
120extern void ChFi3d_SetcontextNOOPT(const Standard_Boolean b);
121#endif
122
123#ifdef DRAW
124static void drawline(const Handle(BRepBlend_Line)& lin,
125 const Standard_Boolean iscs)
126{
127 Handle(Draw_Marker3D) p3d;
128 Handle(Draw_Marker2D) p2d;
129 Handle(Draw_Segment3D) tg3d;
130 Handle(Draw_Segment2D) tg2d;
131
132 for(Standard_Integer i = 1; i <= lin->NbPoints(); i++){
133 const Blend_Point& pt = lin->Point(i);
134 gp_Pnt point = pt.PointOnS1();
135 gp_Pnt extr = point.Translated(pt.TangentOnS1());
136 p3d = new Draw_Marker3D(point,Draw_Square,Draw_rouge);
137 dout<<p3d;
138 tg3d = new Draw_Segment3D(point,extr,Draw_rouge);
139 dout<<tg3d;
140 point = pt.PointOnS2();
141 extr = point.Translated(pt.TangentOnS2());
142 p3d = new Draw_Marker3D(point,Draw_Plus,Draw_jaune);
143 dout<<p3d;
144 tg3d = new Draw_Segment3D(point,extr,Draw_jaune);
145 dout<<tg3d;
146
147 Standard_Real u,v;
148 pt.ParametersOnS1(u,v);
149 gp_Pnt2d point2d(u,v);
150 gp_Pnt2d extr2d = point2d.Translated(pt.Tangent2dOnS1());
151 p2d = new Draw_Marker2D(point2d,Draw_Square,Draw_rouge);
152 dout<<p2d;
153 tg2d = new Draw_Segment2D(point2d,extr2d,Draw_rouge);
154 dout<<tg2d;
155 pt.ParametersOnS2(u,v);
156 point2d.SetCoord(u,v);
157 extr2d = point2d.Translated(pt.Tangent2dOnS2());
158 p2d = new Draw_Marker2D(point2d,Draw_Plus,Draw_jaune);
159 dout<<p2d;
160 tg2d = new Draw_Segment2D(point2d,extr2d,Draw_jaune);
161 dout<<tg2d;
162 dout.Flush();
163 }
164}
165#endif
166//=======================================================================
167//function : SearchIndex
168//purpose :
169//
170//=======================================================================
171static Standard_Integer SearchIndex(const Standard_Real Value,
172 Handle(BRepBlend_Line)& Lin)
173{
174 Standard_Integer NbPnt = Lin->NbPoints(), Ind;
175
176 for (Ind = 1;
177 (Ind < NbPnt) && (Lin->Point(Ind).Parameter() < Value); )
178 Ind++;
179 return Ind;
180}
181
182
183//=======================================================================
184//function : IsObst
185//purpose :
186//
187//=======================================================================
188static Standard_Integer nbedconnex(const TopTools_ListOfShape& L)
189{
190 Standard_Integer nb = 0, i = 0;
191 TopTools_ListIteratorOfListOfShape It1(L);
192 for(;It1.More();It1.Next(),i++){
193 const TopoDS_Shape& curs = It1.Value();
194 Standard_Boolean dejavu = 0;
195 TopTools_ListIteratorOfListOfShape It2(L);
196 for(Standard_Integer j = 0; j < i && It2.More(); j++, It2.Next()){
197 if(curs.IsSame(It2.Value())){
198 dejavu = 1;
199 break;
200 }
201 }
202 if(!dejavu) nb++;
203 }
204 return nb;
205}
206
207static Standard_Boolean IsVois(const TopoDS_Edge& E,
208 const TopoDS_Vertex& Vref,
209 const ChFiDS_Map& VEMap,
210 TopTools_MapOfShape& DONE,
211 const Standard_Integer prof,
212 const Standard_Integer profmax)
213{
214 if(prof > profmax) return Standard_False;
215 if(DONE.Contains(E)) return Standard_False;
216 TopoDS_Vertex V1,V2;
217 TopExp::Vertices(E,V1,V2);
218 if(Vref.IsSame(V1) || Vref.IsSame(V2)) return Standard_True;
219 DONE.Add(E);
220 const TopTools_ListOfShape& L1 = VEMap(V1);
221 Standard_Integer i1 = nbedconnex(L1);
222 TopTools_ListIteratorOfListOfShape It1(L1);
223 for(;It1.More();It1.Next()){
224 const TopoDS_Edge& curE = TopoDS::Edge(It1.Value());
225 if(i1 <= 2){
226 if(IsVois(curE,Vref,VEMap,DONE,prof,profmax)) return Standard_True;
227 }
228 else if(IsVois(curE,Vref,VEMap,DONE,prof+1,profmax)) return Standard_True;
229 }
230 const TopTools_ListOfShape& L2 = VEMap(V2);
231#ifdef DEB
232// Standard_Integer i2 = nbedconnex(L2);
233#endif
234 TopTools_ListIteratorOfListOfShape It2(L2);
235 for(;It2.More();It2.Next()){
236 const TopoDS_Edge& curE = TopoDS::Edge(It2.Value());
237 if(i1 <= 2){
238 if(IsVois(curE,Vref,VEMap,DONE,prof,profmax)) return Standard_True;
239 }
240 else if(IsVois(curE,Vref,VEMap,DONE,prof+1,profmax)) return Standard_True;
241 }
242 return Standard_False;
243}
244
245static Standard_Boolean IsObst(const ChFiDS_CommonPoint& CP,
246 const TopoDS_Vertex& Vref,
247 const ChFiDS_Map& VEMap)
248{
249 if(!CP.IsOnArc()) return Standard_False;
250 const TopoDS_Edge& E = CP.Arc();
251 TopTools_MapOfShape DONE;
252 Standard_Integer prof = 4;
253 return !IsVois(E,Vref,VEMap,DONE,0,prof);
254}
255
256//=======================================================================
257//function : CompParam
258//purpose :
259//
260//=======================================================================
261
262static void CompParam(Geom2dAdaptor_Curve Carc,
263 Handle(Geom2d_Curve) Ctg,
264 Standard_Real& parc,
265 Standard_Real& ptg,
266 const Standard_Real prefarc,
267 const Standard_Real preftg)
268{
269 Standard_Boolean found = 0;
81bba717 270 //(1) It is checked if the provided parameters are good
271 // if pcurves have the same parameters as the spine.
7fd59977 272 gp_Pnt2d point = Carc.Value(prefarc);
273 Standard_Real distini = point.Distance(Ctg->Value(preftg));
274 if (distini <= Precision::PConfusion()) {
275 parc = prefarc;
276 ptg = preftg;
277 found = Standard_True;
278 }
279 else {
81bba717 280 //(2) Intersection
7fd59977 281#ifdef DEB
81bba717 282 cout<< "CompParam : bad intersection parameters"<<endl;
7fd59977 283#endif
284 IntRes2d_IntersectionPoint int2d;
285 Geom2dInt_GInter Intersection;
286 Standard_Integer nbpt,nbseg;
287 Intersection.Perform(Geom2dAdaptor_Curve(Ctg),Carc,
288 Precision::PIntersection(),
289 Precision::PIntersection());
290
291 Standard_Real dist = Precision::Infinite(), p1, p2;
292 if (Intersection.IsDone()){
293 if (!Intersection.IsEmpty()){
294 nbseg = Intersection.NbSegments();
295 if ( nbseg > 0 ){
296#ifdef DEB
81bba717 297 cout<< "segments of intersection on the restrictions"<<endl;
7fd59977 298#endif
299 }
300 nbpt = Intersection.NbPoints();
301 for (Standard_Integer i = 1; i <= nbpt; i++) {
302 int2d = Intersection.Point(i);
303 p1 = int2d.ParamOnFirst();
304 p2 = int2d.ParamOnSecond();
305 if(Abs(prefarc - p2) < dist){
306 ptg = p1;
307 parc = p2;
308 dist = Abs(prefarc - p2);
309 found = 1;
310 }
311 }
312 }
313 }
314 }
315
316 if(!found){
81bba717 317 // (3) Projection...
7fd59977 318#ifdef DEB
81bba717 319 cout<<"CompParam : failed intersection PC, projection is created."<<endl;
7fd59977 320#endif
321 parc = prefarc;
322 Geom2dAPI_ProjectPointOnCurve projector(point,Ctg);
323
324 if(projector.NbPoints() == 0){
81bba717 325 // This happens in some cases when there is a vertex
326 // at the end of spine...
7fd59977 327 ptg = preftg;
328#ifdef DEB
81bba717 329 cout<<"CompParam : failed proj p2d/c2d, the extremity is taken!" <<endl;
7fd59977 330#endif
331 }
332 else {
81bba717 333 // It is checked if everything was calculated correctly (EDC402 C2)
7fd59977 334 if (projector.LowerDistance() < distini)
335 ptg = projector.LowerDistanceParameter();
336 else ptg = preftg;
337 }
338 }
339}
340
341//=======================================================================
342//function : CompBlendPoint
81bba717 343//purpose : create BlendPoint corresponding to a tangency on Vertex
344// pmn : 15/10/1997 : returns false, if there is no pcurve
7fd59977 345//=======================================================================
346
347static Standard_Boolean CompBlendPoint(const TopoDS_Vertex& V,
348 const TopoDS_Edge& E,
349 const Standard_Real W,
350 const TopoDS_Face F1,
351 const TopoDS_Face F2,
352 Blend_Point& BP)
353{
354 gp_Pnt2d P1, P2;
355 gp_Pnt P3d;
356 Standard_Real param, f, l;
357 Handle(Geom2d_Curve) pc;
358
359 P3d = BRep_Tool::Pnt(V);
360 param = BRep_Tool::Parameter(V,E,F1);
361 pc = BRep_Tool::CurveOnSurface(E,F1,f,l);
362 if (pc.IsNull()) return Standard_False;
363 P1 = pc->Value(param);
364 param = BRep_Tool::Parameter(V,E,F2);
365 pc = BRep_Tool::CurveOnSurface(E,F2,f,l);
366 if (pc.IsNull()) return Standard_False;
367 P2 = pc->Value(param);
368 BP.SetValue(P3d, P3d, W, P1.X(), P1.Y(), P2.X(), P2.Y());
369 return Standard_True;
370}
371
372//=======================================================================
373//function : UpdateLine
81bba717 374//purpose : Updates extremities after a partial invalidation
7fd59977 375//=======================================================================
376
377static void UpdateLine(Handle(BRepBlend_Line)& Line,
378 const Standard_Boolean isfirst)
379{
380 Standard_Real tguide, U, V;
381 if (isfirst) {
382 const Blend_Point& BP = Line->Point(1);
383 tguide = BP.Parameter();
384 if (Line->StartPointOnFirst().ParameterOnGuide() < tguide) {
385 BRepBlend_Extremity BE;
386 BP.ParametersOnS1(U, V);
387 BE.SetValue(BP.PointOnS1(), U, V, Precision::Confusion());
388 Line->SetStartPoints(BE, Line->StartPointOnSecond());
389 }
390 if (Line->StartPointOnSecond().ParameterOnGuide() < tguide) {
391 BRepBlend_Extremity BE;
392 BP.ParametersOnS2(U, V);
393 BE.SetValue(BP.PointOnS2(), U, V, Precision::Confusion());
394 Line->SetStartPoints(Line->StartPointOnFirst(), BE);
395 }
396 }
397 else {
398 const Blend_Point& BP = Line->Point(Line->NbPoints());
399 tguide = BP.Parameter();
400 if (Line->EndPointOnFirst().ParameterOnGuide() > tguide) {
401 BRepBlend_Extremity BE;
402 BP.ParametersOnS1(U, V);
403 BE.SetValue(BP.PointOnS1(), U, V, Precision::Confusion());
404 Line->SetEndPoints(BE, Line->EndPointOnSecond());
405 }
406 if (Line->EndPointOnSecond().ParameterOnGuide() > tguide) {
407 BRepBlend_Extremity BE;
408 BP.ParametersOnS2(U, V);
409 BE.SetValue(BP.PointOnS2(), U, V, Precision::Confusion());
410 Line->SetEndPoints(Line->EndPointOnFirst(), BE);
411 }
412 }
413}
414
415//=======================================================================
416//function : CompleteData
81bba717 417//purpose : Calculates curves and CommonPoints from the data
418// calculated by filling.
7fd59977 419//=======================================================================
420
421Standard_Boolean ChFi3d_Builder::CompleteData
422(Handle(ChFiDS_SurfData)& Data,
423 const Handle(Geom_Surface)& Surfcoin,
424 const Handle(Adaptor3d_HSurface)& S1,
425 const Handle(Geom2d_Curve)& PC1,
426 const Handle(Adaptor3d_HSurface)& S2,
427 const Handle(Geom2d_Curve)& PC2,
428 const TopAbs_Orientation Or,
429 const Standard_Boolean On1,
430 const Standard_Boolean Gd1,
431 const Standard_Boolean Gd2,
432 const Standard_Boolean Gf1,
433 const Standard_Boolean Gf2)
434{
435 TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
436 Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surfcoin,tolesp)));
437#ifdef DRAW
438 ChFi3d_SettraceDRAWFIL(Standard_True);
439 if (ChFi3d_GettraceDRAWFIL()) {
440 IndexOfConge++;
441// char name[100];
442 char* name = new char[100];
443 sprintf(name,"%s_%d","Surf",IndexOfConge);
444 DrawTrSurf::Set(name,Surfcoin);
445 }
446#endif
447
448 Standard_Real UFirst,ULast,VFirst,VLast;
449 Surfcoin->Bounds(UFirst,ULast,VFirst,VLast);
450 if(!Gd1) Data->ChangeVertexFirstOnS1().SetPoint(Surfcoin->Value(UFirst,VFirst));
451 if(!Gd2) Data->ChangeVertexFirstOnS2().SetPoint(Surfcoin->Value(UFirst,VLast));
452 if(!Gf1) Data->ChangeVertexLastOnS1().SetPoint(Surfcoin->Value(ULast,VFirst));
453 if(!Gf2) Data->ChangeVertexLastOnS2().SetPoint(Surfcoin->Value(ULast,VLast));
454
81bba717 455 //calculate curves side S1
7fd59977 456 Handle(Geom_Curve) Crv3d1;
457 if(!PC1.IsNull()) Crv3d1= Surfcoin->VIso(VFirst);
458 gp_Pnt2d pd1(UFirst,VFirst), pf1(ULast,VFirst);
459 gp_Lin2d lfil1(pd1,gp_Dir2d(gp_Vec2d(pd1,pf1)));
460 Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1);
461 TopAbs_Orientation tra1 = TopAbs_FORWARD, orsurf = Or;
462 Standard_Real x,y,w = 0.5*(UFirst+ULast);
463 gp_Pnt p;
464 gp_Vec du,dv;
465 Handle(Geom2d_Curve) c2dtrim;
466 Standard_Real tolreached;
467 if(!PC1.IsNull()){
468 Handle(GeomAdaptor_HCurve) hcS1 = new GeomAdaptor_HCurve(Crv3d1);
469 c2dtrim = new Geom2d_TrimmedCurve(PC1,UFirst,ULast);
470 ChFi3d_SameParameter(hcS1,c2dtrim,S1,tolapp3d,tolreached);
471 c2dtrim->Value(w).Coord(x,y);
472 S1->D1(x,y,p,du,dv);
473 gp_Vec nf = du.Crossed(dv);
474 Surfcoin->D1(w,VFirst,p,du,dv);
475 gp_Vec ns = du.Crossed(dv);
476 if(nf.Dot(ns) > 0.) tra1 = TopAbs_REVERSED;
477 else if(On1) orsurf = TopAbs::Reverse(orsurf);
478 }
479 Standard_Integer Index1OfCurve =
480 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolreached));
481 ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1();
482 Fint1.SetFirstParameter(UFirst);
483 Fint1.SetLastParameter(ULast);
484 Fint1.SetInterference(Index1OfCurve,tra1,c2dtrim,PCurveOnSurf);
81bba717 485 //calculate curves side S2
7fd59977 486 Handle(Geom_Curve) Crv3d2;
487 if(!PC2.IsNull()) Crv3d2 = Surfcoin->VIso(VLast);
488 gp_Pnt2d pd2(UFirst,VLast), pf2(ULast,VLast);
489 gp_Lin2d lfil2(pd2,gp_Dir2d(gp_Vec2d(pd2,pf2)));
490 PCurveOnSurf = new Geom2d_Line(lfil2);
491 TopAbs_Orientation tra2 = TopAbs_FORWARD;
492 if(!PC2.IsNull()){
493 Handle(GeomAdaptor_HCurve) hcS2 = new GeomAdaptor_HCurve(Crv3d2);
494 c2dtrim = new Geom2d_TrimmedCurve(PC2,UFirst,ULast);
495 ChFi3d_SameParameter(hcS2,c2dtrim,S2,tolapp3d,tolreached);
496 c2dtrim->Value(w).Coord(x,y);
497 S2->D1(x,y,p,du,dv);
498 gp_Vec np = du.Crossed(dv);
499 Surfcoin->D1(w,VLast,p,du,dv);
500 gp_Vec ns = du.Crossed(dv);
501 if(np.Dot(ns) < 0.) {
502 tra2 = TopAbs_REVERSED;
503 if(!On1) orsurf = TopAbs::Reverse(orsurf);
504 }
505 }
506 Standard_Integer Index2OfCurve =
507 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolreached));
508 ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2();
509 Fint2.SetFirstParameter(UFirst);
510 Fint2.SetLastParameter(ULast);
511 Fint2.SetInterference(Index2OfCurve,tra2,c2dtrim,PCurveOnSurf);
512 Data->ChangeOrientation() = orsurf;
513 return Standard_True;
514}
515
516//=======================================================================
517//function : CompleteData
81bba717 518//purpose : Calculates the surface of curves and eventually
519// CommonPoints from the data calculated in ComputeData.
7fd59977 520//
81bba717 521// 11/08/1996 : Use of F(t)
7fd59977 522//
523//=======================================================================
524
525Standard_Boolean ChFi3d_Builder::CompleteData
526(Handle(ChFiDS_SurfData)& Data,
527 Blend_Function& Func,
528 Handle(BRepBlend_Line)& lin,
529 const Handle(Adaptor3d_HSurface)& S1,
530 const Handle(Adaptor3d_HSurface)& S2,
531 const TopAbs_Orientation Or1,
532 const Standard_Boolean Gd1,
533 const Standard_Boolean Gd2,
534 const Standard_Boolean Gf1,
535 const Standard_Boolean Gf2,
536 const Standard_Boolean Reversed)
537{
538 Handle(BRepBlend_AppFunc) TheFunc
539 = new (BRepBlend_AppFunc)(lin, Func, tolapp3d, 1.e-5);
822ffdff 540
ea9632bc 541 Standard_Integer Degmax = 20, Segmax = 5000;
7fd59977 542 BRepBlend_AppSurface approx (TheFunc,
543 lin->Point(1).Parameter(),
544 lin->Point(lin->NbPoints()).Parameter(),
545 tolapp3d, 1.e-5, //tolapp2d, tolerance max
546 tolappangle, // Contact G1
822ffdff 547 myConti, Degmax, Segmax);
7fd59977 548 if (!approx.IsDone()) {
549#ifdef DEB
550 cout << "Approximation non faite !!!" << endl;
551#endif
552 return Standard_False;
553 }
554#ifdef DEB
555 approx.Dump(cout);
556#endif
557 return StoreData( Data, approx, lin, S1, S2, Or1, Gd1, Gd2, Gf1, Gf2, Reversed);
558}
559
560
561//=======================================================================
562//function : CompleteData
81bba717 563//purpose : New overload for functions surf/rst
7fd59977 564// jlr le 28/07/97 branchement F(t)
565//=======================================================================
566
567Standard_Boolean ChFi3d_Builder::CompleteData
568(Handle(ChFiDS_SurfData)& Data,
569 Blend_SurfRstFunction& Func,
570 Handle(BRepBlend_Line)& lin,
571 const Handle(Adaptor3d_HSurface)& S1,
572 const Handle(Adaptor3d_HSurface)& S2,
573 const TopAbs_Orientation Or,
574 const Standard_Boolean Reversed)
575{
576 Handle(BRepBlend_AppFuncRst) TheFunc
577 = new (BRepBlend_AppFuncRst)(lin, Func, tolapp3d, 1.e-5);
578 BRepBlend_AppSurface approx (TheFunc,
579 lin->Point(1).Parameter(),
580 lin->Point(lin->NbPoints()).Parameter(),
581 tolapp3d, 1.e-5, //tolapp2d, tolerance max
582 tolappangle, // Contact G1
583 myConti);
584 if (!approx.IsDone()) {
585#ifdef DEB
81bba717 586 cout << "Approximation is not done!" << endl;
7fd59977 587#endif
588 return Standard_False;
589 }
590#ifdef DEB
591 approx.Dump(cout);
592#endif
593
594 return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0,Reversed);
595}
596
597
598
599//=======================================================================
600//function : CompleteData
81bba717 601//purpose : New overload for functions rst/rst
7fd59977 602// jlr le 28/07/97 branchement F(t)
603//=======================================================================
604
605Standard_Boolean ChFi3d_Builder::CompleteData
606(Handle(ChFiDS_SurfData)& Data,
607 Blend_RstRstFunction& Func,
608 Handle(BRepBlend_Line)& lin,
609 const Handle(Adaptor3d_HSurface)& S1,
610 const Handle(Adaptor3d_HSurface)& S2,
611 const TopAbs_Orientation Or)
612{
613 Handle(BRepBlend_AppFuncRstRst) TheFunc
614 = new (BRepBlend_AppFuncRstRst)(lin, Func, tolapp3d, 1.e-5);
615 BRepBlend_AppSurface approx (TheFunc,
616 lin->Point(1).Parameter(),
617 lin->Point(lin->NbPoints()).Parameter(),
618 tolapp3d, 1.e-5, //tolapp2d, tolerance max
619 tolappangle, // Contact G1
620 myConti);
621 if (!approx.IsDone()) {
622#ifdef DEB
623 cout << "Approximation non faite !!!" << endl;
624#endif
625 return Standard_False;
626 }
627#ifdef DEB
628 approx.Dump(cout);
629#endif
630
631 return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0);
632}
633
634
635
636
637//=======================================================================
638//function : StoreData
81bba717 639//purpose : Copy of an approximation result in SurfData.
7fd59977 640//=======================================================================
641
642Standard_Boolean ChFi3d_Builder::StoreData(Handle(ChFiDS_SurfData)& Data,
643 const AppBlend_Approx& approx,
644 const Handle(BRepBlend_Line)& lin,
645 const Handle(Adaptor3d_HSurface)& S1,
646 const Handle(Adaptor3d_HSurface)& S2,
647 const TopAbs_Orientation Or1,
648 const Standard_Boolean Gd1,
649 const Standard_Boolean Gd2,
650 const Standard_Boolean Gf1,
651 const Standard_Boolean Gf2,
652 const Standard_Boolean Reversed)
653{
81bba717 654 // Small control tools.
7fd59977 655 static Handle(GeomAdaptor_HCurve) checkcurve;
656 if(checkcurve.IsNull()) checkcurve = new GeomAdaptor_HCurve();
657 GeomAdaptor_Curve& chc = checkcurve->ChangeCurve();
658 Standard_Real tolget3d, tolget2d, tolaux, tolC1, tolcheck;
7fd59977 659 Standard_Real tolC2 = 0.;
7fd59977 660 approx.TolReached(tolget3d, tolget2d);
661 tolaux = approx.TolCurveOnSurf(1);
662 tolC1 = tolget3d + tolaux;
663 if(!S2.IsNull()) {
664 tolaux = approx.TolCurveOnSurf(2);
665 tolC2 = tolget3d + tolaux;
666 }
667
668 TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
81bba717 669 // By default parametric space is created using a square surface
670 // to be able to parameterize in U by # R*teta // a revoir lbo 29/08/97
7fd59977 671 const TColStd_Array1OfReal& ku = approx.SurfUKnots();
672 const TColStd_Array1OfReal& kv = approx.SurfVKnots();
673 Standard_Real larg = (kv(kv.Upper())-kv(kv.Lower()));
674 TColStd_Array1OfReal& kku = *((TColStd_Array1OfReal*)((void*)&ku));
675 BSplCLib::Reparametrize(0.,larg,kku);
676 Handle(Geom_BSplineSurface) Surf =
677 new Geom_BSplineSurface(approx.SurfPoles(),approx.SurfWeights(),
678 kku,kv,
679 approx.SurfUMults(),approx.SurfVMults(),
680 approx.UDegree(),approx.VDegree());
81bba717 681// extension of the surface
7fd59977 682
683 Standard_Real length1,length2;
684 length1=Data->FirstExtensionValue();
685 length2=Data->LastExtensionValue();
686 if (length1 > Precision::Confusion())
687 GeomLib::ExtendSurfByLength(Surf,length1,1,Standard_False,Standard_False);
688 if (length2 > Precision::Confusion())
689 GeomLib::ExtendSurfByLength(Surf,length2,1,Standard_False,Standard_True);
690
691 Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surf,tolget3d)));
692
693#ifdef DRAW
694 ChFi3d_SettraceDRAWFIL(Standard_True);
695 if (ChFi3d_GettraceDRAWFIL()) {
696 IndexOfConge++;
697// char name[100];
698 char* name=new char[100];
699 sprintf(name,"%s_%d","Surf",IndexOfConge);
700 DrawTrSurf::Set(name,Surf);
701 }
702#endif
703 Standard_Real UFirst,ULast,VFirst,VLast,pppdeb,pppfin;
704 Surf->Bounds(UFirst,ULast,VFirst,VLast);
705 BRepAdaptor_Curve2d brc;
706 BRepAdaptor_Curve CArc;
707 Handle(BRepAdaptor_HSurface)
708 BS1 = Handle(BRepAdaptor_HSurface)::DownCast(S1);
709 Handle(BRepAdaptor_HSurface)
710 BS2 = Handle(BRepAdaptor_HSurface)::DownCast(S2);
711 Geom2dAPI_ProjectPointOnCurve projector;
712
713 Standard_Real Uon1 = UFirst, Uon2 = ULast;
714 Standard_Integer ion1 = 1, ion2 = 2;
715 if(Reversed) { Uon1 = ULast; Uon2 = UFirst; ion1 = 2; ion2 = 1; }
716
81bba717 717 // The SurfData is filled in what concerns S1,
7fd59977 718 Handle(Geom_Curve) Crv3d1 = Surf->UIso(Uon1);
719 gp_Pnt2d pori1(Uon1,0.);
720 gp_Lin2d lfil1(pori1,gp::DY2d());
721 Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1);
722 Handle(Geom2d_Curve) PCurveOnFace;
723 PCurveOnFace = new
724 Geom2d_BSplineCurve(approx.Curve2dPoles(ion1),approx.Curves2dKnots(),
725 approx.Curves2dMults(),approx.Curves2dDegree());
726
727
728 Standard_Real par1=PCurveOnFace->FirstParameter();
729 Standard_Real par2= PCurveOnFace->LastParameter();
730 chc.Load(Crv3d1,par1,par2);
731
732 if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S1,tolC1,tolcheck)){
733#ifdef DEB
81bba717 734 cout<<"aaproximate tolerance under-valued : "<<tolC1<<" for "<<tolcheck<<endl;
7fd59977 735#endif
736 tolC1 = tolcheck;
737 }
738 Standard_Integer Index1OfCurve =
739 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolC1));
740
741 Standard_Real uarc,utg;
742 if(Gd1){
743 TopoDS_Face forwfac = BS1->ChangeSurface().Face();
744 forwfac.Orientation(TopAbs_FORWARD);
745 brc.Initialize(Data->VertexFirstOnS1().Arc(),forwfac);
746 ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS1();
747 CArc.Initialize(V.Arc());
748 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
749 tolcheck = CArc.Value(uarc).Distance(V.Point());
750 V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
751 pppdeb = utg;
752 }
753 else pppdeb = VFirst;
754 if(Gf1){
755 TopoDS_Face forwfac = BS1->ChangeSurface().Face();
756 forwfac.Orientation(TopAbs_FORWARD);
757 ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS1();
758 brc.Initialize(V.Arc(),forwfac);
759 CArc.Initialize(V.Arc());
760 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
761 tolcheck = CArc.Value(uarc).Distance(V.Point());
762 V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
763 pppfin = utg;
764 }
765 else pppfin = VLast;
766 ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1();
767 Fint1.SetFirstParameter(pppdeb);
768 Fint1.SetLastParameter(pppfin);
769 TopAbs_Orientation TraOn1;
770 if(Reversed) TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
771 else TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
772 Fint1.SetInterference(Index1OfCurve,TraOn1,PCurveOnFace,PCurveOnSurf);
773
81bba717 774 // SurfData is filled in what concerns S2,
7fd59977 775 Handle(Geom_Curve) Crv3d2 = Surf->UIso(Uon2);
776 gp_Pnt2d pori2(Uon2,0.);
777 gp_Lin2d lfil2(pori2,gp::DY2d());
778 PCurveOnSurf = new Geom2d_Line(lfil2);
779 if(!S2.IsNull()){
780 PCurveOnFace = new Geom2d_BSplineCurve(approx.Curve2dPoles(ion2),
781 approx.Curves2dKnots(),
782 approx.Curves2dMults(),
783 approx.Curves2dDegree());
784 chc.Load(Crv3d2,par1,par2);
785 if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S2,tolC2,tolcheck)){
786#ifdef DEB
81bba717 787 cout<<"approximate tolerance under-evaluated : "<<tolC2<<" for "<<tolcheck<<endl;
7fd59977 788#endif
789 tolC2 = tolcheck;
790 }
791 }
792 Standard_Integer Index2OfCurve =
793 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolC2));
794 if(Gd2){
795 TopoDS_Face forwfac = BS2->ChangeSurface().Face();
796 forwfac.Orientation(TopAbs_FORWARD);
797 brc.Initialize(Data->VertexFirstOnS2().Arc(),forwfac);
798 ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS2();
799 CArc.Initialize(V.Arc());
800 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
801 tolcheck = CArc.Value(uarc).Distance(V.Point());
802 V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
803 pppdeb = utg;
804 }
805 else pppdeb = VFirst;
806 if(Gf2){
807 TopoDS_Face forwfac = BS2->ChangeSurface().Face();
808 forwfac.Orientation(TopAbs_FORWARD);
809 brc.Initialize(Data->VertexLastOnS2().Arc(),forwfac);
810 ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS2();
811 CArc.Initialize(V.Arc());
812 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
813 tolcheck = CArc.Value(uarc).Distance(V.Point());
814 V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
815 pppfin = utg;
816 }
817 else pppfin = VLast;
818 ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2();
819 Fint2.SetFirstParameter(pppdeb);
820 Fint2.SetLastParameter(pppfin);
821 if(!S2.IsNull()){
822 TopAbs_Orientation TraOn2;
823 if(Reversed) TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
824 else TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
825 Fint2.SetInterference(Index2OfCurve,TraOn2,PCurveOnFace,PCurveOnSurf);
826 }
827 else {
828 Handle(Geom2d_Curve) bidpc;
829 Fint2.SetInterference
830 (Index2OfCurve,TopAbs_FORWARD,bidpc,PCurveOnSurf);
831 }
832
81bba717 833 // the orientation of the fillet in relation to the faces is evaluated,
7fd59977 834
835 Handle(Adaptor3d_HSurface) Sref = S1;
836 PCurveOnFace = Fint1.PCurveOnFace();
837 if(Reversed){ Sref = S2; PCurveOnFace = Fint2.PCurveOnFace(); }
838
839// Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898 Begin
840// gp_Pnt2d PUV = PCurveOnFace->Value((VFirst+VLast)/2.);
841// gp_Pnt P;
842// gp_Vec Du1,Du2,Dv1,Dv2;
843// Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
844// Du1.Cross(Dv1);
845// if (Or1 == TopAbs_REVERSED) Du1.Reverse();
846// Surf->D1(UFirst,(VFirst+VLast)/2.,P,Du2,Dv2);
847// Du2.Cross(Dv2);
848// if (Du1.Dot(Du2)>0) Data->ChangeOrientation() = TopAbs_FORWARD;
849// else Data->ChangeOrientation() = TopAbs_REVERSED;
850
851 Standard_Real aDelta = VLast - VFirst;
852 Standard_Integer aDenom = 2;
853
854 while (Standard_True) {
855 Standard_Real aDeltav = aDelta/aDenom;
856 Standard_Real aParam = VFirst + aDeltav;
857 gp_Pnt2d PUV = PCurveOnFace->Value(aParam);
858 gp_Pnt P;
859 gp_Vec Du1,Du2,Dv1,Dv2;
860
861 Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
862 Du1.Cross(Dv1);
863
864 if (Or1 == TopAbs_REVERSED)
865 Du1.Reverse();
866
867 Surf->D1(UFirst, aParam, P, Du2, Dv2);
868 Du2.Cross(Dv2);
869
870 if (Du1.Magnitude() <= tolget3d ||
871 Du2.Magnitude() <= tolget3d) {
872 aDenom++;
873
874 if (Abs(aDeltav) <= tolget2d)
875 return Standard_False;
876
877 continue;
878 }
879
880 if (Du1.Dot(Du2)>0)
881 Data->ChangeOrientation() = TopAbs_FORWARD;
882 else
883 Data->ChangeOrientation() = TopAbs_REVERSED;
884
885 break;
886 }
887// Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898 End
888
889 if(!Gd1 && !S1.IsNull())
890 ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(),
891 Standard_True, Data->ChangeVertex(1,ion1),tolC1);
892 if(!Gf1 && !S1.IsNull())
893 ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(),
894 Standard_False,Data->ChangeVertex(0,ion1),tolC1);
895 if(!Gd2 && !S2.IsNull())
896 ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(),
897 Standard_True, Data->ChangeVertex(1,ion2),tolC2);
898 if(!Gf2 && !S2.IsNull())
899 ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(),
900 Standard_False, Data->ChangeVertex(0,ion2),tolC2);
81bba717 901 // Parameters on ElSpine
7fd59977 902 Standard_Integer nbp = lin->NbPoints();
903 Data->FirstSpineParam(lin->Point(1).Parameter());
904 Data->LastSpineParam(lin->Point(nbp).Parameter());
905 return Standard_True;
906}
907
908
909
910//=======================================================================
911//function : ComputeData
81bba717 912//purpose : Head of the path edge/face for the bypass of obstacle.
7fd59977 913//=======================================================================
914
915Standard_Boolean ChFi3d_Builder::ComputeData
916(Handle(ChFiDS_SurfData)& Data,
917 const Handle(ChFiDS_HElSpine)& HGuide,
918 Handle(BRepBlend_Line)& Lin,
919 const Handle(Adaptor3d_HSurface)& S1,
920 const Handle(Adaptor3d_TopolTool)& I1,
921 const Handle(Adaptor3d_HSurface)& S2,
922 const Handle(Adaptor2d_HCurve2d)& PC2,
923 const Handle(Adaptor3d_TopolTool)& I2,
924 Standard_Boolean& Decroch,
925 Blend_SurfRstFunction& Func,
926 Blend_FuncInv& FInv,
927 Blend_SurfPointFuncInv& FInvP,
928 Blend_SurfCurvFuncInv& FInvC,
929 const Standard_Real PFirst,
930 const Standard_Real MaxStep,
931 const Standard_Real Fleche,
932 const Standard_Real TolGuide,
933 Standard_Real& First,
934 Standard_Real& Last,
935 const math_Vector& Soldep,
936 const Standard_Boolean Inside,
937 const Standard_Boolean Appro,
938 const Standard_Boolean Forward,
939 const Standard_Boolean RecP,
940 const Standard_Boolean RecS,
941 const Standard_Boolean RecRst)
942{
943 BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
944
945 Data->FirstExtensionValue(0);
946 Data->LastExtensionValue(0);
947
948 Standard_Boolean reverse = (!Forward || Inside);
949 Standard_Real SpFirst = HGuide->FirstParameter();
950 Standard_Real SpLast = HGuide->LastParameter();
951 Standard_Real Target = SpLast;
952 if(reverse) Target = SpFirst;
953 Standard_Real Targetsov = Target;
954
955 Standard_Real MS = MaxStep;
956 Standard_Integer again = 0;
957 Standard_Integer nbptmin = 3; //jlr
7fd59977 958 Standard_Integer Nbpnt = 0;
81bba717 959 // the initial solution is reframed if necessary.
7fd59977 960 math_Vector ParSol(1,3);
961 Standard_Real NewFirst = PFirst;
962 if(RecP || RecS || RecRst){
963 if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep,
964 tolesp,TolGuide,RecRst,RecP,RecS,
965 NewFirst,ParSol)){
966#ifdef DEB
81bba717 967 cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<endl;
7fd59977 968#endif
969 return Standard_False;
970 }
971 }
972 else {
973 ParSol = Soldep;
974 }
975
976 while (again < 2){
977 TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last,
978 MS,TolGuide,ParSol,tolesp,Fleche,Appro);
979
980 if (!TheWalk.IsDone()) {
981#ifdef DEB
81bba717 982 cout << "Path not created" << endl;
7fd59977 983#endif
984 return Standard_False;
985 }
986
987 if (reverse) {
988 if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) {
989#ifdef DEB
81bba717 990 cout << "Not completed" << endl;
7fd59977 991#endif
992 }
993 }
994
995
996 Lin = TheWalk.Line();
997 Nbpnt = Lin->NbPoints();
998 if (Nbpnt <= 1 && again == 0) {
999 again++;
1000#ifdef DEB
81bba717 1001 cout <<"one point of the path MS/50 is attempted."<<endl;
7fd59977 1002#endif
1003 MS = MS/50.; Target = Targetsov;
1004 }
1005 else if (Nbpnt<=nbptmin && again == 0) {
1006 again++;
1007#ifdef DEB
81bba717 1008 cout <<"Number of points is too small, the step is reduced"<<endl;
7fd59977 1009#endif
1010 Standard_Real u1 = Lin->Point(1).Parameter();
1011 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1012 MS = (u2-u1)/(nbptmin+1.0);
1013// cout << " MS : " << MS << " u1 : " << u1 << " u2 : " << u2 << " nbptmin : " << nbptmin << endl;
1014 Target = Targetsov;
1015 }
1016 else if(Nbpnt<=nbptmin){
1017#ifdef DEB
81bba717 1018 cout <<"Number of points is still too small, quit"<<endl;
7fd59977 1019#endif
1020 return Standard_False;
1021 }
1022 else {
1023 again = 2;
1024 }
1025 }
1026#ifdef DRAW
1027 ChFi3d_SettraceDRAWWALK(Standard_True);
1028 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1029#endif
1030 if(Forward) Decroch = TheWalk.DecrochEnd();
1031 else Decroch = TheWalk.DecrochStart();
1032 Last = Lin->Point(Nbpnt).Parameter();
1033 First = Lin->Point(1).Parameter();
1034 return Standard_True;
1035}
1036
1037
1038//=======================================================================
1039//function : ComputeData
81bba717 1040//purpose : Heading of the path edge/edge for the bypass of obstacle.
7fd59977 1041//=======================================================================
1042
1043Standard_Boolean ChFi3d_Builder::ComputeData
1044(Handle(ChFiDS_SurfData)& Data,
1045 const Handle(ChFiDS_HElSpine)& HGuide,
1046 Handle(BRepBlend_Line)& Lin,
1047 const Handle(Adaptor3d_HSurface)& S1,
1048 const Handle(Adaptor2d_HCurve2d)& PC1,
1049 const Handle(Adaptor3d_TopolTool)& I1,
1050 Standard_Boolean& Decroch1,
1051 const Handle(Adaptor3d_HSurface)& S2,
1052 const Handle(Adaptor2d_HCurve2d)& PC2,
1053 const Handle(Adaptor3d_TopolTool)& I2,
1054 Standard_Boolean& Decroch2,
1055 Blend_RstRstFunction& Func,
1056 Blend_SurfCurvFuncInv& FInv1,
1057 Blend_CurvPointFuncInv& FInvP1,
1058 Blend_SurfCurvFuncInv& FInv2,
1059 Blend_CurvPointFuncInv& FInvP2,
1060 const Standard_Real PFirst,
1061 const Standard_Real MaxStep,
1062 const Standard_Real Fleche,
1063 const Standard_Real TolGuide,
1064 Standard_Real& First,
1065 Standard_Real& Last,
1066 const math_Vector& Soldep,
1067 const Standard_Boolean Inside,
1068 const Standard_Boolean Appro,
1069 const Standard_Boolean Forward,
1070 const Standard_Boolean RecP1,
1071 const Standard_Boolean RecRst1,
1072 const Standard_Boolean RecP2,
1073 const Standard_Boolean RecRst2)
1074{
1075 BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1076
1077 Data->FirstExtensionValue(0);
1078 Data->LastExtensionValue(0);
1079
1080 Standard_Boolean reverse = (!Forward || Inside);
1081 Standard_Real SpFirst = HGuide->FirstParameter();
1082 Standard_Real SpLast = HGuide->LastParameter();
1083 Standard_Real Target = SpLast;
1084 if(reverse) Target = SpFirst;
1085 Standard_Real Targetsov = Target;
1086
1087 Standard_Real MS = MaxStep;
1088 Standard_Integer again = 0;
1089 Standard_Integer nbptmin = 3; //jlr
7fd59977 1090 Standard_Integer Nbpnt = 0;
81bba717 1091 // the initial solution is reframed if necessary.
7fd59977 1092 math_Vector ParSol(1,2);
1093 Standard_Real NewFirst = PFirst;
1094 if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1095 if (!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1096 tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1097 NewFirst, ParSol)){
1098#ifdef DEB
81bba717 1099 cout<<"ChFi3d_Builder::ComputeData : fail calculation first section"<<endl;
7fd59977 1100#endif
1101 return Standard_False;
1102 }
1103 }
1104 else {
1105 ParSol = Soldep;
1106 }
1107
1108 while (again < 2){
1109 TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1110 MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1111
1112 if (!TheWalk.IsDone()) {
1113#ifdef DEB
81bba717 1114 cout << "Path not done" << endl;
7fd59977 1115#endif
1116 return Standard_False;
1117 }
1118
1119 if (reverse) {
1120 if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1121#ifdef DEB
81bba717 1122 cout << "Not completed" << endl;
7fd59977 1123#endif
1124 }
1125 }
1126
1127
1128 Lin = TheWalk.Line();
1129 Nbpnt = Lin->NbPoints();
1130 if (Nbpnt <= 1 && again == 0) {
1131 again++;
1132#ifdef DEB
81bba717 1133 cout <<"one point of path MS/50 is attempted."<<endl;
7fd59977 1134#endif
1135 MS = MS/50.; Target = Targetsov;
1136 }
1137 else if (Nbpnt<=nbptmin && again == 0) {
1138 again++;
1139#ifdef DEB
81bba717 1140 cout <<"Number of points is too small, the step is reduced"<<endl;
7fd59977 1141#endif
1142 Standard_Real u1 = Lin->Point(1).Parameter();
1143 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1144 MS = (u2-u1)/(nbptmin+1);
1145 Target = Targetsov;
1146 }
1147 else if(Nbpnt<=nbptmin){
1148#ifdef DEB
81bba717 1149 cout <<"Number of points is still too small, quit"<<endl;
7fd59977 1150#endif
1151 return Standard_False;
1152 }
1153 else {
1154 again = 2;
1155 }
1156 }
1157#ifdef DRAW
1158 ChFi3d_SettraceDRAWWALK(Standard_True);
1159 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1160#endif
1161 if (Forward) {
1162 Decroch1 = TheWalk.Decroch1End();
1163 Decroch2 = TheWalk.Decroch2End();
1164 }
1165 else {
1166 Decroch1 = TheWalk.Decroch1Start();
1167 Decroch2 = TheWalk.Decroch2Start();
1168 }
1169 Last = Lin->Point(Nbpnt).Parameter();
1170 First = Lin->Point(1).Parameter();
1171 return Standard_True;
1172}
1173
1174
1175//=======================================================================
1176//function : SimulData
81bba717 1177//purpose : Heading of the path edge/face for the bypass of obstacle in simulation mode.
7fd59977 1178//=======================================================================
1179
1180Standard_Boolean ChFi3d_Builder::SimulData
1181(Handle(ChFiDS_SurfData)& /*Data*/,
1182 const Handle(ChFiDS_HElSpine)& HGuide,
1183 Handle(BRepBlend_Line)& Lin,
1184 const Handle(Adaptor3d_HSurface)& S1,
1185 const Handle(Adaptor3d_TopolTool)& I1,
1186 const Handle(Adaptor3d_HSurface)& S2,
1187 const Handle(Adaptor2d_HCurve2d)& PC2,
1188 const Handle(Adaptor3d_TopolTool)& I2,
1189 Standard_Boolean& Decroch,
1190 Blend_SurfRstFunction& Func,
1191 Blend_FuncInv& FInv,
1192 Blend_SurfPointFuncInv& FInvP,
1193 Blend_SurfCurvFuncInv& FInvC,
1194 const Standard_Real PFirst,
1195 const Standard_Real MaxStep,
1196 const Standard_Real Fleche,
1197 const Standard_Real TolGuide,
1198 Standard_Real& First,
1199 Standard_Real& Last,
1200 const math_Vector& Soldep,
1201 const Standard_Integer NbSecMin,
1202 const Standard_Boolean Inside,
1203 const Standard_Boolean Appro,
1204 const Standard_Boolean Forward,
1205 const Standard_Boolean RecP,
1206 const Standard_Boolean RecS,
1207 const Standard_Boolean RecRst)
1208{
1209 BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
1210
1211 Standard_Boolean reverse = (!Forward || Inside);
1212 Standard_Real SpFirst = HGuide->FirstParameter();
1213 Standard_Real SpLast = HGuide->LastParameter();
1214 Standard_Real Target = SpLast;
1215 if(reverse) Target = SpFirst;
1216 Standard_Real Targetsov = Target;
1217
1218 Standard_Real MS = MaxStep;
1219 Standard_Integer again = 0;
7fd59977 1220 Standard_Integer Nbpnt = 0;
81bba717 1221 // the starting solution is reframed if needed.
7fd59977 1222 math_Vector ParSol(1,3);
1223 Standard_Real NewFirst = PFirst;
1224 if(RecP || RecS || RecRst){
1225 if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep,
1226 tolesp,TolGuide,RecRst,RecP,RecS,
1227 NewFirst,ParSol)){
1228#ifdef DEB
1229
81bba717 1230 cout<<"ChFi3d_Builder::SimulData : fail calculate first section"<<endl;
7fd59977 1231#endif
1232 return Standard_False;
1233 }
1234 }
1235 else {
1236 ParSol = Soldep;
1237 }
1238
1239 while (again < 2){
1240 TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last,
1241 MS,TolGuide,ParSol,tolesp,Fleche,Appro);
1242 if (!TheWalk.IsDone()) {
1243#ifdef DEB
81bba717 1244 cout << "Path not done" << endl;
7fd59977 1245#endif
1246 return Standard_False;
1247 }
1248 if (reverse) {
1249 if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) {
1250#ifdef DEB
81bba717 1251 cout << "Not completed" << endl;
7fd59977 1252#endif
1253 }
1254 }
1255 Lin = TheWalk.Line();
1256 Nbpnt = Lin->NbPoints();
1257 if (Nbpnt <= 1 && again == 0) {
1258 again++;
1259#ifdef DEB
81bba717 1260 cout <<"one point of path MS/50 is attempted."<<endl;
7fd59977 1261#endif
1262 MS = MS/50.; Target = Targetsov;
1263 }
1264 else if (Nbpnt <= NbSecMin && again == 0) {
1265 again++;
1266#ifdef DEB
81bba717 1267 cout <<"Number of points is too small, the step is reduced"<<endl;
7fd59977 1268#endif
1269 Standard_Real u1 = Lin->Point(1).Parameter();
1270 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1271 MS = (u2-u1)/(NbSecMin+1);
1272 Target = Targetsov;
1273 }
1274 else if(Nbpnt<=NbSecMin){
1275#ifdef DEB
81bba717 1276 cout <<"Number of points is still too small, quit"<<endl;
7fd59977 1277#endif
1278 return Standard_False;
1279 }
1280 else {
1281 again = 2;
1282 }
1283 }
1284#ifdef DRAW
1285 ChFi3d_SettraceDRAWWALK(Standard_True);
1286 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1287#endif
1288 if(Forward) Decroch = TheWalk.DecrochEnd();
1289 else Decroch = TheWalk.DecrochStart();
1290 Last = Lin->Point(Nbpnt).Parameter();
1291 First = Lin->Point(1).Parameter();
1292 return Standard_True;
1293}
1294
1295
1296//=======================================================================
1297//function : SimulData
81bba717 1298//purpose : Heading of path edge/edge for the bypass
1299// of obstacle in simulation mode.
7fd59977 1300//=======================================================================
1301
1302Standard_Boolean ChFi3d_Builder::SimulData
1303(Handle(ChFiDS_SurfData)& /*Data*/,
1304 const Handle(ChFiDS_HElSpine)& HGuide,
1305 Handle(BRepBlend_Line)& Lin,
1306 const Handle(Adaptor3d_HSurface)& S1,
1307 const Handle(Adaptor2d_HCurve2d)& PC1,
1308 const Handle(Adaptor3d_TopolTool)& I1,
1309 Standard_Boolean& Decroch1,
1310 const Handle(Adaptor3d_HSurface)& S2,
1311 const Handle(Adaptor2d_HCurve2d)& PC2,
1312 const Handle(Adaptor3d_TopolTool)& I2,
1313 Standard_Boolean& Decroch2,
1314 Blend_RstRstFunction& Func,
1315 Blend_SurfCurvFuncInv& FInv1,
1316 Blend_CurvPointFuncInv& FInvP1,
1317 Blend_SurfCurvFuncInv& FInv2,
1318 Blend_CurvPointFuncInv& FInvP2,
1319 const Standard_Real PFirst,
1320 const Standard_Real MaxStep,
1321 const Standard_Real Fleche,
1322 const Standard_Real TolGuide,
1323 Standard_Real& First,
1324 Standard_Real& Last,
1325 const math_Vector& Soldep,
1326 const Standard_Integer NbSecMin,
1327 const Standard_Boolean Inside,
1328 const Standard_Boolean Appro,
1329 const Standard_Boolean Forward,
1330 const Standard_Boolean RecP1,
1331 const Standard_Boolean RecRst1,
1332 const Standard_Boolean RecP2,
1333 const Standard_Boolean RecRst2)
1334{
1335 BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1336
1337 Standard_Boolean reverse = (!Forward || Inside);
1338 Standard_Real SpFirst = HGuide->FirstParameter();
1339 Standard_Real SpLast = HGuide->LastParameter();
1340 Standard_Real Target = SpLast;
1341 if(reverse) Target = SpFirst;
1342 Standard_Real Targetsov = Target;
1343
1344 Standard_Real MS = MaxStep;
1345 Standard_Integer again = 0;
7fd59977 1346 Standard_Integer Nbpnt = 0;
81bba717 1347 // The initial solution is reframed if necessary.
7fd59977 1348 math_Vector ParSol(1,2);
1349 Standard_Real NewFirst = PFirst;
1350 if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1351 if(!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1352 tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1353 NewFirst,ParSol)){
1354#ifdef DEB
1355
81bba717 1356 cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<endl;
7fd59977 1357#endif
1358 return Standard_False;
1359 }
1360 }
1361 else {
1362 ParSol = Soldep;
1363 }
1364
1365 while (again < 2){
1366 TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1367 MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1368 if (!TheWalk.IsDone()) {
1369#ifdef DEB
81bba717 1370 cout << "Path not created" << endl;
7fd59977 1371#endif
1372 return Standard_False;
1373 }
1374 if (reverse) {
1375 if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1376#ifdef DEB
81bba717 1377 cout << "Not completed" << endl;
7fd59977 1378#endif
1379 }
1380 }
1381 Lin = TheWalk.Line();
1382 Nbpnt = Lin->NbPoints();
1383 if (Nbpnt <= 1 && again == 0) {
1384 again++;
1385#ifdef DEB
81bba717 1386 cout <<"only one point of path MS/50 is attempted."<<endl;
7fd59977 1387#endif
1388 MS = MS/50.; Target = Targetsov;
1389 }
1390 else if (Nbpnt <= NbSecMin && again == 0) {
1391 again++;
1392#ifdef DEB
81bba717 1393 cout <<"Number of points is too small, the step is reduced"<<endl;
7fd59977 1394#endif
1395 Standard_Real u1 = Lin->Point(1).Parameter();
1396 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1397 MS = (u2-u1)/(NbSecMin+1);
1398 Target = Targetsov;
1399 }
1400 else if(Nbpnt<=NbSecMin){
1401#ifdef DEB
81bba717 1402 cout <<"Number of points is still too small, quit"<<endl;
7fd59977 1403#endif
1404 return Standard_False;
1405 }
1406 else {
1407 again = 2;
1408 }
1409 }
1410#ifdef DRAW
1411 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1412#endif
1413 if (Forward) {
1414 Decroch1 = TheWalk.Decroch1End();
1415 Decroch2 = TheWalk.Decroch2End();
1416 }
1417 else {
1418 Decroch1 = TheWalk.Decroch1Start();
1419 Decroch2 = TheWalk.Decroch2Start();
1420 }
1421
1422 Last = Lin->Point(Nbpnt).Parameter();
1423 First = Lin->Point(1).Parameter();
1424 return Standard_True;
1425}
1426
1427
1428
1429
1430//=======================================================================
1431//function : ComputeData
81bba717 1432//purpose : Construction of elementary fillet by path.
7fd59977 1433//
1434//=======================================================================
1435
1436Standard_Boolean ChFi3d_Builder::ComputeData
1437(Handle(ChFiDS_SurfData)& Data,
1438 const Handle(ChFiDS_HElSpine)& HGuide,
1439 const Handle(ChFiDS_Spine)& Spine,
1440 Handle(BRepBlend_Line)& Lin,
1441 const Handle(Adaptor3d_HSurface)& S1,
1442 const Handle(Adaptor3d_TopolTool)& I1,
1443 const Handle(Adaptor3d_HSurface)& S2,
1444 const Handle(Adaptor3d_TopolTool)& I2,
1445 Blend_Function& Func,
1446 Blend_FuncInv& FInv,
1447 const Standard_Real PFirst,
1448 const Standard_Real MaxStep,
1449 const Standard_Real Fleche,
1450 const Standard_Real tolguide,
1451 Standard_Real& First,
1452 Standard_Real& Last,
1453 const Standard_Boolean Inside,
1454 const Standard_Boolean Appro,
1455 const Standard_Boolean Forward,
1456 const math_Vector& Soldep,
1457 Standard_Boolean& intf,
1458 Standard_Boolean& intl,
1459 Standard_Boolean& Gd1,
1460 Standard_Boolean& Gd2,
1461 Standard_Boolean& Gf1,
1462 Standard_Boolean& Gf2,
1463 const Standard_Boolean RecOnS1,
1464 const Standard_Boolean RecOnS2)
1465{
81bba717 1466 //The extrensions are created in case of output of two domains
1467 //directly and not by path ( too hasardous ).
7fd59977 1468 Data->FirstExtensionValue(0);
1469 Data-> LastExtensionValue(0);
1470
81bba717 1471 //The eventual faces are restored to test the jump of edge.
7fd59977 1472 TopoDS_Face F1, F2;
1473 Handle(BRepAdaptor_HSurface) HS = Handle(BRepAdaptor_HSurface)::DownCast(S1);
1474 if(!HS.IsNull()) F1 = HS->ChangeSurface().Face();
1475 HS = Handle(BRepAdaptor_HSurface)::DownCast(S2);
1476 if(!HS.IsNull()) F2 = HS->ChangeSurface().Face();
1477
81bba717 1478 // Path framing variables
7fd59977 1479 Standard_Real TolGuide=tolguide, TolEsp = tolesp;
1480 Standard_Integer nbptmin = 4;
1481
1482 BRepBlend_Walking TheWalk(S1,S2,I1,I2);
1483
81bba717 1484 //Start of removal, 2D path controls
1485 //that qui s'accomodent mal des surfaces a parametrages non homogenes
1486 //en u et en v are extinguished.
7fd59977 1487 TheWalk.Check2d(0);
1488
1489 Standard_Real MS = MaxStep;
1490 Standard_Integer Nbpnt;
1491 Standard_Real SpFirst = HGuide->FirstParameter();
1492 Standard_Real SpLast = HGuide->LastParameter();
1493
81bba717 1494 // When the start point is inside, the path goes first to the left
1495 // to determine the Last for the periodicals.
7fd59977 1496 Standard_Boolean reverse = (!Forward || Inside);
1497 Standard_Real Target;
1498 if(reverse){
1499 Target = SpFirst;
1500 if(!intf) Target = Last;
1501 }
1502 else{
1503 Target = SpLast + Abs(SpLast);
1504 if(!intl) Target = Last;
1505 }
1506
81bba717 1507 // In case if the singularity is pre-determined,
1508 // the path is indicated.
7fd59977 1509 if (!Spine.IsNull()){
1510 if (Spine->IsTangencyExtremity(Standard_True)) {
1511 TopoDS_Vertex V = Spine->FirstVertex();
1512 TopoDS_Edge E = Spine->Edges(1);
1513 Standard_Real param = Spine->FirstParameter();
1514 Blend_Point BP;
1515 if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1516 math_Vector vec(1,4);
1517 BP.ParametersOnS1(vec(1),vec(2));
1518 BP.ParametersOnS2(vec(3),vec(4));
1519 Func.Set(param);
1520 if (Func.IsSolution(vec, tolesp)) {
1521 TheWalk.AddSingularPoint(BP);
1522 }
1523 }
1524 }
1525 if (Spine->IsTangencyExtremity(Standard_False)) {
1526 TopoDS_Vertex V = Spine->LastVertex();
1527 TopoDS_Edge E = Spine->Edges( Spine->NbEdges());
1528 Standard_Real param = Spine->LastParameter();
1529 Blend_Point BP;
1530 if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1531 math_Vector vec(1,4);
1532 BP.ParametersOnS1(vec(1),vec(2));
1533 BP.ParametersOnS2(vec(3),vec(4));
1534 Func.Set(param);
1535 if (Func.IsSolution(vec, tolesp)) {
1536 TheWalk.AddSingularPoint(BP);
1537 }
1538 }
1539 }
1540 }
1541
81bba717 1542 //The starting solution is reframed if necessary.
7fd59977 1543 //**********************************************//
1544 math_Vector ParSol(1,4);
1545 Standard_Real NewFirst = PFirst;
1546 if(RecOnS1 || RecOnS2){
1547 if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
1548 tolesp,TolGuide,RecOnS1,RecOnS2,
1549 NewFirst,ParSol)){
1550#ifdef DEB
81bba717 1551 cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<endl;
7fd59977 1552#endif
1553 return Standard_False;
1554 }
1555 }
1556 else {
1557 ParSol = Soldep;
1558 }
1559
81bba717 1560 //First the valid part is calculate, without caring for the extensions.
7fd59977 1561 //******************************************************************//
1562 Standard_Integer again = 0;
1563 Standard_Boolean tchernobyl = 0;
7fd59977 1564 Standard_Real u1sov = 0., u2sov = 0.;
7fd59977 1565 TopoDS_Face bif;
81bba717 1566 //Max step is relevant, but too great, the vector is required to detect
1567 //the twists.
7fd59977 1568 if( (Abs(Last-First) <= MS * 5.) &&
1569 (Abs(Last-First) >= 0.01*Abs(NewFirst-Target)) ){
1570 MS = Abs(Last-First)*0.2;
1571 }
1572
1573 while(again < 3){
81bba717 1574 //Path.
7fd59977 1575 if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
1576 else {
1577 if (5*TolGuide > MS) TolGuide = MS/5;
1578 if (5*TolEsp > MS) TolEsp = MS/5;
1579 }
1580 TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
1581 ParSol,TolEsp,Fleche,Appro);
1582 if (!TheWalk.IsDone()) {
1583#ifdef DEB
81bba717 1584 cout << "Path is not created" << endl;
7fd59977 1585#endif
1586 return Standard_False;
1587 }
1588 Lin = TheWalk.Line();
1589 if(HGuide->IsPeriodic() && Inside) {
1590 SpFirst = Lin->Point(1).Parameter();
1591 SpLast = SpFirst + HGuide->Period();
1592 HGuide->ChangeCurve().FirstParameter(SpFirst);
1593 HGuide->ChangeCurve().LastParameter (SpLast );
1594 HGuide->ChangeCurve().SetOrigin(SpFirst);
1595 }
1596 Standard_Boolean complmnt = Standard_True;
1597 if (Inside) complmnt = TheWalk.Complete(Func,FInv,SpLast);
1598 if(!complmnt){
1599#ifdef DEB
81bba717 1600 cout << "Not completed" << endl;
7fd59977 1601#endif
1602 return Standard_False;
1603 }
1604
81bba717 1605 //The result is controlled using two criterions :
1606 //- if there is enough points,
1607 //- if one has gone far enough.
7fd59977 1608 Nbpnt = Lin->NbPoints();
1609 if (Nbpnt == 0){
1610#ifdef DEB
81bba717 1611 cout <<"0 point of path, quit."<<endl;
7fd59977 1612#endif
1613 return Standard_False;
1614 }
1615 Standard_Real fpointpar = Lin->Point(1).Parameter();
1616 Standard_Real lpointpar = Lin->Point(Nbpnt).Parameter();
1617
1618 Standard_Real factor = 1./(nbptmin + 1);
1619 Standard_Boolean okdeb = (Forward && !Inside);
1620 Standard_Boolean okfin = (!Forward && !Inside);
1621 if(!okdeb){
1622 Standard_Integer narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1623 Standard_Integer narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1624 okdeb = (narc1 > 0 || narc2 > 0 || (fpointpar-First) < 10*TolGuide);
1625 }
1626 if(!okfin){
1627 Standard_Integer narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1628 Standard_Integer narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1629 okfin = (narc1 > 0 || narc2 > 0 || (Last-lpointpar) < 10*TolGuide);
1630 }
1631 if(!okdeb || !okfin || Nbpnt == 1){
81bba717 1632 //It drags, the controls are extended, it is expected to evaluate a
1633 //satisfactory maximum step. If it already done, quit.
7fd59977 1634 if(tchernobyl){
1635#ifdef DEB
81bba717 1636 cout <<"If it drags without control, quit."<<endl;
7fd59977 1637#endif
1638 return Standard_False;
1639 }
1640 tchernobyl = Standard_True;
1641 TheWalk.Check(0);
1642 if (Nbpnt == 1){
1643#ifdef DEB
81bba717 1644 cout <<"only one point of path MS/100 is attempted"<<endl;
1645 cout <<"and the controls are extended."<<endl;
7fd59977 1646#endif
1647 MS *= 0.01;
1648 }
1649 else{
1650#ifdef DEB
81bba717 1651 cout <<"It drags, the controls are extended."<<endl;
7fd59977 1652#endif
1653 MS = (lpointpar-fpointpar)/Nbpnt; //EvalStep(Lin);
1654 }
1655 }
1656 else if (Nbpnt < nbptmin){
1657 if(again == 0){
1658#ifdef DEB
81bba717 1659 cout <<"Number of points is too small, the step is reduced"<<endl;
7fd59977 1660#endif
1661 u1sov = fpointpar;
1662 u2sov = lpointpar;
1663 MS = (lpointpar - fpointpar) * factor;
1664 }
1665 else if(again == 1){
1666 if(Abs(fpointpar-u1sov)>=TolGuide ||
1667 Abs(lpointpar-u2sov)>=TolGuide){
1668#ifdef DEB
81bba717 1669 cout <<"Number of points is still too small, the step is reduced"<<endl;
7fd59977 1670#endif
1671 MS = (lpointpar - fpointpar) * factor;
1672 }
1673 else{
1674#ifdef DEB
81bba717 1675 cout <<"Number of points is still too small, quit"<<endl;
7fd59977 1676#endif
1677 return Standard_False;
1678 }
1679 }
1680 again++;
1681 }
1682 else {
1683 again = 3;
1684 }
1685 }
1686
1687 if(TheWalk.TwistOnS1()){
1688 Data->TwistOnS1(Standard_True);
1689#ifdef DEB
81bba717 1690 cout<<"Path completed, but TWIST on S1"<<endl;
7fd59977 1691#endif
1692 }
1693 if(TheWalk.TwistOnS2()){
1694 Data->TwistOnS2(Standard_True);
1695#ifdef DEB
81bba717 1696 cout<<"Parh completed, but TWIST on S2"<<endl;
7fd59977 1697#endif
1698 }
1699
1700
81bba717 1701 //Here there is a more or less presentable result
1702 //however it covers a the minimum zone.
1703 //The extensions are targeted.
7fd59977 1704 //*****************************//
1705
1706 Gd1 = Gd2 = Gf1 = Gf2 = Standard_False;
1707
1708 Standard_Boolean unseulsuffitdeb = (intf >= 2);
1709 Standard_Boolean unseulsuffitfin = (intl >= 2);
1710 Standard_Boolean noproldeb = (intf >= 3);
1711 Standard_Boolean noprolfin = (intl >= 3);
1712
1713 Standard_Real Rab = 0.03*(SpLast-SpFirst);
1714
1715 Standard_Boolean debarc1 = 0, debarc2 = 0;
1716 Standard_Boolean debcas1 = 0, debcas2 = 0;
1717 Standard_Boolean debobst1 = 0, debobst2 = 0;
1718
1719 Standard_Boolean finarc1 = 0, finarc2 = 0;
1720 Standard_Boolean fincas1 = 0, fincas2 = 0;
1721 Standard_Boolean finobst1 = 0, finobst2 = 0;
1722
1723 Standard_Integer narc1, narc2;
1724
1725 Standard_Boolean backwContinueFailed = Standard_False; // eap
1726 if(reverse && intf) {
1727 narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1728 narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1729 if(narc1 != 0) {
1730 ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1731 Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1732 debarc1 = Standard_True;
1733 if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
81bba717 1734 //It is checked if there is not an obstacle.
7fd59977 1735 debcas1 = Standard_True;
1736 if(!Spine.IsNull()){
1737 if(Spine->IsPeriodic()){
1738 debobst1 = 1;
1739 }
1740 else{
1741 debobst1 = IsObst(Data->VertexFirstOnS1(),
1742 Spine->FirstVertex(),myVEMap);
1743 }
1744 }
1745 }
1746 }
1747 if(narc2 != 0){
1748 ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1749 Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1750 debarc2 = Standard_True;
1751 if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
81bba717 1752 //It is checked if it is not an obstacle.
7fd59977 1753 debcas2 = Standard_True;
1754 if(!Spine.IsNull()){
1755 if(Spine->IsPeriodic()){
1756 debobst2 = 1;
1757 }
1758 else{
1759 debobst2 = IsObst(Data->VertexFirstOnS2(),
1760 Spine->FirstVertex(),myVEMap);
1761 }
1762 }
1763 }
1764 }
1765 Standard_Boolean oncontinue = !noproldeb && (narc1 != 0 || narc2 != 0);
1766 if(debobst1 || debobst2) oncontinue = Standard_False;
1767 else if(debcas1 && debcas2) oncontinue = Standard_False;
1768 else if((!debcas1 && debarc1) || (!debcas2 && debarc2)) oncontinue = Standard_False;
1769
1770 if(oncontinue) {
1771 TheWalk.ClassificationOnS1(!debarc1);
1772 TheWalk.ClassificationOnS2(!debarc2);
81bba717 1773 TheWalk.Check2d(Standard_True); // It should be strict (PMN)
7fd59977 1774 TheWalk.Continu(Func,FInv,Target);
1775 TheWalk.ClassificationOnS1(Standard_True);
1776 TheWalk.ClassificationOnS2(Standard_True);
1777 TheWalk.Check2d(Standard_False);
1778 narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1779 narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1780// modified by eap Fri Feb 8 11:43:48 2002 ___BEGIN___
1781 if(!debarc1)
1782 if (narc1 == 0)
1783 backwContinueFailed = Lin->StartPointOnFirst().ParameterOnGuide() > Target;
1784 else {
1785 ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1786 Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1787 debarc1 = Standard_True;
1788 if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
81bba717 1789 //It is checked if it is not an obstacle.
7fd59977 1790 debcas1 = Standard_True;
1791// if(!Spine.IsNull()) {
1792// if(Spine->IsPeriodic()){
1793// debobst1 = 1;
1794// }
1795// else{
1796// debobst1 = IsObst(Data->VertexFirstOnS1(),
1797// Spine->FirstVertex(),myVEMap);
1798// }
1799// }
1800 }
1801 }
1802 if(!debarc2)
1803 if (narc2 == 0)
1804 backwContinueFailed = Lin->StartPointOnSecond().ParameterOnGuide() > Target;
1805 else {
1806 ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1807 Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1808 debarc2 = Standard_True;
1809 if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
81bba717 1810 //It is checked if it is not an obstacle.
7fd59977 1811 debcas2 = Standard_True;
1812// if(!Spine.IsNull()){
1813// if(Spine->IsPeriodic()){
1814// debobst2 = 1;
1815// }
1816// else{
1817// debobst2 = IsObst(Data->VertexFirstOnS2(),
1818// Spine->FirstVertex(),myVEMap);
1819// }
1820// }
1821 }
1822 }
1823 if (backwContinueFailed) {
1824 // if we leave backwContinueFailed as is, we will stop in this direction
1825 // but we are to continue if there are no more faces on the side with arc
1826 // check this condition
1827 const ChFiDS_CommonPoint& aCP
1828 = debarc1 ? Data->VertexFirstOnS1() : Data->VertexFirstOnS2();
1829 if (aCP.IsOnArc() && bif.IsNull())
1830 backwContinueFailed = Standard_False;
1831 }
1832 }
1833 }
1834 Standard_Boolean forwContinueFailed = Standard_False;
1835// modified by eap Fri Feb 8 11:44:11 2002 ___END___
1836 if(Forward && intl) {
1837 Target = SpLast;
1838 narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1839 narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1840 if(narc1 != 0){
1841 ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1842 Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1843 finarc1 = Standard_True;
1844 if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
81bba717 1845 //It is checked if it is not an obstacle.
7fd59977 1846 fincas1 = Standard_True;
1847 if(!Spine.IsNull()){
1848 finobst1 = IsObst(Data->VertexLastOnS1(),
1849 Spine->LastVertex(),myVEMap);
1850 }
1851 }
1852 }
1853 if(narc2 != 0){
1854 ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1855 Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1856 finarc2 = Standard_True;
1857 if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
81bba717 1858 //It is checked if it is not an obstacle.
7fd59977 1859 fincas2 = Standard_True;
1860 if(!Spine.IsNull()){
1861 finobst2 = IsObst(Data->VertexLastOnS2(),
1862 Spine->LastVertex(),myVEMap);
1863 }
1864 }
1865 }
1866 Standard_Boolean oncontinue = !noprolfin && (narc1 != 0 || narc2 != 0);
1867 if(finobst1 || finobst2) oncontinue = Standard_False;
1868 else if(fincas1 && fincas2) oncontinue = Standard_False;
1869 else if((!fincas1 && finarc1) || (!fincas2 && finarc2)) oncontinue = Standard_False;
1870
1871 if(oncontinue){
1872 TheWalk.ClassificationOnS1(!finarc1);
1873 TheWalk.ClassificationOnS2(!finarc2);
81bba717 1874 TheWalk.Check2d(Standard_True); // It should be strict (PMN)
7fd59977 1875 TheWalk.Continu(Func,FInv,Target);
1876 TheWalk.ClassificationOnS1(Standard_True);
1877 TheWalk.ClassificationOnS2(Standard_True);
1878 TheWalk.Check2d(Standard_False);
1879 narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1880 narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1881// modified by eap Fri Feb 8 11:44:57 2002 ___BEGIN___
1882 if(!finarc1)
1883 if (narc1 == 0)
1884 forwContinueFailed = Lin->EndPointOnFirst().ParameterOnGuide() < Target;
1885 else {
1886 ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1887 Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1888 finarc1 = Standard_True;
1889 if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
81bba717 1890 //It is checked if it is not an obstacle.
7fd59977 1891 fincas1 = Standard_True;
1892// if(!Spine.IsNull()){
1893// finobst1 = IsObst(Data->VertexLastOnS1(),
1894// Spine->LastVertex(),myVEMap);
1895// }
1896 }
1897 }
1898 if(!finarc2)
1899 if (narc2 == 0)
1900 forwContinueFailed = Lin->EndPointOnSecond().ParameterOnGuide() < Target;
1901 else {
1902 ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1903 Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1904 finarc2 = Standard_True;
1905 if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1906 //On regarde si ce n'est pas un obstacle.
1907 fincas2 = Standard_True;
1908// if(!Spine.IsNull()){
1909// finobst2 = IsObst(Data->VertexLastOnS2(),
1910// Spine->LastVertex(),myVEMap);
1911// }
1912 }
1913 }
1914 if (forwContinueFailed) {
1915 // if we leave forwContinueFailed as is, we will stop in this direction
1916 // but we are to continue if there are no more faces on the side with arc
1917 // check this condition
1918 const ChFiDS_CommonPoint& aCP
1919 = finarc1 ? Data->VertexLastOnS1() : Data->VertexLastOnS2();
1920 if (aCP.IsOnArc() && bif.IsNull())
1921 forwContinueFailed = Standard_False;
1922 }
1923// modified by eap Fri Feb 8 11:45:10 2002 ___END___
1924 }
1925 }
1926 Nbpnt = Lin->NbPoints();
1927#ifdef DRAW
1928 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
1929#endif
1930 First = Lin->Point(1).Parameter();
1931 Last = Lin->Point(Nbpnt).Parameter();
1932
1933 // ============= INVALIDATION EVENTUELLE =============
1934 // ------ Preparation des prolongement par plan tangent -----
1935 if(reverse && intf){
1936 Gd1 = debcas1/* && !debobst1*/; // skv(occ67)
1937 Gd2 = debcas2/* && !debobst2*/; // skv(occ67)
1938 if ((debarc1^debarc2) && !unseulsuffitdeb && (First!=SpFirst)) {
81bba717 1939 // Case of incomplete path, of course this ends badly :
1940 // the result is truncated instead of exit.
7fd59977 1941 Standard_Real sortie;
1942 Standard_Integer ind;
1943 if (debarc1) sortie = Data->VertexFirstOnS1().Parameter();
1944 else sortie = Data->VertexFirstOnS2().Parameter();
1945 if (sortie - First > tolesp) {
1946 ind = SearchIndex(sortie, Lin);
1947 if (Lin->Point(ind).Parameter() == sortie) ind--;
1948 if (ind >= 1) {
1949 Lin->Remove(1, ind);
1950 UpdateLine(Lin, Standard_True);
1951 }
1952 Nbpnt = Lin->NbPoints();
1953 First = Lin->Point(1).Parameter();
1954 }
1955 }
1956 else if ((intf>=5) && !debarc1 && !debarc2 && (First!=SpFirst)) {
1957 Standard_Real sortie = (2*First+Last)/3;
1958 Standard_Integer ind;
1959 if (sortie - First > tolesp) {
1960 ind = SearchIndex(sortie, Lin);
1961 if (Lin->Point(ind).Parameter() == sortie) ind--;
1962 if (Nbpnt-ind < 3) ind = Nbpnt -3;
1963 if (ind >= 1) {
1964 Lin->Remove(1, ind);
1965 UpdateLine(Lin, Standard_True);
1966 }
1967 Nbpnt = Lin->NbPoints();
1968 First = Lin->Point(1).Parameter();
1969 }
1970 }
1971 if(Gd1 && Gd2){
1972 Target = Min((Lin->Point(1).Parameter() - Rab),First);
1973 Target = Max(Target,SpFirst);
1974 Data->FirstExtensionValue(Abs(Lin->Point(1).Parameter()-Target));
1975 }
1976 if (intf && !unseulsuffitdeb) intf = (Gd1 && Gd2)//;
1977 || backwContinueFailed; // eap
1978 else if (intf && unseulsuffitdeb && (intf<5)) {
1979 intf = (Gd1 || Gd2);
81bba717 1980 // It is checked if there is no new face.
7fd59977 1981 if (intf &&
1982 ((!debcas1 && debarc1) || (!debcas2 && debarc2)) ) intf = 0;
1983 }
1984 else if (intf < 5) intf = 0;
1985 }
1986
1987 if(Forward && intl){
1988 Gf1 = fincas1/* && !finobst1*/; // skv(occ67)
1989 Gf2 = fincas2/* && !finobst2*/; // skv(occ67)
1990 if ((finarc1 ^finarc2) && !unseulsuffitfin && (Last!=SpLast)) {
81bba717 1991 // Case of incomplete path, of course, this ends badly :
1992 // the result is truncated instead of exit.
7fd59977 1993 Standard_Real sortie;
1994 Standard_Integer ind;
1995 if (finarc1) sortie = Data->VertexLastOnS1().Parameter();
1996 else sortie = Data->VertexLastOnS2().Parameter();
1997 if (Last - sortie > tolesp) {
1998 ind = SearchIndex(sortie, Lin);
1999 if (Lin->Point(ind).Parameter() == sortie) ind++;
2000 if (ind<= Nbpnt) {
2001 Lin->Remove(ind, Nbpnt);
2002 UpdateLine(Lin, Standard_False);
2003 }
2004 Nbpnt = Lin->NbPoints();
2005 Last = Lin->Point(Nbpnt).Parameter();
2006 }
2007 }
2008 else if ((intl>=5) && !finarc1 && !finarc2 && (Last!=SpLast) ) {
81bba717 2009 // The same in case when the entire "Lin" is an extension
7fd59977 2010 Standard_Real sortie = (First+2*Last)/3;
2011 Standard_Integer ind;
2012 if (Last - sortie > tolesp) {
2013 ind = SearchIndex(sortie, Lin);
2014 if (Lin->Point(ind).Parameter() == sortie) ind++;
2015 if (ind < 3) ind = 3;
2016 if (ind <= Nbpnt) {
2017 Lin->Remove(ind, Nbpnt);
2018 UpdateLine(Lin, Standard_False);
2019 }
2020 Nbpnt = Lin->NbPoints();
2021 Last = Lin->Point(Nbpnt).Parameter();
2022 }
2023 }
2024 if(Gf1 && Gf2) {
2025 Target = Max((Lin->Point(Nbpnt).Parameter() + Rab),Last);
2026 Target = Min(Target,SpLast);
2027 Data->LastExtensionValue(Abs(Target-Lin->Point(Nbpnt).Parameter()));
2028 }
2029
2030 if (intl && !unseulsuffitfin) intl = (Gf1 && Gf2)//;
2031 || forwContinueFailed; // eap
2032 else if (intl && unseulsuffitfin && (intl<5)) {
81bba717 2033 intl = (Gf1 || Gf2);// It is checked if there is no new face.
7fd59977 2034 if (intl &&
2035 ((!fincas1 && finarc1) || (!fincas2 && finarc2)) ) intl = 0;
2036 }
2037 else if (intl <5) intl = 0;
2038 }
2039 return Standard_True;
2040}
2041
2042//=======================================================================
2043//function : SimulData
2044//purpose :
2045//=======================================================================
2046
2047Standard_Boolean ChFi3d_Builder::SimulData
2048(Handle(ChFiDS_SurfData)& /*Data*/,
2049 const Handle(ChFiDS_HElSpine)& HGuide,
2050 Handle(BRepBlend_Line)& Lin,
2051 const Handle(Adaptor3d_HSurface)& S1,
2052 const Handle(Adaptor3d_TopolTool)& I1,
2053 const Handle(Adaptor3d_HSurface)& S2,
2054 const Handle(Adaptor3d_TopolTool)& I2,
2055 Blend_Function& Func,
2056 Blend_FuncInv& FInv,
2057 const Standard_Real PFirst,
2058 const Standard_Real MaxStep,
2059 const Standard_Real Fleche,
2060 const Standard_Real tolguide,
2061 Standard_Real& First,
2062 Standard_Real& Last,
2063 const Standard_Boolean Inside,
2064 const Standard_Boolean Appro,
2065 const Standard_Boolean Forward,
2066 const math_Vector& Soldep,
2067 const Standard_Integer NbSecMin,
2068 const Standard_Boolean RecOnS1,
2069 const Standard_Boolean RecOnS2)
2070{
2071 BRepBlend_Walking TheWalk(S1,S2,I1,I2);
2072 TheWalk.Check2d(Standard_False);
2073
2074 Standard_Real MS = MaxStep;
2075 Standard_Real TolGuide=tolguide, TolEsp = tolesp;
2076 Standard_Integer Nbpnt;
2077 Standard_Real SpFirst = HGuide->FirstParameter();
2078 Standard_Real SpLast = HGuide->LastParameter();
2079 Standard_Boolean reverse = (!Forward || Inside);
2080 Standard_Real Target;
2081 if(reverse){
2082 Target = SpFirst;
2083 }
2084 else{
2085 Target = SpLast;
2086 }
2087
2088 Standard_Real Targetsov = Target;
7fd59977 2089 Standard_Real u1sov = 0., u2sov = 0.;
7fd59977 2090 // on recadre la solution de depart a la demande.
2091 math_Vector ParSol(1,4);
2092 Standard_Real NewFirst = PFirst;
2093 if(RecOnS1 || RecOnS2){
2094 if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
2095 tolesp,TolGuide,RecOnS1,RecOnS2,
2096 NewFirst,ParSol)){
2097#ifdef DEB
81bba717 2098 cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<endl;
7fd59977 2099#endif
2100 return Standard_False;
2101 }
2102 }
2103 else {
2104 ParSol = Soldep;
2105 }
2106 Standard_Integer again = 0;
2107 while(again < 3){
81bba717 2108 // When the start point is inside, the path goes first to the left
2109 // to determine the Last for the periodicals.
7fd59977 2110 if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
2111 else {
2112 if (5*TolGuide > MS) TolGuide = MS/5;
2113 if (5*TolEsp > MS) TolEsp = MS/5;
2114 }
2115
2116 TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
2117 ParSol,TolEsp,Fleche,Appro);
2118
2119 if (!TheWalk.IsDone()) {
2120#ifdef DEB
81bba717 2121 cout << "Path not created" << endl;
7fd59977 2122#endif
2123 return Standard_False;
2124 }
2125 Lin = TheWalk.Line();
2126 if(reverse){
2127 if(HGuide->IsPeriodic()) {
2128 SpFirst = Lin->Point(1).Parameter();
2129 SpLast = SpFirst + HGuide->Period();
2130 HGuide->ChangeCurve().FirstParameter(SpFirst);
2131 HGuide->ChangeCurve().LastParameter (SpLast );
2132 }
2133 Standard_Boolean complmnt = Standard_True;
2134 if (Inside) complmnt = TheWalk.Complete(Func,FInv,SpLast);
2135 if(!complmnt){
2136#ifdef DEB
81bba717 2137 cout << "Not completed" << endl;
7fd59977 2138#endif
2139 return Standard_False;
2140 }
2141 }
2142 Nbpnt = Lin->NbPoints();
2143 Standard_Real factor = 1./(NbSecMin + 1);
2144 if (Nbpnt == 0){
2145#ifdef DEB
81bba717 2146 cout <<"0 point of path, quit."<<endl;
7fd59977 2147#endif
2148 return Standard_False;
2149 }
2150 else if (Nbpnt == 1 && again == 0) {
2151 again++;
2152#ifdef DEB
81bba717 2153 cout <<"only one point of path, MS/100 is attempted."<<endl;
7fd59977 2154#endif
2155 MS *= 0.01; Target = Targetsov;
2156 u1sov = u2sov = Lin->Point(1).Parameter();
2157 }
2158 else if (Nbpnt< NbSecMin && again == 0) {
2159 again++;
2160#ifdef DEB
81bba717 2161 cout <<"Number of points is too small, the step is reduced"<<endl;
7fd59977 2162#endif
2163 Standard_Real u1 = u1sov = Lin->Point(1).Parameter();
2164 Standard_Real u2 = u2sov = Lin->Point(Nbpnt).Parameter();
2165 MS = (u2-u1)*factor;
2166 Target = Targetsov;
2167 }
2168 else if (Nbpnt < NbSecMin && again == 1) {
2169 Standard_Real u1 = Lin->Point(1).Parameter();
2170 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
2171 if(Abs(u1-u1sov)>=TolGuide || Abs(u2-u2sov)>=TolGuide){
2172 again++;
2173#ifdef DEB
81bba717 2174 cout <<"Number of points is still too small, the step is reduced"<<endl;
7fd59977 2175#endif
2176 MS /= 100;
2177 Target = Targetsov;
2178 }
2179 else{
2180#ifdef DEB
81bba717 2181 cout <<"Number of points is still too small, quit"<<endl;
7fd59977 2182#endif
2183 return Standard_False;
2184 }
2185 }
2186 else if(Nbpnt < NbSecMin){
2187#ifdef DEB
81bba717 2188 cout <<"Number of points is still too small, quit"<<endl;
7fd59977 2189#endif
2190 return Standard_False;
2191 }
2192 else {
2193 again = 3;
2194 }
2195 }
2196#ifdef DRAW
2197 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
2198#endif
2199 First = Lin->Point(1).Parameter();
2200 Last = Lin->Point(Nbpnt).Parameter();
2201 return Standard_True;
2202}
2203