1 // Created on: 1997-01-24
2 // Created by: Laurent BOURESCHE
3 // Copyright (c) 1997-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.
18 #include <Adaptor2d_Curve2d.hxx>
19 #include <Adaptor3d_Surface.hxx>
20 #include <Adaptor3d_HVertex.hxx>
21 #include <Adaptor3d_TopolTool.hxx>
22 #include <Blend_FuncInv.hxx>
23 #include <Blend_Point.hxx>
24 #include <Blend_SurfCurvFuncInv.hxx>
25 #include <Blend_SurfPointFuncInv.hxx>
26 #include <Blend_SurfRstFunction.hxx>
27 #include <BRepBlend_BlendTool.hxx>
28 #include <BRepBlend_Extremity.hxx>
29 #include <BRepBlend_Line.hxx>
30 #include <BRepBlend_SurfRstLineBuilder.hxx>
32 #include <gp_Pnt2d.hxx>
34 #include <gp_Vec2d.hxx>
35 #include <IntSurf.hxx>
36 #include <IntSurf_Transition.hxx>
37 #include <math_FunctionSetRoot.hxx>
42 #include <TColStd_Array1OfInteger.hxx>
43 #include <TColStd_Array1OfReal.hxx>
44 #include <TColgp_Array1OfPnt2d.hxx>
45 #include <TColgp_Array1OfVec.hxx>
46 #include <TColgp_Array1OfVec2d.hxx>
47 #include <TColgp_Array1OfPnt.hxx>
48 #include <Geom_BSplineCurve.hxx>
50 #include <DrawTrSurf.hxx>
52 static Standard_Integer IndexOfSection = 0;
53 extern Standard_Boolean Blend_GettraceDRAWSECT();
54 #ifdef OCCT_DEBUG_BBPP_N_TRDERIV
55 // for debug : visualisation of the section
56 static Standard_Boolean BBPP(const Standard_Real param,
57 Blend_SurfRstFunction& Func,
58 const math_Vector& sol,
59 const Standard_Real tol,
62 if(!Func.IsSolution(sol,tol)) return 0;
63 gp_Pnt pnts = Func.PointOnS();
64 gp_Pnt pntrst = Func.PointOnRst();
65 gp_Pnt2d p2ds = Func.Pnt2dOnS();
66 gp_Pnt2d p2drst = Func.Pnt2dOnRst();
67 Standard_Real w = Func.ParameterOnRst();
68 BP = Blend_Point(pnts,pntrst,param,
70 p2drst.X(),p2drst.Y(),w);
73 static void tracederiv(Blend_SurfRstFunction& Func,
74 const Blend_Point& BP1,
75 const Blend_Point& BP2)
77 Standard_Integer hp,hk,hd,hp2d,i;
78 Func.GetShape(hp,hk,hd,hp2d);
79 TColgp_Array1OfPnt TP1(1,hp);
80 TColgp_Array1OfVec TDP1(1,hp);
81 TColgp_Array1OfPnt2d TP2d1(1,hp2d);
82 TColgp_Array1OfVec2d TDP2d1(1,hp2d);
83 TColStd_Array1OfReal TW1(1,hp);
84 TColStd_Array1OfReal TDW1(1,hp);
85 Func.Section(BP1,TP1,TDP1,TP2d1,TDP2d1,TW1,TDW1);
87 TColgp_Array1OfPnt TP2(1,hp);
88 TColgp_Array1OfVec TDP2(1,hp);
89 TColgp_Array1OfPnt2d TP2d2(1,hp2d);
90 TColgp_Array1OfVec2d TDP2d2(1,hp2d);
91 TColStd_Array1OfReal TW2(1,hp);
92 TColStd_Array1OfReal TDW2(1,hp);
93 Func.Section(BP2,TP2,TDP2,TP2d2,TDP2d2,TW2,TDW2);
95 Standard_Real param1 = BP1.Parameter();
96 Standard_Real param2 = BP2.Parameter();
97 Standard_Real scal = 1./(param1-param2);
100 std::cout<<"control derivatives at point : "<<param1<<std::endl;
102 for(i = 1; i <= hp; i++){
103 std::cout<<std::endl;
104 std::cout<<"point : "<<i<<std::endl;
105 std::cout<<"dx calculated : "<<TDP1(i).X()<<std::endl;
106 std::cout<<"dx estimated : "<<scal*(TP1(i).X()-TP2(i).X())<<std::endl;
107 std::cout<<"dy calculated : "<<TDP1(i).Y()<<std::endl;
108 std::cout<<"dy estimated : "<<scal*(TP1(i).Y()-TP2(i).Y())<<std::endl;
109 std::cout<<"dz calculated : "<<TDP1(i).Z()<<std::endl;
110 std::cout<<"dz estimated : "<<scal*(TP1(i).Z()-TP2(i).Z())<<std::endl;
111 std::cout<<"dw calculated : "<<TDW1(i)<<std::endl;
112 std::cout<<"dw estimated : "<<scal*(TW1(i)-TW2(i))<<std::endl;
114 for(i = 1; i <= hp2d; i++){
115 std::cout<<std::endl;
116 std::cout<<"point 2d : "<<i<<std::endl;
117 std::cout<<"dx calculated : "<<TDP2d1(i).X()<<std::endl;
118 std::cout<<"dx estimated : "<<scal*(TP2d1(i).X()-TP2d2(i).X())<<std::endl;
119 std::cout<<"dy calculated : "<<TDP2d1(i).Y()<<std::endl;
120 std::cout<<"dy estimated : "<<scal*(TP2d1(i).Y()-TP2d2(i).Y())<<std::endl;
124 static void Drawsect(const Standard_Real param,
125 Blend_SurfRstFunction& Func)
127 gp_Pnt pnts = Func.PointOnS();
128 gp_Pnt pntrst = Func.PointOnRst();
129 gp_Pnt2d p2ds = Func.Pnt2dOnS();
130 gp_Pnt2d p2drst = Func.Pnt2dOnRst();
131 Standard_Real w = Func.ParameterOnRst();
132 Blend_Point BP(pnts,pntrst,param,
134 p2drst.X(),p2drst.Y(),w);
135 Standard_Integer hp,hk,hd,hp2d;
136 Func.GetShape(hp,hk,hd,hp2d);
137 TColStd_Array1OfReal TK(1,hk);
139 TColStd_Array1OfInteger TMul(1,hk);
141 TColgp_Array1OfPnt TP(1,hp);
142 TColgp_Array1OfPnt2d TP2d(1,hp2d);
143 TColStd_Array1OfReal TW(1,hp);
144 Func.Section(BP,TP,TP2d,TW);
145 Handle(Geom_BSplineCurve) sect = new Geom_BSplineCurve
150 Standard_CString name = tname ;
151 sprintf(name,"%s_%d","Section",IndexOfSection);
152 DrawTrSurf::Set(name,sect);
157 //=======================================================================
158 //function : ArcToRecadre
159 //purpose : Find a suitable arc
160 // PrevIndex is used to reject an already tested arc
161 //=======================================================================
163 Standard_Integer BRepBlend_SurfRstLineBuilder::
164 ArcToRecadre(const math_Vector& theSol,
165 const Standard_Integer PrevIndex,
168 Standard_Real& ponarc)
170 Standard_Integer IndexSol = 0, nbarc = 0;
171 Standard_Boolean ok = Standard_False;
172 Standard_Boolean byinter = (line->NbPoints() != 0), okinter = 0;
173 Standard_Real distmin = RealLast();
174 Standard_Real uprev = 0.,vprev = 0., prm = 0., dist = 0.;
176 if(byinter) previousP.ParametersOnS(uprev,vprev);
177 pt2d.SetCoord(theSol(1),theSol(2));
178 lastpt2d.SetCoord(uprev,vprev);
181 while (domain1->More()) {
184 ok = okinter = BRepBlend_BlendTool::Inters(pt2d,lastpt2d,
186 domain1->Value(),prm,dist);
188 if(!ok) ok = BRepBlend_BlendTool::Project(pt2d,surf1,
189 domain1->Value(),prm,dist);
191 if (ok && (nbarc != PrevIndex) ) {
192 if (dist<distmin || okinter) {
196 if(okinter && (PrevIndex==0) ) break;
204 //=======================================================================
205 //function : BRepBlend_SurfRstLineBuilder
207 //=======================================================================
209 BRepBlend_SurfRstLineBuilder::BRepBlend_SurfRstLineBuilder
210 (const Handle(Adaptor3d_Surface)& Surf1,
211 const Handle(Adaptor3d_TopolTool)& Domain1,
212 const Handle(Adaptor3d_Surface)& Surf2,
213 const Handle(Adaptor2d_Curve2d)& Rst,
214 const Handle(Adaptor3d_TopolTool)& Domain2):
215 done(Standard_False), sol(1, 3), surf1(Surf1),
216 domain1(Domain1), surf2(Surf2), rst(Rst),
217 domain2(Domain2), tolesp(0.0), tolgui(0.0),
218 pasmax(0.0), fleche(0.0), param(0.0),
219 rebrou(Standard_False), iscomplete(Standard_False),
220 comptra(Standard_False), sens(0.0),
221 decrochdeb(Standard_False), decrochfin(Standard_False)
225 //=======================================================================
228 //=======================================================================
230 void BRepBlend_SurfRstLineBuilder::Perform(Blend_SurfRstFunction& Func,
232 Blend_SurfPointFuncInv& FinvP,
233 Blend_SurfCurvFuncInv& FinvC,
234 const Standard_Real Pdep,
235 const Standard_Real Pmax,
236 const Standard_Real MaxStep,
237 const Standard_Real TolGuide,
238 const math_Vector& ParDep,
239 const Standard_Real Tolesp,
240 const Standard_Real Fleche,
241 const Standard_Boolean Appro)
243 done = Standard_False;
244 iscomplete = Standard_False;
245 comptra = Standard_False;
246 line = new BRepBlend_Line();
247 tolesp = Abs(Tolesp);
248 tolgui = Abs(TolGuide);
249 fleche = Abs(Fleche);
250 rebrou = Standard_False;
251 pasmax = Abs(MaxStep);
253 if (Pmax-Pdep >= 0.) {
266 TopAbs_State siturst,situs;
267 Standard_Boolean decroch;
268 math_Vector tolerance(1,3),infbound(1,3),supbound(1,3);
269 Func.GetTolerance(tolerance,tolesp);
270 Func.GetBounds(infbound,supbound);
271 math_FunctionSetRoot rsnld(Func,tolerance,30);
273 rsnld.Perform(Func,ParDep,infbound,supbound);
275 if (!rsnld.IsDone()) {
279 if (!CheckInside(Func,siturst,situs,decroch)) {
287 State = TestArret(Func,Standard_False,Blend_OK);
288 if (State!=Blend_OK) {
292 if (Blend_GettraceDRAWSECT()){
293 Drawsect(param,Func);
297 line->Append(previousP);
299 previousP.ParametersOnS(U,V);
300 // W = previousP.ParameterOnC();
302 BRepBlend_Extremity ptf1(previousP.PointOnS(),
303 U,V,previousP.Parameter(),tolesp);
304 BRepBlend_Extremity ptf2(previousP.PointOnC(),
305 U,V,previousP.Parameter(),tolesp);
306 if (!previousP.IsTangencyPoint()) {
307 ptf1.SetTangent(previousP.TangentOnS());
308 ptf2.SetTangent(previousP.TangentOnC());
311 line->SetStartPoints(ptf1, ptf2);
314 line->SetEndPoints(ptf1, ptf2);
317 InternalPerform(Func,Finv,FinvP,FinvC,Pmax);
318 done = Standard_True;
321 //=======================================================================
322 //function : PerformFirstSection
324 //=======================================================================
326 Standard_Boolean BRepBlend_SurfRstLineBuilder::PerformFirstSection
327 (Blend_SurfRstFunction& Func,
329 Blend_SurfPointFuncInv& FinvP,
330 Blend_SurfCurvFuncInv& FinvC,
331 const Standard_Real Pdep,
332 const Standard_Real Pmax,
333 const math_Vector& ParDep,
334 const Standard_Real Tolesp,
335 const Standard_Real TolGuide,
336 const Standard_Boolean RecRst,
337 const Standard_Boolean RecP,
338 const Standard_Boolean RecS,
342 done = Standard_False;
343 iscomplete = Standard_False;
344 comptra = Standard_False;
345 line = new BRepBlend_Line();
346 tolesp = Abs(Tolesp);
347 tolgui = Abs(TolGuide);
348 rebrou = Standard_False;
350 if (Pmax-Pdep >= 0.) {
356 Blend_Status State = Blend_OnRst12;
357 Standard_Real trst = 0.;
358 Standard_Boolean recadp,recadrst,recads;
359 Standard_Real wp,wrst,ws;
360 Standard_Real U = 0.,V = 0.;
361 math_Vector infbound(1,3),supbound(1,3),tolerance(1,3);
362 math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
363 Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
364 Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
365 Handle(Adaptor2d_Curve2d) Arc;
366 wp = wrst = ws = Pmax;
369 Func.GetTolerance(tolerance,tolesp);
370 Func.GetBounds(infbound,supbound);
372 math_FunctionSetRoot rsnld(Func,tolerance,30);
373 rsnld.Perform(Func,ParDep,infbound,supbound);
374 if (!rsnld.IsDone()) return Standard_False;
377 recads = RecS && Recadre(FinvC,solinvs,Arc,IsVtxs,Vtxs);
381 recadp = RecP && Recadre(FinvP,solinvp,IsVtxp,Vtxp);
385 recadrst = RecRst && Recadre(Func,Finv,solinvrst,IsVtxrst,Vtxrst);
389 if (!recads && !recadp && !recadrst) return Standard_False;
390 if (recadp && recadrst) {
391 if(sens*(wrst-wp) > tolgui){ //first one leaves the domain
395 trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
409 trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
412 recadrst = Standard_True;
419 if(recads && recadrst){
420 if(Abs(ws - wrst) < tolgui){
421 State = Blend_OnRst12;
422 param = 0.5*(ws+wrst);
427 else if(sens*(ws-wrst)<0){
429 State = Blend_OnRst1;
431 Arc->Value(solinvs(3)).Coord(U,V);
438 State = Blend_OnRst2;
448 State = Blend_OnRst1;
450 Arc->Value(solinvs(3)).Coord(U,V);
458 State = Blend_OnRst2;
465 State = TestArret(Func,Standard_False,State);
468 return Standard_True;
471 //=======================================================================
472 //function : Complete
474 //=======================================================================
476 Standard_Boolean BRepBlend_SurfRstLineBuilder::Complete(Blend_SurfRstFunction& Func,
478 Blend_SurfPointFuncInv& FinvP,
479 Blend_SurfCurvFuncInv& FinvC,
480 const Standard_Real Pmin)
482 if (!done) {throw StdFail_NotDone();}
483 if (iscomplete) {return Standard_True;}
485 previousP = line->Point(1);
488 previousP = line->Point(line->NbPoints());
491 param = previousP.Parameter();
492 previousP.ParametersOnS(sol(1),sol(2));
493 sol(3) = previousP.ParameterOnC();
495 InternalPerform(Func,Finv,FinvP,FinvC,Pmin);
496 iscomplete = Standard_True;
497 return Standard_True;
500 //=======================================================================
501 //function : InternalPerform
503 //=======================================================================
505 void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction& Func,
507 Blend_SurfPointFuncInv& FinvP,
508 Blend_SurfCurvFuncInv& FinvC,
509 const Standard_Real Bound)
511 Standard_Real stepw = pasmax;
512 Standard_Integer nbp = line->NbPoints();
513 if(nbp >= 2){ //The last step is reproduced if it is not too small.
515 stepw = (line->Point(2).Parameter() - line->Point(1).Parameter());
518 stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter());
520 stepw = Max(stepw,100.*tolgui);
522 Standard_Real parprec = param;
523 if (sens*(parprec - Bound) >= -tolgui) {
526 Blend_Status State = Blend_OnRst12;
527 TopAbs_State situonc = TopAbs_UNKNOWN, situons = TopAbs_UNKNOWN;
528 Standard_Boolean decroch = Standard_False;
529 Standard_Boolean Arrive,recadp,recadrst,recads,echecrecad;
530 Standard_Real wp,wrst,ws;
531 Standard_Real U = 0.,V = 0.;
532 Standard_Real trst = 0.;
533 math_Vector infbound(1,3),supbound(1,3);
534 math_Vector parinit(1,3),tolerance(1,3);
535 math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
536 Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
537 Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
538 BRepBlend_Extremity Extrst,Exts;
539 Handle(Adaptor2d_Curve2d) Arc;
541 //IntSurf_Transition Tline,Tarc;
543 Func.GetTolerance(tolerance,tolesp);
544 Func.GetBounds(infbound,supbound);
546 math_FunctionSetRoot rsnld(Func,tolerance,30);
549 Arrive = Standard_False;
550 param = parprec + sens*stepw;
551 if(sens *(param - Bound) > 0.) {
552 stepw = sens*(Bound - parprec)*0.5;
553 param = parprec + sens*stepw;
557 Standard_Boolean bonpoint = 1;
558 #ifdef OCCT_DEBUG_BBPP_N_TRDERIV
561 rsnld.Perform(Func,parinit,infbound,supbound);
562 if (rsnld.IsDone()) {
565 if(BBPP(param,Func,sol,tolesp,bp1)){
566 Standard_Real dw = 1.e-10;
568 rsnld.Perform(Func,parinit,infbound,supbound);
569 if (rsnld.IsDone()) {
572 if(BBPP(param+dw,Func,sol,tolesp,bp2)){
573 tracederiv(Func,bp1,bp2);
581 rsnld.Perform(Func,parinit,infbound,supbound);
583 if (rsnld.IsDone()) {
585 if(!CheckInside(Func,situonc,situons,decroch) && line->NbPoints() == 1){
586 State = Blend_StepTooLarge;
591 State = Blend_StepTooLarge;
595 wp = wrst = ws = Bound;
596 recadp = recadrst = recads = Standard_False;
597 echecrecad = Standard_False;
598 if (situons == TopAbs_OUT || situons == TopAbs_ON) {
599 // pb inverse rst/rst
600 recads = Recadre(FinvC,solinvs,Arc,IsVtxs,Vtxs);
603 // It is necessary to reevaluate the deviation (BUC60360)
606 Arc->Value(solinvs(3)).Coord(U,V);
610 decroch = Func.Decroch(sol, t, n);
613 echecrecad = Standard_True;
616 if (situonc == TopAbs_OUT || situonc == TopAbs_ON) {
617 // pb inverse point/surf
618 recadp = Recadre(FinvP,solinvp,IsVtxp,Vtxp);
623 echecrecad = Standard_True;
627 // pb inverse rst/surf
628 recadrst = Recadre(Func,Finv,solinvrst,IsVtxrst,Vtxrst);
633 echecrecad = Standard_True;
637 if(recadp || recads || recadrst) echecrecad = Standard_False;
639 if (recadp && recadrst) {
640 if(sens*(wrst-wp) > tolgui){ //first one leaves the domain
644 trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
659 trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
662 recadrst = Standard_True;
670 if(recads && recadrst){
671 if(Abs(ws - wrst) < tolgui){
672 State = Blend_OnRst12;
673 param = 0.5*(ws+wrst);
678 else if(sens*(ws-wrst)<0){
681 State = Blend_OnRst1;
683 Arc->Value(solinvs(3)).Coord(U,V);
690 State = Blend_OnRst2;
700 State = Blend_OnRst1;
702 Arc->Value(solinvs(3)).Coord(U,V);
710 State = Blend_OnRst2;
720 State = TestArret(Func,Standard_True,State);
723 // Failed reframing. Leave with PointsConfondus
725 std::cout<<"SurfRstLineBuilder : failed reframing"<<std::endl;
727 State = Blend_SamePoints;
735 if (Blend_GettraceDRAWSECT()){
736 Drawsect(param,Func);
741 line->Append(previousP);
744 line->Prepend(previousP);
749 if (param == Bound) {
750 Arrive = Standard_True;
751 Exts.SetValue(previousP.PointOnS(),
753 previousP.Parameter(),tolesp);
754 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
755 // Indicate end on Bound.
758 param = param + sens*stepw;
759 if (sens*(param - Bound) > - tolgui) {
766 case Blend_StepTooLarge :
769 if (Abs(stepw) < tolgui) {
770 previousP.ParametersOnS(U,V);
771 Exts.SetValue(previousP.PointOnS(),U,V,
772 previousP.Parameter(),tolesp);
773 Extrst.SetValue(previousP.PointOnC(),
774 previousP.ParameterOnC(),
775 previousP.Parameter(),tolesp);
776 Arrive = Standard_True;
777 if (line->NbPoints()>=2) {
778 // Indicate that one stops during the processing
780 std::cout<<"SurfRstLineBuilder : No advancement in the processing"<<std::endl;
785 param = parprec + sens*stepw; // no risk to exceed Bound.
790 case Blend_StepTooSmall :
793 if (Blend_GettraceDRAWSECT()){
794 Drawsect(param,Func);
799 line->Append(previousP);
802 line->Prepend(previousP);
807 stepw = Min(1.5*stepw,pasmax);
808 if (param == Bound) {
809 Arrive = Standard_True;
810 Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),
811 previousP.Parameter(),tolesp);
812 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
813 // Indicate end on Bound.
816 param = param + sens*stepw;
817 if (sens*(param - Bound) > - tolgui) {
827 if (Blend_GettraceDRAWSECT()){
828 Drawsect(param,Func);
832 line->Append(previousP);
835 line->Prepend(previousP);
837 MakeExtremity(Exts,Standard_True,Arc,solinvs(3),IsVtxs,Vtxs);
838 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
839 Arrive = Standard_True;
846 if (Blend_GettraceDRAWSECT()){
847 Drawsect(param,Func);
851 line->Append(previousP);
854 line->Prepend(previousP);
856 Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),
857 previousP.Parameter(),tolesp);
858 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
859 Arrive = Standard_True;
866 if (Blend_GettraceDRAWSECT()){
867 Drawsect(param,Func);
871 line->Append(previousP);
874 line->Prepend(previousP);
876 MakeExtremity(Exts,Standard_True,Arc,solinvs(1),IsVtxs,Vtxs);
877 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
878 Arrive = Standard_True;
882 case Blend_SamePoints :
886 std::cout << "SurfRstLineBuilder Points mixed in the processing" << std::endl;
888 previousP.ParametersOnS(U,V);
889 Exts.SetValue(previousP.PointOnS(),U,V,
890 previousP.Parameter(),tolesp);
891 Extrst.SetValue(previousP.PointOnC(),
892 previousP.ParameterOnC(),
893 previousP.Parameter(),tolesp);
894 Arrive = Standard_True;
902 line->SetEndPoints(Exts,Extrst);
903 decrochfin = decroch;
906 line->SetStartPoints(Exts,Extrst);
907 decrochdeb = decroch;
913 //=======================================================================
915 //purpose : Reframe section Surface / Restriction
916 //=======================================================================
918 Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfCurvFuncInv& FinvC,
920 Handle(Adaptor2d_Curve2d)& Arc,
921 Standard_Boolean& IsVtx,
922 Handle(Adaptor3d_HVertex)& Vtx)
924 Standard_Boolean recadre = Standard_False;
926 gp_Pnt2d pt2d, lastpt2d;
927 Standard_Integer IndexSol, nbarc;
930 IndexSol = ArcToRecadre(sol, 0, lastpt2d, pt2d, pmin);
932 IsVtx = Standard_False;
934 return Standard_False;
939 while (nbarc < IndexSol) {
943 Arc = domain1->Value();
947 math_Vector toler(1,3),infb(1,3),supb(1,3);
948 FinvC.GetTolerance(toler,tolesp);
949 FinvC.GetBounds(infb,supb);
954 math_FunctionSetRoot rsnld(FinvC,toler,30);
955 rsnld.Perform(FinvC,Solinv,infb,supb);
957 if (!rsnld.IsDone()) {
959 std::cout << "SurfRstLineBuilder : RSNLD not done "<< std::endl << std::endl;
963 // It is necessary to check the value of the function
965 recadre = FinvC.IsSolution(Solinv,tolesp);
968 // In case of fail, it is checked if another arc
969 // can be useful (case of output at the proximity of a vertex)
972 IndexSol = ArcToRecadre(sol, IndexSol,
973 lastpt2d, pt2d, pmin);
975 return Standard_False; // No other solution
980 while (nbarc < IndexSol) {
985 Arc = domain1->Value();
988 FinvC.GetTolerance(toler,tolesp);
989 FinvC.GetBounds(infb,supb);
993 math_FunctionSetRoot aRsnld(FinvC,toler,30);
994 aRsnld.Perform(FinvC,Solinv,infb,supb);
996 if (!aRsnld.IsDone()) {
998 std::cout << "SurfRstLineBuilder : RSNLD not done "<< std::endl << std::endl;
1002 // It is necessary to check the value of the function
1003 aRsnld.Root(Solinv);
1004 recadre = FinvC.IsSolution(Solinv,tolesp);
1009 Standard_Real w = Solinv(2);
1010 if(w < rst->FirstParameter() - toler(2)||
1011 w > rst->LastParameter() + toler(2)){
1012 return Standard_False;
1014 domain1->Initialize(Arc);
1015 domain1->InitVertexIterator();
1016 IsVtx = !domain1->MoreVertex();
1018 Vtx = domain1->Vertex();
1019 if (Abs(BRepBlend_BlendTool::Parameter(Vtx,Arc)-Solinv(3)) <=
1020 BRepBlend_BlendTool::Tolerance(Vtx,Arc)) {
1021 IsVtx = Standard_True;
1024 domain1->NextVertex();
1025 IsVtx = !domain1->MoreVertex();
1028 if (!domain1->MoreVertex()) {
1029 IsVtx = Standard_False;
1031 return Standard_True;
1033 return Standard_False;
1036 //=======================================================================
1037 //function : Recadre
1039 //=======================================================================
1041 Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfRstFunction& Func,
1042 Blend_FuncInv& Finv,
1043 math_Vector& Solinv,
1044 Standard_Boolean& IsVtx,
1045 Handle(Adaptor3d_HVertex)& Vtx)
1047 math_Vector toler(1,4),infb(1,4),supb(1,4);
1048 Finv.GetTolerance(toler,tolesp);
1049 Finv.GetBounds(infb,supb);
1055 math_FunctionSetRoot rsnld(Finv,toler,30);
1056 rsnld.Perform(Finv,Solinv,infb,supb);
1057 if (!rsnld.IsDone()) {
1059 std::cout << "SurfRstLineBuilder :RSNLD not done "<< std::endl;
1061 return Standard_False;
1065 if(Finv.IsSolution(Solinv,tolesp)){
1066 gp_Pnt2d p2d(Solinv(3),Solinv(4));
1067 TopAbs_State situ = domain1->Classify(p2d,Min(toler(3),toler(4)),0);
1068 if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
1069 return Standard_False;
1071 domain2->Initialize(rst);
1072 domain2->InitVertexIterator();
1073 IsVtx = !domain2->MoreVertex();
1075 Vtx = domain2->Vertex();
1076 if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-Solinv(1)) <=
1077 BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
1078 IsVtx = Standard_True;
1081 domain2->NextVertex();
1082 IsVtx = !domain2->MoreVertex();
1085 if (!domain2->MoreVertex()) {
1086 IsVtx = Standard_False;
1088 // The section is recalculated by direct resolution, otherwise
1089 // incoherences between the parameter and the ground caused by yawn are returned.
1091 math_Vector infbound(1,3),supbound(1,3);
1092 math_Vector parinit(1,3),tolerance(1,3);
1093 Func.GetTolerance(tolerance,tolesp);
1094 Func.GetBounds(infbound,supbound);
1096 math_FunctionSetRoot rsnld2(Func,tolerance,30);
1097 parinit(1) = Solinv(3);
1098 parinit(2) = Solinv(4);
1099 parinit(3) = Solinv(1);
1100 Func.Set(Solinv(2));
1101 rsnld2.Perform(Func,parinit,infbound,supbound);
1102 if(!rsnld2.IsDone()) return Standard_False;
1103 rsnld2.Root(parinit);
1104 Solinv(3) = parinit(1);
1105 Solinv(4) = parinit(2);
1106 Solinv(1) = parinit(3);
1107 return Standard_True;
1109 return Standard_False;
1112 //=======================================================================
1113 //function : Recadre
1115 //=======================================================================
1117 Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfPointFuncInv& FinvP,
1118 math_Vector& Solinv,
1119 Standard_Boolean& IsVtx,
1120 Handle(Adaptor3d_HVertex)& Vtx)
1124 Standard_Real firstrst = rst->FirstParameter();
1125 Standard_Real lastrst = rst->LastParameter();
1126 Standard_Real wpoint = firstrst;
1127 if((sol(3) - firstrst) > (lastrst - sol(3))) wpoint = lastrst;
1128 p2drst = rst->Value(wpoint);
1129 gp_Pnt thepoint = surf2->Value(p2drst.X(),p2drst.Y());
1131 FinvP.Set(thepoint);
1132 math_Vector toler(1,3),infb(1,3),supb(1,3);
1133 FinvP.GetTolerance(toler,tolesp);
1134 FinvP.GetBounds(infb,supb);
1139 math_FunctionSetRoot rsnld(FinvP,toler,30);
1140 rsnld.Perform(FinvP,Solinv,infb,supb);
1141 if (!rsnld.IsDone()) {
1143 std::cout << "SurfRstLineBuilder :RSNLD not done "<< std::endl;
1145 return Standard_False;
1149 if(FinvP.IsSolution(Solinv,tolesp)){
1150 gp_Pnt2d p2d(Solinv(2),Solinv(3));
1151 TopAbs_State situ = domain1->Classify(p2d,Min(toler(2),toler(3)),0);
1152 if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
1153 return Standard_False;
1155 domain2->Initialize(rst);
1156 domain2->InitVertexIterator();
1157 IsVtx = !domain2->MoreVertex();
1159 Vtx = domain2->Vertex();
1160 if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-wpoint) <=
1161 BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
1162 IsVtx = Standard_True;
1165 domain2->NextVertex();
1166 IsVtx = !domain2->MoreVertex();
1169 if (!domain2->MoreVertex()) {
1170 IsVtx = Standard_False;
1172 return Standard_True;
1174 return Standard_False;
1177 //=======================================================================
1178 //function : Transition
1180 //=======================================================================
1182 void BRepBlend_SurfRstLineBuilder::Transition(const Standard_Boolean OnFirst,
1183 const Handle(Adaptor2d_Curve2d)& Arc,
1184 const Standard_Real Param,
1185 IntSurf_Transition& TLine,
1186 IntSurf_Transition& TArc)
1188 Standard_Boolean computetranstionaveclacorde = 0;
1190 Blend_Point prevprev;
1192 if(previousP.IsTangencyPoint()){
1193 if(line->NbPoints() < 2) return;
1194 computetranstionaveclacorde = 1;
1196 prevprev = line->Point(2);
1199 prevprev = line->Point(line->NbPoints() - 1);
1206 gp_Vec d1u,d1v,normale,tgrst;
1208 Arc->D1(Param,p2d,dp2d);
1210 surf1->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v);
1211 if(!computetranstionaveclacorde) tgline = previousP.TangentOnS1();
1212 else tgline = gp_Vec(prevprev.PointOnS(),previousP.PointOnS());
1215 surf2->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v);
1216 if(!computetranstionaveclacorde) tgline = previousP.TangentOnS2();
1217 else tgline = gp_Vec(prevprev.PointOnC(),previousP.PointOnC());
1220 tgrst.SetLinearForm(dp2d.X(),d1u,dp2d.Y(),d1v);
1221 normale = d1u.Crossed(d1v);
1223 IntSurf::MakeTransition(tgline,tgrst,normale,TLine,TArc);
1226 //=======================================================================
1227 //function : MakeExtremity
1229 //=======================================================================
1231 void BRepBlend_SurfRstLineBuilder::MakeExtremity(BRepBlend_Extremity& Extrem,
1232 const Standard_Boolean OnFirst,
1233 const Handle(Adaptor2d_Curve2d)& Arc,
1234 const Standard_Real Param,
1235 const Standard_Boolean IsVtx,
1236 const Handle(Adaptor3d_HVertex)& Vtx)
1238 IntSurf_Transition Tline,Tarc;
1240 Handle(Adaptor3d_TopolTool) Iter;
1242 Extrem.SetValue(previousP.PointOnS(),
1244 previousP.Parameter(),tolesp);
1245 if (!previousP.IsTangencyPoint())
1246 Extrem.SetTangent(previousP.TangentOnS());
1250 Extrem.SetValue(previousP.PointOnC(),
1252 previousP.Parameter(),tolesp);
1253 if (!previousP.IsTangencyPoint())
1254 Extrem.SetTangent(previousP.TangentOnC());
1260 Transition(OnFirst,Arc,Param,Tline,Tarc);
1261 Extrem.AddArc(Arc,Param,Tline,Tarc);
1264 Extrem.SetVertex(Vtx);
1265 while (Iter->More()) {
1266 Handle(Adaptor2d_Curve2d) arc = Iter->Value();
1268 Iter->Initialize(arc);
1269 Iter->InitVertexIterator();
1270 while (Iter->MoreVertex()) {
1271 if (Iter->Identical(Vtx,Iter->Vertex())) {
1272 prm = BRepBlend_BlendTool::Parameter(Vtx,arc);
1273 Transition(OnFirst,arc,prm,Tline,Tarc);
1274 Extrem.AddArc(arc,prm,Tline,Tarc);
1280 Transition(OnFirst,arc,Param,Tline,Tarc);
1281 Extrem.AddArc(arc,Param,Tline,Tarc);
1288 //=======================================================================
1289 //function : CheckDeflectionOnSurf
1291 //=======================================================================
1293 Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnSurf(const Blend_Point& CurPoint)
1295 //Controls 3d of Blend_CSWalking.
1297 //rule by tests in U4 corresponds to 11.478 d
1298 const Standard_Real CosRef3D = 0.98;
1299 Standard_Real Cosi=0, Cosi2=0;
1300 Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
1301 Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
1303 gp_Pnt Psurf = CurPoint.PointOnS();
1305 if(!curpointistangent){
1306 Tgsurf = CurPoint.TangentOnS();
1308 gp_Pnt prevP = previousP.PointOnS();
1310 if(!prevpointistangent){
1311 prevTg = previousP.TangentOnS();
1313 Standard_Real Norme,prevNorme = 0.;
1314 gp_Vec Corde(prevP,Psurf);
1315 Norme = Corde.SquareMagnitude();
1316 // if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
1317 if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
1319 if (Norme <= tolesp*tolesp){
1320 // it can be necessary to force same point
1321 return Blend_SamePoints;
1323 if(!prevpointistangent){
1324 if(prevNorme <= tolesp*tolesp) {
1325 return Blend_SamePoints;
1327 Cosi = sens*Corde*prevTg;
1328 if (Cosi <0.) { // angle 3d>pi/2. --> return back
1329 return Blend_Backward;
1332 Cosi2 = Cosi * Cosi / prevNorme / Norme;
1333 if (Cosi2 < CosRef3D) {
1334 return Blend_StepTooLarge;
1338 if(!curpointistangent){
1339 // Check if it is necessary to control the sign of prevtg*Tgsurf
1340 Cosi = sens*Corde*Tgsurf;
1341 Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
1342 if (Cosi2 < CosRef3D || Cosi < 0.) {
1343 return Blend_StepTooLarge;
1347 if(!curpointistangent && !prevpointistangent){
1348 // Estimation of the current arrow
1349 Standard_Real FlecheCourante =
1350 (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.;
1352 if (FlecheCourante <= 0.25*fleche*fleche) {
1353 return Blend_StepTooSmall;
1355 if (FlecheCourante > fleche*fleche) {
1357 return Blend_StepTooLarge;
1364 //=======================================================================
1365 //function : CheckDeflectionOnRst
1367 //=======================================================================
1369 Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnRst(const Blend_Point& CurPoint)
1371 //Controls 3D of Blend_CSWalking.
1373 // rule by tests in U4 corresponds to 11.478 d
1374 const Standard_Real CosRef3D = 0.98;
1375 Standard_Real Cosi, Cosi2;
1376 Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
1377 Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
1379 gp_Pnt Psurf = CurPoint.PointOnC();
1381 if(!curpointistangent){
1382 Tgsurf = CurPoint.TangentOnC();
1384 gp_Pnt prevP = previousP.PointOnC();
1386 if(!prevpointistangent){
1387 prevTg = previousP.TangentOnC();
1389 Standard_Real Norme,prevNorme = 0.;
1390 gp_Vec Corde(prevP,Psurf);
1391 Norme = Corde.SquareMagnitude();
1392 // if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
1393 if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
1395 if (Norme <= tolesp*tolesp){
1396 // it can be necessary to force same point
1397 return Blend_SamePoints;
1399 if(!prevpointistangent){
1400 if(prevNorme <= tolesp*tolesp) {
1401 return Blend_SamePoints;
1403 Cosi = sens*Corde*prevTg;
1404 if (Cosi <0.) { // angle 3d>pi/2. --> return back
1405 return Blend_Backward;
1408 Cosi2 = Cosi * Cosi / prevNorme / Norme;
1409 if (Cosi2 < CosRef3D) {
1410 return Blend_StepTooLarge;
1414 if(!curpointistangent){
1415 // Check if it is necessary to control the sign of prevtg*Tgsurf
1416 Cosi = sens*Corde*Tgsurf;
1417 Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
1418 if (Cosi2 < CosRef3D || Cosi < 0.) {
1419 return Blend_StepTooLarge;
1423 if(!curpointistangent && !prevpointistangent){
1424 // Estimation of the current arrow
1425 Standard_Real FlecheCourante =
1426 (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.;
1428 if (FlecheCourante <= 0.25*fleche*fleche) {
1429 return Blend_StepTooSmall;
1431 if (FlecheCourante > fleche*fleche) {
1433 return Blend_StepTooLarge;
1439 static IntSurf_TypeTrans ConvOrToTra(const TopAbs_Orientation O)
1441 if(O == TopAbs_FORWARD) return IntSurf_In;
1445 //=======================================================================
1446 //function : TestArret
1448 //=======================================================================
1450 Blend_Status BRepBlend_SurfRstLineBuilder::TestArret(Blend_SurfRstFunction& Func,
1451 const Standard_Boolean TestDeflection,
1452 const Blend_Status State)
1457 gp_Vec2d tg2ds,tg2drst;
1458 Blend_Status StateS,StateRst;
1459 IntSurf_TypeTrans tras = IntSurf_Undecided, trarst = IntSurf_Undecided;
1460 Blend_Point curpoint;
1462 if (Func.IsSolution(sol,tolesp)) {
1463 Standard_Boolean curpointistangent = Func.IsTangencyPoint();
1464 pts = Func.PointOnS();
1465 ptrst = Func.PointOnRst();
1466 pt2drst = Func.Pnt2dOnRst();
1467 if(curpointistangent){
1468 curpoint.SetValue(pts,ptrst,param,sol(1),sol(2),
1469 pt2drst.X(),pt2drst.Y(),sol(3));
1472 tgs = Func.TangentOnS();
1473 tgrst = Func.TangentOnRst();
1474 tg2ds = Func.Tangent2dOnS();
1475 tg2drst = Func.Tangent2dOnRst();
1477 curpoint.SetValue(pts,ptrst,param,sol(1),sol(2),
1478 pt2drst.X(),pt2drst.Y(),sol(3),
1479 tgs,tgrst,tg2ds,tg2drst);
1481 if (TestDeflection) {
1482 StateS = CheckDeflectionOnSurf(curpoint);
1483 StateRst = CheckDeflectionOnRst(curpoint);
1486 StateS = StateRst = Blend_OK;
1488 if (StateS == Blend_Backward) {
1489 StateS = Blend_StepTooLarge;
1490 rebrou= Standard_True;
1492 if (StateRst == Blend_Backward) {
1493 StateRst = Blend_StepTooLarge;
1494 rebrou = Standard_True;
1496 if (StateS == Blend_StepTooLarge ||
1497 StateRst == Blend_StepTooLarge) {
1498 return Blend_StepTooLarge;
1501 if (!comptra && !curpointistangent) {
1503 Func.Decroch(sol,nors,tgsecs);
1505 Standard_Real testra = tgsecs.Dot(nors.Crossed(tgs));
1506 if (Abs(testra) > tolesp) {
1510 else if (testra >0.) {
1513 gp_Pnt2d p2drstref; gp_Vec2d tg2drstref;
1514 rst->D1(sol(3),p2drstref,tg2drstref);
1515 testra = tg2drst.Dot(tg2drstref);
1516 TopAbs_Orientation Or = domain2->Orientation(rst);
1517 if (Abs(testra) > 1.e-8) {
1519 trarst = ConvOrToTra(TopAbs::Reverse(Or));
1521 else if (testra >0.) {
1522 trarst = ConvOrToTra(Or);
1524 comptra = Standard_True;
1525 line->Set(tras,trarst);
1529 if (StateS == Blend_OK ||
1530 StateRst == Blend_OK ) {
1531 previousP = curpoint;
1534 if (StateS == Blend_StepTooSmall &&
1535 StateRst == Blend_StepTooSmall) {
1536 previousP = curpoint;
1537 if (State == Blend_OK) {
1538 return Blend_StepTooSmall;
1544 if (State == Blend_OK) {
1545 return Blend_SamePoints;
1551 return Blend_StepTooLarge;
1554 //=======================================================================
1555 //function : CheckInside
1557 //=======================================================================
1559 Standard_Boolean BRepBlend_SurfRstLineBuilder::CheckInside(Blend_SurfRstFunction& Func,
1560 TopAbs_State& SituOnC,
1561 TopAbs_State& SituOnS,
1562 Standard_Boolean& Decroch)
1564 math_Vector tolerance(1,3);
1565 Func.GetTolerance(tolerance,tolesp);
1567 Standard_Real w = sol(3);
1568 if(w < rst->FirstParameter() - tolerance(3)||
1569 w > rst->LastParameter() + tolerance(3)){
1570 SituOnC = TopAbs_OUT;
1572 else if (w > rst->FirstParameter() &&
1573 w < rst->LastParameter()){
1574 SituOnC = TopAbs_IN;
1576 else SituOnC = TopAbs_ON;
1579 gp_Pnt2d p2d(sol(1),sol(2));
1580 SituOnS = domain1->Classify(p2d,Min(tolerance(1),tolerance(2)),0);
1584 Decroch = Func.Decroch(sol,tgs,nors);
1586 return (SituOnC == TopAbs_IN && SituOnS == TopAbs_IN && !Decroch);