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_Curve2d.hxx>
23 #include <Adaptor3d_Surface.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_Surface.hxx>
39 #include <BRepBlend_AppFunc.hxx>
40 #include <BRepBlend_AppFuncRst.hxx>
41 #include <BRepBlend_AppFuncRstRst.hxx>
42 #include <BRepBlend_AppSurf.hxx>
43 #include <BRepBlend_AppSurface.hxx>
44 #include <BRepBlend_ConstRad.hxx>
45 #include <BRepBlend_ConstRadInv.hxx>
46 #include <BRepBlend_CSWalking.hxx>
47 #include <BRepBlend_Extremity.hxx>
48 #include <BRepBlend_Line.hxx>
49 #include <BRepBlend_PointOnRst.hxx>
50 #include <BRepBlend_RstRstLineBuilder.hxx>
51 #include <BRepBlend_SurfRstLineBuilder.hxx>
52 #include <BRepBlend_Walking.hxx>
53 #include <BRepTopAdaptor_HVertex.hxx>
54 #include <BRepTopAdaptor_TopolTool.hxx>
55 #include <BSplCLib.hxx>
56 #include <ChFi3d_Builder.hxx>
57 #include <ChFi3d_Builder_0.hxx>
58 #include <ChFiDS_CommonPoint.hxx>
59 #include <ChFiDS_FaceInterference.hxx>
60 #include <ChFiDS_ElSpine.hxx>
61 #include <ChFiDS_Spine.hxx>
62 #include <ChFiDS_Stripe.hxx>
63 #include <ChFiDS_SurfData.hxx>
64 #include <Geom2d_BSplineCurve.hxx>
65 #include <Geom2d_Curve.hxx>
66 #include <Geom2d_Line.hxx>
67 #include <Geom2d_TrimmedCurve.hxx>
68 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
69 #include <Geom2dInt_GInter.hxx>
70 #include <Geom_BSplineSurface.hxx>
71 #include <Geom_Curve.hxx>
72 #include <Geom_Surface.hxx>
73 #include <GeomAdaptor_Curve.hxx>
74 #include <GeomAdaptor_Surface.hxx>
75 #include <GeomLib.hxx>
76 #include <gp_Dir2d.hxx>
78 #include <gp_Pnt2d.hxx>
80 #include <gp_Vec2d.hxx>
81 #include <IntRes2d_IntersectionPoint.hxx>
82 #include <math_Vector.hxx>
83 #include <Precision.hxx>
84 #include <Standard_ConstructionError.hxx>
85 #include <Standard_NoSuchObject.hxx>
86 #include <Standard_OutOfRange.hxx>
88 #include <TopoDS_Edge.hxx>
89 #include <TopoDS_Face.hxx>
90 #include <TopoDS_Shape.hxx>
91 #include <TopoDS_Vertex.hxx>
92 #include <TopOpeBRepBuild_HBuilder.hxx>
93 #include <TopOpeBRepDS_Curve.hxx>
94 #include <TopOpeBRepDS_DataStructure.hxx>
95 #include <TopOpeBRepDS_HDataStructure.hxx>
96 #include <TopOpeBRepDS_Surface.hxx>
97 #include <TopTools_ListIteratorOfListOfShape.hxx>
98 #include <TopTools_ListOfShape.hxx>
105 #include <Draw_Appli.hxx>
106 #include <Draw_Segment2D.hxx>
107 #include <Draw_Marker2D.hxx>
108 #include <Draw_Segment3D.hxx>
109 #include <Draw_Marker3D.hxx>
111 #include <DrawTrSurf.hxx>
112 #include <BRepAdaptor_Surface.hxx>
113 static Standard_Integer IndexOfConge = 0;
117 extern Standard_Boolean ChFi3d_GettraceDRAWFIL();
118 extern Standard_Boolean ChFi3d_GettraceDRAWWALK();
119 extern Standard_Boolean ChFi3d_GetcontextNOOPT();
120 extern void ChFi3d_SettraceDRAWFIL(const Standard_Boolean b);
121 extern void ChFi3d_SettraceDRAWWALK(const Standard_Boolean b);
122 extern void ChFi3d_SetcontextNOOPT(const Standard_Boolean b);
126 static void drawline(const Handle(BRepBlend_Line)& lin,
127 const Standard_Boolean iscs)
129 Handle(Draw_Marker3D) p3d;
130 Handle(Draw_Marker2D) p2d;
131 Handle(Draw_Segment3D) tg3d;
132 Handle(Draw_Segment2D) tg2d;
134 for(Standard_Integer i = 1; i <= lin->NbPoints(); i++){
135 const Blend_Point& pt = lin->Point(i);
136 gp_Pnt point = pt.PointOnS1();
137 gp_Pnt extr = point.Translated(pt.TangentOnS1());
138 p3d = new Draw_Marker3D(point,Draw_Square,Draw_rouge);
140 tg3d = new Draw_Segment3D(point,extr,Draw_rouge);
142 point = pt.PointOnS2();
143 extr = point.Translated(pt.TangentOnS2());
144 p3d = new Draw_Marker3D(point,Draw_Plus,Draw_jaune);
146 tg3d = new Draw_Segment3D(point,extr,Draw_jaune);
150 pt.ParametersOnS1(u,v);
151 gp_Pnt2d point2d(u,v);
152 gp_Pnt2d extr2d = point2d.Translated(pt.Tangent2dOnS1());
153 p2d = new Draw_Marker2D(point2d,Draw_Square,Draw_rouge);
155 tg2d = new Draw_Segment2D(point2d,extr2d,Draw_rouge);
157 pt.ParametersOnS2(u,v);
158 point2d.SetCoord(u,v);
159 extr2d = point2d.Translated(pt.Tangent2dOnS2());
160 p2d = new Draw_Marker2D(point2d,Draw_Plus,Draw_jaune);
162 tg2d = new Draw_Segment2D(point2d,extr2d,Draw_jaune);
168 //=======================================================================
169 //function : SearchIndex
172 //=======================================================================
173 static Standard_Integer SearchIndex(const Standard_Real Value,
174 Handle(BRepBlend_Line)& Lin)
176 Standard_Integer NbPnt = Lin->NbPoints(), Ind;
179 (Ind < NbPnt) && (Lin->Point(Ind).Parameter() < Value); )
185 //=======================================================================
189 //=======================================================================
190 static Standard_Integer nbedconnex(const TopTools_ListOfShape& L)
192 Standard_Integer nb = 0, i = 0;
193 TopTools_ListIteratorOfListOfShape It1(L);
194 for(;It1.More();It1.Next(),i++){
195 const TopoDS_Shape& curs = It1.Value();
196 Standard_Boolean dejavu = 0;
197 TopTools_ListIteratorOfListOfShape It2(L);
198 for(Standard_Integer j = 0; j < i && It2.More(); j++, It2.Next()){
199 if(curs.IsSame(It2.Value())){
209 static Standard_Boolean IsVois(const TopoDS_Edge& E,
210 const TopoDS_Vertex& Vref,
211 const ChFiDS_Map& VEMap,
212 TopTools_MapOfShape& DONE,
213 const Standard_Integer prof,
214 const Standard_Integer profmax)
216 if(prof > profmax) return Standard_False;
217 if(DONE.Contains(E)) return Standard_False;
219 TopExp::Vertices(E,V1,V2);
220 if(Vref.IsSame(V1) || Vref.IsSame(V2)) return Standard_True;
222 const TopTools_ListOfShape& L1 = VEMap(V1);
223 Standard_Integer i1 = nbedconnex(L1);
224 TopTools_ListIteratorOfListOfShape It1(L1);
225 for(;It1.More();It1.Next()){
226 const TopoDS_Edge& curE = TopoDS::Edge(It1.Value());
228 if(IsVois(curE,Vref,VEMap,DONE,prof,profmax)) return Standard_True;
230 else if(IsVois(curE,Vref,VEMap,DONE,prof+1,profmax)) return Standard_True;
232 const TopTools_ListOfShape& L2 = VEMap(V2);
234 // Standard_Integer i2 = nbedconnex(L2);
236 TopTools_ListIteratorOfListOfShape It2(L2);
237 for(;It2.More();It2.Next()){
238 const TopoDS_Edge& curE = TopoDS::Edge(It2.Value());
240 if(IsVois(curE,Vref,VEMap,DONE,prof,profmax)) return Standard_True;
242 else if(IsVois(curE,Vref,VEMap,DONE,prof+1,profmax)) return Standard_True;
244 return Standard_False;
247 static Standard_Boolean IsObst(const ChFiDS_CommonPoint& CP,
248 const TopoDS_Vertex& Vref,
249 const ChFiDS_Map& VEMap)
251 if(!CP.IsOnArc()) return Standard_False;
252 const TopoDS_Edge& E = CP.Arc();
253 TopTools_MapOfShape DONE;
254 Standard_Integer prof = 4;
255 return !IsVois(E,Vref,VEMap,DONE,0,prof);
258 //=======================================================================
259 //function : CompParam
262 //=======================================================================
264 static void CompParam(Geom2dAdaptor_Curve Carc,
265 Handle(Geom2d_Curve) Ctg,
268 const Standard_Real prefarc,
269 const Standard_Real preftg)
271 Standard_Boolean found = 0;
272 //(1) It is checked if the provided parameters are good
273 // if pcurves have the same parameters as the spine.
274 gp_Pnt2d point = Carc.Value(prefarc);
275 Standard_Real distini = point.Distance(Ctg->Value(preftg));
276 if (distini <= Precision::PConfusion()) {
279 found = Standard_True;
284 std::cout<< "CompParam : bad intersection parameters"<<std::endl;
286 IntRes2d_IntersectionPoint int2d;
287 Geom2dInt_GInter Intersection;
288 Standard_Integer nbpt,nbseg;
289 Intersection.Perform(Geom2dAdaptor_Curve(Ctg),Carc,
290 Precision::PIntersection(),
291 Precision::PIntersection());
293 Standard_Real dist = Precision::Infinite(), p1, p2;
294 if (Intersection.IsDone()){
295 if (!Intersection.IsEmpty()){
296 nbseg = Intersection.NbSegments();
299 std::cout<< "segments of intersection on the restrictions"<<std::endl;
302 nbpt = Intersection.NbPoints();
303 for (Standard_Integer i = 1; i <= nbpt; i++) {
304 int2d = Intersection.Point(i);
305 p1 = int2d.ParamOnFirst();
306 p2 = int2d.ParamOnSecond();
307 if(Abs(prefarc - p2) < dist){
310 dist = Abs(prefarc - p2);
321 std::cout<<"CompParam : failed intersection PC, projection is created."<<std::endl;
324 Geom2dAPI_ProjectPointOnCurve projector(point,Ctg);
326 if(projector.NbPoints() == 0){
327 // This happens in some cases when there is a vertex
328 // at the end of spine...
331 std::cout<<"CompParam : failed proj p2d/c2d, the extremity is taken!" <<std::endl;
335 // It is checked if everything was calculated correctly (EDC402 C2)
336 if (projector.LowerDistance() < distini)
337 ptg = projector.LowerDistanceParameter();
343 //=======================================================================
344 //function : CompBlendPoint
345 //purpose : create BlendPoint corresponding to a tangency on Vertex
346 // pmn : 15/10/1997 : returns false, if there is no pcurve
347 //=======================================================================
349 static Standard_Boolean CompBlendPoint(const TopoDS_Vertex& V,
350 const TopoDS_Edge& E,
351 const Standard_Real W,
352 const TopoDS_Face F1,
353 const TopoDS_Face F2,
358 Standard_Real param, f, l;
359 Handle(Geom2d_Curve) pc;
361 P3d = BRep_Tool::Pnt(V);
362 param = BRep_Tool::Parameter(V,E,F1);
363 pc = BRep_Tool::CurveOnSurface(E,F1,f,l);
364 if (pc.IsNull()) return Standard_False;
365 P1 = pc->Value(param);
366 param = BRep_Tool::Parameter(V,E,F2);
367 pc = BRep_Tool::CurveOnSurface(E,F2,f,l);
368 if (pc.IsNull()) return Standard_False;
369 P2 = pc->Value(param);
370 BP.SetValue(P3d, P3d, W, P1.X(), P1.Y(), P2.X(), P2.Y());
371 return Standard_True;
374 //=======================================================================
375 //function : UpdateLine
376 //purpose : Updates extremities after a partial invalidation
377 //=======================================================================
379 static void UpdateLine(Handle(BRepBlend_Line)& Line,
380 const Standard_Boolean isfirst)
382 Standard_Real tguide, U, V;
384 const Blend_Point& BP = Line->Point(1);
385 tguide = BP.Parameter();
386 if (Line->StartPointOnFirst().ParameterOnGuide() < tguide) {
387 BRepBlend_Extremity BE;
388 BP.ParametersOnS1(U, V);
389 BE.SetValue(BP.PointOnS1(), U, V, Precision::Confusion());
390 Line->SetStartPoints(BE, Line->StartPointOnSecond());
392 if (Line->StartPointOnSecond().ParameterOnGuide() < tguide) {
393 BRepBlend_Extremity BE;
394 BP.ParametersOnS2(U, V);
395 BE.SetValue(BP.PointOnS2(), U, V, Precision::Confusion());
396 Line->SetStartPoints(Line->StartPointOnFirst(), BE);
400 const Blend_Point& BP = Line->Point(Line->NbPoints());
401 tguide = BP.Parameter();
402 if (Line->EndPointOnFirst().ParameterOnGuide() > tguide) {
403 BRepBlend_Extremity BE;
404 BP.ParametersOnS1(U, V);
405 BE.SetValue(BP.PointOnS1(), U, V, Precision::Confusion());
406 Line->SetEndPoints(BE, Line->EndPointOnSecond());
408 if (Line->EndPointOnSecond().ParameterOnGuide() > tguide) {
409 BRepBlend_Extremity BE;
410 BP.ParametersOnS2(U, V);
411 BE.SetValue(BP.PointOnS2(), U, V, Precision::Confusion());
412 Line->SetEndPoints(Line->EndPointOnFirst(), BE);
417 //=======================================================================
418 //function : CompleteData
419 //purpose : Calculates curves and CommonPoints from the data
420 // calculated by filling.
421 //=======================================================================
423 Standard_Boolean ChFi3d_Builder::CompleteData
424 (Handle(ChFiDS_SurfData)& Data,
425 const Handle(Geom_Surface)& Surfcoin,
426 const Handle(Adaptor3d_Surface)& S1,
427 const Handle(Geom2d_Curve)& PC1,
428 const Handle(Adaptor3d_Surface)& S2,
429 const Handle(Geom2d_Curve)& PC2,
430 const TopAbs_Orientation Or,
431 const Standard_Boolean On1,
432 const Standard_Boolean Gd1,
433 const Standard_Boolean Gd2,
434 const Standard_Boolean Gf1,
435 const Standard_Boolean Gf2)
437 TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
438 Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surfcoin,tolesp)));
440 ChFi3d_SettraceDRAWFIL(Standard_True);
441 if (ChFi3d_GettraceDRAWFIL()) {
444 char* name = new char[100];
445 sprintf(name,"%s_%d","Surf",IndexOfConge);
446 DrawTrSurf::Set(name,Surfcoin);
450 Standard_Real UFirst,ULast,VFirst,VLast;
451 Surfcoin->Bounds(UFirst,ULast,VFirst,VLast);
452 if(!Gd1) Data->ChangeVertexFirstOnS1().SetPoint(Surfcoin->Value(UFirst,VFirst));
453 if(!Gd2) Data->ChangeVertexFirstOnS2().SetPoint(Surfcoin->Value(UFirst,VLast));
454 if(!Gf1) Data->ChangeVertexLastOnS1().SetPoint(Surfcoin->Value(ULast,VFirst));
455 if(!Gf2) Data->ChangeVertexLastOnS2().SetPoint(Surfcoin->Value(ULast,VLast));
457 //calculate curves side S1
458 Handle(Geom_Curve) Crv3d1;
459 if(!PC1.IsNull()) Crv3d1= Surfcoin->VIso(VFirst);
460 gp_Pnt2d pd1(UFirst,VFirst), pf1(ULast,VFirst);
461 gp_Lin2d lfil1(pd1,gp_Dir2d(gp_Vec2d(pd1,pf1)));
462 Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1);
463 TopAbs_Orientation tra1 = TopAbs_FORWARD, orsurf = Or;
464 Standard_Real x,y,w = 0.5*(UFirst+ULast);
467 Handle(Geom2d_Curve) c2dtrim;
468 Standard_Real tolreached = 1.e-5;
470 Handle(GeomAdaptor_Curve) hcS1 = new GeomAdaptor_Curve(Crv3d1);
471 c2dtrim = new Geom2d_TrimmedCurve(PC1,UFirst,ULast);
472 ChFi3d_SameParameter(hcS1,c2dtrim,S1,tolapp3d,tolreached);
473 c2dtrim->Value(w).Coord(x,y);
475 gp_Vec nf = du.Crossed(dv);
476 Surfcoin->D1(w,VFirst,p,du,dv);
477 gp_Vec ns = du.Crossed(dv);
478 if(nf.Dot(ns) > 0.) tra1 = TopAbs_REVERSED;
479 else if(On1) orsurf = TopAbs::Reverse(orsurf);
481 Standard_Integer Index1OfCurve =
482 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolreached));
483 ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1();
484 Fint1.SetFirstParameter(UFirst);
485 Fint1.SetLastParameter(ULast);
486 Fint1.SetInterference(Index1OfCurve,tra1,c2dtrim,PCurveOnSurf);
487 //calculate curves side S2
488 Handle(Geom_Curve) Crv3d2;
489 if(!PC2.IsNull()) Crv3d2 = Surfcoin->VIso(VLast);
490 gp_Pnt2d pd2(UFirst,VLast), pf2(ULast,VLast);
491 gp_Lin2d lfil2(pd2,gp_Dir2d(gp_Vec2d(pd2,pf2)));
492 PCurveOnSurf = new Geom2d_Line(lfil2);
493 TopAbs_Orientation tra2 = TopAbs_FORWARD;
495 Handle(GeomAdaptor_Curve) hcS2 = new GeomAdaptor_Curve(Crv3d2);
496 c2dtrim = new Geom2d_TrimmedCurve(PC2,UFirst,ULast);
497 ChFi3d_SameParameter(hcS2,c2dtrim,S2,tolapp3d,tolreached);
498 c2dtrim->Value(w).Coord(x,y);
500 gp_Vec np = du.Crossed(dv);
501 Surfcoin->D1(w,VLast,p,du,dv);
502 gp_Vec ns = du.Crossed(dv);
503 if(np.Dot(ns) < 0.) {
504 tra2 = TopAbs_REVERSED;
505 if(!On1) orsurf = TopAbs::Reverse(orsurf);
508 Standard_Integer Index2OfCurve =
509 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolreached));
510 ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2();
511 Fint2.SetFirstParameter(UFirst);
512 Fint2.SetLastParameter(ULast);
513 Fint2.SetInterference(Index2OfCurve,tra2,c2dtrim,PCurveOnSurf);
514 Data->ChangeOrientation() = orsurf;
515 return Standard_True;
518 //=======================================================================
519 //function : CompleteData
520 //purpose : Calculates the surface of curves and eventually
521 // CommonPoints from the data calculated in ComputeData.
523 // 11/08/1996 : Use of F(t)
525 //=======================================================================
527 Standard_Boolean ChFi3d_Builder::CompleteData
528 (Handle(ChFiDS_SurfData)& Data,
529 Blend_Function& Func,
530 Handle(BRepBlend_Line)& lin,
531 const Handle(Adaptor3d_Surface)& S1,
532 const Handle(Adaptor3d_Surface)& S2,
533 const TopAbs_Orientation Or1,
534 const Standard_Boolean Gd1,
535 const Standard_Boolean Gd2,
536 const Standard_Boolean Gf1,
537 const Standard_Boolean Gf2,
538 const Standard_Boolean Reversed)
540 Handle(BRepBlend_AppFunc) TheFunc
541 = new (BRepBlend_AppFunc)(lin, Func, tolapp3d, 1.e-5);
543 Standard_Integer Degmax = 20, Segmax = 5000;
544 BRepBlend_AppSurface approx (TheFunc,
545 lin->Point(1).Parameter(),
546 lin->Point(lin->NbPoints()).Parameter(),
547 tolapp3d, 1.e-5, //tolapp2d, tolerance max
548 tolappangle, // Contact G1
549 myConti, Degmax, Segmax);
550 if (!approx.IsDone()) {
552 std::cout << "Approximation non faite !!!" << std::endl;
554 return Standard_False;
557 approx.Dump(std::cout);
559 return StoreData( Data, approx, lin, S1, S2, Or1, Gd1, Gd2, Gf1, Gf2, Reversed);
563 //=======================================================================
564 //function : CompleteData
565 //purpose : New overload for functions surf/rst
566 // jlr le 28/07/97 branchement F(t)
567 //=======================================================================
569 Standard_Boolean ChFi3d_Builder::CompleteData
570 (Handle(ChFiDS_SurfData)& Data,
571 Blend_SurfRstFunction& Func,
572 Handle(BRepBlend_Line)& lin,
573 const Handle(Adaptor3d_Surface)& S1,
574 const Handle(Adaptor3d_Surface)& S2,
575 const TopAbs_Orientation Or,
576 const Standard_Boolean Reversed)
578 Handle(BRepBlend_AppFuncRst) TheFunc
579 = new (BRepBlend_AppFuncRst)(lin, Func, tolapp3d, 1.e-5);
580 BRepBlend_AppSurface approx (TheFunc,
581 lin->Point(1).Parameter(),
582 lin->Point(lin->NbPoints()).Parameter(),
583 tolapp3d, 1.e-5, //tolapp2d, tolerance max
584 tolappangle, // Contact G1
586 if (!approx.IsDone()) {
588 std::cout << "Approximation is not done!" << std::endl;
590 return Standard_False;
593 approx.Dump(std::cout);
596 return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0,Reversed);
601 //=======================================================================
602 //function : CompleteData
603 //purpose : New overload for functions rst/rst
604 // jlr le 28/07/97 branchement F(t)
605 //=======================================================================
607 Standard_Boolean ChFi3d_Builder::CompleteData
608 (Handle(ChFiDS_SurfData)& Data,
609 Blend_RstRstFunction& Func,
610 Handle(BRepBlend_Line)& lin,
611 const Handle(Adaptor3d_Surface)& S1,
612 const Handle(Adaptor3d_Surface)& S2,
613 const TopAbs_Orientation Or)
615 Handle(BRepBlend_AppFuncRstRst) TheFunc
616 = new (BRepBlend_AppFuncRstRst)(lin, Func, tolapp3d, 1.e-5);
617 BRepBlend_AppSurface approx (TheFunc,
618 lin->Point(1).Parameter(),
619 lin->Point(lin->NbPoints()).Parameter(),
620 tolapp3d, 1.e-5, //tolapp2d, tolerance max
621 tolappangle, // Contact G1
623 if (!approx.IsDone()) {
625 std::cout << "Approximation non faite !!!" << std::endl;
627 return Standard_False;
630 approx.Dump(std::cout);
633 return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0);
639 //=======================================================================
640 //function : StoreData
641 //purpose : Copy of an approximation result in SurfData.
642 //=======================================================================
644 Standard_Boolean ChFi3d_Builder::StoreData(Handle(ChFiDS_SurfData)& Data,
645 const AppBlend_Approx& approx,
646 const Handle(BRepBlend_Line)& lin,
647 const Handle(Adaptor3d_Surface)& S1,
648 const Handle(Adaptor3d_Surface)& S2,
649 const TopAbs_Orientation Or1,
650 const Standard_Boolean Gd1,
651 const Standard_Boolean Gd2,
652 const Standard_Boolean Gf1,
653 const Standard_Boolean Gf2,
654 const Standard_Boolean Reversed)
656 // Small control tools.
657 static Handle(GeomAdaptor_Curve) checkcurve;
658 if(checkcurve.IsNull()) checkcurve = new GeomAdaptor_Curve();
659 GeomAdaptor_Curve& chc = *checkcurve;
660 Standard_Real tolget3d, tolget2d, tolaux, tolC1, tolcheck;
661 Standard_Real tolC2 = 0.;
662 approx.TolReached(tolget3d, tolget2d);
663 tolaux = approx.TolCurveOnSurf(1);
664 tolC1 = tolget3d + tolaux;
666 tolaux = approx.TolCurveOnSurf(2);
667 tolC2 = tolget3d + tolaux;
670 TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
671 // By default parametric space is created using a square surface
672 // to be able to parameterize in U by # R*teta // a revoir lbo 29/08/97
673 const TColStd_Array1OfReal& ku = approx.SurfUKnots();
674 const TColStd_Array1OfReal& kv = approx.SurfVKnots();
675 Standard_Real larg = (kv(kv.Upper())-kv(kv.Lower()));
676 TColStd_Array1OfReal& kku = *((TColStd_Array1OfReal*)((void*)&ku));
677 BSplCLib::Reparametrize(0.,larg,kku);
678 Handle(Geom_BSplineSurface) Surf =
679 new Geom_BSplineSurface(approx.SurfPoles(),approx.SurfWeights(),
681 approx.SurfUMults(),approx.SurfVMults(),
682 approx.UDegree(),approx.VDegree());
683 // extension of the surface
685 Standard_Real length1,length2;
686 length1=Data->FirstExtensionValue();
687 length2=Data->LastExtensionValue();
689 Handle(Geom_BoundedSurface) aBndSurf = Surf;
690 Standard_Boolean ext1 = Standard_False, ext2 = Standard_False;
691 Standard_Real eps = Max(tolget3d, 2. * Precision::Confusion());
695 P11 = Surf->Pole(1, 1);
696 P21 = Surf->Pole(Surf->NbUPoles(), 1);
697 if (P11.Distance(P21) > eps)
699 //to avoid extending surface with singular boundary
700 GeomLib::ExtendSurfByLength(aBndSurf, length1, 1, Standard_False, Standard_False);
701 ext1 = Standard_True;
707 P12 = Surf->Pole(1, Surf->NbVPoles());
708 P22 = Surf->Pole(Surf->NbUPoles(), Surf->NbVPoles());
709 if (P12.Distance(P22) > eps)
711 //to avoid extending surface with singular boundary
712 GeomLib::ExtendSurfByLength(aBndSurf, length2, 1, Standard_False, Standard_True);
713 ext2 = Standard_True;
716 Surf = Handle(Geom_BSplineSurface)::DownCast(aBndSurf);
718 //Correction of surface on extremities
722 P11 = lin->StartPointOnFirst().Value();
723 P21 = lin->StartPointOnSecond().Value();
724 Surf->SetPole(1, 1, P11);
725 Surf->SetPole(Surf->NbUPoles(), 1, P21);
730 P12 = lin->EndPointOnFirst().Value();
731 P22 = lin->EndPointOnSecond().Value();
732 Surf->SetPole(1, Surf->NbVPoles(), P12);
733 Surf->SetPole(Surf->NbUPoles(), Surf->NbVPoles(), P22);
736 Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surf,tolget3d)));
739 ChFi3d_SettraceDRAWFIL(Standard_True);
740 if (ChFi3d_GettraceDRAWFIL()) {
743 char* name=new char[100];
744 sprintf(name,"%s_%d","Surf",IndexOfConge);
745 DrawTrSurf::Set(name,Surf);
748 Standard_Real UFirst,ULast,VFirst,VLast,pppdeb,pppfin;
749 Surf->Bounds(UFirst,ULast,VFirst,VLast);
750 BRepAdaptor_Curve2d brc;
751 BRepAdaptor_Curve CArc;
752 Handle(BRepAdaptor_Surface)
753 BS1 = Handle(BRepAdaptor_Surface)::DownCast(S1);
754 Handle(BRepAdaptor_Surface)
755 BS2 = Handle(BRepAdaptor_Surface)::DownCast(S2);
756 Geom2dAPI_ProjectPointOnCurve projector;
758 Standard_Real Uon1 = UFirst, Uon2 = ULast;
759 Standard_Integer ion1 = 1, ion2 = 2;
760 if(Reversed) { Uon1 = ULast; Uon2 = UFirst; ion1 = 2; ion2 = 1; }
762 // The SurfData is filled in what concerns S1,
763 Handle(Geom_Curve) Crv3d1 = Surf->UIso(Uon1);
764 gp_Pnt2d pori1(Uon1,0.);
765 gp_Lin2d lfil1(pori1,gp::DY2d());
766 Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1);
767 Handle(Geom2d_Curve) PCurveOnFace;
769 Geom2d_BSplineCurve(approx.Curve2dPoles(ion1),approx.Curves2dKnots(),
770 approx.Curves2dMults(),approx.Curves2dDegree());
773 Standard_Real par1=PCurveOnFace->FirstParameter();
774 Standard_Real par2= PCurveOnFace->LastParameter();
775 chc.Load(Crv3d1,par1,par2);
777 if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S1,tolC1,tolcheck)){
779 std::cout<<"approximate tolerance under-valued : "<<tolC1<<" for "<<tolcheck<<std::endl;
783 Standard_Integer Index1OfCurve =
784 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolC1));
786 Standard_Real uarc,utg;
788 TopoDS_Face forwfac = BS1->Face();
789 forwfac.Orientation(TopAbs_FORWARD);
790 brc.Initialize(Data->VertexFirstOnS1().Arc(),forwfac);
791 ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS1();
792 CArc.Initialize(V.Arc());
793 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
794 tolcheck = CArc.Value(uarc).Distance(V.Point());
795 V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
798 else pppdeb = VFirst;
800 TopoDS_Face forwfac = BS1->Face();
801 forwfac.Orientation(TopAbs_FORWARD);
802 ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS1();
803 brc.Initialize(V.Arc(),forwfac);
804 CArc.Initialize(V.Arc());
805 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
806 tolcheck = CArc.Value(uarc).Distance(V.Point());
807 V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
811 ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1();
812 Fint1.SetFirstParameter(pppdeb);
813 Fint1.SetLastParameter(pppfin);
814 TopAbs_Orientation TraOn1;
815 if(Reversed) TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
816 else TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
817 Fint1.SetInterference(Index1OfCurve,TraOn1,PCurveOnFace,PCurveOnSurf);
819 // SurfData is filled in what concerns S2,
820 Handle(Geom_Curve) Crv3d2 = Surf->UIso(Uon2);
821 gp_Pnt2d pori2(Uon2,0.);
822 gp_Lin2d lfil2(pori2,gp::DY2d());
823 PCurveOnSurf = new Geom2d_Line(lfil2);
825 PCurveOnFace = new Geom2d_BSplineCurve(approx.Curve2dPoles(ion2),
826 approx.Curves2dKnots(),
827 approx.Curves2dMults(),
828 approx.Curves2dDegree());
829 chc.Load(Crv3d2,par1,par2);
830 if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S2,tolC2,tolcheck)){
832 std::cout<<"approximate tolerance under-evaluated : "<<tolC2<<" for "<<tolcheck<<std::endl;
837 Standard_Integer Index2OfCurve =
838 DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolC2));
840 TopoDS_Face forwfac = BS2->Face();
841 forwfac.Orientation(TopAbs_FORWARD);
842 brc.Initialize(Data->VertexFirstOnS2().Arc(),forwfac);
843 ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS2();
844 CArc.Initialize(V.Arc());
845 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
846 tolcheck = CArc.Value(uarc).Distance(V.Point());
847 V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
850 else pppdeb = VFirst;
852 TopoDS_Face forwfac = BS2->Face();
853 forwfac.Orientation(TopAbs_FORWARD);
854 brc.Initialize(Data->VertexLastOnS2().Arc(),forwfac);
855 ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS2();
856 CArc.Initialize(V.Arc());
857 CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
858 tolcheck = CArc.Value(uarc).Distance(V.Point());
859 V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
863 ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2();
864 Fint2.SetFirstParameter(pppdeb);
865 Fint2.SetLastParameter(pppfin);
867 TopAbs_Orientation TraOn2;
868 if(Reversed) TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
869 else TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
870 Fint2.SetInterference(Index2OfCurve,TraOn2,PCurveOnFace,PCurveOnSurf);
873 Handle(Geom2d_Curve) bidpc;
874 Fint2.SetInterference
875 (Index2OfCurve,TopAbs_FORWARD,bidpc,PCurveOnSurf);
878 // the orientation of the fillet in relation to the faces is evaluated,
880 Handle(Adaptor3d_Surface) Sref = S1;
881 PCurveOnFace = Fint1.PCurveOnFace();
882 if(Reversed){ Sref = S2; PCurveOnFace = Fint2.PCurveOnFace(); }
884 // Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898 Begin
885 // gp_Pnt2d PUV = PCurveOnFace->Value((VFirst+VLast)/2.);
887 // gp_Vec Du1,Du2,Dv1,Dv2;
888 // Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
890 // if (Or1 == TopAbs_REVERSED) Du1.Reverse();
891 // Surf->D1(UFirst,(VFirst+VLast)/2.,P,Du2,Dv2);
893 // if (Du1.Dot(Du2)>0) Data->ChangeOrientation() = TopAbs_FORWARD;
894 // else Data->ChangeOrientation() = TopAbs_REVERSED;
896 Standard_Real aDelta = VLast - VFirst;
897 Standard_Integer aDenom = 2;
900 Standard_Real aDeltav = aDelta/aDenom;
901 Standard_Real aParam = VFirst + aDeltav;
902 gp_Pnt2d PUV = PCurveOnFace->Value(aParam);
904 gp_Vec Du1,Du2,Dv1,Dv2;
906 Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
909 if (Or1 == TopAbs_REVERSED)
912 Surf->D1(UFirst, aParam, P, Du2, Dv2);
915 if (Du1.Magnitude() <= tolget3d ||
916 Du2.Magnitude() <= tolget3d) {
919 if (Abs(aDeltav) <= tolget2d)
920 return Standard_False;
926 Data->ChangeOrientation() = TopAbs_FORWARD;
928 Data->ChangeOrientation() = TopAbs_REVERSED;
932 // Modified by skv - Wed Jun 9 17:16:26 2004 OCC5898 End
934 if(!Gd1 && !S1.IsNull())
935 ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(),
936 Standard_True, Data->ChangeVertex(1,ion1),tolC1);
937 if(!Gf1 && !S1.IsNull())
938 ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(),
939 Standard_False,Data->ChangeVertex(0,ion1),tolC1);
940 if(!Gd2 && !S2.IsNull())
941 ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(),
942 Standard_True, Data->ChangeVertex(1,ion2),tolC2);
943 if(!Gf2 && !S2.IsNull())
944 ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(),
945 Standard_False, Data->ChangeVertex(0,ion2),tolC2);
946 // Parameters on ElSpine
947 Standard_Integer nbp = lin->NbPoints();
948 Data->FirstSpineParam(lin->Point(1).Parameter());
949 Data->LastSpineParam(lin->Point(nbp).Parameter());
950 return Standard_True;
955 //=======================================================================
956 //function : ComputeData
957 //purpose : Head of the path edge/face for the bypass of obstacle.
958 //=======================================================================
960 Standard_Boolean ChFi3d_Builder::ComputeData
961 (Handle(ChFiDS_SurfData)& Data,
962 const Handle(ChFiDS_ElSpine)& HGuide,
963 Handle(BRepBlend_Line)& Lin,
964 const Handle(Adaptor3d_Surface)& S1,
965 const Handle(Adaptor3d_TopolTool)& I1,
966 const Handle(Adaptor3d_Surface)& S2,
967 const Handle(Adaptor2d_Curve2d)& PC2,
968 const Handle(Adaptor3d_TopolTool)& I2,
969 Standard_Boolean& Decroch,
970 Blend_SurfRstFunction& Func,
972 Blend_SurfPointFuncInv& FInvP,
973 Blend_SurfCurvFuncInv& FInvC,
974 const Standard_Real PFirst,
975 const Standard_Real MaxStep,
976 const Standard_Real Fleche,
977 const Standard_Real TolGuide,
978 Standard_Real& First,
980 const math_Vector& Soldep,
981 const Standard_Boolean Inside,
982 const Standard_Boolean Appro,
983 const Standard_Boolean Forward,
984 const Standard_Boolean RecP,
985 const Standard_Boolean RecS,
986 const Standard_Boolean RecRst)
988 BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
990 Data->FirstExtensionValue(0);
991 Data->LastExtensionValue(0);
993 Standard_Boolean reverse = (!Forward || Inside);
994 Standard_Real SpFirst = HGuide->FirstParameter();
995 Standard_Real SpLast = HGuide->LastParameter();
996 Standard_Real Target = SpLast;
997 if(reverse) Target = SpFirst;
998 Standard_Real Targetsov = Target;
1000 Standard_Real MS = MaxStep;
1001 Standard_Integer again = 0;
1002 Standard_Integer nbptmin = 3; //jlr
1003 Standard_Integer Nbpnt = 1;
1004 // the initial solution is reframed if necessary.
1005 math_Vector ParSol(1,3);
1006 Standard_Real NewFirst = PFirst;
1007 if(RecP || RecS || RecRst){
1008 if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep,
1009 tolesp,TolGuide,RecRst,RecP,RecS,
1012 std::cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<std::endl;
1014 return Standard_False;
1022 TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last,
1023 MS,TolGuide,ParSol,tolesp,Fleche,Appro);
1025 if (!TheWalk.IsDone()) {
1027 std::cout << "Path not created" << std::endl;
1029 return Standard_False;
1033 if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) {
1035 std::cout << "Not completed" << std::endl;
1041 Lin = TheWalk.Line();
1042 Nbpnt = Lin->NbPoints();
1043 if (Nbpnt <= 1 && again == 0) {
1046 std::cout <<"one point of the path MS/50 is attempted."<<std::endl;
1048 MS = MS/50.; Target = Targetsov;
1050 else if (Nbpnt<=nbptmin && again == 0) {
1053 std::cout <<"Number of points is too small, the step is reduced"<<std::endl;
1055 Standard_Real u1 = Lin->Point(1).Parameter();
1056 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1057 MS = (u2-u1)/(nbptmin+1.0);
1058 // std::cout << " MS : " << MS << " u1 : " << u1 << " u2 : " << u2 << " nbptmin : " << nbptmin << std::endl;
1061 else if(Nbpnt<=nbptmin){
1063 std::cout <<"Number of points is still too small, quit"<<std::endl;
1065 return Standard_False;
1072 ChFi3d_SettraceDRAWWALK(Standard_True);
1073 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1075 if(Forward) Decroch = TheWalk.DecrochEnd();
1076 else Decroch = TheWalk.DecrochStart();
1077 Last = Lin->Point(Nbpnt).Parameter();
1078 First = Lin->Point(1).Parameter();
1079 return Standard_True;
1083 //=======================================================================
1084 //function : ComputeData
1085 //purpose : Heading of the path edge/edge for the bypass of obstacle.
1086 //=======================================================================
1088 Standard_Boolean ChFi3d_Builder::ComputeData
1089 (Handle(ChFiDS_SurfData)& Data,
1090 const Handle(ChFiDS_ElSpine)& HGuide,
1091 Handle(BRepBlend_Line)& Lin,
1092 const Handle(Adaptor3d_Surface)& S1,
1093 const Handle(Adaptor2d_Curve2d)& PC1,
1094 const Handle(Adaptor3d_TopolTool)& I1,
1095 Standard_Boolean& Decroch1,
1096 const Handle(Adaptor3d_Surface)& S2,
1097 const Handle(Adaptor2d_Curve2d)& PC2,
1098 const Handle(Adaptor3d_TopolTool)& I2,
1099 Standard_Boolean& Decroch2,
1100 Blend_RstRstFunction& Func,
1101 Blend_SurfCurvFuncInv& FInv1,
1102 Blend_CurvPointFuncInv& FInvP1,
1103 Blend_SurfCurvFuncInv& FInv2,
1104 Blend_CurvPointFuncInv& FInvP2,
1105 const Standard_Real PFirst,
1106 const Standard_Real MaxStep,
1107 const Standard_Real Fleche,
1108 const Standard_Real TolGuide,
1109 Standard_Real& First,
1110 Standard_Real& Last,
1111 const math_Vector& Soldep,
1112 const Standard_Boolean Inside,
1113 const Standard_Boolean Appro,
1114 const Standard_Boolean Forward,
1115 const Standard_Boolean RecP1,
1116 const Standard_Boolean RecRst1,
1117 const Standard_Boolean RecP2,
1118 const Standard_Boolean RecRst2)
1120 BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1122 Data->FirstExtensionValue(0);
1123 Data->LastExtensionValue(0);
1125 Standard_Boolean reverse = (!Forward || Inside);
1126 Standard_Real SpFirst = HGuide->FirstParameter();
1127 Standard_Real SpLast = HGuide->LastParameter();
1128 Standard_Real Target = SpLast;
1129 if(reverse) Target = SpFirst;
1130 Standard_Real Targetsov = Target;
1132 Standard_Real MS = MaxStep;
1133 Standard_Integer again = 0;
1134 Standard_Integer nbptmin = 3; //jlr
1135 Standard_Integer Nbpnt = 0;
1136 // the initial solution is reframed if necessary.
1137 math_Vector ParSol(1,2);
1138 Standard_Real NewFirst = PFirst;
1139 if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1140 if (!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1141 tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1144 std::cout<<"ChFi3d_Builder::ComputeData : fail calculation first section"<<std::endl;
1146 return Standard_False;
1154 TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1155 MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1157 if (!TheWalk.IsDone()) {
1159 std::cout << "Path not done" << std::endl;
1161 return Standard_False;
1165 if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1167 std::cout << "Not completed" << std::endl;
1173 Lin = TheWalk.Line();
1174 Nbpnt = Lin->NbPoints();
1175 if (Nbpnt <= 1 && again == 0) {
1178 std::cout <<"one point of path MS/50 is attempted."<<std::endl;
1180 MS = MS/50.; Target = Targetsov;
1182 else if (Nbpnt<=nbptmin && again == 0) {
1185 std::cout <<"Number of points is too small, the step is reduced"<<std::endl;
1187 Standard_Real u1 = Lin->Point(1).Parameter();
1188 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1189 MS = (u2-u1)/(nbptmin+1);
1192 else if(Nbpnt<=nbptmin){
1194 std::cout <<"Number of points is still too small, quit"<<std::endl;
1196 return Standard_False;
1203 ChFi3d_SettraceDRAWWALK(Standard_True);
1204 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1207 Decroch1 = TheWalk.Decroch1End();
1208 Decroch2 = TheWalk.Decroch2End();
1211 Decroch1 = TheWalk.Decroch1Start();
1212 Decroch2 = TheWalk.Decroch2Start();
1214 Last = Lin->Point(Nbpnt).Parameter();
1215 First = Lin->Point(1).Parameter();
1216 return Standard_True;
1220 //=======================================================================
1221 //function : SimulData
1222 //purpose : Heading of the path edge/face for the bypass of obstacle in simulation mode.
1223 //=======================================================================
1225 Standard_Boolean ChFi3d_Builder::SimulData
1226 (Handle(ChFiDS_SurfData)& /*Data*/,
1227 const Handle(ChFiDS_ElSpine)& HGuide,
1228 Handle(BRepBlend_Line)& Lin,
1229 const Handle(Adaptor3d_Surface)& S1,
1230 const Handle(Adaptor3d_TopolTool)& I1,
1231 const Handle(Adaptor3d_Surface)& S2,
1232 const Handle(Adaptor2d_Curve2d)& PC2,
1233 const Handle(Adaptor3d_TopolTool)& I2,
1234 Standard_Boolean& Decroch,
1235 Blend_SurfRstFunction& Func,
1236 Blend_FuncInv& FInv,
1237 Blend_SurfPointFuncInv& FInvP,
1238 Blend_SurfCurvFuncInv& FInvC,
1239 const Standard_Real PFirst,
1240 const Standard_Real MaxStep,
1241 const Standard_Real Fleche,
1242 const Standard_Real TolGuide,
1243 Standard_Real& First,
1244 Standard_Real& Last,
1245 const math_Vector& Soldep,
1246 const Standard_Integer NbSecMin,
1247 const Standard_Boolean Inside,
1248 const Standard_Boolean Appro,
1249 const Standard_Boolean Forward,
1250 const Standard_Boolean RecP,
1251 const Standard_Boolean RecS,
1252 const Standard_Boolean RecRst)
1254 BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
1256 Standard_Boolean reverse = (!Forward || Inside);
1257 Standard_Real SpFirst = HGuide->FirstParameter();
1258 Standard_Real SpLast = HGuide->LastParameter();
1259 Standard_Real Target = SpLast;
1260 if(reverse) Target = SpFirst;
1261 Standard_Real Targetsov = Target;
1263 Standard_Real MS = MaxStep;
1264 Standard_Integer again = 0;
1265 Standard_Integer Nbpnt = 0;
1266 // the starting solution is reframed if needed.
1267 math_Vector ParSol(1,3);
1268 Standard_Real NewFirst = PFirst;
1269 if(RecP || RecS || RecRst){
1270 if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep,
1271 tolesp,TolGuide,RecRst,RecP,RecS,
1275 std::cout<<"ChFi3d_Builder::SimulData : fail calculate first section"<<std::endl;
1277 return Standard_False;
1285 TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last,
1286 MS,TolGuide,ParSol,tolesp,Fleche,Appro);
1287 if (!TheWalk.IsDone()) {
1289 std::cout << "Path not done" << std::endl;
1291 return Standard_False;
1294 if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) {
1296 std::cout << "Not completed" << std::endl;
1300 Lin = TheWalk.Line();
1301 Nbpnt = Lin->NbPoints();
1302 if (Nbpnt <= 1 && again == 0) {
1305 std::cout <<"one point of path MS/50 is attempted."<<std::endl;
1307 MS = MS/50.; Target = Targetsov;
1309 else if (Nbpnt <= NbSecMin && again == 0) {
1312 std::cout <<"Number of points is too small, the step is reduced"<<std::endl;
1314 Standard_Real u1 = Lin->Point(1).Parameter();
1315 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1316 MS = (u2-u1)/(NbSecMin+1);
1319 else if(Nbpnt<=NbSecMin){
1321 std::cout <<"Number of points is still too small, quit"<<std::endl;
1323 return Standard_False;
1330 ChFi3d_SettraceDRAWWALK(Standard_True);
1331 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1333 if(Forward) Decroch = TheWalk.DecrochEnd();
1334 else Decroch = TheWalk.DecrochStart();
1335 Last = Lin->Point(Nbpnt).Parameter();
1336 First = Lin->Point(1).Parameter();
1337 return Standard_True;
1341 //=======================================================================
1342 //function : SimulData
1343 //purpose : Heading of path edge/edge for the bypass
1344 // of obstacle in simulation mode.
1345 //=======================================================================
1347 Standard_Boolean ChFi3d_Builder::SimulData
1348 (Handle(ChFiDS_SurfData)& /*Data*/,
1349 const Handle(ChFiDS_ElSpine)& HGuide,
1350 Handle(BRepBlend_Line)& Lin,
1351 const Handle(Adaptor3d_Surface)& S1,
1352 const Handle(Adaptor2d_Curve2d)& PC1,
1353 const Handle(Adaptor3d_TopolTool)& I1,
1354 Standard_Boolean& Decroch1,
1355 const Handle(Adaptor3d_Surface)& S2,
1356 const Handle(Adaptor2d_Curve2d)& PC2,
1357 const Handle(Adaptor3d_TopolTool)& I2,
1358 Standard_Boolean& Decroch2,
1359 Blend_RstRstFunction& Func,
1360 Blend_SurfCurvFuncInv& FInv1,
1361 Blend_CurvPointFuncInv& FInvP1,
1362 Blend_SurfCurvFuncInv& FInv2,
1363 Blend_CurvPointFuncInv& FInvP2,
1364 const Standard_Real PFirst,
1365 const Standard_Real MaxStep,
1366 const Standard_Real Fleche,
1367 const Standard_Real TolGuide,
1368 Standard_Real& First,
1369 Standard_Real& Last,
1370 const math_Vector& Soldep,
1371 const Standard_Integer NbSecMin,
1372 const Standard_Boolean Inside,
1373 const Standard_Boolean Appro,
1374 const Standard_Boolean Forward,
1375 const Standard_Boolean RecP1,
1376 const Standard_Boolean RecRst1,
1377 const Standard_Boolean RecP2,
1378 const Standard_Boolean RecRst2)
1380 BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1382 Standard_Boolean reverse = (!Forward || Inside);
1383 Standard_Real SpFirst = HGuide->FirstParameter();
1384 Standard_Real SpLast = HGuide->LastParameter();
1385 Standard_Real Target = SpLast;
1386 if(reverse) Target = SpFirst;
1387 Standard_Real Targetsov = Target;
1389 Standard_Real MS = MaxStep;
1390 Standard_Integer again = 0;
1391 Standard_Integer Nbpnt = 0;
1392 // The initial solution is reframed if necessary.
1393 math_Vector ParSol(1,2);
1394 Standard_Real NewFirst = PFirst;
1395 if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1396 if(!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1397 tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1401 std::cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<std::endl;
1403 return Standard_False;
1411 TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1412 MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1413 if (!TheWalk.IsDone()) {
1415 std::cout << "Path not created" << std::endl;
1417 return Standard_False;
1420 if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1422 std::cout << "Not completed" << std::endl;
1426 Lin = TheWalk.Line();
1427 Nbpnt = Lin->NbPoints();
1428 if (Nbpnt <= 1 && again == 0) {
1431 std::cout <<"only one point of path MS/50 is attempted."<<std::endl;
1433 MS = MS/50.; Target = Targetsov;
1435 else if (Nbpnt <= NbSecMin && again == 0) {
1438 std::cout <<"Number of points is too small, the step is reduced"<<std::endl;
1440 Standard_Real u1 = Lin->Point(1).Parameter();
1441 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1442 MS = (u2-u1)/(NbSecMin+1);
1445 else if(Nbpnt<=NbSecMin){
1447 std::cout <<"Number of points is still too small, quit"<<std::endl;
1449 return Standard_False;
1456 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1459 Decroch1 = TheWalk.Decroch1End();
1460 Decroch2 = TheWalk.Decroch2End();
1463 Decroch1 = TheWalk.Decroch1Start();
1464 Decroch2 = TheWalk.Decroch2Start();
1467 Last = Lin->Point(Nbpnt).Parameter();
1468 First = Lin->Point(1).Parameter();
1469 return Standard_True;
1475 //=======================================================================
1476 //function : ComputeData
1477 //purpose : Construction of elementary fillet by path.
1479 //=======================================================================
1481 Standard_Boolean ChFi3d_Builder::ComputeData
1482 (Handle(ChFiDS_SurfData)& Data,
1483 const Handle(ChFiDS_ElSpine)& HGuide,
1484 const Handle(ChFiDS_Spine)& Spine,
1485 Handle(BRepBlend_Line)& Lin,
1486 const Handle(Adaptor3d_Surface)& S1,
1487 const Handle(Adaptor3d_TopolTool)& I1,
1488 const Handle(Adaptor3d_Surface)& S2,
1489 const Handle(Adaptor3d_TopolTool)& I2,
1490 Blend_Function& Func,
1491 Blend_FuncInv& FInv,
1492 const Standard_Real PFirst,
1493 const Standard_Real MaxStep,
1494 const Standard_Real Fleche,
1495 const Standard_Real tolguide,
1496 Standard_Real& First,
1497 Standard_Real& Last,
1498 const Standard_Boolean Inside,
1499 const Standard_Boolean Appro,
1500 const Standard_Boolean Forward,
1501 const math_Vector& Soldep,
1502 Standard_Integer& intf,
1503 Standard_Integer& intl,
1504 Standard_Boolean& Gd1,
1505 Standard_Boolean& Gd2,
1506 Standard_Boolean& Gf1,
1507 Standard_Boolean& Gf2,
1508 const Standard_Boolean RecOnS1,
1509 const Standard_Boolean RecOnS2)
1511 //Get offset guide if exists
1512 Handle(ChFiDS_ElSpine) OffsetHGuide;
1513 if (!Spine.IsNull() &&
1514 Spine->Mode() == ChFiDS_ConstThroatWithPenetrationChamfer)
1516 ChFiDS_ListOfHElSpine& ll = Spine->ChangeElSpines();
1517 ChFiDS_ListOfHElSpine& ll_offset = Spine->ChangeOffsetElSpines();
1518 ChFiDS_ListIteratorOfListOfHElSpine ILES(ll), ILES_offset(ll_offset);
1519 for ( ; ILES.More(); ILES.Next(),ILES_offset.Next())
1521 const Handle(ChFiDS_ElSpine)& aHElSpine = ILES.Value();
1522 if (aHElSpine == HGuide)
1523 OffsetHGuide = ILES_offset.Value();
1527 //The extrensions are created in case of output of two domains
1528 //directly and not by path ( too hasardous ).
1529 Data->FirstExtensionValue(0);
1530 Data-> LastExtensionValue(0);
1532 //The eventual faces are restored to test the jump of edge.
1534 Handle(BRepAdaptor_Surface) HS = Handle(BRepAdaptor_Surface)::DownCast(S1);
1535 if(!HS.IsNull()) F1 = HS->Face();
1536 HS = Handle(BRepAdaptor_Surface)::DownCast(S2);
1537 if(!HS.IsNull()) F2 = HS->Face();
1539 // Path framing variables
1540 Standard_Real TolGuide=tolguide, TolEsp = tolesp;
1541 Standard_Integer nbptmin = 4;
1543 BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide);
1545 //Start of removal, 2D path controls
1546 //that qui s'accomodent mal des surfaces a parametrages non homogenes
1547 //en u et en v are extinguished.
1550 Standard_Real MS = MaxStep;
1551 Standard_Integer Nbpnt;
1552 Standard_Real SpFirst = HGuide->FirstParameter();
1553 Standard_Real SpLast = HGuide->LastParameter();
1555 // When the start point is inside, the path goes first to the left
1556 // to determine the Last for the periodicals.
1557 Standard_Boolean reverse = (!Forward || Inside);
1558 Standard_Real Target;
1561 if(!intf) Target = Last;
1564 Target = SpLast + Abs(SpLast);
1565 if(!intl) Target = Last;
1568 // In case if the singularity is pre-determined,
1569 // the path is indicated.
1570 if (!Spine.IsNull()){
1571 if (Spine->IsTangencyExtremity(Standard_True)) {
1572 TopoDS_Vertex V = Spine->FirstVertex();
1573 TopoDS_Edge E = Spine->Edges(1);
1574 Standard_Real param = Spine->FirstParameter();
1576 if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1577 math_Vector vec(1,4);
1578 BP.ParametersOnS1(vec(1),vec(2));
1579 BP.ParametersOnS2(vec(3),vec(4));
1581 if (Func.IsSolution(vec, tolesp)) {
1582 TheWalk.AddSingularPoint(BP);
1586 if (Spine->IsTangencyExtremity(Standard_False)) {
1587 TopoDS_Vertex V = Spine->LastVertex();
1588 TopoDS_Edge E = Spine->Edges( Spine->NbEdges());
1589 Standard_Real param = Spine->LastParameter();
1591 if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1592 math_Vector vec(1,4);
1593 BP.ParametersOnS1(vec(1),vec(2));
1594 BP.ParametersOnS2(vec(3),vec(4));
1596 if (Func.IsSolution(vec, tolesp)) {
1597 TheWalk.AddSingularPoint(BP);
1603 //The starting solution is reframed if necessary.
1604 //**********************************************//
1605 math_Vector ParSol(1,4);
1606 Standard_Real NewFirst = PFirst;
1607 if(RecOnS1 || RecOnS2){
1608 if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
1609 tolesp,TolGuide,RecOnS1,RecOnS2,
1612 std::cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<std::endl;
1614 return Standard_False;
1621 //First the valid part is calculate, without caring for the extensions.
1622 //******************************************************************//
1623 Standard_Integer again = 0;
1624 Standard_Boolean tchernobyl = 0;
1625 Standard_Real u1sov = 0., u2sov = 0.;
1627 //Max step is relevant, but too great, the vector is required to detect
1629 if( (Abs(Last-First) <= MS * 5.) &&
1630 (Abs(Last-First) >= 0.01*Abs(NewFirst-Target)) ){
1631 MS = Abs(Last-First)*0.2;
1636 if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
1638 if (5*TolGuide > MS) TolGuide = MS/5;
1639 if (5*TolEsp > MS) TolEsp = MS/5;
1641 TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
1642 ParSol,TolEsp,Fleche,Appro);
1643 if (!TheWalk.IsDone()) {
1645 std::cout << "Path is not created" << std::endl;
1647 return Standard_False;
1649 Lin = TheWalk.Line();
1650 if(HGuide->IsPeriodic() && Inside) {
1651 SpFirst = Lin->Point(1).Parameter();
1652 SpLast = SpFirst + HGuide->Period();
1653 HGuide->FirstParameter(SpFirst);
1654 HGuide->LastParameter (SpLast );
1655 HGuide->SetOrigin(SpFirst);
1656 if (!OffsetHGuide.IsNull())
1658 OffsetHGuide->FirstParameter(SpFirst);
1659 OffsetHGuide->LastParameter (SpLast );
1660 OffsetHGuide->SetOrigin(SpFirst);
1663 Standard_Boolean complmnt = Standard_True;
1664 if (Inside) complmnt = TheWalk.Complete(Func,FInv,SpLast);
1667 std::cout << "Not completed" << std::endl;
1669 return Standard_False;
1672 //The result is controlled using two criterions :
1673 //- if there is enough points,
1674 //- if one has gone far enough.
1675 Nbpnt = Lin->NbPoints();
1678 std::cout <<"0 point of path, quit."<<std::endl;
1680 return Standard_False;
1682 Standard_Real fpointpar = Lin->Point(1).Parameter();
1683 Standard_Real lpointpar = Lin->Point(Nbpnt).Parameter();
1685 Standard_Real factor = 1./(nbptmin + 1);
1686 Standard_Boolean okdeb = (Forward && !Inside);
1687 Standard_Boolean okfin = (!Forward && !Inside);
1689 Standard_Integer narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1690 Standard_Integer narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1691 okdeb = (narc1 > 0 || narc2 > 0 || (fpointpar-First) < 10*TolGuide);
1694 Standard_Integer narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1695 Standard_Integer narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1696 okfin = (narc1 > 0 || narc2 > 0 || (Last-lpointpar) < 10*TolGuide);
1698 if(!okdeb || !okfin || Nbpnt == 1){
1699 //It drags, the controls are extended, it is expected to evaluate a
1700 //satisfactory maximum step. If it already done, quit.
1703 std::cout <<"If it drags without control, quit."<<std::endl;
1705 return Standard_False;
1707 tchernobyl = Standard_True;
1711 std::cout <<"only one point of path MS/100 is attempted"<<std::endl;
1712 std::cout <<"and the controls are extended."<<std::endl;
1718 std::cout <<"It drags, the controls are extended."<<std::endl;
1720 MS = (lpointpar-fpointpar)/Nbpnt; //EvalStep(Lin);
1723 else if (Nbpnt < nbptmin){
1726 std::cout <<"Number of points is too small, the step is reduced"<<std::endl;
1730 MS = (lpointpar - fpointpar) * factor;
1732 else if(again == 1){
1733 if(Abs(fpointpar-u1sov)>=TolGuide ||
1734 Abs(lpointpar-u2sov)>=TolGuide){
1736 std::cout <<"Number of points is still too small, the step is reduced"<<std::endl;
1738 MS = (lpointpar - fpointpar) * factor;
1742 std::cout <<"Number of points is still too small, quit"<<std::endl;
1744 return Standard_False;
1754 if(TheWalk.TwistOnS1()){
1755 Data->TwistOnS1(Standard_True);
1757 std::cout<<"Path completed, but TWIST on S1"<<std::endl;
1760 if(TheWalk.TwistOnS2()){
1761 Data->TwistOnS2(Standard_True);
1763 std::cout<<"Parh completed, but TWIST on S2"<<std::endl;
1768 //Here there is a more or less presentable result
1769 //however it covers a the minimum zone.
1770 //The extensions are targeted.
1771 //*****************************//
1773 Gd1 = Gd2 = Gf1 = Gf2 = Standard_False;
1775 Standard_Boolean unseulsuffitdeb = (intf >= 2);
1776 Standard_Boolean unseulsuffitfin = (intl >= 2);
1777 Standard_Boolean noproldeb = (intf >= 3);
1778 Standard_Boolean noprolfin = (intl >= 3);
1780 Standard_Real Rab = 0.03*(SpLast-SpFirst);
1782 Standard_Boolean debarc1 = 0, debarc2 = 0;
1783 Standard_Boolean debcas1 = 0, debcas2 = 0;
1784 Standard_Boolean debobst1 = 0, debobst2 = 0;
1786 Standard_Boolean finarc1 = 0, finarc2 = 0;
1787 Standard_Boolean fincas1 = 0, fincas2 = 0;
1788 Standard_Boolean finobst1 = 0, finobst2 = 0;
1790 Standard_Integer narc1, narc2;
1792 Standard_Boolean backwContinueFailed = Standard_False; // eap
1793 if(reverse && intf) {
1794 narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1795 narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1797 ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1798 Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1799 debarc1 = Standard_True;
1800 if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
1801 //It is checked if there is not an obstacle.
1802 debcas1 = Standard_True;
1803 if(!Spine.IsNull()){
1804 if(Spine->IsPeriodic()){
1808 debobst1 = IsObst(Data->VertexFirstOnS1(),
1809 Spine->FirstVertex(),myVEMap);
1815 ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1816 Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1817 debarc2 = Standard_True;
1818 if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
1819 //It is checked if it is not an obstacle.
1820 debcas2 = Standard_True;
1821 if(!Spine.IsNull()){
1822 if(Spine->IsPeriodic()){
1826 debobst2 = IsObst(Data->VertexFirstOnS2(),
1827 Spine->FirstVertex(),myVEMap);
1832 Standard_Boolean oncontinue = !noproldeb && (narc1 != 0 || narc2 != 0);
1833 if(debobst1 || debobst2) oncontinue = Standard_False;
1834 else if(debcas1 && debcas2) oncontinue = Standard_False;
1835 else if((!debcas1 && debarc1) || (!debcas2 && debarc2)) oncontinue = Standard_False;
1838 TheWalk.ClassificationOnS1(!debarc1);
1839 TheWalk.ClassificationOnS2(!debarc2);
1840 TheWalk.Check2d(Standard_True); // It should be strict (PMN)
1841 TheWalk.Continu(Func,FInv,Target);
1842 TheWalk.ClassificationOnS1(Standard_True);
1843 TheWalk.ClassificationOnS2(Standard_True);
1844 TheWalk.Check2d(Standard_False);
1845 narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1846 narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1847 // modified by eap Fri Feb 8 11:43:48 2002 ___BEGIN___
1850 backwContinueFailed = Lin->StartPointOnFirst().ParameterOnGuide() > Target;
1852 ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1853 Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1854 debarc1 = Standard_True;
1855 if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
1856 //It is checked if it is not an obstacle.
1857 debcas1 = Standard_True;
1858 // if(!Spine.IsNull()) {
1859 // if(Spine->IsPeriodic()){
1863 // debobst1 = IsObst(Data->VertexFirstOnS1(),
1864 // Spine->FirstVertex(),myVEMap);
1872 backwContinueFailed = Lin->StartPointOnSecond().ParameterOnGuide() > Target;
1874 ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1875 Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1876 debarc2 = Standard_True;
1877 if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
1878 //It is checked if it is not an obstacle.
1879 debcas2 = Standard_True;
1880 // if(!Spine.IsNull()){
1881 // if(Spine->IsPeriodic()){
1885 // debobst2 = IsObst(Data->VertexFirstOnS2(),
1886 // Spine->FirstVertex(),myVEMap);
1892 if (backwContinueFailed) {
1893 // if we leave backwContinueFailed as is, we will stop in this direction
1894 // but we are to continue if there are no more faces on the side with arc
1895 // check this condition
1896 const ChFiDS_CommonPoint& aCP
1897 = debarc1 ? Data->VertexFirstOnS1() : Data->VertexFirstOnS2();
1898 if (aCP.IsOnArc() && bif.IsNull())
1899 backwContinueFailed = Standard_False;
1903 Standard_Boolean forwContinueFailed = Standard_False;
1904 // modified by eap Fri Feb 8 11:44:11 2002 ___END___
1905 if(Forward && intl) {
1907 narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1908 narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1910 ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1911 Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1912 finarc1 = Standard_True;
1913 if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
1914 //It is checked if it is not an obstacle.
1915 fincas1 = Standard_True;
1916 if(!Spine.IsNull()){
1917 finobst1 = IsObst(Data->VertexLastOnS1(),
1918 Spine->LastVertex(),myVEMap);
1923 ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1924 Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1925 finarc2 = Standard_True;
1926 if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1927 //It is checked if it is not an obstacle.
1928 fincas2 = Standard_True;
1929 if(!Spine.IsNull()){
1930 finobst2 = IsObst(Data->VertexLastOnS2(),
1931 Spine->LastVertex(),myVEMap);
1935 Standard_Boolean oncontinue = !noprolfin && (narc1 != 0 || narc2 != 0);
1936 if(finobst1 || finobst2) oncontinue = Standard_False;
1937 else if(fincas1 && fincas2) oncontinue = Standard_False;
1938 else if((!fincas1 && finarc1) || (!fincas2 && finarc2)) oncontinue = Standard_False;
1941 TheWalk.ClassificationOnS1(!finarc1);
1942 TheWalk.ClassificationOnS2(!finarc2);
1943 TheWalk.Check2d(Standard_True); // It should be strict (PMN)
1944 TheWalk.Continu(Func,FInv,Target);
1945 TheWalk.ClassificationOnS1(Standard_True);
1946 TheWalk.ClassificationOnS2(Standard_True);
1947 TheWalk.Check2d(Standard_False);
1948 narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1949 narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1950 // modified by eap Fri Feb 8 11:44:57 2002 ___BEGIN___
1953 forwContinueFailed = Lin->EndPointOnFirst().ParameterOnGuide() < Target;
1955 ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1956 Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1957 finarc1 = Standard_True;
1958 if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
1959 //It is checked if it is not an obstacle.
1960 fincas1 = Standard_True;
1961 // if(!Spine.IsNull()){
1962 // finobst1 = IsObst(Data->VertexLastOnS1(),
1963 // Spine->LastVertex(),myVEMap);
1970 forwContinueFailed = Lin->EndPointOnSecond().ParameterOnGuide() < Target;
1972 ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1973 Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1974 finarc2 = Standard_True;
1975 if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1976 //On regarde si ce n'est pas un obstacle.
1977 fincas2 = Standard_True;
1978 // if(!Spine.IsNull()){
1979 // finobst2 = IsObst(Data->VertexLastOnS2(),
1980 // Spine->LastVertex(),myVEMap);
1985 if (forwContinueFailed) {
1986 // if we leave forwContinueFailed as is, we will stop in this direction
1987 // but we are to continue if there are no more faces on the side with arc
1988 // check this condition
1989 const ChFiDS_CommonPoint& aCP
1990 = finarc1 ? Data->VertexLastOnS1() : Data->VertexLastOnS2();
1991 if (aCP.IsOnArc() && bif.IsNull())
1992 forwContinueFailed = Standard_False;
1994 // modified by eap Fri Feb 8 11:45:10 2002 ___END___
1997 Nbpnt = Lin->NbPoints();
1999 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
2001 First = Lin->Point(1).Parameter();
2002 Last = Lin->Point(Nbpnt).Parameter();
2004 // ============= INVALIDATION EVENTUELLE =============
2005 // ------ Preparation des prolongement par plan tangent -----
2006 if(reverse && intf){
2007 Gd1 = debcas1/* && !debobst1*/; // skv(occ67)
2008 Gd2 = debcas2/* && !debobst2*/; // skv(occ67)
2009 if ((debarc1^debarc2) && !unseulsuffitdeb && (First!=SpFirst)) {
2010 // Case of incomplete path, of course this ends badly :
2011 // the result is truncated instead of exit.
2012 Standard_Real sortie;
2013 Standard_Integer ind;
2014 if (debarc1) sortie = Data->VertexFirstOnS1().Parameter();
2015 else sortie = Data->VertexFirstOnS2().Parameter();
2016 if (sortie - First > tolesp) {
2017 ind = SearchIndex(sortie, Lin);
2018 if (Lin->Point(ind).Parameter() == sortie) ind--;
2020 Lin->Remove(1, ind);
2021 UpdateLine(Lin, Standard_True);
2023 Nbpnt = Lin->NbPoints();
2024 First = Lin->Point(1).Parameter();
2027 else if ((intf>=5) && !debarc1 && !debarc2 && (First!=SpFirst)) {
2028 Standard_Real sortie = (2*First+Last)/3;
2029 Standard_Integer ind;
2030 if (sortie - First > tolesp) {
2031 ind = SearchIndex(sortie, Lin);
2032 if (Lin->Point(ind).Parameter() == sortie) ind--;
2033 if (Nbpnt-ind < 3) ind = Nbpnt -3;
2035 Lin->Remove(1, ind);
2036 UpdateLine(Lin, Standard_True);
2038 Nbpnt = Lin->NbPoints();
2039 First = Lin->Point(1).Parameter();
2043 Target = Min((Lin->Point(1).Parameter() - Rab),First);
2044 Target = Max(Target,SpFirst);
2045 Data->FirstExtensionValue(Abs(Lin->Point(1).Parameter()-Target));
2047 if (intf && !unseulsuffitdeb) intf = (Gd1 && Gd2)//;
2048 || backwContinueFailed; // eap
2049 else if (intf && unseulsuffitdeb && (intf<5)) {
2050 intf = (Gd1 || Gd2);
2051 // It is checked if there is no new face.
2053 ((!debcas1 && debarc1) || (!debcas2 && debarc2)) ) intf = 0;
2055 else if (intf < 5) intf = 0;
2058 if(Forward && intl){
2059 Gf1 = fincas1/* && !finobst1*/; // skv(occ67)
2060 Gf2 = fincas2/* && !finobst2*/; // skv(occ67)
2061 if ((finarc1 ^finarc2) && !unseulsuffitfin && (Last!=SpLast)) {
2062 // Case of incomplete path, of course, this ends badly :
2063 // the result is truncated instead of exit.
2064 Standard_Real sortie;
2065 Standard_Integer ind;
2066 if (finarc1) sortie = Data->VertexLastOnS1().Parameter();
2067 else sortie = Data->VertexLastOnS2().Parameter();
2068 if (Last - sortie > tolesp) {
2069 ind = SearchIndex(sortie, Lin);
2070 if (Lin->Point(ind).Parameter() == sortie) ind++;
2072 Lin->Remove(ind, Nbpnt);
2073 UpdateLine(Lin, Standard_False);
2075 Nbpnt = Lin->NbPoints();
2076 Last = Lin->Point(Nbpnt).Parameter();
2079 else if ((intl>=5) && !finarc1 && !finarc2 && (Last!=SpLast) ) {
2080 // The same in case when the entire "Lin" is an extension
2081 Standard_Real sortie = (First+2*Last)/3;
2082 Standard_Integer ind;
2083 if (Last - sortie > tolesp) {
2084 ind = SearchIndex(sortie, Lin);
2085 if (Lin->Point(ind).Parameter() == sortie) ind++;
2086 if (ind < 3) ind = 3;
2088 Lin->Remove(ind, Nbpnt);
2089 UpdateLine(Lin, Standard_False);
2091 Nbpnt = Lin->NbPoints();
2092 Last = Lin->Point(Nbpnt).Parameter();
2096 Target = Max((Lin->Point(Nbpnt).Parameter() + Rab),Last);
2097 Target = Min(Target,SpLast);
2098 Data->LastExtensionValue(Abs(Target-Lin->Point(Nbpnt).Parameter()));
2101 if (intl && !unseulsuffitfin) intl = (Gf1 && Gf2)//;
2102 || forwContinueFailed; // eap
2103 else if (intl && unseulsuffitfin && (intl<5)) {
2104 intl = (Gf1 || Gf2);// It is checked if there is no new face.
2106 ((!fincas1 && finarc1) || (!fincas2 && finarc2)) ) intl = 0;
2108 else if (intl <5) intl = 0;
2110 return Standard_True;
2113 //=======================================================================
2114 //function : SimulData
2116 //=======================================================================
2118 Standard_Boolean ChFi3d_Builder::SimulData
2119 (Handle(ChFiDS_SurfData)& /*Data*/,
2120 const Handle(ChFiDS_ElSpine)& HGuide,
2121 const Handle(ChFiDS_ElSpine)& AdditionalHGuide,
2122 Handle(BRepBlend_Line)& Lin,
2123 const Handle(Adaptor3d_Surface)& S1,
2124 const Handle(Adaptor3d_TopolTool)& I1,
2125 const Handle(Adaptor3d_Surface)& S2,
2126 const Handle(Adaptor3d_TopolTool)& I2,
2127 Blend_Function& Func,
2128 Blend_FuncInv& FInv,
2129 const Standard_Real PFirst,
2130 const Standard_Real MaxStep,
2131 const Standard_Real Fleche,
2132 const Standard_Real tolguide,
2133 Standard_Real& First,
2134 Standard_Real& Last,
2135 const Standard_Boolean Inside,
2136 const Standard_Boolean Appro,
2137 const Standard_Boolean Forward,
2138 const math_Vector& Soldep,
2139 const Standard_Integer NbSecMin,
2140 const Standard_Boolean RecOnS1,
2141 const Standard_Boolean RecOnS2)
2143 BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide);
2144 TheWalk.Check2d(Standard_False);
2146 Standard_Real MS = MaxStep;
2147 Standard_Real TolGuide=tolguide, TolEsp = tolesp;
2148 Standard_Integer Nbpnt = 0;
2149 Standard_Real SpFirst = HGuide->FirstParameter();
2150 Standard_Real SpLast = HGuide->LastParameter();
2151 Standard_Boolean reverse = (!Forward || Inside);
2152 Standard_Real Target;
2160 Standard_Real Targetsov = Target;
2161 Standard_Real u1sov = 0., u2sov = 0.;
2162 // on recadre la solution de depart a la demande.
2163 math_Vector ParSol(1,4);
2164 Standard_Real NewFirst = PFirst;
2165 if(RecOnS1 || RecOnS2){
2166 if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
2167 tolesp,TolGuide,RecOnS1,RecOnS2,
2170 std::cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<std::endl;
2172 return Standard_False;
2178 Standard_Integer again = 0;
2180 // When the start point is inside, the path goes first to the left
2181 // to determine the Last for the periodicals.
2182 if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
2184 if (5*TolGuide > MS) TolGuide = MS/5;
2185 if (5*TolEsp > MS) TolEsp = MS/5;
2188 TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
2189 ParSol,TolEsp,Fleche,Appro);
2191 if (!TheWalk.IsDone()) {
2193 std::cout << "Path not created" << std::endl;
2195 return Standard_False;
2197 Lin = TheWalk.Line();
2199 if(HGuide->IsPeriodic()) {
2200 SpFirst = Lin->Point(1).Parameter();
2201 SpLast = SpFirst + HGuide->Period();
2202 HGuide->FirstParameter(SpFirst);
2203 HGuide->LastParameter (SpLast );
2204 if (!AdditionalHGuide.IsNull())
2206 AdditionalHGuide->FirstParameter(SpFirst);
2207 AdditionalHGuide->LastParameter (SpLast );
2210 Standard_Boolean complmnt = Standard_True;
2211 if (Inside) complmnt = TheWalk.Complete(Func,FInv,SpLast);
2214 std::cout << "Not completed" << std::endl;
2216 return Standard_False;
2219 Nbpnt = Lin->NbPoints();
2220 Standard_Real factor = 1./(NbSecMin + 1);
2223 std::cout <<"0 point of path, quit."<<std::endl;
2225 return Standard_False;
2227 else if (Nbpnt == 1 && again == 0) {
2230 std::cout <<"only one point of path, MS/100 is attempted."<<std::endl;
2232 MS *= 0.01; Target = Targetsov;
2233 u1sov = u2sov = Lin->Point(1).Parameter();
2235 else if (Nbpnt< NbSecMin && again == 0) {
2238 std::cout <<"Number of points is too small, the step is reduced"<<std::endl;
2240 Standard_Real u1 = u1sov = Lin->Point(1).Parameter();
2241 Standard_Real u2 = u2sov = Lin->Point(Nbpnt).Parameter();
2242 MS = (u2-u1)*factor;
2245 else if (Nbpnt < NbSecMin && again == 1) {
2246 Standard_Real u1 = Lin->Point(1).Parameter();
2247 Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
2248 if(Abs(u1-u1sov)>=TolGuide || Abs(u2-u2sov)>=TolGuide){
2251 std::cout <<"Number of points is still too small, the step is reduced"<<std::endl;
2258 std::cout <<"Number of points is still too small, quit"<<std::endl;
2260 return Standard_False;
2263 else if(Nbpnt < NbSecMin){
2265 std::cout <<"Number of points is still too small, quit"<<std::endl;
2267 return Standard_False;
2274 if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
2276 First = Lin->Point(1).Parameter();
2277 Last = Lin->Point(Nbpnt).Parameter();
2278 return Standard_True;