1 // Created on: 1994-10-25
2 // Created by: Laurent BOURESCHE
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // modif : jlr branchement F(t) pour Edge/Face
18 // Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898
19 // modified by Edward AGAPOV (eap) Fri Feb 8 2002 (bug occ67 == BUC61052)
20 // ComputeData(), case where BRepBlend_Walking::Continu() can't get up to Target
22 #include <Adaptor2d_HCurve2d.hxx>
23 #include <Adaptor3d_HSurface.hxx>
24 #include <Adaptor3d_TopolTool.hxx>
25 #include <AppBlend_Approx.hxx>
26 #include <Approx_SweepFunction.hxx>
27 #include <Blend_CurvPointFuncInv.hxx>
28 #include <Blend_FuncInv.hxx>
29 #include <Blend_Function.hxx>
30 #include <Blend_Point.hxx>
31 #include <Blend_RstRstFunction.hxx>
32 #include <Blend_SurfCurvFuncInv.hxx>
33 #include <Blend_SurfPointFuncInv.hxx>
34 #include <Blend_SurfRstFunction.hxx>
35 #include <BRep_Tool.hxx>
36 #include <BRepAdaptor_Curve.hxx>
37 #include <BRepAdaptor_Curve2d.hxx>
38 #include <BRepAdaptor_HCurve2d.hxx>
39 #include <BRepAdaptor_HSurface.hxx>
40 #include <BRepAdaptor_Surface.hxx>
41 #include <BRepBlend_AppFunc.hxx>
42 #include <BRepBlend_AppFuncRst.hxx>
43 #include <BRepBlend_AppFuncRstRst.hxx>
44 #include <BRepBlend_AppSurf.hxx>
45 #include <BRepBlend_AppSurface.hxx>
46 #include <BRepBlend_ConstRad.hxx>
47 #include <BRepBlend_ConstRadInv.hxx>
48 #include <BRepBlend_CSWalking.hxx>
49 #include <BRepBlend_Extremity.hxx>
50 #include <BRepBlend_Line.hxx>
51 #include <BRepBlend_PointOnRst.hxx>
52 #include <BRepBlend_RstRstLineBuilder.hxx>
53 #include <BRepBlend_SurfRstLineBuilder.hxx>
54 #include <BRepBlend_Walking.hxx>
55 #include <BRepTopAdaptor_HVertex.hxx>
56 #include <BRepTopAdaptor_TopolTool.hxx>
57 #include <BSplCLib.hxx>
58 #include <ChFi3d_Builder.hxx>
59 #include <ChFi3d_Builder_0.hxx>
60 #include <ChFiDS_CommonPoint.hxx>
61 #include <ChFiDS_FaceInterference.hxx>
62 #include <ChFiDS_HElSpine.hxx>
63 #include <ChFiDS_Spine.hxx>
64 #include <ChFiDS_Stripe.hxx>
65 #include <ChFiDS_SurfData.hxx>
66 #include <Geom2d_BSplineCurve.hxx>
67 #include <Geom2d_Curve.hxx>
68 #include <Geom2d_Line.hxx>
69 #include <Geom2d_TrimmedCurve.hxx>
70 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
71 #include <Geom2dInt_GInter.hxx>
72 #include <Geom_BSplineSurface.hxx>
73 #include <Geom_Curve.hxx>
74 #include <Geom_Surface.hxx>
75 #include <GeomAdaptor_HCurve.hxx>
76 #include <GeomAdaptor_HSurface.hxx>
77 #include <GeomLib.hxx>
78 #include <gp_Dir2d.hxx>
80 #include <gp_Pnt2d.hxx>
82 #include <gp_Vec2d.hxx>
83 #include <IntRes2d_IntersectionPoint.hxx>
84 #include <math_Vector.hxx>
85 #include <Precision.hxx>
86 #include <Standard_ConstructionError.hxx>
87 #include <Standard_NoSuchObject.hxx>
88 #include <Standard_OutOfRange.hxx>
90 #include <TopoDS_Edge.hxx>
91 #include <TopoDS_Face.hxx>
92 #include <TopoDS_Shape.hxx>
93 #include <TopoDS_Vertex.hxx>
94 #include <TopOpeBRepBuild_HBuilder.hxx>
95 #include <TopOpeBRepDS_Curve.hxx>
96 #include <TopOpeBRepDS_DataStructure.hxx>
97 #include <TopOpeBRepDS_HDataStructure.hxx>
98 #include <TopOpeBRepDS_Surface.hxx>
99 #include <TopTools_ListIteratorOfListOfShape.hxx>
100 #include <TopTools_ListOfShape.hxx>
105 #include <OSD_Chronometer.hxx>
106 //static OSD_Chronometer appclock;
112 #include <Draw_Appli.hxx>
113 #include <Draw_Segment2D.hxx>
114 #include <Draw_Marker2D.hxx>
115 #include <Draw_Segment3D.hxx>
116 #include <Draw_Marker3D.hxx>
118 #include <DrawTrSurf.hxx>
119 #include <BRepAdaptor_HSurface.hxx>
120 static Standard_Integer IndexOfConge = 0;
124 extern Standard_Boolean ChFi3d_GettraceDRAWFIL();
125 extern Standard_Boolean ChFi3d_GettraceDRAWWALK();
126 extern Standard_Boolean ChFi3d_GetcontextNOOPT();
127 extern void ChFi3d_SettraceDRAWFIL(const Standard_Boolean b);
128 extern void ChFi3d_SettraceDRAWWALK(const Standard_Boolean b);
129 extern void ChFi3d_SetcontextNOOPT(const Standard_Boolean b);
133 static void drawline(const Handle(BRepBlend_Line)& lin,
134 const Standard_Boolean iscs)
136 Handle(Draw_Marker3D) p3d;
137 Handle(Draw_Marker2D) p2d;
138 Handle(Draw_Segment3D) tg3d;
139 Handle(Draw_Segment2D) tg2d;
141 for(Standard_Integer i = 1; i <= lin->NbPoints(); i++){
142 const Blend_Point& pt = lin->Point(i);
143 gp_Pnt point = pt.PointOnS1();
144 gp_Pnt extr = point.Translated(pt.TangentOnS1());
145 p3d = new Draw_Marker3D(point,Draw_Square,Draw_rouge);
147 tg3d = new Draw_Segment3D(point,extr,Draw_rouge);
149 point = pt.PointOnS2();
150 extr = point.Translated(pt.TangentOnS2());
151 p3d = new Draw_Marker3D(point,Draw_Plus,Draw_jaune);
153 tg3d = new Draw_Segment3D(point,extr,Draw_jaune);
157 pt.ParametersOnS1(u,v);
158 gp_Pnt2d point2d(u,v);
159 gp_Pnt2d extr2d = point2d.Translated(pt.Tangent2dOnS1());
160 p2d = new Draw_Marker2D(point2d,Draw_Square,Draw_rouge);
162 tg2d = new Draw_Segment2D(point2d,extr2d,Draw_rouge);
164 pt.ParametersOnS2(u,v);
165 point2d.SetCoord(u,v);
166 extr2d = point2d.Translated(pt.Tangent2dOnS2());
167 p2d = new Draw_Marker2D(point2d,Draw_Plus,Draw_jaune);
169 tg2d = new Draw_Segment2D(point2d,extr2d,Draw_jaune);
175 //=======================================================================
176 //function : SearchIndex
179 //=======================================================================
180 static Standard_Integer SearchIndex(const Standard_Real Value,
181 Handle(BRepBlend_Line)& Lin)
183 Standard_Integer NbPnt = Lin->NbPoints(), Ind;
186 (Ind < NbPnt) && (Lin->Point(Ind).Parameter() < Value); )
192 //=======================================================================
196 //=======================================================================
197 static Standard_Integer nbedconnex(const TopTools_ListOfShape& L)
199 Standard_Integer nb = 0, i = 0;
200 TopTools_ListIteratorOfListOfShape It1(L);
201 for(;It1.More();It1.Next(),i++){
202 const TopoDS_Shape& curs = It1.Value();
203 Standard_Boolean dejavu = 0;
204 TopTools_ListIteratorOfListOfShape It2(L);
205 for(Standard_Integer j = 0; j < i && It2.More(); j++, It2.Next()){
206 if(curs.IsSame(It2.Value())){
216 static Standard_Boolean IsVois(const TopoDS_Edge& E,
217 const TopoDS_Vertex& Vref,
218 const ChFiDS_Map& VEMap,
219 TopTools_MapOfShape& DONE,
220 const Standard_Integer prof,
221 const Standard_Integer profmax)
223 if(prof > profmax) return Standard_False;
224 if(DONE.Contains(E)) return Standard_False;
226 TopExp::Vertices(E,V1,V2);
227 if(Vref.IsSame(V1) || Vref.IsSame(V2)) return Standard_True;
229 const TopTools_ListOfShape& L1 = VEMap(V1);
230 Standard_Integer i1 = nbedconnex(L1);
231 TopTools_ListIteratorOfListOfShape It1(L1);
232 for(;It1.More();It1.Next()){
233 const TopoDS_Edge& curE = TopoDS::Edge(It1.Value());
235 if(IsVois(curE,Vref,VEMap,DONE,prof,profmax)) return Standard_True;
237 else if(IsVois(curE,Vref,VEMap,DONE,prof+1,profmax)) return Standard_True;
239 const TopTools_ListOfShape& L2 = VEMap(V2);
241 // Standard_Integer i2 = nbedconnex(L2);
243 TopTools_ListIteratorOfListOfShape It2(L2);
244 for(;It2.More();It2.Next()){
245 const TopoDS_Edge& curE = TopoDS::Edge(It2.Value());
247 if(IsVois(curE,Vref,VEMap,DONE,prof,profmax)) return Standard_True;
249 else if(IsVois(curE,Vref,VEMap,DONE,prof+1,profmax)) return Standard_True;
251 return Standard_False;
254 static Standard_Boolean IsObst(const ChFiDS_CommonPoint& CP,
255 const TopoDS_Vertex& Vref,
256 const ChFiDS_Map& VEMap)
258 if(!CP.IsOnArc()) return Standard_False;
259 const TopoDS_Edge& E = CP.Arc();
260 TopTools_MapOfShape DONE;
261 Standard_Integer prof = 4;
262 return !IsVois(E,Vref,VEMap,DONE,0,prof);
265 //=======================================================================
266 //function : CompParam
269 //=======================================================================
271 static void CompParam(Geom2dAdaptor_Curve Carc,
272 Handle(Geom2d_Curve) Ctg,
275 const Standard_Real prefarc,
276 const Standard_Real preftg)
278 Standard_Boolean found = 0;
279 //(1) It is checked if the provided parameters are good
280 // if pcurves have the same parameters as the spine.
281 gp_Pnt2d point = Carc.Value(prefarc);
282 Standard_Real distini = point.Distance(Ctg->Value(preftg));
283 if (distini <= Precision::PConfusion()) {
286 found = Standard_True;
291 cout<< "CompParam : bad intersection parameters"<<endl;
293 IntRes2d_IntersectionPoint int2d;
294 Geom2dInt_GInter Intersection;
295 Standard_Integer nbpt,nbseg;
296 Intersection.Perform(Geom2dAdaptor_Curve(Ctg),Carc,
297 Precision::PIntersection(),
298 Precision::PIntersection());
300 Standard_Real dist = Precision::Infinite(), p1, p2;
301 if (Intersection.IsDone()){
302 if (!Intersection.IsEmpty()){
303 nbseg = Intersection.NbSegments();
306 cout<< "segments of intersection on the restrictions"<<endl;
309 nbpt = Intersection.NbPoints();
310 for (Standard_Integer i = 1; i <= nbpt; i++) {
311 int2d = Intersection.Point(i);
312 p1 = int2d.ParamOnFirst();
313 p2 = int2d.ParamOnSecond();
314 if(Abs(prefarc - p2) < dist){
317 dist = Abs(prefarc - p2);
328 cout<<"CompParam : failed intersection PC, projection is created."<<endl;
331 Geom2dAPI_ProjectPointOnCurve projector(point,Ctg);
333 if(projector.NbPoints() == 0){
334 // This happens in some cases when there is a vertex
335 // at the end of spine...
338 cout<<"CompParam : failed proj p2d/c2d, the extremity is taken!" <<endl;
342 // It is checked if everything was calculated correctly (EDC402 C2)
343 if (projector.LowerDistance() < distini)
344 ptg = projector.LowerDistanceParameter();
350 //=======================================================================
351 //function : CompBlendPoint
352 //purpose : create BlendPoint corresponding to a tangency on Vertex
353 // pmn : 15/10/1997 : returns false, if there is no pcurve
354 //=======================================================================
356 static Standard_Boolean CompBlendPoint(const TopoDS_Vertex& V,
357 const TopoDS_Edge& E,
358 const Standard_Real W,
359 const TopoDS_Face F1,
360 const TopoDS_Face F2,
365 Standard_Real param, f, l;
366 Handle(Geom2d_Curve) pc;
368 P3d = BRep_Tool::Pnt(V);
369 param = BRep_Tool::Parameter(V,E,F1);
370 pc = BRep_Tool::CurveOnSurface(E,F1,f,l);
371 if (pc.IsNull()) return Standard_False;
372 P1 = pc->Value(param);
373 param = BRep_Tool::Parameter(V,E,F2);
374 pc = BRep_Tool::CurveOnSurface(E,F2,f,l);
375 if (pc.IsNull()) return Standard_False;
376 P2 = pc->Value(param);
377 BP.SetValue(P3d, P3d, W, P1.X(), P1.Y(), P2.X(), P2.Y());
378 return Standard_True;
381 //=======================================================================
382 //function : UpdateLine
383 //purpose : Updates extremities after a partial invalidation
384 //=======================================================================
386 static void UpdateLine(Handle(BRepBlend_Line)& Line,
387 const Standard_Boolean isfirst)
389 Standard_Real tguide, U, V;
391 const Blend_Point& BP = Line->Point(1);
392 tguide = BP.Parameter();
393 if (Line->StartPointOnFirst().ParameterOnGuide() < tguide) {
394 BRepBlend_Extremity BE;
395 BP.ParametersOnS1(U, V);
396 BE.SetValue(BP.PointOnS1(), U, V, Precision::Confusion());
397 Line->SetStartPoints(BE, Line->StartPointOnSecond());
399 if (Line->StartPointOnSecond().ParameterOnGuide() < tguide) {
400 BRepBlend_Extremity BE;
401 BP.ParametersOnS2(U, V);
402 BE.SetValue(BP.PointOnS2(), U, V, Precision::Confusion());
403 Line->SetStartPoints(Line->StartPointOnFirst(), BE);
407 const Blend_Point& BP = Line->Point(Line->NbPoints());
408 tguide = BP.Parameter();
409 if (Line->EndPointOnFirst().ParameterOnGuide() > tguide) {
410 BRepBlend_Extremity BE;
411 BP.ParametersOnS1(U, V);
412 BE.SetValue(BP.PointOnS1(), U, V, Precision::Confusion());
413 Line->SetEndPoints(BE, Line->EndPointOnSecond());
415 if (Line->EndPointOnSecond().ParameterOnGuide() > tguide) {
416 BRepBlend_Extremity BE;
417 BP.ParametersOnS2(U, V);
418 BE.SetValue(BP.PointOnS2(), U, V, Precision::Confusion());
419 Line->SetEndPoints(Line->EndPointOnFirst(), BE);
424 //=======================================================================
425 //function : CompleteData
426 //purpose : Calculates curves and CommonPoints from the data
427 // calculated by filling.
428 //=======================================================================
430 Standard_Boolean ChFi3d_Builder::CompleteData
431 (Handle(ChFiDS_SurfData)& Data,
432 const Handle(Geom_Surface)& Surfcoin,
433 const Handle(Adaptor3d_HSurface)& S1,
434 const Handle(Geom2d_Curve)& PC1,
435 const Handle(Adaptor3d_HSurface)& S2,
436 const Handle(Geom2d_Curve)& PC2,
437 const TopAbs_Orientation Or,
438 const Standard_Boolean On1,
439 const Standard_Boolean Gd1,
440 const Standard_Boolean Gd2,
441 const Standard_Boolean Gf1,
442 const Standard_Boolean Gf2)
444 TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
445 Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surfcoin,tolesp)));
447 ChFi3d_SettraceDRAWFIL(Standard_True);
448 if (ChFi3d_GettraceDRAWFIL()) {
451 char* name = new char[100];
452 sprintf(name,"%s_%d","Surf",IndexOfConge);
453 DrawTrSurf::Set(name,Surfcoin);
457 Standard_Real UFirst,ULast,VFirst,VLast;
458 Surfcoin->Bounds(UFirst,ULast,VFirst,VLast);
459 if(!Gd1) Data->ChangeVertexFirstOnS1().SetPoint(Surfcoin->Value(UFirst,VFirst));
460 if(!Gd2) Data->ChangeVertexFirstOnS2().SetPoint(Surfcoin->Value(UFirst,VLast));
461 if(!Gf1) Data->ChangeVertexLastOnS1().SetPoint(Surfcoin->Value(ULast,VFirst));
462 if(!Gf2) Data->ChangeVertexLastOnS2().SetPoint(Surfcoin->Value(ULast,VLast));
464 //calculate curves side S1
465 Handle(Geom_Curve) Crv3d1;
466 if(!PC1.IsNull()) Crv3d1= Surfcoin->VIso(VFirst);
467 gp_Pnt2d pd1(UFirst,VFirst), pf1(ULast,VFirst);
468 gp_Lin2d lfil1(pd1,gp_Dir2d(gp_Vec2d(pd1,pf1)));
469 Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1);
470 TopAbs_Orientation tra1 = TopAbs_FORWARD, orsurf = Or;
471 Standard_Real x,y,w = 0.5*(UFirst+ULast);
474 Handle(Geom2d_Curve) c2dtrim;
475 Standard_Real tolreached = 1.e-5;
477 Handle(GeomAdaptor_HCurve) hcS1 = new GeomAdaptor_HCurve(Crv3d1);
478 c2dtrim = new Geom2d_TrimmedCurve(PC1,UFirst,ULast);
479 ChFi3d_SameParameter(hcS1,c2dtrim,S1,tolapp3d,tolreached);
480 c2dtrim->Value(w).Coord(x,y);
482 gp_Vec nf = du.Crossed(dv);
483 Surfcoin->D1(w,VFirst,p,du,dv);
484 gp_Vec ns = du.Crossed(dv);
485 if(nf.Dot(ns) > 0.) tra1 = TopAbs_REVERSED;
486 else if(On1) orsurf = TopAbs::Reverse(orsurf);
488 Standard_Integer Index1OfCurve =
489 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolreached));
490 ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1();
491 Fint1.SetFirstParameter(UFirst);
492 Fint1.SetLastParameter(ULast);
493 Fint1.SetInterference(Index1OfCurve,tra1,c2dtrim,PCurveOnSurf);
494 //calculate curves side S2
495 Handle(Geom_Curve) Crv3d2;
496 if(!PC2.IsNull()) Crv3d2 = Surfcoin->VIso(VLast);
497 gp_Pnt2d pd2(UFirst,VLast), pf2(ULast,VLast);
498 gp_Lin2d lfil2(pd2,gp_Dir2d(gp_Vec2d(pd2,pf2)));
499 PCurveOnSurf = new Geom2d_Line(lfil2);
500 TopAbs_Orientation tra2 = TopAbs_FORWARD;
502 Handle(GeomAdaptor_HCurve) hcS2 = new GeomAdaptor_HCurve(Crv3d2);
503 c2dtrim = new Geom2d_TrimmedCurve(PC2,UFirst,ULast);
504 ChFi3d_SameParameter(hcS2,c2dtrim,S2,tolapp3d,tolreached);
505 c2dtrim->Value(w).Coord(x,y);
507 gp_Vec np = du.Crossed(dv);
508 Surfcoin->D1(w,VLast,p,du,dv);
509 gp_Vec ns = du.Crossed(dv);
510 if(np.Dot(ns) < 0.) {
511 tra2 = TopAbs_REVERSED;
512 if(!On1) orsurf = TopAbs::Reverse(orsurf);
515 Standard_Integer Index2OfCurve =
516 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolreached));
517 ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2();
518 Fint2.SetFirstParameter(UFirst);
519 Fint2.SetLastParameter(ULast);
520 Fint2.SetInterference(Index2OfCurve,tra2,c2dtrim,PCurveOnSurf);
521 Data->ChangeOrientation() = orsurf;
522 return Standard_True;
525 //=======================================================================
526 //function : CompleteData
527 //purpose : Calculates the surface of curves and eventually
528 // CommonPoints from the data calculated in ComputeData.
530 // 11/08/1996 : Use of F(t)
532 //=======================================================================
534 Standard_Boolean ChFi3d_Builder::CompleteData
535 (Handle(ChFiDS_SurfData)& Data,
536 Blend_Function& Func,
537 Handle(BRepBlend_Line)& lin,
538 const Handle(Adaptor3d_HSurface)& S1,
539 const Handle(Adaptor3d_HSurface)& S2,
540 const TopAbs_Orientation Or1,
541 const Standard_Boolean Gd1,
542 const Standard_Boolean Gd2,
543 const Standard_Boolean Gf1,
544 const Standard_Boolean Gf2,
545 const Standard_Boolean Reversed)
547 Handle(BRepBlend_AppFunc) TheFunc
548 = new (BRepBlend_AppFunc)(lin, Func, tolapp3d, 1.e-5);
550 Standard_Integer Degmax = 20, Segmax = 5000;
551 BRepBlend_AppSurface approx (TheFunc,
552 lin->Point(1).Parameter(),
553 lin->Point(lin->NbPoints()).Parameter(),
554 tolapp3d, 1.e-5, //tolapp2d, tolerance max
555 tolappangle, // Contact G1
556 myConti, Degmax, Segmax);
557 if (!approx.IsDone()) {
559 cout << "Approximation non faite !!!" << endl;
561 return Standard_False;
566 return StoreData( Data, approx, lin, S1, S2, Or1, Gd1, Gd2, Gf1, Gf2, Reversed);
570 //=======================================================================
571 //function : CompleteData
572 //purpose : New overload for functions surf/rst
573 // jlr le 28/07/97 branchement F(t)
574 //=======================================================================
576 Standard_Boolean ChFi3d_Builder::CompleteData
577 (Handle(ChFiDS_SurfData)& Data,
578 Blend_SurfRstFunction& Func,
579 Handle(BRepBlend_Line)& lin,
580 const Handle(Adaptor3d_HSurface)& S1,
581 const Handle(Adaptor3d_HSurface)& S2,
582 const TopAbs_Orientation Or,
583 const Standard_Boolean Reversed)
585 Handle(BRepBlend_AppFuncRst) TheFunc
586 = new (BRepBlend_AppFuncRst)(lin, Func, tolapp3d, 1.e-5);
587 BRepBlend_AppSurface approx (TheFunc,
588 lin->Point(1).Parameter(),
589 lin->Point(lin->NbPoints()).Parameter(),
590 tolapp3d, 1.e-5, //tolapp2d, tolerance max
591 tolappangle, // Contact G1
593 if (!approx.IsDone()) {
595 cout << "Approximation is not done!" << endl;
597 return Standard_False;
603 return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0,Reversed);
608 //=======================================================================
609 //function : CompleteData
610 //purpose : New overload for functions rst/rst
611 // jlr le 28/07/97 branchement F(t)
612 //=======================================================================
614 Standard_Boolean ChFi3d_Builder::CompleteData
615 (Handle(ChFiDS_SurfData)& Data,
616 Blend_RstRstFunction& Func,
617 Handle(BRepBlend_Line)& lin,
618 const Handle(Adaptor3d_HSurface)& S1,
619 const Handle(Adaptor3d_HSurface)& S2,
620 const TopAbs_Orientation Or)
622 Handle(BRepBlend_AppFuncRstRst) TheFunc
623 = new (BRepBlend_AppFuncRstRst)(lin, Func, tolapp3d, 1.e-5);
624 BRepBlend_AppSurface approx (TheFunc,
625 lin->Point(1).Parameter(),
626 lin->Point(lin->NbPoints()).Parameter(),
627 tolapp3d, 1.e-5, //tolapp2d, tolerance max
628 tolappangle, // Contact G1
630 if (!approx.IsDone()) {
632 cout << "Approximation non faite !!!" << endl;
634 return Standard_False;
640 return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0);
646 //=======================================================================
647 //function : StoreData
648 //purpose : Copy of an approximation result in SurfData.
649 //=======================================================================
651 Standard_Boolean ChFi3d_Builder::StoreData(Handle(ChFiDS_SurfData)& Data,
652 const AppBlend_Approx& approx,
653 const Handle(BRepBlend_Line)& lin,
654 const Handle(Adaptor3d_HSurface)& S1,
655 const Handle(Adaptor3d_HSurface)& S2,
656 const TopAbs_Orientation Or1,
657 const Standard_Boolean Gd1,
658 const Standard_Boolean Gd2,
659 const Standard_Boolean Gf1,
660 const Standard_Boolean Gf2,
661 const Standard_Boolean Reversed)
663 // Small control tools.
664 static Handle(GeomAdaptor_HCurve) checkcurve;
665 if(checkcurve.IsNull()) checkcurve = new GeomAdaptor_HCurve();
666 GeomAdaptor_Curve& chc = checkcurve->ChangeCurve();
667 Standard_Real tolget3d, tolget2d, tolaux, tolC1, tolcheck;
668 Standard_Real tolC2 = 0.;
669 approx.TolReached(tolget3d, tolget2d);
670 tolaux = approx.TolCurveOnSurf(1);
671 tolC1 = tolget3d + tolaux;
673 tolaux = approx.TolCurveOnSurf(2);
674 tolC2 = tolget3d + tolaux;
677 TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
678 // By default parametric space is created using a square surface
679 // to be able to parameterize in U by # R*teta // a revoir lbo 29/08/97
680 const TColStd_Array1OfReal& ku = approx.SurfUKnots();
681 const TColStd_Array1OfReal& kv = approx.SurfVKnots();
682 Standard_Real larg = (kv(kv.Upper())-kv(kv.Lower()));
683 TColStd_Array1OfReal& kku = *((TColStd_Array1OfReal*)((void*)&ku));
684 BSplCLib::Reparametrize(0.,larg,kku);
685 Handle(Geom_BSplineSurface) Surf =
686 new Geom_BSplineSurface(approx.SurfPoles(),approx.SurfWeights(),
688 approx.SurfUMults(),approx.SurfVMults(),
689 approx.UDegree(),approx.VDegree());
690 // extension of the surface
692 Standard_Real length1,length2;
693 length1=Data->FirstExtensionValue();
694 length2=Data->LastExtensionValue();
696 Handle(Geom_BoundedSurface) aBndSurf = Surf;
697 if (length1 > Precision::Confusion())
698 GeomLib::ExtendSurfByLength(aBndSurf,length1,1,Standard_False,Standard_False);
699 if (length2 > Precision::Confusion())
700 GeomLib::ExtendSurfByLength(aBndSurf,length2,1,Standard_False,Standard_True);
701 Surf = Handle(Geom_BSplineSurface)::DownCast (aBndSurf);
703 //Correction of surface on extremities
704 if (length1 <= Precision::Confusion())
707 P11 = lin->StartPointOnFirst().Value();
708 P21 = lin->StartPointOnSecond().Value();
709 Surf->SetPole(1, 1, P11);
710 Surf->SetPole(Surf->NbUPoles(), 1, P21);
712 if (length2 <= Precision::Confusion())
715 P12 = lin->EndPointOnFirst().Value();
716 P22 = lin->EndPointOnSecond().Value();
717 Surf->SetPole(1, Surf->NbVPoles(), P12);
718 Surf->SetPole(Surf->NbUPoles(), Surf->NbVPoles(), P22);
721 Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surf,tolget3d)));
724 ChFi3d_SettraceDRAWFIL(Standard_True);
725 if (ChFi3d_GettraceDRAWFIL()) {
728 char* name=new char[100];
729 sprintf(name,"%s_%d","Surf",IndexOfConge);
730 DrawTrSurf::Set(name,Surf);
733 Standard_Real UFirst,ULast,VFirst,VLast,pppdeb,pppfin;
734 Surf->Bounds(UFirst,ULast,VFirst,VLast);
735 BRepAdaptor_Curve2d brc;
736 BRepAdaptor_Curve CArc;
737 Handle(BRepAdaptor_HSurface)
738 BS1 = Handle(BRepAdaptor_HSurface)::DownCast(S1);
739 Handle(BRepAdaptor_HSurface)
740 BS2 = Handle(BRepAdaptor_HSurface)::DownCast(S2);
741 Geom2dAPI_ProjectPointOnCurve projector;
743 Standard_Real Uon1 = UFirst, Uon2 = ULast;
744 Standard_Integer ion1 = 1, ion2 = 2;
745 if(Reversed) { Uon1 = ULast; Uon2 = UFirst; ion1 = 2; ion2 = 1; }
747 // The SurfData is filled in what concerns S1,
748 Handle(Geom_Curve) Crv3d1 = Surf->UIso(Uon1);
749 gp_Pnt2d pori1(Uon1,0.);
750 gp_Lin2d lfil1(pori1,gp::DY2d());
751 Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1);
752 Handle(Geom2d_Curve) PCurveOnFace;
754 Geom2d_BSplineCurve(approx.Curve2dPoles(ion1),approx.Curves2dKnots(),
755 approx.Curves2dMults(),approx.Curves2dDegree());
758 Standard_Real par1=PCurveOnFace->FirstParameter();
759 Standard_Real par2= PCurveOnFace->LastParameter();
760 chc.Load(Crv3d1,par1,par2);
762 if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S1,tolC1,tolcheck)){
764 cout<<"aaproximate tolerance under-valued : "<<tolC1<<" for "<<tolcheck<<endl;
768 Standard_Integer Index1OfCurve =
769 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolC1));
771 Standard_Real uarc,utg;
773 TopoDS_Face forwfac = BS1->ChangeSurface().Face();
774 forwfac.Orientation(TopAbs_FORWARD);
775 brc.Initialize(Data->VertexFirstOnS1().Arc(),forwfac);
776 ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS1();
777 CArc.Initialize(V.Arc());
778 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
779 tolcheck = CArc.Value(uarc).Distance(V.Point());
780 V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
783 else pppdeb = VFirst;
785 TopoDS_Face forwfac = BS1->ChangeSurface().Face();
786 forwfac.Orientation(TopAbs_FORWARD);
787 ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS1();
788 brc.Initialize(V.Arc(),forwfac);
789 CArc.Initialize(V.Arc());
790 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
791 tolcheck = CArc.Value(uarc).Distance(V.Point());
792 V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
796 ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1();
797 Fint1.SetFirstParameter(pppdeb);
798 Fint1.SetLastParameter(pppfin);
799 TopAbs_Orientation TraOn1;
800 if(Reversed) TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
801 else TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
802 Fint1.SetInterference(Index1OfCurve,TraOn1,PCurveOnFace,PCurveOnSurf);
804 // SurfData is filled in what concerns S2,
805 Handle(Geom_Curve) Crv3d2 = Surf->UIso(Uon2);
806 gp_Pnt2d pori2(Uon2,0.);
807 gp_Lin2d lfil2(pori2,gp::DY2d());
808 PCurveOnSurf = new Geom2d_Line(lfil2);
810 PCurveOnFace = new Geom2d_BSplineCurve(approx.Curve2dPoles(ion2),
811 approx.Curves2dKnots(),
812 approx.Curves2dMults(),
813 approx.Curves2dDegree());
814 chc.Load(Crv3d2,par1,par2);
815 if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S2,tolC2,tolcheck)){
817 cout<<"approximate tolerance under-evaluated : "<<tolC2<<" for "<<tolcheck<<endl;
822 Standard_Integer Index2OfCurve =
823 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolC2));
825 TopoDS_Face forwfac = BS2->ChangeSurface().Face();
826 forwfac.Orientation(TopAbs_FORWARD);
827 brc.Initialize(Data->VertexFirstOnS2().Arc(),forwfac);
828 ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS2();
829 CArc.Initialize(V.Arc());
830 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
831 tolcheck = CArc.Value(uarc).Distance(V.Point());
832 V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
835 else pppdeb = VFirst;
837 TopoDS_Face forwfac = BS2->ChangeSurface().Face();
838 forwfac.Orientation(TopAbs_FORWARD);
839 brc.Initialize(Data->VertexLastOnS2().Arc(),forwfac);
840 ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS2();
841 CArc.Initialize(V.Arc());
842 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
843 tolcheck = CArc.Value(uarc).Distance(V.Point());
844 V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
848 ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2();
849 Fint2.SetFirstParameter(pppdeb);
850 Fint2.SetLastParameter(pppfin);
852 TopAbs_Orientation TraOn2;
853 if(Reversed) TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
854 else TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
855 Fint2.SetInterference(Index2OfCurve,TraOn2,PCurveOnFace,PCurveOnSurf);
858 Handle(Geom2d_Curve) bidpc;
859 Fint2.SetInterference
860 (Index2OfCurve,TopAbs_FORWARD,bidpc,PCurveOnSurf);
863 // the orientation of the fillet in relation to the faces is evaluated,
865 Handle(Adaptor3d_HSurface) Sref = S1;
866 PCurveOnFace = Fint1.PCurveOnFace();
867 if(Reversed){ Sref = S2; PCurveOnFace = Fint2.PCurveOnFace(); }
869 // Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898 Begin
870 // gp_Pnt2d PUV = PCurveOnFace->Value((VFirst+VLast)/2.);
872 // gp_Vec Du1,Du2,Dv1,Dv2;
873 // Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
875 // if (Or1 == TopAbs_REVERSED) Du1.Reverse();
876 // Surf->D1(UFirst,(VFirst+VLast)/2.,P,Du2,Dv2);
878 // if (Du1.Dot(Du2)>0) Data->ChangeOrientation() = TopAbs_FORWARD;
879 // else Data->ChangeOrientation() = TopAbs_REVERSED;
881 Standard_Real aDelta = VLast - VFirst;
882 Standard_Integer aDenom = 2;
885 Standard_Real aDeltav = aDelta/aDenom;
886 Standard_Real aParam = VFirst + aDeltav;
887 gp_Pnt2d PUV = PCurveOnFace->Value(aParam);
889 gp_Vec Du1,Du2,Dv1,Dv2;
891 Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
894 if (Or1 == TopAbs_REVERSED)
897 Surf->D1(UFirst, aParam, P, Du2, Dv2);
900 if (Du1.Magnitude() <= tolget3d ||
901 Du2.Magnitude() <= tolget3d) {
904 if (Abs(aDeltav) <= tolget2d)
905 return Standard_False;
911 Data->ChangeOrientation() = TopAbs_FORWARD;
913 Data->ChangeOrientation() = TopAbs_REVERSED;
917 // Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898 End
919 if(!Gd1 && !S1.IsNull())
920 ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(),
921 Standard_True, Data->ChangeVertex(1,ion1),tolC1);
922 if(!Gf1 && !S1.IsNull())
923 ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(),
924 Standard_False,Data->ChangeVertex(0,ion1),tolC1);
925 if(!Gd2 && !S2.IsNull())
926 ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(),
927 Standard_True, Data->ChangeVertex(1,ion2),tolC2);
928 if(!Gf2 && !S2.IsNull())
929 ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(),
930 Standard_False, Data->ChangeVertex(0,ion2),tolC2);
931 // Parameters on ElSpine
932 Standard_Integer nbp = lin->NbPoints();
933 Data->FirstSpineParam(lin->Point(1).Parameter());
934 Data->LastSpineParam(lin->Point(nbp).Parameter());
935 return Standard_True;
940 //=======================================================================
941 //function : ComputeData
942 //purpose : Head of the path edge/face for the bypass of obstacle.
943 //=======================================================================
945 Standard_Boolean ChFi3d_Builder::ComputeData
946 (Handle(ChFiDS_SurfData)& Data,
947 const Handle(ChFiDS_HElSpine)& HGuide,
948 Handle(BRepBlend_Line)& Lin,
949 const Handle(Adaptor3d_HSurface)& S1,
950 const Handle(Adaptor3d_TopolTool)& I1,
951 const Handle(Adaptor3d_HSurface)& S2,
952 const Handle(Adaptor2d_HCurve2d)& PC2,
953 const Handle(Adaptor3d_TopolTool)& I2,
954 Standard_Boolean& Decroch,
955 Blend_SurfRstFunction& Func,
957 Blend_SurfPointFuncInv& FInvP,
958 Blend_SurfCurvFuncInv& FInvC,
959 const Standard_Real PFirst,
960 const Standard_Real MaxStep,
961 const Standard_Real Fleche,
962 const Standard_Real TolGuide,
963 Standard_Real& First,
965 const math_Vector& Soldep,
966 const Standard_Boolean Inside,
967 const Standard_Boolean Appro,
968 const Standard_Boolean Forward,
969 const Standard_Boolean RecP,
970 const Standard_Boolean RecS,
971 const Standard_Boolean RecRst)
973 BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
975 Data->FirstExtensionValue(0);
976 Data->LastExtensionValue(0);
978 Standard_Boolean reverse = (!Forward || Inside);
979 Standard_Real SpFirst = HGuide->FirstParameter();
980 Standard_Real SpLast = HGuide->LastParameter();
981 Standard_Real Target = SpLast;
982 if(reverse) Target = SpFirst;
983 Standard_Real Targetsov = Target;
985 Standard_Real MS = MaxStep;
986 Standard_Integer again = 0;
987 Standard_Integer nbptmin = 3; //jlr
988 Standard_Integer Nbpnt = 1;
989 // the initial solution is reframed if necessary.
990 math_Vector ParSol(1,3);
991 Standard_Real NewFirst = PFirst;
992 if(RecP || RecS || RecRst){
993 if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep,
994 tolesp,TolGuide,RecRst,RecP,RecS,
997 cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<endl;
999 return Standard_False;
1007 TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last,
1008 MS,TolGuide,ParSol,tolesp,Fleche,Appro);
1010 if (!TheWalk.IsDone()) {
1012 cout << "Path not created" << endl;
1014 return Standard_False;
1018 if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) {
1020 cout << "Not completed" << endl;
1026 Lin = TheWalk.Line();
1027 Nbpnt = Lin->NbPoints();
1028 if (Nbpnt <= 1 && again == 0) {
1031 cout <<"one point of the path MS/50 is attempted."<<endl;
1033 MS = MS/50.; Target = Targetsov;
1035 else if (Nbpnt<=nbptmin && again == 0) {
1038 cout <<"Number of points is too small, the step is reduced"<<endl;
1040 Standard_Real u1 = Lin->Point(1).Parameter();
1041 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1042 MS = (u2-u1)/(nbptmin+1.0);
1043 // cout << " MS : " << MS << " u1 : " << u1 << " u2 : " << u2 << " nbptmin : " << nbptmin << endl;
1046 else if(Nbpnt<=nbptmin){
1048 cout <<"Number of points is still too small, quit"<<endl;
1050 return Standard_False;
1057 ChFi3d_SettraceDRAWWALK(Standard_True);
1058 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1060 if(Forward) Decroch = TheWalk.DecrochEnd();
1061 else Decroch = TheWalk.DecrochStart();
1062 Last = Lin->Point(Nbpnt).Parameter();
1063 First = Lin->Point(1).Parameter();
1064 return Standard_True;
1068 //=======================================================================
1069 //function : ComputeData
1070 //purpose : Heading of the path edge/edge for the bypass of obstacle.
1071 //=======================================================================
1073 Standard_Boolean ChFi3d_Builder::ComputeData
1074 (Handle(ChFiDS_SurfData)& Data,
1075 const Handle(ChFiDS_HElSpine)& HGuide,
1076 Handle(BRepBlend_Line)& Lin,
1077 const Handle(Adaptor3d_HSurface)& S1,
1078 const Handle(Adaptor2d_HCurve2d)& PC1,
1079 const Handle(Adaptor3d_TopolTool)& I1,
1080 Standard_Boolean& Decroch1,
1081 const Handle(Adaptor3d_HSurface)& S2,
1082 const Handle(Adaptor2d_HCurve2d)& PC2,
1083 const Handle(Adaptor3d_TopolTool)& I2,
1084 Standard_Boolean& Decroch2,
1085 Blend_RstRstFunction& Func,
1086 Blend_SurfCurvFuncInv& FInv1,
1087 Blend_CurvPointFuncInv& FInvP1,
1088 Blend_SurfCurvFuncInv& FInv2,
1089 Blend_CurvPointFuncInv& FInvP2,
1090 const Standard_Real PFirst,
1091 const Standard_Real MaxStep,
1092 const Standard_Real Fleche,
1093 const Standard_Real TolGuide,
1094 Standard_Real& First,
1095 Standard_Real& Last,
1096 const math_Vector& Soldep,
1097 const Standard_Boolean Inside,
1098 const Standard_Boolean Appro,
1099 const Standard_Boolean Forward,
1100 const Standard_Boolean RecP1,
1101 const Standard_Boolean RecRst1,
1102 const Standard_Boolean RecP2,
1103 const Standard_Boolean RecRst2)
1105 BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1107 Data->FirstExtensionValue(0);
1108 Data->LastExtensionValue(0);
1110 Standard_Boolean reverse = (!Forward || Inside);
1111 Standard_Real SpFirst = HGuide->FirstParameter();
1112 Standard_Real SpLast = HGuide->LastParameter();
1113 Standard_Real Target = SpLast;
1114 if(reverse) Target = SpFirst;
1115 Standard_Real Targetsov = Target;
1117 Standard_Real MS = MaxStep;
1118 Standard_Integer again = 0;
1119 Standard_Integer nbptmin = 3; //jlr
1120 Standard_Integer Nbpnt = 0;
1121 // the initial solution is reframed if necessary.
1122 math_Vector ParSol(1,2);
1123 Standard_Real NewFirst = PFirst;
1124 if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1125 if (!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1126 tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1129 cout<<"ChFi3d_Builder::ComputeData : fail calculation first section"<<endl;
1131 return Standard_False;
1139 TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1140 MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1142 if (!TheWalk.IsDone()) {
1144 cout << "Path not done" << endl;
1146 return Standard_False;
1150 if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1152 cout << "Not completed" << endl;
1158 Lin = TheWalk.Line();
1159 Nbpnt = Lin->NbPoints();
1160 if (Nbpnt <= 1 && again == 0) {
1163 cout <<"one point of path MS/50 is attempted."<<endl;
1165 MS = MS/50.; Target = Targetsov;
1167 else if (Nbpnt<=nbptmin && again == 0) {
1170 cout <<"Number of points is too small, the step is reduced"<<endl;
1172 Standard_Real u1 = Lin->Point(1).Parameter();
1173 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1174 MS = (u2-u1)/(nbptmin+1);
1177 else if(Nbpnt<=nbptmin){
1179 cout <<"Number of points is still too small, quit"<<endl;
1181 return Standard_False;
1188 ChFi3d_SettraceDRAWWALK(Standard_True);
1189 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1192 Decroch1 = TheWalk.Decroch1End();
1193 Decroch2 = TheWalk.Decroch2End();
1196 Decroch1 = TheWalk.Decroch1Start();
1197 Decroch2 = TheWalk.Decroch2Start();
1199 Last = Lin->Point(Nbpnt).Parameter();
1200 First = Lin->Point(1).Parameter();
1201 return Standard_True;
1205 //=======================================================================
1206 //function : SimulData
1207 //purpose : Heading of the path edge/face for the bypass of obstacle in simulation mode.
1208 //=======================================================================
1210 Standard_Boolean ChFi3d_Builder::SimulData
1211 (Handle(ChFiDS_SurfData)& /*Data*/,
1212 const Handle(ChFiDS_HElSpine)& HGuide,
1213 Handle(BRepBlend_Line)& Lin,
1214 const Handle(Adaptor3d_HSurface)& S1,
1215 const Handle(Adaptor3d_TopolTool)& I1,
1216 const Handle(Adaptor3d_HSurface)& S2,
1217 const Handle(Adaptor2d_HCurve2d)& PC2,
1218 const Handle(Adaptor3d_TopolTool)& I2,
1219 Standard_Boolean& Decroch,
1220 Blend_SurfRstFunction& Func,
1221 Blend_FuncInv& FInv,
1222 Blend_SurfPointFuncInv& FInvP,
1223 Blend_SurfCurvFuncInv& FInvC,
1224 const Standard_Real PFirst,
1225 const Standard_Real MaxStep,
1226 const Standard_Real Fleche,
1227 const Standard_Real TolGuide,
1228 Standard_Real& First,
1229 Standard_Real& Last,
1230 const math_Vector& Soldep,
1231 const Standard_Integer NbSecMin,
1232 const Standard_Boolean Inside,
1233 const Standard_Boolean Appro,
1234 const Standard_Boolean Forward,
1235 const Standard_Boolean RecP,
1236 const Standard_Boolean RecS,
1237 const Standard_Boolean RecRst)
1239 BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
1241 Standard_Boolean reverse = (!Forward || Inside);
1242 Standard_Real SpFirst = HGuide->FirstParameter();
1243 Standard_Real SpLast = HGuide->LastParameter();
1244 Standard_Real Target = SpLast;
1245 if(reverse) Target = SpFirst;
1246 Standard_Real Targetsov = Target;
1248 Standard_Real MS = MaxStep;
1249 Standard_Integer again = 0;
1250 Standard_Integer Nbpnt = 0;
1251 // the starting solution is reframed if needed.
1252 math_Vector ParSol(1,3);
1253 Standard_Real NewFirst = PFirst;
1254 if(RecP || RecS || RecRst){
1255 if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep,
1256 tolesp,TolGuide,RecRst,RecP,RecS,
1260 cout<<"ChFi3d_Builder::SimulData : fail calculate first section"<<endl;
1262 return Standard_False;
1270 TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last,
1271 MS,TolGuide,ParSol,tolesp,Fleche,Appro);
1272 if (!TheWalk.IsDone()) {
1274 cout << "Path not done" << endl;
1276 return Standard_False;
1279 if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) {
1281 cout << "Not completed" << endl;
1285 Lin = TheWalk.Line();
1286 Nbpnt = Lin->NbPoints();
1287 if (Nbpnt <= 1 && again == 0) {
1290 cout <<"one point of path MS/50 is attempted."<<endl;
1292 MS = MS/50.; Target = Targetsov;
1294 else if (Nbpnt <= NbSecMin && again == 0) {
1297 cout <<"Number of points is too small, the step is reduced"<<endl;
1299 Standard_Real u1 = Lin->Point(1).Parameter();
1300 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1301 MS = (u2-u1)/(NbSecMin+1);
1304 else if(Nbpnt<=NbSecMin){
1306 cout <<"Number of points is still too small, quit"<<endl;
1308 return Standard_False;
1315 ChFi3d_SettraceDRAWWALK(Standard_True);
1316 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1318 if(Forward) Decroch = TheWalk.DecrochEnd();
1319 else Decroch = TheWalk.DecrochStart();
1320 Last = Lin->Point(Nbpnt).Parameter();
1321 First = Lin->Point(1).Parameter();
1322 return Standard_True;
1326 //=======================================================================
1327 //function : SimulData
1328 //purpose : Heading of path edge/edge for the bypass
1329 // of obstacle in simulation mode.
1330 //=======================================================================
1332 Standard_Boolean ChFi3d_Builder::SimulData
1333 (Handle(ChFiDS_SurfData)& /*Data*/,
1334 const Handle(ChFiDS_HElSpine)& HGuide,
1335 Handle(BRepBlend_Line)& Lin,
1336 const Handle(Adaptor3d_HSurface)& S1,
1337 const Handle(Adaptor2d_HCurve2d)& PC1,
1338 const Handle(Adaptor3d_TopolTool)& I1,
1339 Standard_Boolean& Decroch1,
1340 const Handle(Adaptor3d_HSurface)& S2,
1341 const Handle(Adaptor2d_HCurve2d)& PC2,
1342 const Handle(Adaptor3d_TopolTool)& I2,
1343 Standard_Boolean& Decroch2,
1344 Blend_RstRstFunction& Func,
1345 Blend_SurfCurvFuncInv& FInv1,
1346 Blend_CurvPointFuncInv& FInvP1,
1347 Blend_SurfCurvFuncInv& FInv2,
1348 Blend_CurvPointFuncInv& FInvP2,
1349 const Standard_Real PFirst,
1350 const Standard_Real MaxStep,
1351 const Standard_Real Fleche,
1352 const Standard_Real TolGuide,
1353 Standard_Real& First,
1354 Standard_Real& Last,
1355 const math_Vector& Soldep,
1356 const Standard_Integer NbSecMin,
1357 const Standard_Boolean Inside,
1358 const Standard_Boolean Appro,
1359 const Standard_Boolean Forward,
1360 const Standard_Boolean RecP1,
1361 const Standard_Boolean RecRst1,
1362 const Standard_Boolean RecP2,
1363 const Standard_Boolean RecRst2)
1365 BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1367 Standard_Boolean reverse = (!Forward || Inside);
1368 Standard_Real SpFirst = HGuide->FirstParameter();
1369 Standard_Real SpLast = HGuide->LastParameter();
1370 Standard_Real Target = SpLast;
1371 if(reverse) Target = SpFirst;
1372 Standard_Real Targetsov = Target;
1374 Standard_Real MS = MaxStep;
1375 Standard_Integer again = 0;
1376 Standard_Integer Nbpnt = 0;
1377 // The initial solution is reframed if necessary.
1378 math_Vector ParSol(1,2);
1379 Standard_Real NewFirst = PFirst;
1380 if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1381 if(!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1382 tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1386 cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<endl;
1388 return Standard_False;
1396 TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1397 MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1398 if (!TheWalk.IsDone()) {
1400 cout << "Path not created" << endl;
1402 return Standard_False;
1405 if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1407 cout << "Not completed" << endl;
1411 Lin = TheWalk.Line();
1412 Nbpnt = Lin->NbPoints();
1413 if (Nbpnt <= 1 && again == 0) {
1416 cout <<"only one point of path MS/50 is attempted."<<endl;
1418 MS = MS/50.; Target = Targetsov;
1420 else if (Nbpnt <= NbSecMin && again == 0) {
1423 cout <<"Number of points is too small, the step is reduced"<<endl;
1425 Standard_Real u1 = Lin->Point(1).Parameter();
1426 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1427 MS = (u2-u1)/(NbSecMin+1);
1430 else if(Nbpnt<=NbSecMin){
1432 cout <<"Number of points is still too small, quit"<<endl;
1434 return Standard_False;
1441 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1444 Decroch1 = TheWalk.Decroch1End();
1445 Decroch2 = TheWalk.Decroch2End();
1448 Decroch1 = TheWalk.Decroch1Start();
1449 Decroch2 = TheWalk.Decroch2Start();
1452 Last = Lin->Point(Nbpnt).Parameter();
1453 First = Lin->Point(1).Parameter();
1454 return Standard_True;
1460 //=======================================================================
1461 //function : ComputeData
1462 //purpose : Construction of elementary fillet by path.
1464 //=======================================================================
1466 Standard_Boolean ChFi3d_Builder::ComputeData
1467 (Handle(ChFiDS_SurfData)& Data,
1468 const Handle(ChFiDS_HElSpine)& HGuide,
1469 const Handle(ChFiDS_Spine)& Spine,
1470 Handle(BRepBlend_Line)& Lin,
1471 const Handle(Adaptor3d_HSurface)& S1,
1472 const Handle(Adaptor3d_TopolTool)& I1,
1473 const Handle(Adaptor3d_HSurface)& S2,
1474 const Handle(Adaptor3d_TopolTool)& I2,
1475 Blend_Function& Func,
1476 Blend_FuncInv& FInv,
1477 const Standard_Real PFirst,
1478 const Standard_Real MaxStep,
1479 const Standard_Real Fleche,
1480 const Standard_Real tolguide,
1481 Standard_Real& First,
1482 Standard_Real& Last,
1483 const Standard_Boolean Inside,
1484 const Standard_Boolean Appro,
1485 const Standard_Boolean Forward,
1486 const math_Vector& Soldep,
1487 Standard_Boolean& intf,
1488 Standard_Boolean& intl,
1489 Standard_Boolean& Gd1,
1490 Standard_Boolean& Gd2,
1491 Standard_Boolean& Gf1,
1492 Standard_Boolean& Gf2,
1493 const Standard_Boolean RecOnS1,
1494 const Standard_Boolean RecOnS2)
1496 //The extrensions are created in case of output of two domains
1497 //directly and not by path ( too hasardous ).
1498 Data->FirstExtensionValue(0);
1499 Data-> LastExtensionValue(0);
1501 //The eventual faces are restored to test the jump of edge.
1503 Handle(BRepAdaptor_HSurface) HS = Handle(BRepAdaptor_HSurface)::DownCast(S1);
1504 if(!HS.IsNull()) F1 = HS->ChangeSurface().Face();
1505 HS = Handle(BRepAdaptor_HSurface)::DownCast(S2);
1506 if(!HS.IsNull()) F2 = HS->ChangeSurface().Face();
1508 // Path framing variables
1509 Standard_Real TolGuide=tolguide, TolEsp = tolesp;
1510 Standard_Integer nbptmin = 4;
1512 BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide);
1514 //Start of removal, 2D path controls
1515 //that qui s'accomodent mal des surfaces a parametrages non homogenes
1516 //en u et en v are extinguished.
1519 Standard_Real MS = MaxStep;
1520 Standard_Integer Nbpnt;
1521 Standard_Real SpFirst = HGuide->FirstParameter();
1522 Standard_Real SpLast = HGuide->LastParameter();
1524 // When the start point is inside, the path goes first to the left
1525 // to determine the Last for the periodicals.
1526 Standard_Boolean reverse = (!Forward || Inside);
1527 Standard_Real Target;
1530 if(!intf) Target = Last;
1533 Target = SpLast + Abs(SpLast);
1534 if(!intl) Target = Last;
1537 // In case if the singularity is pre-determined,
1538 // the path is indicated.
1539 if (!Spine.IsNull()){
1540 if (Spine->IsTangencyExtremity(Standard_True)) {
1541 TopoDS_Vertex V = Spine->FirstVertex();
1542 TopoDS_Edge E = Spine->Edges(1);
1543 Standard_Real param = Spine->FirstParameter();
1545 if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1546 math_Vector vec(1,4);
1547 BP.ParametersOnS1(vec(1),vec(2));
1548 BP.ParametersOnS2(vec(3),vec(4));
1550 if (Func.IsSolution(vec, tolesp)) {
1551 TheWalk.AddSingularPoint(BP);
1555 if (Spine->IsTangencyExtremity(Standard_False)) {
1556 TopoDS_Vertex V = Spine->LastVertex();
1557 TopoDS_Edge E = Spine->Edges( Spine->NbEdges());
1558 Standard_Real param = Spine->LastParameter();
1560 if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1561 math_Vector vec(1,4);
1562 BP.ParametersOnS1(vec(1),vec(2));
1563 BP.ParametersOnS2(vec(3),vec(4));
1565 if (Func.IsSolution(vec, tolesp)) {
1566 TheWalk.AddSingularPoint(BP);
1572 //The starting solution is reframed if necessary.
1573 //**********************************************//
1574 math_Vector ParSol(1,4);
1575 Standard_Real NewFirst = PFirst;
1576 if(RecOnS1 || RecOnS2){
1577 if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
1578 tolesp,TolGuide,RecOnS1,RecOnS2,
1581 cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<endl;
1583 return Standard_False;
1590 //First the valid part is calculate, without caring for the extensions.
1591 //******************************************************************//
1592 Standard_Integer again = 0;
1593 Standard_Boolean tchernobyl = 0;
1594 Standard_Real u1sov = 0., u2sov = 0.;
1596 //Max step is relevant, but too great, the vector is required to detect
1598 if( (Abs(Last-First) <= MS * 5.) &&
1599 (Abs(Last-First) >= 0.01*Abs(NewFirst-Target)) ){
1600 MS = Abs(Last-First)*0.2;
1605 if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
1607 if (5*TolGuide > MS) TolGuide = MS/5;
1608 if (5*TolEsp > MS) TolEsp = MS/5;
1610 TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
1611 ParSol,TolEsp,Fleche,Appro);
1612 if (!TheWalk.IsDone()) {
1614 cout << "Path is not created" << endl;
1616 return Standard_False;
1618 Lin = TheWalk.Line();
1619 if(HGuide->IsPeriodic() && Inside) {
1620 SpFirst = Lin->Point(1).Parameter();
1621 SpLast = SpFirst + HGuide->Period();
1622 HGuide->ChangeCurve().FirstParameter(SpFirst);
1623 HGuide->ChangeCurve().LastParameter (SpLast );
1624 HGuide->ChangeCurve().SetOrigin(SpFirst);
1626 Standard_Boolean complmnt = Standard_True;
1627 if (Inside) complmnt = TheWalk.Complete(Func,FInv,SpLast);
1630 cout << "Not completed" << endl;
1632 return Standard_False;
1635 //The result is controlled using two criterions :
1636 //- if there is enough points,
1637 //- if one has gone far enough.
1638 Nbpnt = Lin->NbPoints();
1641 cout <<"0 point of path, quit."<<endl;
1643 return Standard_False;
1645 Standard_Real fpointpar = Lin->Point(1).Parameter();
1646 Standard_Real lpointpar = Lin->Point(Nbpnt).Parameter();
1648 Standard_Real factor = 1./(nbptmin + 1);
1649 Standard_Boolean okdeb = (Forward && !Inside);
1650 Standard_Boolean okfin = (!Forward && !Inside);
1652 Standard_Integer narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1653 Standard_Integer narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1654 okdeb = (narc1 > 0 || narc2 > 0 || (fpointpar-First) < 10*TolGuide);
1657 Standard_Integer narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1658 Standard_Integer narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1659 okfin = (narc1 > 0 || narc2 > 0 || (Last-lpointpar) < 10*TolGuide);
1661 if(!okdeb || !okfin || Nbpnt == 1){
1662 //It drags, the controls are extended, it is expected to evaluate a
1663 //satisfactory maximum step. If it already done, quit.
1666 cout <<"If it drags without control, quit."<<endl;
1668 return Standard_False;
1670 tchernobyl = Standard_True;
1674 cout <<"only one point of path MS/100 is attempted"<<endl;
1675 cout <<"and the controls are extended."<<endl;
1681 cout <<"It drags, the controls are extended."<<endl;
1683 MS = (lpointpar-fpointpar)/Nbpnt; //EvalStep(Lin);
1686 else if (Nbpnt < nbptmin){
1689 cout <<"Number of points is too small, the step is reduced"<<endl;
1693 MS = (lpointpar - fpointpar) * factor;
1695 else if(again == 1){
1696 if(Abs(fpointpar-u1sov)>=TolGuide ||
1697 Abs(lpointpar-u2sov)>=TolGuide){
1699 cout <<"Number of points is still too small, the step is reduced"<<endl;
1701 MS = (lpointpar - fpointpar) * factor;
1705 cout <<"Number of points is still too small, quit"<<endl;
1707 return Standard_False;
1717 if(TheWalk.TwistOnS1()){
1718 Data->TwistOnS1(Standard_True);
1720 cout<<"Path completed, but TWIST on S1"<<endl;
1723 if(TheWalk.TwistOnS2()){
1724 Data->TwistOnS2(Standard_True);
1726 cout<<"Parh completed, but TWIST on S2"<<endl;
1731 //Here there is a more or less presentable result
1732 //however it covers a the minimum zone.
1733 //The extensions are targeted.
1734 //*****************************//
1736 Gd1 = Gd2 = Gf1 = Gf2 = Standard_False;
1738 Standard_Boolean unseulsuffitdeb = (intf >= 2);
1739 Standard_Boolean unseulsuffitfin = (intl >= 2);
1740 Standard_Boolean noproldeb = (intf >= 3);
1741 Standard_Boolean noprolfin = (intl >= 3);
1743 Standard_Real Rab = 0.03*(SpLast-SpFirst);
1745 Standard_Boolean debarc1 = 0, debarc2 = 0;
1746 Standard_Boolean debcas1 = 0, debcas2 = 0;
1747 Standard_Boolean debobst1 = 0, debobst2 = 0;
1749 Standard_Boolean finarc1 = 0, finarc2 = 0;
1750 Standard_Boolean fincas1 = 0, fincas2 = 0;
1751 Standard_Boolean finobst1 = 0, finobst2 = 0;
1753 Standard_Integer narc1, narc2;
1755 Standard_Boolean backwContinueFailed = Standard_False; // eap
1756 if(reverse && intf) {
1757 narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1758 narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1760 ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1761 Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1762 debarc1 = Standard_True;
1763 if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
1764 //It is checked if there is not an obstacle.
1765 debcas1 = Standard_True;
1766 if(!Spine.IsNull()){
1767 if(Spine->IsPeriodic()){
1771 debobst1 = IsObst(Data->VertexFirstOnS1(),
1772 Spine->FirstVertex(),myVEMap);
1778 ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1779 Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1780 debarc2 = Standard_True;
1781 if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
1782 //It is checked if it is not an obstacle.
1783 debcas2 = Standard_True;
1784 if(!Spine.IsNull()){
1785 if(Spine->IsPeriodic()){
1789 debobst2 = IsObst(Data->VertexFirstOnS2(),
1790 Spine->FirstVertex(),myVEMap);
1795 Standard_Boolean oncontinue = !noproldeb && (narc1 != 0 || narc2 != 0);
1796 if(debobst1 || debobst2) oncontinue = Standard_False;
1797 else if(debcas1 && debcas2) oncontinue = Standard_False;
1798 else if((!debcas1 && debarc1) || (!debcas2 && debarc2)) oncontinue = Standard_False;
1801 TheWalk.ClassificationOnS1(!debarc1);
1802 TheWalk.ClassificationOnS2(!debarc2);
1803 TheWalk.Check2d(Standard_True); // It should be strict (PMN)
1804 TheWalk.Continu(Func,FInv,Target);
1805 TheWalk.ClassificationOnS1(Standard_True);
1806 TheWalk.ClassificationOnS2(Standard_True);
1807 TheWalk.Check2d(Standard_False);
1808 narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1809 narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1810 // modified by eap Fri Feb 8 11:43:48 2002 ___BEGIN___
1813 backwContinueFailed = Lin->StartPointOnFirst().ParameterOnGuide() > Target;
1815 ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1816 Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1817 debarc1 = Standard_True;
1818 if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
1819 //It is checked if it is not an obstacle.
1820 debcas1 = Standard_True;
1821 // if(!Spine.IsNull()) {
1822 // if(Spine->IsPeriodic()){
1826 // debobst1 = IsObst(Data->VertexFirstOnS1(),
1827 // Spine->FirstVertex(),myVEMap);
1835 backwContinueFailed = Lin->StartPointOnSecond().ParameterOnGuide() > Target;
1837 ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1838 Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1839 debarc2 = Standard_True;
1840 if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
1841 //It is checked if it is not an obstacle.
1842 debcas2 = Standard_True;
1843 // if(!Spine.IsNull()){
1844 // if(Spine->IsPeriodic()){
1848 // debobst2 = IsObst(Data->VertexFirstOnS2(),
1849 // Spine->FirstVertex(),myVEMap);
1855 if (backwContinueFailed) {
1856 // if we leave backwContinueFailed as is, we will stop in this direction
1857 // but we are to continue if there are no more faces on the side with arc
1858 // check this condition
1859 const ChFiDS_CommonPoint& aCP
1860 = debarc1 ? Data->VertexFirstOnS1() : Data->VertexFirstOnS2();
1861 if (aCP.IsOnArc() && bif.IsNull())
1862 backwContinueFailed = Standard_False;
1866 Standard_Boolean forwContinueFailed = Standard_False;
1867 // modified by eap Fri Feb 8 11:44:11 2002 ___END___
1868 if(Forward && intl) {
1870 narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1871 narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1873 ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1874 Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1875 finarc1 = Standard_True;
1876 if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
1877 //It is checked if it is not an obstacle.
1878 fincas1 = Standard_True;
1879 if(!Spine.IsNull()){
1880 finobst1 = IsObst(Data->VertexLastOnS1(),
1881 Spine->LastVertex(),myVEMap);
1886 ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1887 Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1888 finarc2 = Standard_True;
1889 if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1890 //It is checked if it is not an obstacle.
1891 fincas2 = Standard_True;
1892 if(!Spine.IsNull()){
1893 finobst2 = IsObst(Data->VertexLastOnS2(),
1894 Spine->LastVertex(),myVEMap);
1898 Standard_Boolean oncontinue = !noprolfin && (narc1 != 0 || narc2 != 0);
1899 if(finobst1 || finobst2) oncontinue = Standard_False;
1900 else if(fincas1 && fincas2) oncontinue = Standard_False;
1901 else if((!fincas1 && finarc1) || (!fincas2 && finarc2)) oncontinue = Standard_False;
1904 TheWalk.ClassificationOnS1(!finarc1);
1905 TheWalk.ClassificationOnS2(!finarc2);
1906 TheWalk.Check2d(Standard_True); // It should be strict (PMN)
1907 TheWalk.Continu(Func,FInv,Target);
1908 TheWalk.ClassificationOnS1(Standard_True);
1909 TheWalk.ClassificationOnS2(Standard_True);
1910 TheWalk.Check2d(Standard_False);
1911 narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1912 narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1913 // modified by eap Fri Feb 8 11:44:57 2002 ___BEGIN___
1916 forwContinueFailed = Lin->EndPointOnFirst().ParameterOnGuide() < Target;
1918 ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1919 Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1920 finarc1 = Standard_True;
1921 if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
1922 //It is checked if it is not an obstacle.
1923 fincas1 = Standard_True;
1924 // if(!Spine.IsNull()){
1925 // finobst1 = IsObst(Data->VertexLastOnS1(),
1926 // Spine->LastVertex(),myVEMap);
1933 forwContinueFailed = Lin->EndPointOnSecond().ParameterOnGuide() < Target;
1935 ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1936 Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1937 finarc2 = Standard_True;
1938 if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1939 //On regarde si ce n'est pas un obstacle.
1940 fincas2 = Standard_True;
1941 // if(!Spine.IsNull()){
1942 // finobst2 = IsObst(Data->VertexLastOnS2(),
1943 // Spine->LastVertex(),myVEMap);
1948 if (forwContinueFailed) {
1949 // if we leave forwContinueFailed as is, we will stop in this direction
1950 // but we are to continue if there are no more faces on the side with arc
1951 // check this condition
1952 const ChFiDS_CommonPoint& aCP
1953 = finarc1 ? Data->VertexLastOnS1() : Data->VertexLastOnS2();
1954 if (aCP.IsOnArc() && bif.IsNull())
1955 forwContinueFailed = Standard_False;
1957 // modified by eap Fri Feb 8 11:45:10 2002 ___END___
1960 Nbpnt = Lin->NbPoints();
1962 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
1964 First = Lin->Point(1).Parameter();
1965 Last = Lin->Point(Nbpnt).Parameter();
1967 // ============= INVALIDATION EVENTUELLE =============
1968 // ------ Preparation des prolongement par plan tangent -----
1969 if(reverse && intf){
1970 Gd1 = debcas1/* && !debobst1*/; // skv(occ67)
1971 Gd2 = debcas2/* && !debobst2*/; // skv(occ67)
1972 if ((debarc1^debarc2) && !unseulsuffitdeb && (First!=SpFirst)) {
1973 // Case of incomplete path, of course this ends badly :
1974 // the result is truncated instead of exit.
1975 Standard_Real sortie;
1976 Standard_Integer ind;
1977 if (debarc1) sortie = Data->VertexFirstOnS1().Parameter();
1978 else sortie = Data->VertexFirstOnS2().Parameter();
1979 if (sortie - First > tolesp) {
1980 ind = SearchIndex(sortie, Lin);
1981 if (Lin->Point(ind).Parameter() == sortie) ind--;
1983 Lin->Remove(1, ind);
1984 UpdateLine(Lin, Standard_True);
1986 Nbpnt = Lin->NbPoints();
1987 First = Lin->Point(1).Parameter();
1990 else if ((intf>=5) && !debarc1 && !debarc2 && (First!=SpFirst)) {
1991 Standard_Real sortie = (2*First+Last)/3;
1992 Standard_Integer ind;
1993 if (sortie - First > tolesp) {
1994 ind = SearchIndex(sortie, Lin);
1995 if (Lin->Point(ind).Parameter() == sortie) ind--;
1996 if (Nbpnt-ind < 3) ind = Nbpnt -3;
1998 Lin->Remove(1, ind);
1999 UpdateLine(Lin, Standard_True);
2001 Nbpnt = Lin->NbPoints();
2002 First = Lin->Point(1).Parameter();
2006 Target = Min((Lin->Point(1).Parameter() - Rab),First);
2007 Target = Max(Target,SpFirst);
2008 Data->FirstExtensionValue(Abs(Lin->Point(1).Parameter()-Target));
2010 if (intf && !unseulsuffitdeb) intf = (Gd1 && Gd2)//;
2011 || backwContinueFailed; // eap
2012 else if (intf && unseulsuffitdeb && (intf<5)) {
2013 intf = (Gd1 || Gd2);
2014 // It is checked if there is no new face.
2016 ((!debcas1 && debarc1) || (!debcas2 && debarc2)) ) intf = 0;
2018 else if (intf < 5) intf = 0;
2021 if(Forward && intl){
2022 Gf1 = fincas1/* && !finobst1*/; // skv(occ67)
2023 Gf2 = fincas2/* && !finobst2*/; // skv(occ67)
2024 if ((finarc1 ^finarc2) && !unseulsuffitfin && (Last!=SpLast)) {
2025 // Case of incomplete path, of course, this ends badly :
2026 // the result is truncated instead of exit.
2027 Standard_Real sortie;
2028 Standard_Integer ind;
2029 if (finarc1) sortie = Data->VertexLastOnS1().Parameter();
2030 else sortie = Data->VertexLastOnS2().Parameter();
2031 if (Last - sortie > tolesp) {
2032 ind = SearchIndex(sortie, Lin);
2033 if (Lin->Point(ind).Parameter() == sortie) ind++;
2035 Lin->Remove(ind, Nbpnt);
2036 UpdateLine(Lin, Standard_False);
2038 Nbpnt = Lin->NbPoints();
2039 Last = Lin->Point(Nbpnt).Parameter();
2042 else if ((intl>=5) && !finarc1 && !finarc2 && (Last!=SpLast) ) {
2043 // The same in case when the entire "Lin" is an extension
2044 Standard_Real sortie = (First+2*Last)/3;
2045 Standard_Integer ind;
2046 if (Last - sortie > tolesp) {
2047 ind = SearchIndex(sortie, Lin);
2048 if (Lin->Point(ind).Parameter() == sortie) ind++;
2049 if (ind < 3) ind = 3;
2051 Lin->Remove(ind, Nbpnt);
2052 UpdateLine(Lin, Standard_False);
2054 Nbpnt = Lin->NbPoints();
2055 Last = Lin->Point(Nbpnt).Parameter();
2059 Target = Max((Lin->Point(Nbpnt).Parameter() + Rab),Last);
2060 Target = Min(Target,SpLast);
2061 Data->LastExtensionValue(Abs(Target-Lin->Point(Nbpnt).Parameter()));
2064 if (intl && !unseulsuffitfin) intl = (Gf1 && Gf2)//;
2065 || forwContinueFailed; // eap
2066 else if (intl && unseulsuffitfin && (intl<5)) {
2067 intl = (Gf1 || Gf2);// It is checked if there is no new face.
2069 ((!fincas1 && finarc1) || (!fincas2 && finarc2)) ) intl = 0;
2071 else if (intl <5) intl = 0;
2073 return Standard_True;
2076 //=======================================================================
2077 //function : SimulData
2079 //=======================================================================
2081 Standard_Boolean ChFi3d_Builder::SimulData
2082 (Handle(ChFiDS_SurfData)& /*Data*/,
2083 const Handle(ChFiDS_HElSpine)& HGuide,
2084 Handle(BRepBlend_Line)& Lin,
2085 const Handle(Adaptor3d_HSurface)& S1,
2086 const Handle(Adaptor3d_TopolTool)& I1,
2087 const Handle(Adaptor3d_HSurface)& S2,
2088 const Handle(Adaptor3d_TopolTool)& I2,
2089 Blend_Function& Func,
2090 Blend_FuncInv& FInv,
2091 const Standard_Real PFirst,
2092 const Standard_Real MaxStep,
2093 const Standard_Real Fleche,
2094 const Standard_Real tolguide,
2095 Standard_Real& First,
2096 Standard_Real& Last,
2097 const Standard_Boolean Inside,
2098 const Standard_Boolean Appro,
2099 const Standard_Boolean Forward,
2100 const math_Vector& Soldep,
2101 const Standard_Integer NbSecMin,
2102 const Standard_Boolean RecOnS1,
2103 const Standard_Boolean RecOnS2)
2105 BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide);
2106 TheWalk.Check2d(Standard_False);
2108 Standard_Real MS = MaxStep;
2109 Standard_Real TolGuide=tolguide, TolEsp = tolesp;
2110 Standard_Integer Nbpnt = 0;
2111 Standard_Real SpFirst = HGuide->FirstParameter();
2112 Standard_Real SpLast = HGuide->LastParameter();
2113 Standard_Boolean reverse = (!Forward || Inside);
2114 Standard_Real Target;
2122 Standard_Real Targetsov = Target;
2123 Standard_Real u1sov = 0., u2sov = 0.;
2124 // on recadre la solution de depart a la demande.
2125 math_Vector ParSol(1,4);
2126 Standard_Real NewFirst = PFirst;
2127 if(RecOnS1 || RecOnS2){
2128 if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
2129 tolesp,TolGuide,RecOnS1,RecOnS2,
2132 cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<endl;
2134 return Standard_False;
2140 Standard_Integer again = 0;
2142 // When the start point is inside, the path goes first to the left
2143 // to determine the Last for the periodicals.
2144 if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
2146 if (5*TolGuide > MS) TolGuide = MS/5;
2147 if (5*TolEsp > MS) TolEsp = MS/5;
2150 TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
2151 ParSol,TolEsp,Fleche,Appro);
2153 if (!TheWalk.IsDone()) {
2155 cout << "Path not created" << endl;
2157 return Standard_False;
2159 Lin = TheWalk.Line();
2161 if(HGuide->IsPeriodic()) {
2162 SpFirst = Lin->Point(1).Parameter();
2163 SpLast = SpFirst + HGuide->Period();
2164 HGuide->ChangeCurve().FirstParameter(SpFirst);
2165 HGuide->ChangeCurve().LastParameter (SpLast );
2167 Standard_Boolean complmnt = Standard_True;
2168 if (Inside) complmnt = TheWalk.Complete(Func,FInv,SpLast);
2171 cout << "Not completed" << endl;
2173 return Standard_False;
2176 Nbpnt = Lin->NbPoints();
2177 Standard_Real factor = 1./(NbSecMin + 1);
2180 cout <<"0 point of path, quit."<<endl;
2182 return Standard_False;
2184 else if (Nbpnt == 1 && again == 0) {
2187 cout <<"only one point of path, MS/100 is attempted."<<endl;
2189 MS *= 0.01; Target = Targetsov;
2190 u1sov = u2sov = Lin->Point(1).Parameter();
2192 else if (Nbpnt< NbSecMin && again == 0) {
2195 cout <<"Number of points is too small, the step is reduced"<<endl;
2197 Standard_Real u1 = u1sov = Lin->Point(1).Parameter();
2198 Standard_Real u2 = u2sov = Lin->Point(Nbpnt).Parameter();
2199 MS = (u2-u1)*factor;
2202 else if (Nbpnt < NbSecMin && again == 1) {
2203 Standard_Real u1 = Lin->Point(1).Parameter();
2204 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
2205 if(Abs(u1-u1sov)>=TolGuide || Abs(u2-u2sov)>=TolGuide){
2208 cout <<"Number of points is still too small, the step is reduced"<<endl;
2215 cout <<"Number of points is still too small, quit"<<endl;
2217 return Standard_False;
2220 else if(Nbpnt < NbSecMin){
2222 cout <<"Number of points is still too small, quit"<<endl;
2224 return Standard_False;
2231 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
2233 First = Lin->Point(1).Parameter();
2234 Last = Lin->Point(Nbpnt).Parameter();
2235 return Standard_True;