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>
107 #include <Draw_Appli.hxx>
108 #include <Draw_Segment2D.hxx>
109 #include <Draw_Marker2D.hxx>
110 #include <Draw_Segment3D.hxx>
111 #include <Draw_Marker3D.hxx>
113 #include <DrawTrSurf.hxx>
114 #include <BRepAdaptor_HSurface.hxx>
115 static Standard_Integer IndexOfConge = 0;
119 extern Standard_Boolean ChFi3d_GettraceDRAWFIL();
120 extern Standard_Boolean ChFi3d_GettraceDRAWWALK();
121 extern Standard_Boolean ChFi3d_GetcontextNOOPT();
122 extern void ChFi3d_SettraceDRAWFIL(const Standard_Boolean b);
123 extern void ChFi3d_SettraceDRAWWALK(const Standard_Boolean b);
124 extern void ChFi3d_SetcontextNOOPT(const Standard_Boolean b);
128 static void drawline(const Handle(BRepBlend_Line)& lin,
129 const Standard_Boolean iscs)
131 Handle(Draw_Marker3D) p3d;
132 Handle(Draw_Marker2D) p2d;
133 Handle(Draw_Segment3D) tg3d;
134 Handle(Draw_Segment2D) tg2d;
136 for(Standard_Integer i = 1; i <= lin->NbPoints(); i++){
137 const Blend_Point& pt = lin->Point(i);
138 gp_Pnt point = pt.PointOnS1();
139 gp_Pnt extr = point.Translated(pt.TangentOnS1());
140 p3d = new Draw_Marker3D(point,Draw_Square,Draw_rouge);
142 tg3d = new Draw_Segment3D(point,extr,Draw_rouge);
144 point = pt.PointOnS2();
145 extr = point.Translated(pt.TangentOnS2());
146 p3d = new Draw_Marker3D(point,Draw_Plus,Draw_jaune);
148 tg3d = new Draw_Segment3D(point,extr,Draw_jaune);
152 pt.ParametersOnS1(u,v);
153 gp_Pnt2d point2d(u,v);
154 gp_Pnt2d extr2d = point2d.Translated(pt.Tangent2dOnS1());
155 p2d = new Draw_Marker2D(point2d,Draw_Square,Draw_rouge);
157 tg2d = new Draw_Segment2D(point2d,extr2d,Draw_rouge);
159 pt.ParametersOnS2(u,v);
160 point2d.SetCoord(u,v);
161 extr2d = point2d.Translated(pt.Tangent2dOnS2());
162 p2d = new Draw_Marker2D(point2d,Draw_Plus,Draw_jaune);
164 tg2d = new Draw_Segment2D(point2d,extr2d,Draw_jaune);
170 //=======================================================================
171 //function : SearchIndex
174 //=======================================================================
175 static Standard_Integer SearchIndex(const Standard_Real Value,
176 Handle(BRepBlend_Line)& Lin)
178 Standard_Integer NbPnt = Lin->NbPoints(), Ind;
181 (Ind < NbPnt) && (Lin->Point(Ind).Parameter() < Value); )
187 //=======================================================================
191 //=======================================================================
192 static Standard_Integer nbedconnex(const TopTools_ListOfShape& L)
194 Standard_Integer nb = 0, i = 0;
195 TopTools_ListIteratorOfListOfShape It1(L);
196 for(;It1.More();It1.Next(),i++){
197 const TopoDS_Shape& curs = It1.Value();
198 Standard_Boolean dejavu = 0;
199 TopTools_ListIteratorOfListOfShape It2(L);
200 for(Standard_Integer j = 0; j < i && It2.More(); j++, It2.Next()){
201 if(curs.IsSame(It2.Value())){
211 static Standard_Boolean IsVois(const TopoDS_Edge& E,
212 const TopoDS_Vertex& Vref,
213 const ChFiDS_Map& VEMap,
214 TopTools_MapOfShape& DONE,
215 const Standard_Integer prof,
216 const Standard_Integer profmax)
218 if(prof > profmax) return Standard_False;
219 if(DONE.Contains(E)) return Standard_False;
221 TopExp::Vertices(E,V1,V2);
222 if(Vref.IsSame(V1) || Vref.IsSame(V2)) return Standard_True;
224 const TopTools_ListOfShape& L1 = VEMap(V1);
225 Standard_Integer i1 = nbedconnex(L1);
226 TopTools_ListIteratorOfListOfShape It1(L1);
227 for(;It1.More();It1.Next()){
228 const TopoDS_Edge& curE = TopoDS::Edge(It1.Value());
230 if(IsVois(curE,Vref,VEMap,DONE,prof,profmax)) return Standard_True;
232 else if(IsVois(curE,Vref,VEMap,DONE,prof+1,profmax)) return Standard_True;
234 const TopTools_ListOfShape& L2 = VEMap(V2);
236 // Standard_Integer i2 = nbedconnex(L2);
238 TopTools_ListIteratorOfListOfShape It2(L2);
239 for(;It2.More();It2.Next()){
240 const TopoDS_Edge& curE = TopoDS::Edge(It2.Value());
242 if(IsVois(curE,Vref,VEMap,DONE,prof,profmax)) return Standard_True;
244 else if(IsVois(curE,Vref,VEMap,DONE,prof+1,profmax)) return Standard_True;
246 return Standard_False;
249 static Standard_Boolean IsObst(const ChFiDS_CommonPoint& CP,
250 const TopoDS_Vertex& Vref,
251 const ChFiDS_Map& VEMap)
253 if(!CP.IsOnArc()) return Standard_False;
254 const TopoDS_Edge& E = CP.Arc();
255 TopTools_MapOfShape DONE;
256 Standard_Integer prof = 4;
257 return !IsVois(E,Vref,VEMap,DONE,0,prof);
260 //=======================================================================
261 //function : CompParam
264 //=======================================================================
266 static void CompParam(Geom2dAdaptor_Curve Carc,
267 Handle(Geom2d_Curve) Ctg,
270 const Standard_Real prefarc,
271 const Standard_Real preftg)
273 Standard_Boolean found = 0;
274 //(1) It is checked if the provided parameters are good
275 // if pcurves have the same parameters as the spine.
276 gp_Pnt2d point = Carc.Value(prefarc);
277 Standard_Real distini = point.Distance(Ctg->Value(preftg));
278 if (distini <= Precision::PConfusion()) {
281 found = Standard_True;
286 cout<< "CompParam : bad intersection parameters"<<endl;
288 IntRes2d_IntersectionPoint int2d;
289 Geom2dInt_GInter Intersection;
290 Standard_Integer nbpt,nbseg;
291 Intersection.Perform(Geom2dAdaptor_Curve(Ctg),Carc,
292 Precision::PIntersection(),
293 Precision::PIntersection());
295 Standard_Real dist = Precision::Infinite(), p1, p2;
296 if (Intersection.IsDone()){
297 if (!Intersection.IsEmpty()){
298 nbseg = Intersection.NbSegments();
301 cout<< "segments of intersection on the restrictions"<<endl;
304 nbpt = Intersection.NbPoints();
305 for (Standard_Integer i = 1; i <= nbpt; i++) {
306 int2d = Intersection.Point(i);
307 p1 = int2d.ParamOnFirst();
308 p2 = int2d.ParamOnSecond();
309 if(Abs(prefarc - p2) < dist){
312 dist = Abs(prefarc - p2);
323 cout<<"CompParam : failed intersection PC, projection is created."<<endl;
326 Geom2dAPI_ProjectPointOnCurve projector(point,Ctg);
328 if(projector.NbPoints() == 0){
329 // This happens in some cases when there is a vertex
330 // at the end of spine...
333 cout<<"CompParam : failed proj p2d/c2d, the extremity is taken!" <<endl;
337 // It is checked if everything was calculated correctly (EDC402 C2)
338 if (projector.LowerDistance() < distini)
339 ptg = projector.LowerDistanceParameter();
345 //=======================================================================
346 //function : CompBlendPoint
347 //purpose : create BlendPoint corresponding to a tangency on Vertex
348 // pmn : 15/10/1997 : returns false, if there is no pcurve
349 //=======================================================================
351 static Standard_Boolean CompBlendPoint(const TopoDS_Vertex& V,
352 const TopoDS_Edge& E,
353 const Standard_Real W,
354 const TopoDS_Face F1,
355 const TopoDS_Face F2,
360 Standard_Real param, f, l;
361 Handle(Geom2d_Curve) pc;
363 P3d = BRep_Tool::Pnt(V);
364 param = BRep_Tool::Parameter(V,E,F1);
365 pc = BRep_Tool::CurveOnSurface(E,F1,f,l);
366 if (pc.IsNull()) return Standard_False;
367 P1 = pc->Value(param);
368 param = BRep_Tool::Parameter(V,E,F2);
369 pc = BRep_Tool::CurveOnSurface(E,F2,f,l);
370 if (pc.IsNull()) return Standard_False;
371 P2 = pc->Value(param);
372 BP.SetValue(P3d, P3d, W, P1.X(), P1.Y(), P2.X(), P2.Y());
373 return Standard_True;
376 //=======================================================================
377 //function : UpdateLine
378 //purpose : Updates extremities after a partial invalidation
379 //=======================================================================
381 static void UpdateLine(Handle(BRepBlend_Line)& Line,
382 const Standard_Boolean isfirst)
384 Standard_Real tguide, U, V;
386 const Blend_Point& BP = Line->Point(1);
387 tguide = BP.Parameter();
388 if (Line->StartPointOnFirst().ParameterOnGuide() < tguide) {
389 BRepBlend_Extremity BE;
390 BP.ParametersOnS1(U, V);
391 BE.SetValue(BP.PointOnS1(), U, V, Precision::Confusion());
392 Line->SetStartPoints(BE, Line->StartPointOnSecond());
394 if (Line->StartPointOnSecond().ParameterOnGuide() < tguide) {
395 BRepBlend_Extremity BE;
396 BP.ParametersOnS2(U, V);
397 BE.SetValue(BP.PointOnS2(), U, V, Precision::Confusion());
398 Line->SetStartPoints(Line->StartPointOnFirst(), BE);
402 const Blend_Point& BP = Line->Point(Line->NbPoints());
403 tguide = BP.Parameter();
404 if (Line->EndPointOnFirst().ParameterOnGuide() > tguide) {
405 BRepBlend_Extremity BE;
406 BP.ParametersOnS1(U, V);
407 BE.SetValue(BP.PointOnS1(), U, V, Precision::Confusion());
408 Line->SetEndPoints(BE, Line->EndPointOnSecond());
410 if (Line->EndPointOnSecond().ParameterOnGuide() > tguide) {
411 BRepBlend_Extremity BE;
412 BP.ParametersOnS2(U, V);
413 BE.SetValue(BP.PointOnS2(), U, V, Precision::Confusion());
414 Line->SetEndPoints(Line->EndPointOnFirst(), BE);
419 //=======================================================================
420 //function : CompleteData
421 //purpose : Calculates curves and CommonPoints from the data
422 // calculated by filling.
423 //=======================================================================
425 Standard_Boolean ChFi3d_Builder::CompleteData
426 (Handle(ChFiDS_SurfData)& Data,
427 const Handle(Geom_Surface)& Surfcoin,
428 const Handle(Adaptor3d_HSurface)& S1,
429 const Handle(Geom2d_Curve)& PC1,
430 const Handle(Adaptor3d_HSurface)& S2,
431 const Handle(Geom2d_Curve)& PC2,
432 const TopAbs_Orientation Or,
433 const Standard_Boolean On1,
434 const Standard_Boolean Gd1,
435 const Standard_Boolean Gd2,
436 const Standard_Boolean Gf1,
437 const Standard_Boolean Gf2)
439 TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
440 Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surfcoin,tolesp)));
442 ChFi3d_SettraceDRAWFIL(Standard_True);
443 if (ChFi3d_GettraceDRAWFIL()) {
446 char* name = new char[100];
447 sprintf(name,"%s_%d","Surf",IndexOfConge);
448 DrawTrSurf::Set(name,Surfcoin);
452 Standard_Real UFirst,ULast,VFirst,VLast;
453 Surfcoin->Bounds(UFirst,ULast,VFirst,VLast);
454 if(!Gd1) Data->ChangeVertexFirstOnS1().SetPoint(Surfcoin->Value(UFirst,VFirst));
455 if(!Gd2) Data->ChangeVertexFirstOnS2().SetPoint(Surfcoin->Value(UFirst,VLast));
456 if(!Gf1) Data->ChangeVertexLastOnS1().SetPoint(Surfcoin->Value(ULast,VFirst));
457 if(!Gf2) Data->ChangeVertexLastOnS2().SetPoint(Surfcoin->Value(ULast,VLast));
459 //calculate curves side S1
460 Handle(Geom_Curve) Crv3d1;
461 if(!PC1.IsNull()) Crv3d1= Surfcoin->VIso(VFirst);
462 gp_Pnt2d pd1(UFirst,VFirst), pf1(ULast,VFirst);
463 gp_Lin2d lfil1(pd1,gp_Dir2d(gp_Vec2d(pd1,pf1)));
464 Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1);
465 TopAbs_Orientation tra1 = TopAbs_FORWARD, orsurf = Or;
466 Standard_Real x,y,w = 0.5*(UFirst+ULast);
469 Handle(Geom2d_Curve) c2dtrim;
470 Standard_Real tolreached = 1.e-5;
472 Handle(GeomAdaptor_HCurve) hcS1 = new GeomAdaptor_HCurve(Crv3d1);
473 c2dtrim = new Geom2d_TrimmedCurve(PC1,UFirst,ULast);
474 ChFi3d_SameParameter(hcS1,c2dtrim,S1,tolapp3d,tolreached);
475 c2dtrim->Value(w).Coord(x,y);
477 gp_Vec nf = du.Crossed(dv);
478 Surfcoin->D1(w,VFirst,p,du,dv);
479 gp_Vec ns = du.Crossed(dv);
480 if(nf.Dot(ns) > 0.) tra1 = TopAbs_REVERSED;
481 else if(On1) orsurf = TopAbs::Reverse(orsurf);
483 Standard_Integer Index1OfCurve =
484 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolreached));
485 ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1();
486 Fint1.SetFirstParameter(UFirst);
487 Fint1.SetLastParameter(ULast);
488 Fint1.SetInterference(Index1OfCurve,tra1,c2dtrim,PCurveOnSurf);
489 //calculate curves side S2
490 Handle(Geom_Curve) Crv3d2;
491 if(!PC2.IsNull()) Crv3d2 = Surfcoin->VIso(VLast);
492 gp_Pnt2d pd2(UFirst,VLast), pf2(ULast,VLast);
493 gp_Lin2d lfil2(pd2,gp_Dir2d(gp_Vec2d(pd2,pf2)));
494 PCurveOnSurf = new Geom2d_Line(lfil2);
495 TopAbs_Orientation tra2 = TopAbs_FORWARD;
497 Handle(GeomAdaptor_HCurve) hcS2 = new GeomAdaptor_HCurve(Crv3d2);
498 c2dtrim = new Geom2d_TrimmedCurve(PC2,UFirst,ULast);
499 ChFi3d_SameParameter(hcS2,c2dtrim,S2,tolapp3d,tolreached);
500 c2dtrim->Value(w).Coord(x,y);
502 gp_Vec np = du.Crossed(dv);
503 Surfcoin->D1(w,VLast,p,du,dv);
504 gp_Vec ns = du.Crossed(dv);
505 if(np.Dot(ns) < 0.) {
506 tra2 = TopAbs_REVERSED;
507 if(!On1) orsurf = TopAbs::Reverse(orsurf);
510 Standard_Integer Index2OfCurve =
511 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolreached));
512 ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2();
513 Fint2.SetFirstParameter(UFirst);
514 Fint2.SetLastParameter(ULast);
515 Fint2.SetInterference(Index2OfCurve,tra2,c2dtrim,PCurveOnSurf);
516 Data->ChangeOrientation() = orsurf;
517 return Standard_True;
520 //=======================================================================
521 //function : CompleteData
522 //purpose : Calculates the surface of curves and eventually
523 // CommonPoints from the data calculated in ComputeData.
525 // 11/08/1996 : Use of F(t)
527 //=======================================================================
529 Standard_Boolean ChFi3d_Builder::CompleteData
530 (Handle(ChFiDS_SurfData)& Data,
531 Blend_Function& Func,
532 Handle(BRepBlend_Line)& lin,
533 const Handle(Adaptor3d_HSurface)& S1,
534 const Handle(Adaptor3d_HSurface)& S2,
535 const TopAbs_Orientation Or1,
536 const Standard_Boolean Gd1,
537 const Standard_Boolean Gd2,
538 const Standard_Boolean Gf1,
539 const Standard_Boolean Gf2,
540 const Standard_Boolean Reversed)
542 Handle(BRepBlend_AppFunc) TheFunc
543 = new (BRepBlend_AppFunc)(lin, Func, tolapp3d, 1.e-5);
545 Standard_Integer Degmax = 20, Segmax = 5000;
546 BRepBlend_AppSurface approx (TheFunc,
547 lin->Point(1).Parameter(),
548 lin->Point(lin->NbPoints()).Parameter(),
549 tolapp3d, 1.e-5, //tolapp2d, tolerance max
550 tolappangle, // Contact G1
551 myConti, Degmax, Segmax);
552 if (!approx.IsDone()) {
554 cout << "Approximation non faite !!!" << endl;
556 return Standard_False;
561 return StoreData( Data, approx, lin, S1, S2, Or1, Gd1, Gd2, Gf1, Gf2, Reversed);
565 //=======================================================================
566 //function : CompleteData
567 //purpose : New overload for functions surf/rst
568 // jlr le 28/07/97 branchement F(t)
569 //=======================================================================
571 Standard_Boolean ChFi3d_Builder::CompleteData
572 (Handle(ChFiDS_SurfData)& Data,
573 Blend_SurfRstFunction& Func,
574 Handle(BRepBlend_Line)& lin,
575 const Handle(Adaptor3d_HSurface)& S1,
576 const Handle(Adaptor3d_HSurface)& S2,
577 const TopAbs_Orientation Or,
578 const Standard_Boolean Reversed)
580 Handle(BRepBlend_AppFuncRst) TheFunc
581 = new (BRepBlend_AppFuncRst)(lin, Func, tolapp3d, 1.e-5);
582 BRepBlend_AppSurface approx (TheFunc,
583 lin->Point(1).Parameter(),
584 lin->Point(lin->NbPoints()).Parameter(),
585 tolapp3d, 1.e-5, //tolapp2d, tolerance max
586 tolappangle, // Contact G1
588 if (!approx.IsDone()) {
590 cout << "Approximation is not done!" << endl;
592 return Standard_False;
598 return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0,Reversed);
603 //=======================================================================
604 //function : CompleteData
605 //purpose : New overload for functions rst/rst
606 // jlr le 28/07/97 branchement F(t)
607 //=======================================================================
609 Standard_Boolean ChFi3d_Builder::CompleteData
610 (Handle(ChFiDS_SurfData)& Data,
611 Blend_RstRstFunction& Func,
612 Handle(BRepBlend_Line)& lin,
613 const Handle(Adaptor3d_HSurface)& S1,
614 const Handle(Adaptor3d_HSurface)& S2,
615 const TopAbs_Orientation Or)
617 Handle(BRepBlend_AppFuncRstRst) TheFunc
618 = new (BRepBlend_AppFuncRstRst)(lin, Func, tolapp3d, 1.e-5);
619 BRepBlend_AppSurface approx (TheFunc,
620 lin->Point(1).Parameter(),
621 lin->Point(lin->NbPoints()).Parameter(),
622 tolapp3d, 1.e-5, //tolapp2d, tolerance max
623 tolappangle, // Contact G1
625 if (!approx.IsDone()) {
627 cout << "Approximation non faite !!!" << endl;
629 return Standard_False;
635 return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0);
641 //=======================================================================
642 //function : StoreData
643 //purpose : Copy of an approximation result in SurfData.
644 //=======================================================================
646 Standard_Boolean ChFi3d_Builder::StoreData(Handle(ChFiDS_SurfData)& Data,
647 const AppBlend_Approx& approx,
648 const Handle(BRepBlend_Line)& lin,
649 const Handle(Adaptor3d_HSurface)& S1,
650 const Handle(Adaptor3d_HSurface)& S2,
651 const TopAbs_Orientation Or1,
652 const Standard_Boolean Gd1,
653 const Standard_Boolean Gd2,
654 const Standard_Boolean Gf1,
655 const Standard_Boolean Gf2,
656 const Standard_Boolean Reversed)
658 // Small control tools.
659 static Handle(GeomAdaptor_HCurve) checkcurve;
660 if(checkcurve.IsNull()) checkcurve = new GeomAdaptor_HCurve();
661 GeomAdaptor_Curve& chc = checkcurve->ChangeCurve();
662 Standard_Real tolget3d, tolget2d, tolaux, tolC1, tolcheck;
663 Standard_Real tolC2 = 0.;
664 approx.TolReached(tolget3d, tolget2d);
665 tolaux = approx.TolCurveOnSurf(1);
666 tolC1 = tolget3d + tolaux;
668 tolaux = approx.TolCurveOnSurf(2);
669 tolC2 = tolget3d + tolaux;
672 TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
673 // By default parametric space is created using a square surface
674 // to be able to parameterize in U by # R*teta // a revoir lbo 29/08/97
675 const TColStd_Array1OfReal& ku = approx.SurfUKnots();
676 const TColStd_Array1OfReal& kv = approx.SurfVKnots();
677 Standard_Real larg = (kv(kv.Upper())-kv(kv.Lower()));
678 TColStd_Array1OfReal& kku = *((TColStd_Array1OfReal*)((void*)&ku));
679 BSplCLib::Reparametrize(0.,larg,kku);
680 Handle(Geom_BSplineSurface) Surf =
681 new Geom_BSplineSurface(approx.SurfPoles(),approx.SurfWeights(),
683 approx.SurfUMults(),approx.SurfVMults(),
684 approx.UDegree(),approx.VDegree());
685 // extension of the surface
687 Standard_Real length1,length2;
688 length1=Data->FirstExtensionValue();
689 length2=Data->LastExtensionValue();
691 Handle(Geom_BoundedSurface) aBndSurf = Surf;
692 if (length1 > Precision::Confusion())
693 GeomLib::ExtendSurfByLength(aBndSurf,length1,1,Standard_False,Standard_False);
694 if (length2 > Precision::Confusion())
695 GeomLib::ExtendSurfByLength(aBndSurf,length2,1,Standard_False,Standard_True);
696 Surf = Handle(Geom_BSplineSurface)::DownCast (aBndSurf);
698 //Correction of surface on extremities
699 if (length1 <= Precision::Confusion())
702 P11 = lin->StartPointOnFirst().Value();
703 P21 = lin->StartPointOnSecond().Value();
704 Surf->SetPole(1, 1, P11);
705 Surf->SetPole(Surf->NbUPoles(), 1, P21);
707 if (length2 <= Precision::Confusion())
710 P12 = lin->EndPointOnFirst().Value();
711 P22 = lin->EndPointOnSecond().Value();
712 Surf->SetPole(1, Surf->NbVPoles(), P12);
713 Surf->SetPole(Surf->NbUPoles(), Surf->NbVPoles(), P22);
716 Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surf,tolget3d)));
719 ChFi3d_SettraceDRAWFIL(Standard_True);
720 if (ChFi3d_GettraceDRAWFIL()) {
723 char* name=new char[100];
724 sprintf(name,"%s_%d","Surf",IndexOfConge);
725 DrawTrSurf::Set(name,Surf);
728 Standard_Real UFirst,ULast,VFirst,VLast,pppdeb,pppfin;
729 Surf->Bounds(UFirst,ULast,VFirst,VLast);
730 BRepAdaptor_Curve2d brc;
731 BRepAdaptor_Curve CArc;
732 Handle(BRepAdaptor_HSurface)
733 BS1 = Handle(BRepAdaptor_HSurface)::DownCast(S1);
734 Handle(BRepAdaptor_HSurface)
735 BS2 = Handle(BRepAdaptor_HSurface)::DownCast(S2);
736 Geom2dAPI_ProjectPointOnCurve projector;
738 Standard_Real Uon1 = UFirst, Uon2 = ULast;
739 Standard_Integer ion1 = 1, ion2 = 2;
740 if(Reversed) { Uon1 = ULast; Uon2 = UFirst; ion1 = 2; ion2 = 1; }
742 // The SurfData is filled in what concerns S1,
743 Handle(Geom_Curve) Crv3d1 = Surf->UIso(Uon1);
744 gp_Pnt2d pori1(Uon1,0.);
745 gp_Lin2d lfil1(pori1,gp::DY2d());
746 Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1);
747 Handle(Geom2d_Curve) PCurveOnFace;
749 Geom2d_BSplineCurve(approx.Curve2dPoles(ion1),approx.Curves2dKnots(),
750 approx.Curves2dMults(),approx.Curves2dDegree());
753 Standard_Real par1=PCurveOnFace->FirstParameter();
754 Standard_Real par2= PCurveOnFace->LastParameter();
755 chc.Load(Crv3d1,par1,par2);
757 if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S1,tolC1,tolcheck)){
759 cout<<"aaproximate tolerance under-valued : "<<tolC1<<" for "<<tolcheck<<endl;
763 Standard_Integer Index1OfCurve =
764 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolC1));
766 Standard_Real uarc,utg;
768 TopoDS_Face forwfac = BS1->ChangeSurface().Face();
769 forwfac.Orientation(TopAbs_FORWARD);
770 brc.Initialize(Data->VertexFirstOnS1().Arc(),forwfac);
771 ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS1();
772 CArc.Initialize(V.Arc());
773 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
774 tolcheck = CArc.Value(uarc).Distance(V.Point());
775 V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
778 else pppdeb = VFirst;
780 TopoDS_Face forwfac = BS1->ChangeSurface().Face();
781 forwfac.Orientation(TopAbs_FORWARD);
782 ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS1();
783 brc.Initialize(V.Arc(),forwfac);
784 CArc.Initialize(V.Arc());
785 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
786 tolcheck = CArc.Value(uarc).Distance(V.Point());
787 V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
791 ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1();
792 Fint1.SetFirstParameter(pppdeb);
793 Fint1.SetLastParameter(pppfin);
794 TopAbs_Orientation TraOn1;
795 if(Reversed) TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
796 else TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
797 Fint1.SetInterference(Index1OfCurve,TraOn1,PCurveOnFace,PCurveOnSurf);
799 // SurfData is filled in what concerns S2,
800 Handle(Geom_Curve) Crv3d2 = Surf->UIso(Uon2);
801 gp_Pnt2d pori2(Uon2,0.);
802 gp_Lin2d lfil2(pori2,gp::DY2d());
803 PCurveOnSurf = new Geom2d_Line(lfil2);
805 PCurveOnFace = new Geom2d_BSplineCurve(approx.Curve2dPoles(ion2),
806 approx.Curves2dKnots(),
807 approx.Curves2dMults(),
808 approx.Curves2dDegree());
809 chc.Load(Crv3d2,par1,par2);
810 if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S2,tolC2,tolcheck)){
812 cout<<"approximate tolerance under-evaluated : "<<tolC2<<" for "<<tolcheck<<endl;
817 Standard_Integer Index2OfCurve =
818 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolC2));
820 TopoDS_Face forwfac = BS2->ChangeSurface().Face();
821 forwfac.Orientation(TopAbs_FORWARD);
822 brc.Initialize(Data->VertexFirstOnS2().Arc(),forwfac);
823 ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS2();
824 CArc.Initialize(V.Arc());
825 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
826 tolcheck = CArc.Value(uarc).Distance(V.Point());
827 V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
830 else pppdeb = VFirst;
832 TopoDS_Face forwfac = BS2->ChangeSurface().Face();
833 forwfac.Orientation(TopAbs_FORWARD);
834 brc.Initialize(Data->VertexLastOnS2().Arc(),forwfac);
835 ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS2();
836 CArc.Initialize(V.Arc());
837 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
838 tolcheck = CArc.Value(uarc).Distance(V.Point());
839 V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
843 ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2();
844 Fint2.SetFirstParameter(pppdeb);
845 Fint2.SetLastParameter(pppfin);
847 TopAbs_Orientation TraOn2;
848 if(Reversed) TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
849 else TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
850 Fint2.SetInterference(Index2OfCurve,TraOn2,PCurveOnFace,PCurveOnSurf);
853 Handle(Geom2d_Curve) bidpc;
854 Fint2.SetInterference
855 (Index2OfCurve,TopAbs_FORWARD,bidpc,PCurveOnSurf);
858 // the orientation of the fillet in relation to the faces is evaluated,
860 Handle(Adaptor3d_HSurface) Sref = S1;
861 PCurveOnFace = Fint1.PCurveOnFace();
862 if(Reversed){ Sref = S2; PCurveOnFace = Fint2.PCurveOnFace(); }
864 // Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898 Begin
865 // gp_Pnt2d PUV = PCurveOnFace->Value((VFirst+VLast)/2.);
867 // gp_Vec Du1,Du2,Dv1,Dv2;
868 // Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
870 // if (Or1 == TopAbs_REVERSED) Du1.Reverse();
871 // Surf->D1(UFirst,(VFirst+VLast)/2.,P,Du2,Dv2);
873 // if (Du1.Dot(Du2)>0) Data->ChangeOrientation() = TopAbs_FORWARD;
874 // else Data->ChangeOrientation() = TopAbs_REVERSED;
876 Standard_Real aDelta = VLast - VFirst;
877 Standard_Integer aDenom = 2;
880 Standard_Real aDeltav = aDelta/aDenom;
881 Standard_Real aParam = VFirst + aDeltav;
882 gp_Pnt2d PUV = PCurveOnFace->Value(aParam);
884 gp_Vec Du1,Du2,Dv1,Dv2;
886 Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
889 if (Or1 == TopAbs_REVERSED)
892 Surf->D1(UFirst, aParam, P, Du2, Dv2);
895 if (Du1.Magnitude() <= tolget3d ||
896 Du2.Magnitude() <= tolget3d) {
899 if (Abs(aDeltav) <= tolget2d)
900 return Standard_False;
906 Data->ChangeOrientation() = TopAbs_FORWARD;
908 Data->ChangeOrientation() = TopAbs_REVERSED;
912 // Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898 End
914 if(!Gd1 && !S1.IsNull())
915 ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(),
916 Standard_True, Data->ChangeVertex(1,ion1),tolC1);
917 if(!Gf1 && !S1.IsNull())
918 ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(),
919 Standard_False,Data->ChangeVertex(0,ion1),tolC1);
920 if(!Gd2 && !S2.IsNull())
921 ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(),
922 Standard_True, Data->ChangeVertex(1,ion2),tolC2);
923 if(!Gf2 && !S2.IsNull())
924 ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(),
925 Standard_False, Data->ChangeVertex(0,ion2),tolC2);
926 // Parameters on ElSpine
927 Standard_Integer nbp = lin->NbPoints();
928 Data->FirstSpineParam(lin->Point(1).Parameter());
929 Data->LastSpineParam(lin->Point(nbp).Parameter());
930 return Standard_True;
935 //=======================================================================
936 //function : ComputeData
937 //purpose : Head of the path edge/face for the bypass of obstacle.
938 //=======================================================================
940 Standard_Boolean ChFi3d_Builder::ComputeData
941 (Handle(ChFiDS_SurfData)& Data,
942 const Handle(ChFiDS_HElSpine)& HGuide,
943 Handle(BRepBlend_Line)& Lin,
944 const Handle(Adaptor3d_HSurface)& S1,
945 const Handle(Adaptor3d_TopolTool)& I1,
946 const Handle(Adaptor3d_HSurface)& S2,
947 const Handle(Adaptor2d_HCurve2d)& PC2,
948 const Handle(Adaptor3d_TopolTool)& I2,
949 Standard_Boolean& Decroch,
950 Blend_SurfRstFunction& Func,
952 Blend_SurfPointFuncInv& FInvP,
953 Blend_SurfCurvFuncInv& FInvC,
954 const Standard_Real PFirst,
955 const Standard_Real MaxStep,
956 const Standard_Real Fleche,
957 const Standard_Real TolGuide,
958 Standard_Real& First,
960 const math_Vector& Soldep,
961 const Standard_Boolean Inside,
962 const Standard_Boolean Appro,
963 const Standard_Boolean Forward,
964 const Standard_Boolean RecP,
965 const Standard_Boolean RecS,
966 const Standard_Boolean RecRst)
968 BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
970 Data->FirstExtensionValue(0);
971 Data->LastExtensionValue(0);
973 Standard_Boolean reverse = (!Forward || Inside);
974 Standard_Real SpFirst = HGuide->FirstParameter();
975 Standard_Real SpLast = HGuide->LastParameter();
976 Standard_Real Target = SpLast;
977 if(reverse) Target = SpFirst;
978 Standard_Real Targetsov = Target;
980 Standard_Real MS = MaxStep;
981 Standard_Integer again = 0;
982 Standard_Integer nbptmin = 3; //jlr
983 Standard_Integer Nbpnt = 1;
984 // the initial solution is reframed if necessary.
985 math_Vector ParSol(1,3);
986 Standard_Real NewFirst = PFirst;
987 if(RecP || RecS || RecRst){
988 if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep,
989 tolesp,TolGuide,RecRst,RecP,RecS,
992 cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<endl;
994 return Standard_False;
1002 TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last,
1003 MS,TolGuide,ParSol,tolesp,Fleche,Appro);
1005 if (!TheWalk.IsDone()) {
1007 cout << "Path not created" << endl;
1009 return Standard_False;
1013 if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) {
1015 cout << "Not completed" << endl;
1021 Lin = TheWalk.Line();
1022 Nbpnt = Lin->NbPoints();
1023 if (Nbpnt <= 1 && again == 0) {
1026 cout <<"one point of the path MS/50 is attempted."<<endl;
1028 MS = MS/50.; Target = Targetsov;
1030 else if (Nbpnt<=nbptmin && again == 0) {
1033 cout <<"Number of points is too small, the step is reduced"<<endl;
1035 Standard_Real u1 = Lin->Point(1).Parameter();
1036 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1037 MS = (u2-u1)/(nbptmin+1.0);
1038 // cout << " MS : " << MS << " u1 : " << u1 << " u2 : " << u2 << " nbptmin : " << nbptmin << endl;
1041 else if(Nbpnt<=nbptmin){
1043 cout <<"Number of points is still too small, quit"<<endl;
1045 return Standard_False;
1052 ChFi3d_SettraceDRAWWALK(Standard_True);
1053 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1055 if(Forward) Decroch = TheWalk.DecrochEnd();
1056 else Decroch = TheWalk.DecrochStart();
1057 Last = Lin->Point(Nbpnt).Parameter();
1058 First = Lin->Point(1).Parameter();
1059 return Standard_True;
1063 //=======================================================================
1064 //function : ComputeData
1065 //purpose : Heading of the path edge/edge for the bypass of obstacle.
1066 //=======================================================================
1068 Standard_Boolean ChFi3d_Builder::ComputeData
1069 (Handle(ChFiDS_SurfData)& Data,
1070 const Handle(ChFiDS_HElSpine)& HGuide,
1071 Handle(BRepBlend_Line)& Lin,
1072 const Handle(Adaptor3d_HSurface)& S1,
1073 const Handle(Adaptor2d_HCurve2d)& PC1,
1074 const Handle(Adaptor3d_TopolTool)& I1,
1075 Standard_Boolean& Decroch1,
1076 const Handle(Adaptor3d_HSurface)& S2,
1077 const Handle(Adaptor2d_HCurve2d)& PC2,
1078 const Handle(Adaptor3d_TopolTool)& I2,
1079 Standard_Boolean& Decroch2,
1080 Blend_RstRstFunction& Func,
1081 Blend_SurfCurvFuncInv& FInv1,
1082 Blend_CurvPointFuncInv& FInvP1,
1083 Blend_SurfCurvFuncInv& FInv2,
1084 Blend_CurvPointFuncInv& FInvP2,
1085 const Standard_Real PFirst,
1086 const Standard_Real MaxStep,
1087 const Standard_Real Fleche,
1088 const Standard_Real TolGuide,
1089 Standard_Real& First,
1090 Standard_Real& Last,
1091 const math_Vector& Soldep,
1092 const Standard_Boolean Inside,
1093 const Standard_Boolean Appro,
1094 const Standard_Boolean Forward,
1095 const Standard_Boolean RecP1,
1096 const Standard_Boolean RecRst1,
1097 const Standard_Boolean RecP2,
1098 const Standard_Boolean RecRst2)
1100 BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1102 Data->FirstExtensionValue(0);
1103 Data->LastExtensionValue(0);
1105 Standard_Boolean reverse = (!Forward || Inside);
1106 Standard_Real SpFirst = HGuide->FirstParameter();
1107 Standard_Real SpLast = HGuide->LastParameter();
1108 Standard_Real Target = SpLast;
1109 if(reverse) Target = SpFirst;
1110 Standard_Real Targetsov = Target;
1112 Standard_Real MS = MaxStep;
1113 Standard_Integer again = 0;
1114 Standard_Integer nbptmin = 3; //jlr
1115 Standard_Integer Nbpnt = 0;
1116 // the initial solution is reframed if necessary.
1117 math_Vector ParSol(1,2);
1118 Standard_Real NewFirst = PFirst;
1119 if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1120 if (!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1121 tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1124 cout<<"ChFi3d_Builder::ComputeData : fail calculation first section"<<endl;
1126 return Standard_False;
1134 TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1135 MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1137 if (!TheWalk.IsDone()) {
1139 cout << "Path not done" << endl;
1141 return Standard_False;
1145 if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1147 cout << "Not completed" << endl;
1153 Lin = TheWalk.Line();
1154 Nbpnt = Lin->NbPoints();
1155 if (Nbpnt <= 1 && again == 0) {
1158 cout <<"one point of path MS/50 is attempted."<<endl;
1160 MS = MS/50.; Target = Targetsov;
1162 else if (Nbpnt<=nbptmin && again == 0) {
1165 cout <<"Number of points is too small, the step is reduced"<<endl;
1167 Standard_Real u1 = Lin->Point(1).Parameter();
1168 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1169 MS = (u2-u1)/(nbptmin+1);
1172 else if(Nbpnt<=nbptmin){
1174 cout <<"Number of points is still too small, quit"<<endl;
1176 return Standard_False;
1183 ChFi3d_SettraceDRAWWALK(Standard_True);
1184 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1187 Decroch1 = TheWalk.Decroch1End();
1188 Decroch2 = TheWalk.Decroch2End();
1191 Decroch1 = TheWalk.Decroch1Start();
1192 Decroch2 = TheWalk.Decroch2Start();
1194 Last = Lin->Point(Nbpnt).Parameter();
1195 First = Lin->Point(1).Parameter();
1196 return Standard_True;
1200 //=======================================================================
1201 //function : SimulData
1202 //purpose : Heading of the path edge/face for the bypass of obstacle in simulation mode.
1203 //=======================================================================
1205 Standard_Boolean ChFi3d_Builder::SimulData
1206 (Handle(ChFiDS_SurfData)& /*Data*/,
1207 const Handle(ChFiDS_HElSpine)& HGuide,
1208 Handle(BRepBlend_Line)& Lin,
1209 const Handle(Adaptor3d_HSurface)& S1,
1210 const Handle(Adaptor3d_TopolTool)& I1,
1211 const Handle(Adaptor3d_HSurface)& S2,
1212 const Handle(Adaptor2d_HCurve2d)& PC2,
1213 const Handle(Adaptor3d_TopolTool)& I2,
1214 Standard_Boolean& Decroch,
1215 Blend_SurfRstFunction& Func,
1216 Blend_FuncInv& FInv,
1217 Blend_SurfPointFuncInv& FInvP,
1218 Blend_SurfCurvFuncInv& FInvC,
1219 const Standard_Real PFirst,
1220 const Standard_Real MaxStep,
1221 const Standard_Real Fleche,
1222 const Standard_Real TolGuide,
1223 Standard_Real& First,
1224 Standard_Real& Last,
1225 const math_Vector& Soldep,
1226 const Standard_Integer NbSecMin,
1227 const Standard_Boolean Inside,
1228 const Standard_Boolean Appro,
1229 const Standard_Boolean Forward,
1230 const Standard_Boolean RecP,
1231 const Standard_Boolean RecS,
1232 const Standard_Boolean RecRst)
1234 BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
1236 Standard_Boolean reverse = (!Forward || Inside);
1237 Standard_Real SpFirst = HGuide->FirstParameter();
1238 Standard_Real SpLast = HGuide->LastParameter();
1239 Standard_Real Target = SpLast;
1240 if(reverse) Target = SpFirst;
1241 Standard_Real Targetsov = Target;
1243 Standard_Real MS = MaxStep;
1244 Standard_Integer again = 0;
1245 Standard_Integer Nbpnt = 0;
1246 // the starting solution is reframed if needed.
1247 math_Vector ParSol(1,3);
1248 Standard_Real NewFirst = PFirst;
1249 if(RecP || RecS || RecRst){
1250 if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep,
1251 tolesp,TolGuide,RecRst,RecP,RecS,
1255 cout<<"ChFi3d_Builder::SimulData : fail calculate first section"<<endl;
1257 return Standard_False;
1265 TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last,
1266 MS,TolGuide,ParSol,tolesp,Fleche,Appro);
1267 if (!TheWalk.IsDone()) {
1269 cout << "Path not done" << endl;
1271 return Standard_False;
1274 if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) {
1276 cout << "Not completed" << endl;
1280 Lin = TheWalk.Line();
1281 Nbpnt = Lin->NbPoints();
1282 if (Nbpnt <= 1 && again == 0) {
1285 cout <<"one point of path MS/50 is attempted."<<endl;
1287 MS = MS/50.; Target = Targetsov;
1289 else if (Nbpnt <= NbSecMin && again == 0) {
1292 cout <<"Number of points is too small, the step is reduced"<<endl;
1294 Standard_Real u1 = Lin->Point(1).Parameter();
1295 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1296 MS = (u2-u1)/(NbSecMin+1);
1299 else if(Nbpnt<=NbSecMin){
1301 cout <<"Number of points is still too small, quit"<<endl;
1303 return Standard_False;
1310 ChFi3d_SettraceDRAWWALK(Standard_True);
1311 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1313 if(Forward) Decroch = TheWalk.DecrochEnd();
1314 else Decroch = TheWalk.DecrochStart();
1315 Last = Lin->Point(Nbpnt).Parameter();
1316 First = Lin->Point(1).Parameter();
1317 return Standard_True;
1321 //=======================================================================
1322 //function : SimulData
1323 //purpose : Heading of path edge/edge for the bypass
1324 // of obstacle in simulation mode.
1325 //=======================================================================
1327 Standard_Boolean ChFi3d_Builder::SimulData
1328 (Handle(ChFiDS_SurfData)& /*Data*/,
1329 const Handle(ChFiDS_HElSpine)& HGuide,
1330 Handle(BRepBlend_Line)& Lin,
1331 const Handle(Adaptor3d_HSurface)& S1,
1332 const Handle(Adaptor2d_HCurve2d)& PC1,
1333 const Handle(Adaptor3d_TopolTool)& I1,
1334 Standard_Boolean& Decroch1,
1335 const Handle(Adaptor3d_HSurface)& S2,
1336 const Handle(Adaptor2d_HCurve2d)& PC2,
1337 const Handle(Adaptor3d_TopolTool)& I2,
1338 Standard_Boolean& Decroch2,
1339 Blend_RstRstFunction& Func,
1340 Blend_SurfCurvFuncInv& FInv1,
1341 Blend_CurvPointFuncInv& FInvP1,
1342 Blend_SurfCurvFuncInv& FInv2,
1343 Blend_CurvPointFuncInv& FInvP2,
1344 const Standard_Real PFirst,
1345 const Standard_Real MaxStep,
1346 const Standard_Real Fleche,
1347 const Standard_Real TolGuide,
1348 Standard_Real& First,
1349 Standard_Real& Last,
1350 const math_Vector& Soldep,
1351 const Standard_Integer NbSecMin,
1352 const Standard_Boolean Inside,
1353 const Standard_Boolean Appro,
1354 const Standard_Boolean Forward,
1355 const Standard_Boolean RecP1,
1356 const Standard_Boolean RecRst1,
1357 const Standard_Boolean RecP2,
1358 const Standard_Boolean RecRst2)
1360 BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1362 Standard_Boolean reverse = (!Forward || Inside);
1363 Standard_Real SpFirst = HGuide->FirstParameter();
1364 Standard_Real SpLast = HGuide->LastParameter();
1365 Standard_Real Target = SpLast;
1366 if(reverse) Target = SpFirst;
1367 Standard_Real Targetsov = Target;
1369 Standard_Real MS = MaxStep;
1370 Standard_Integer again = 0;
1371 Standard_Integer Nbpnt = 0;
1372 // The initial solution is reframed if necessary.
1373 math_Vector ParSol(1,2);
1374 Standard_Real NewFirst = PFirst;
1375 if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1376 if(!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1377 tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1381 cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<endl;
1383 return Standard_False;
1391 TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1392 MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1393 if (!TheWalk.IsDone()) {
1395 cout << "Path not created" << endl;
1397 return Standard_False;
1400 if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1402 cout << "Not completed" << endl;
1406 Lin = TheWalk.Line();
1407 Nbpnt = Lin->NbPoints();
1408 if (Nbpnt <= 1 && again == 0) {
1411 cout <<"only one point of path MS/50 is attempted."<<endl;
1413 MS = MS/50.; Target = Targetsov;
1415 else if (Nbpnt <= NbSecMin && again == 0) {
1418 cout <<"Number of points is too small, the step is reduced"<<endl;
1420 Standard_Real u1 = Lin->Point(1).Parameter();
1421 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1422 MS = (u2-u1)/(NbSecMin+1);
1425 else if(Nbpnt<=NbSecMin){
1427 cout <<"Number of points is still too small, quit"<<endl;
1429 return Standard_False;
1436 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1439 Decroch1 = TheWalk.Decroch1End();
1440 Decroch2 = TheWalk.Decroch2End();
1443 Decroch1 = TheWalk.Decroch1Start();
1444 Decroch2 = TheWalk.Decroch2Start();
1447 Last = Lin->Point(Nbpnt).Parameter();
1448 First = Lin->Point(1).Parameter();
1449 return Standard_True;
1455 //=======================================================================
1456 //function : ComputeData
1457 //purpose : Construction of elementary fillet by path.
1459 //=======================================================================
1461 Standard_Boolean ChFi3d_Builder::ComputeData
1462 (Handle(ChFiDS_SurfData)& Data,
1463 const Handle(ChFiDS_HElSpine)& HGuide,
1464 const Handle(ChFiDS_Spine)& Spine,
1465 Handle(BRepBlend_Line)& Lin,
1466 const Handle(Adaptor3d_HSurface)& S1,
1467 const Handle(Adaptor3d_TopolTool)& I1,
1468 const Handle(Adaptor3d_HSurface)& S2,
1469 const Handle(Adaptor3d_TopolTool)& I2,
1470 Blend_Function& Func,
1471 Blend_FuncInv& FInv,
1472 const Standard_Real PFirst,
1473 const Standard_Real MaxStep,
1474 const Standard_Real Fleche,
1475 const Standard_Real tolguide,
1476 Standard_Real& First,
1477 Standard_Real& Last,
1478 const Standard_Boolean Inside,
1479 const Standard_Boolean Appro,
1480 const Standard_Boolean Forward,
1481 const math_Vector& Soldep,
1482 Standard_Boolean& intf,
1483 Standard_Boolean& intl,
1484 Standard_Boolean& Gd1,
1485 Standard_Boolean& Gd2,
1486 Standard_Boolean& Gf1,
1487 Standard_Boolean& Gf2,
1488 const Standard_Boolean RecOnS1,
1489 const Standard_Boolean RecOnS2)
1491 //The extrensions are created in case of output of two domains
1492 //directly and not by path ( too hasardous ).
1493 Data->FirstExtensionValue(0);
1494 Data-> LastExtensionValue(0);
1496 //The eventual faces are restored to test the jump of edge.
1498 Handle(BRepAdaptor_HSurface) HS = Handle(BRepAdaptor_HSurface)::DownCast(S1);
1499 if(!HS.IsNull()) F1 = HS->ChangeSurface().Face();
1500 HS = Handle(BRepAdaptor_HSurface)::DownCast(S2);
1501 if(!HS.IsNull()) F2 = HS->ChangeSurface().Face();
1503 // Path framing variables
1504 Standard_Real TolGuide=tolguide, TolEsp = tolesp;
1505 Standard_Integer nbptmin = 4;
1507 BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide);
1509 //Start of removal, 2D path controls
1510 //that qui s'accomodent mal des surfaces a parametrages non homogenes
1511 //en u et en v are extinguished.
1514 Standard_Real MS = MaxStep;
1515 Standard_Integer Nbpnt;
1516 Standard_Real SpFirst = HGuide->FirstParameter();
1517 Standard_Real SpLast = HGuide->LastParameter();
1519 // When the start point is inside, the path goes first to the left
1520 // to determine the Last for the periodicals.
1521 Standard_Boolean reverse = (!Forward || Inside);
1522 Standard_Real Target;
1525 if(!intf) Target = Last;
1528 Target = SpLast + Abs(SpLast);
1529 if(!intl) Target = Last;
1532 // In case if the singularity is pre-determined,
1533 // the path is indicated.
1534 if (!Spine.IsNull()){
1535 if (Spine->IsTangencyExtremity(Standard_True)) {
1536 TopoDS_Vertex V = Spine->FirstVertex();
1537 TopoDS_Edge E = Spine->Edges(1);
1538 Standard_Real param = Spine->FirstParameter();
1540 if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1541 math_Vector vec(1,4);
1542 BP.ParametersOnS1(vec(1),vec(2));
1543 BP.ParametersOnS2(vec(3),vec(4));
1545 if (Func.IsSolution(vec, tolesp)) {
1546 TheWalk.AddSingularPoint(BP);
1550 if (Spine->IsTangencyExtremity(Standard_False)) {
1551 TopoDS_Vertex V = Spine->LastVertex();
1552 TopoDS_Edge E = Spine->Edges( Spine->NbEdges());
1553 Standard_Real param = Spine->LastParameter();
1555 if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1556 math_Vector vec(1,4);
1557 BP.ParametersOnS1(vec(1),vec(2));
1558 BP.ParametersOnS2(vec(3),vec(4));
1560 if (Func.IsSolution(vec, tolesp)) {
1561 TheWalk.AddSingularPoint(BP);
1567 //The starting solution is reframed if necessary.
1568 //**********************************************//
1569 math_Vector ParSol(1,4);
1570 Standard_Real NewFirst = PFirst;
1571 if(RecOnS1 || RecOnS2){
1572 if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
1573 tolesp,TolGuide,RecOnS1,RecOnS2,
1576 cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<endl;
1578 return Standard_False;
1585 //First the valid part is calculate, without caring for the extensions.
1586 //******************************************************************//
1587 Standard_Integer again = 0;
1588 Standard_Boolean tchernobyl = 0;
1589 Standard_Real u1sov = 0., u2sov = 0.;
1591 //Max step is relevant, but too great, the vector is required to detect
1593 if( (Abs(Last-First) <= MS * 5.) &&
1594 (Abs(Last-First) >= 0.01*Abs(NewFirst-Target)) ){
1595 MS = Abs(Last-First)*0.2;
1600 if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
1602 if (5*TolGuide > MS) TolGuide = MS/5;
1603 if (5*TolEsp > MS) TolEsp = MS/5;
1605 TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
1606 ParSol,TolEsp,Fleche,Appro);
1607 if (!TheWalk.IsDone()) {
1609 cout << "Path is not created" << endl;
1611 return Standard_False;
1613 Lin = TheWalk.Line();
1614 if(HGuide->IsPeriodic() && Inside) {
1615 SpFirst = Lin->Point(1).Parameter();
1616 SpLast = SpFirst + HGuide->Period();
1617 HGuide->ChangeCurve().FirstParameter(SpFirst);
1618 HGuide->ChangeCurve().LastParameter (SpLast );
1619 HGuide->ChangeCurve().SetOrigin(SpFirst);
1621 Standard_Boolean complmnt = Standard_True;
1622 if (Inside) complmnt = TheWalk.Complete(Func,FInv,SpLast);
1625 cout << "Not completed" << endl;
1627 return Standard_False;
1630 //The result is controlled using two criterions :
1631 //- if there is enough points,
1632 //- if one has gone far enough.
1633 Nbpnt = Lin->NbPoints();
1636 cout <<"0 point of path, quit."<<endl;
1638 return Standard_False;
1640 Standard_Real fpointpar = Lin->Point(1).Parameter();
1641 Standard_Real lpointpar = Lin->Point(Nbpnt).Parameter();
1643 Standard_Real factor = 1./(nbptmin + 1);
1644 Standard_Boolean okdeb = (Forward && !Inside);
1645 Standard_Boolean okfin = (!Forward && !Inside);
1647 Standard_Integer narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1648 Standard_Integer narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1649 okdeb = (narc1 > 0 || narc2 > 0 || (fpointpar-First) < 10*TolGuide);
1652 Standard_Integer narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1653 Standard_Integer narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1654 okfin = (narc1 > 0 || narc2 > 0 || (Last-lpointpar) < 10*TolGuide);
1656 if(!okdeb || !okfin || Nbpnt == 1){
1657 //It drags, the controls are extended, it is expected to evaluate a
1658 //satisfactory maximum step. If it already done, quit.
1661 cout <<"If it drags without control, quit."<<endl;
1663 return Standard_False;
1665 tchernobyl = Standard_True;
1669 cout <<"only one point of path MS/100 is attempted"<<endl;
1670 cout <<"and the controls are extended."<<endl;
1676 cout <<"It drags, the controls are extended."<<endl;
1678 MS = (lpointpar-fpointpar)/Nbpnt; //EvalStep(Lin);
1681 else if (Nbpnt < nbptmin){
1684 cout <<"Number of points is too small, the step is reduced"<<endl;
1688 MS = (lpointpar - fpointpar) * factor;
1690 else if(again == 1){
1691 if(Abs(fpointpar-u1sov)>=TolGuide ||
1692 Abs(lpointpar-u2sov)>=TolGuide){
1694 cout <<"Number of points is still too small, the step is reduced"<<endl;
1696 MS = (lpointpar - fpointpar) * factor;
1700 cout <<"Number of points is still too small, quit"<<endl;
1702 return Standard_False;
1712 if(TheWalk.TwistOnS1()){
1713 Data->TwistOnS1(Standard_True);
1715 cout<<"Path completed, but TWIST on S1"<<endl;
1718 if(TheWalk.TwistOnS2()){
1719 Data->TwistOnS2(Standard_True);
1721 cout<<"Parh completed, but TWIST on S2"<<endl;
1726 //Here there is a more or less presentable result
1727 //however it covers a the minimum zone.
1728 //The extensions are targeted.
1729 //*****************************//
1731 Gd1 = Gd2 = Gf1 = Gf2 = Standard_False;
1733 Standard_Boolean unseulsuffitdeb = (intf >= 2);
1734 Standard_Boolean unseulsuffitfin = (intl >= 2);
1735 Standard_Boolean noproldeb = (intf >= 3);
1736 Standard_Boolean noprolfin = (intl >= 3);
1738 Standard_Real Rab = 0.03*(SpLast-SpFirst);
1740 Standard_Boolean debarc1 = 0, debarc2 = 0;
1741 Standard_Boolean debcas1 = 0, debcas2 = 0;
1742 Standard_Boolean debobst1 = 0, debobst2 = 0;
1744 Standard_Boolean finarc1 = 0, finarc2 = 0;
1745 Standard_Boolean fincas1 = 0, fincas2 = 0;
1746 Standard_Boolean finobst1 = 0, finobst2 = 0;
1748 Standard_Integer narc1, narc2;
1750 Standard_Boolean backwContinueFailed = Standard_False; // eap
1751 if(reverse && intf) {
1752 narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1753 narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1755 ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1756 Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1757 debarc1 = Standard_True;
1758 if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
1759 //It is checked if there is not an obstacle.
1760 debcas1 = Standard_True;
1761 if(!Spine.IsNull()){
1762 if(Spine->IsPeriodic()){
1766 debobst1 = IsObst(Data->VertexFirstOnS1(),
1767 Spine->FirstVertex(),myVEMap);
1773 ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1774 Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1775 debarc2 = Standard_True;
1776 if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
1777 //It is checked if it is not an obstacle.
1778 debcas2 = Standard_True;
1779 if(!Spine.IsNull()){
1780 if(Spine->IsPeriodic()){
1784 debobst2 = IsObst(Data->VertexFirstOnS2(),
1785 Spine->FirstVertex(),myVEMap);
1790 Standard_Boolean oncontinue = !noproldeb && (narc1 != 0 || narc2 != 0);
1791 if(debobst1 || debobst2) oncontinue = Standard_False;
1792 else if(debcas1 && debcas2) oncontinue = Standard_False;
1793 else if((!debcas1 && debarc1) || (!debcas2 && debarc2)) oncontinue = Standard_False;
1796 TheWalk.ClassificationOnS1(!debarc1);
1797 TheWalk.ClassificationOnS2(!debarc2);
1798 TheWalk.Check2d(Standard_True); // It should be strict (PMN)
1799 TheWalk.Continu(Func,FInv,Target);
1800 TheWalk.ClassificationOnS1(Standard_True);
1801 TheWalk.ClassificationOnS2(Standard_True);
1802 TheWalk.Check2d(Standard_False);
1803 narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1804 narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1805 // modified by eap Fri Feb 8 11:43:48 2002 ___BEGIN___
1808 backwContinueFailed = Lin->StartPointOnFirst().ParameterOnGuide() > Target;
1810 ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1811 Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1812 debarc1 = Standard_True;
1813 if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
1814 //It is checked if it is not an obstacle.
1815 debcas1 = Standard_True;
1816 // if(!Spine.IsNull()) {
1817 // if(Spine->IsPeriodic()){
1821 // debobst1 = IsObst(Data->VertexFirstOnS1(),
1822 // Spine->FirstVertex(),myVEMap);
1830 backwContinueFailed = Lin->StartPointOnSecond().ParameterOnGuide() > Target;
1832 ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1833 Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1834 debarc2 = Standard_True;
1835 if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
1836 //It is checked if it is not an obstacle.
1837 debcas2 = Standard_True;
1838 // if(!Spine.IsNull()){
1839 // if(Spine->IsPeriodic()){
1843 // debobst2 = IsObst(Data->VertexFirstOnS2(),
1844 // Spine->FirstVertex(),myVEMap);
1850 if (backwContinueFailed) {
1851 // if we leave backwContinueFailed as is, we will stop in this direction
1852 // but we are to continue if there are no more faces on the side with arc
1853 // check this condition
1854 const ChFiDS_CommonPoint& aCP
1855 = debarc1 ? Data->VertexFirstOnS1() : Data->VertexFirstOnS2();
1856 if (aCP.IsOnArc() && bif.IsNull())
1857 backwContinueFailed = Standard_False;
1861 Standard_Boolean forwContinueFailed = Standard_False;
1862 // modified by eap Fri Feb 8 11:44:11 2002 ___END___
1863 if(Forward && intl) {
1865 narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1866 narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1868 ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1869 Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1870 finarc1 = Standard_True;
1871 if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
1872 //It is checked if it is not an obstacle.
1873 fincas1 = Standard_True;
1874 if(!Spine.IsNull()){
1875 finobst1 = IsObst(Data->VertexLastOnS1(),
1876 Spine->LastVertex(),myVEMap);
1881 ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1882 Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1883 finarc2 = Standard_True;
1884 if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1885 //It is checked if it is not an obstacle.
1886 fincas2 = Standard_True;
1887 if(!Spine.IsNull()){
1888 finobst2 = IsObst(Data->VertexLastOnS2(),
1889 Spine->LastVertex(),myVEMap);
1893 Standard_Boolean oncontinue = !noprolfin && (narc1 != 0 || narc2 != 0);
1894 if(finobst1 || finobst2) oncontinue = Standard_False;
1895 else if(fincas1 && fincas2) oncontinue = Standard_False;
1896 else if((!fincas1 && finarc1) || (!fincas2 && finarc2)) oncontinue = Standard_False;
1899 TheWalk.ClassificationOnS1(!finarc1);
1900 TheWalk.ClassificationOnS2(!finarc2);
1901 TheWalk.Check2d(Standard_True); // It should be strict (PMN)
1902 TheWalk.Continu(Func,FInv,Target);
1903 TheWalk.ClassificationOnS1(Standard_True);
1904 TheWalk.ClassificationOnS2(Standard_True);
1905 TheWalk.Check2d(Standard_False);
1906 narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1907 narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1908 // modified by eap Fri Feb 8 11:44:57 2002 ___BEGIN___
1911 forwContinueFailed = Lin->EndPointOnFirst().ParameterOnGuide() < Target;
1913 ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1914 Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1915 finarc1 = Standard_True;
1916 if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
1917 //It is checked if it is not an obstacle.
1918 fincas1 = Standard_True;
1919 // if(!Spine.IsNull()){
1920 // finobst1 = IsObst(Data->VertexLastOnS1(),
1921 // Spine->LastVertex(),myVEMap);
1928 forwContinueFailed = Lin->EndPointOnSecond().ParameterOnGuide() < Target;
1930 ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1931 Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1932 finarc2 = Standard_True;
1933 if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1934 //On regarde si ce n'est pas un obstacle.
1935 fincas2 = Standard_True;
1936 // if(!Spine.IsNull()){
1937 // finobst2 = IsObst(Data->VertexLastOnS2(),
1938 // Spine->LastVertex(),myVEMap);
1943 if (forwContinueFailed) {
1944 // if we leave forwContinueFailed as is, we will stop in this direction
1945 // but we are to continue if there are no more faces on the side with arc
1946 // check this condition
1947 const ChFiDS_CommonPoint& aCP
1948 = finarc1 ? Data->VertexLastOnS1() : Data->VertexLastOnS2();
1949 if (aCP.IsOnArc() && bif.IsNull())
1950 forwContinueFailed = Standard_False;
1952 // modified by eap Fri Feb 8 11:45:10 2002 ___END___
1955 Nbpnt = Lin->NbPoints();
1957 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
1959 First = Lin->Point(1).Parameter();
1960 Last = Lin->Point(Nbpnt).Parameter();
1962 // ============= INVALIDATION EVENTUELLE =============
1963 // ------ Preparation des prolongement par plan tangent -----
1964 if(reverse && intf){
1965 Gd1 = debcas1/* && !debobst1*/; // skv(occ67)
1966 Gd2 = debcas2/* && !debobst2*/; // skv(occ67)
1967 if ((debarc1^debarc2) && !unseulsuffitdeb && (First!=SpFirst)) {
1968 // Case of incomplete path, of course this ends badly :
1969 // the result is truncated instead of exit.
1970 Standard_Real sortie;
1971 Standard_Integer ind;
1972 if (debarc1) sortie = Data->VertexFirstOnS1().Parameter();
1973 else sortie = Data->VertexFirstOnS2().Parameter();
1974 if (sortie - First > tolesp) {
1975 ind = SearchIndex(sortie, Lin);
1976 if (Lin->Point(ind).Parameter() == sortie) ind--;
1978 Lin->Remove(1, ind);
1979 UpdateLine(Lin, Standard_True);
1981 Nbpnt = Lin->NbPoints();
1982 First = Lin->Point(1).Parameter();
1985 else if ((intf>=5) && !debarc1 && !debarc2 && (First!=SpFirst)) {
1986 Standard_Real sortie = (2*First+Last)/3;
1987 Standard_Integer ind;
1988 if (sortie - First > tolesp) {
1989 ind = SearchIndex(sortie, Lin);
1990 if (Lin->Point(ind).Parameter() == sortie) ind--;
1991 if (Nbpnt-ind < 3) ind = Nbpnt -3;
1993 Lin->Remove(1, ind);
1994 UpdateLine(Lin, Standard_True);
1996 Nbpnt = Lin->NbPoints();
1997 First = Lin->Point(1).Parameter();
2001 Target = Min((Lin->Point(1).Parameter() - Rab),First);
2002 Target = Max(Target,SpFirst);
2003 Data->FirstExtensionValue(Abs(Lin->Point(1).Parameter()-Target));
2005 if (intf && !unseulsuffitdeb) intf = (Gd1 && Gd2)//;
2006 || backwContinueFailed; // eap
2007 else if (intf && unseulsuffitdeb && (intf<5)) {
2008 intf = (Gd1 || Gd2);
2009 // It is checked if there is no new face.
2011 ((!debcas1 && debarc1) || (!debcas2 && debarc2)) ) intf = 0;
2013 else if (intf < 5) intf = 0;
2016 if(Forward && intl){
2017 Gf1 = fincas1/* && !finobst1*/; // skv(occ67)
2018 Gf2 = fincas2/* && !finobst2*/; // skv(occ67)
2019 if ((finarc1 ^finarc2) && !unseulsuffitfin && (Last!=SpLast)) {
2020 // Case of incomplete path, of course, this ends badly :
2021 // the result is truncated instead of exit.
2022 Standard_Real sortie;
2023 Standard_Integer ind;
2024 if (finarc1) sortie = Data->VertexLastOnS1().Parameter();
2025 else sortie = Data->VertexLastOnS2().Parameter();
2026 if (Last - sortie > tolesp) {
2027 ind = SearchIndex(sortie, Lin);
2028 if (Lin->Point(ind).Parameter() == sortie) ind++;
2030 Lin->Remove(ind, Nbpnt);
2031 UpdateLine(Lin, Standard_False);
2033 Nbpnt = Lin->NbPoints();
2034 Last = Lin->Point(Nbpnt).Parameter();
2037 else if ((intl>=5) && !finarc1 && !finarc2 && (Last!=SpLast) ) {
2038 // The same in case when the entire "Lin" is an extension
2039 Standard_Real sortie = (First+2*Last)/3;
2040 Standard_Integer ind;
2041 if (Last - sortie > tolesp) {
2042 ind = SearchIndex(sortie, Lin);
2043 if (Lin->Point(ind).Parameter() == sortie) ind++;
2044 if (ind < 3) ind = 3;
2046 Lin->Remove(ind, Nbpnt);
2047 UpdateLine(Lin, Standard_False);
2049 Nbpnt = Lin->NbPoints();
2050 Last = Lin->Point(Nbpnt).Parameter();
2054 Target = Max((Lin->Point(Nbpnt).Parameter() + Rab),Last);
2055 Target = Min(Target,SpLast);
2056 Data->LastExtensionValue(Abs(Target-Lin->Point(Nbpnt).Parameter()));
2059 if (intl && !unseulsuffitfin) intl = (Gf1 && Gf2)//;
2060 || forwContinueFailed; // eap
2061 else if (intl && unseulsuffitfin && (intl<5)) {
2062 intl = (Gf1 || Gf2);// It is checked if there is no new face.
2064 ((!fincas1 && finarc1) || (!fincas2 && finarc2)) ) intl = 0;
2066 else if (intl <5) intl = 0;
2068 return Standard_True;
2071 //=======================================================================
2072 //function : SimulData
2074 //=======================================================================
2076 Standard_Boolean ChFi3d_Builder::SimulData
2077 (Handle(ChFiDS_SurfData)& /*Data*/,
2078 const Handle(ChFiDS_HElSpine)& HGuide,
2079 Handle(BRepBlend_Line)& Lin,
2080 const Handle(Adaptor3d_HSurface)& S1,
2081 const Handle(Adaptor3d_TopolTool)& I1,
2082 const Handle(Adaptor3d_HSurface)& S2,
2083 const Handle(Adaptor3d_TopolTool)& I2,
2084 Blend_Function& Func,
2085 Blend_FuncInv& FInv,
2086 const Standard_Real PFirst,
2087 const Standard_Real MaxStep,
2088 const Standard_Real Fleche,
2089 const Standard_Real tolguide,
2090 Standard_Real& First,
2091 Standard_Real& Last,
2092 const Standard_Boolean Inside,
2093 const Standard_Boolean Appro,
2094 const Standard_Boolean Forward,
2095 const math_Vector& Soldep,
2096 const Standard_Integer NbSecMin,
2097 const Standard_Boolean RecOnS1,
2098 const Standard_Boolean RecOnS2)
2100 BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide);
2101 TheWalk.Check2d(Standard_False);
2103 Standard_Real MS = MaxStep;
2104 Standard_Real TolGuide=tolguide, TolEsp = tolesp;
2105 Standard_Integer Nbpnt = 0;
2106 Standard_Real SpFirst = HGuide->FirstParameter();
2107 Standard_Real SpLast = HGuide->LastParameter();
2108 Standard_Boolean reverse = (!Forward || Inside);
2109 Standard_Real Target;
2117 Standard_Real Targetsov = Target;
2118 Standard_Real u1sov = 0., u2sov = 0.;
2119 // on recadre la solution de depart a la demande.
2120 math_Vector ParSol(1,4);
2121 Standard_Real NewFirst = PFirst;
2122 if(RecOnS1 || RecOnS2){
2123 if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
2124 tolesp,TolGuide,RecOnS1,RecOnS2,
2127 cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<endl;
2129 return Standard_False;
2135 Standard_Integer again = 0;
2137 // When the start point is inside, the path goes first to the left
2138 // to determine the Last for the periodicals.
2139 if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
2141 if (5*TolGuide > MS) TolGuide = MS/5;
2142 if (5*TolEsp > MS) TolEsp = MS/5;
2145 TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
2146 ParSol,TolEsp,Fleche,Appro);
2148 if (!TheWalk.IsDone()) {
2150 cout << "Path not created" << endl;
2152 return Standard_False;
2154 Lin = TheWalk.Line();
2156 if(HGuide->IsPeriodic()) {
2157 SpFirst = Lin->Point(1).Parameter();
2158 SpLast = SpFirst + HGuide->Period();
2159 HGuide->ChangeCurve().FirstParameter(SpFirst);
2160 HGuide->ChangeCurve().LastParameter (SpLast );
2162 Standard_Boolean complmnt = Standard_True;
2163 if (Inside) complmnt = TheWalk.Complete(Func,FInv,SpLast);
2166 cout << "Not completed" << endl;
2168 return Standard_False;
2171 Nbpnt = Lin->NbPoints();
2172 Standard_Real factor = 1./(NbSecMin + 1);
2175 cout <<"0 point of path, quit."<<endl;
2177 return Standard_False;
2179 else if (Nbpnt == 1 && again == 0) {
2182 cout <<"only one point of path, MS/100 is attempted."<<endl;
2184 MS *= 0.01; Target = Targetsov;
2185 u1sov = u2sov = Lin->Point(1).Parameter();
2187 else if (Nbpnt< NbSecMin && again == 0) {
2190 cout <<"Number of points is too small, the step is reduced"<<endl;
2192 Standard_Real u1 = u1sov = Lin->Point(1).Parameter();
2193 Standard_Real u2 = u2sov = Lin->Point(Nbpnt).Parameter();
2194 MS = (u2-u1)*factor;
2197 else if (Nbpnt < NbSecMin && again == 1) {
2198 Standard_Real u1 = Lin->Point(1).Parameter();
2199 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
2200 if(Abs(u1-u1sov)>=TolGuide || Abs(u2-u2sov)>=TolGuide){
2203 cout <<"Number of points is still too small, the step is reduced"<<endl;
2210 cout <<"Number of points is still too small, quit"<<endl;
2212 return Standard_False;
2215 else if(Nbpnt < NbSecMin){
2217 cout <<"Number of points is still too small, quit"<<endl;
2219 return Standard_False;
2226 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
2228 First = Lin->Point(1).Parameter();
2229 Last = Lin->Point(Nbpnt).Parameter();
2230 return Standard_True;