1 // Created on: 1997-01-24
2 // Created by: Laurent BOURESCHE
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
24 #include <BRepBlend_SurfRstLineBuilder.ixx>
25 #include <BRepBlend_BlendTool.hxx>
27 #include <IntSurf.hxx>
28 #include <math_FunctionSetRoot.hxx>
29 #include <gp_Pnt2d.hxx>
31 #include <gp_Vec2d.hxx>
35 #include <TColStd_Array1OfInteger.hxx>
36 #include <TColStd_Array1OfReal.hxx>
37 #include <TColgp_Array1OfPnt2d.hxx>
38 #include <TColgp_Array1OfVec.hxx>
39 #include <TColgp_Array1OfVec2d.hxx>
40 #include <TColgp_Array1OfPnt.hxx>
41 #include <Geom_BSplineCurve.hxx>
43 #include <DrawTrSurf.hxx>
45 static Standard_Integer IndexOfSection = 0;
46 extern Standard_Boolean Blend_GettraceDRAWSECT();
47 // for debug : visualisation of the section
48 static Standard_Boolean BBPP(const Standard_Real param,
49 Blend_SurfRstFunction& Func,
50 const math_Vector& sol,
51 const Standard_Real tol,
54 if(!Func.IsSolution(sol,tol)) return 0;
55 gp_Pnt pnts = Func.PointOnS();
56 gp_Pnt pntrst = Func.PointOnRst();
57 gp_Pnt2d p2ds = Func.Pnt2dOnS();
58 gp_Pnt2d p2drst = Func.Pnt2dOnRst();
59 Standard_Real w = Func.ParameterOnRst();
60 BP = Blend_Point(pnts,pntrst,param,
62 p2drst.X(),p2drst.Y(),w);
65 static void tracederiv(Blend_SurfRstFunction& Func,
66 const Blend_Point& BP1,
67 const Blend_Point& BP2)
69 Standard_Integer hp,hk,hd,hp2d,i;
70 Func.GetShape(hp,hk,hd,hp2d);
71 TColgp_Array1OfPnt TP1(1,hp);
72 TColgp_Array1OfVec TDP1(1,hp);
73 TColgp_Array1OfPnt2d TP2d1(1,hp2d);
74 TColgp_Array1OfVec2d TDP2d1(1,hp2d);
75 TColStd_Array1OfReal TW1(1,hp);
76 TColStd_Array1OfReal TDW1(1,hp);
77 Func.Section(BP1,TP1,TDP1,TP2d1,TDP2d1,TW1,TDW1);
79 TColgp_Array1OfPnt TP2(1,hp);
80 TColgp_Array1OfVec TDP2(1,hp);
81 TColgp_Array1OfPnt2d TP2d2(1,hp2d);
82 TColgp_Array1OfVec2d TDP2d2(1,hp2d);
83 TColStd_Array1OfReal TW2(1,hp);
84 TColStd_Array1OfReal TDW2(1,hp);
85 Func.Section(BP2,TP2,TDP2,TP2d2,TDP2d2,TW2,TDW2);
87 Standard_Real param1 = BP1.Parameter();
88 Standard_Real param2 = BP2.Parameter();
89 Standard_Real scal = 1./(param1-param2);
92 cout<<"control derivatives at point : "<<param1<<endl;
94 for(i = 1; i <= hp; i++){
96 cout<<"point : "<<i<<endl;
97 cout<<"dx calculated : "<<TDP1(i).X()<<endl;
98 cout<<"dx estimated : "<<scal*(TP1(i).X()-TP2(i).X())<<endl;
99 cout<<"dy calculated : "<<TDP1(i).Y()<<endl;
100 cout<<"dy estimated : "<<scal*(TP1(i).Y()-TP2(i).Y())<<endl;
101 cout<<"dz calculated : "<<TDP1(i).Z()<<endl;
102 cout<<"dz estimated : "<<scal*(TP1(i).Z()-TP2(i).Z())<<endl;
103 cout<<"dw calculated : "<<TDW1(i)<<endl;
104 cout<<"dw estimated : "<<scal*(TW1(i)-TW2(i))<<endl;
106 for(i = 1; i <= hp2d; i++){
108 cout<<"point 2d : "<<i<<endl;
109 cout<<"dx calculated : "<<TDP2d1(i).X()<<endl;
110 cout<<"dx estimated : "<<scal*(TP2d1(i).X()-TP2d2(i).X())<<endl;
111 cout<<"dy calculated : "<<TDP2d1(i).Y()<<endl;
112 cout<<"dy estimated : "<<scal*(TP2d1(i).Y()-TP2d2(i).Y())<<endl;
116 static void Drawsect(const Standard_Real param,
117 Blend_SurfRstFunction& Func)
119 gp_Pnt pnts = Func.PointOnS();
120 gp_Pnt pntrst = Func.PointOnRst();
121 gp_Pnt2d p2ds = Func.Pnt2dOnS();
122 gp_Pnt2d p2drst = Func.Pnt2dOnRst();
123 Standard_Real w = Func.ParameterOnRst();
124 Blend_Point BP(pnts,pntrst,param,
126 p2drst.X(),p2drst.Y(),w);
127 Standard_Integer hp,hk,hd,hp2d;
128 Func.GetShape(hp,hk,hd,hp2d);
129 TColStd_Array1OfReal TK(1,hk);
131 TColStd_Array1OfInteger TMul(1,hk);
133 TColgp_Array1OfPnt TP(1,hp);
134 TColgp_Array1OfPnt2d TP2d(1,hp2d);
135 TColStd_Array1OfReal TW(1,hp);
136 Func.Section(BP,TP,TP2d,TW);
137 Handle(Geom_BSplineCurve) sect = new Geom_BSplineCurve
142 Standard_CString name = tname ;
143 sprintf(name,"%s_%d","Section",IndexOfSection);
144 DrawTrSurf::Set(name,sect);
149 //=======================================================================
150 //function : ArcToRecadre
151 //purpose : Find a suitable arc
152 // PrevIndex is used to reject an already tested arc
153 //=======================================================================
155 Standard_Integer BRepBlend_SurfRstLineBuilder::
156 ArcToRecadre(const math_Vector& sol,
157 const Standard_Integer PrevIndex,
160 Standard_Real& ponarc)
162 Standard_Integer IndexSol = 0, nbarc = 0;
163 Standard_Boolean ok = Standard_False;
164 Standard_Boolean byinter = (line->NbPoints() != 0), okinter = 0;
165 Standard_Real distmin = RealLast();
166 Standard_Real uprev = 0.0, vprev = 0.0, prm = 0.0, dist = 0.0;
168 if(byinter) previousP.ParametersOnS(uprev,vprev);
169 pt2d.SetCoord(sol(1),sol(2));
170 lastpt2d.SetCoord(uprev,vprev);
173 while (domain1->More()) {
176 ok = okinter = BRepBlend_BlendTool::Inters(pt2d,lastpt2d,
178 domain1->Value(),prm,dist);
180 if(!ok) ok = BRepBlend_BlendTool::Project(pt2d,surf1,
181 domain1->Value(),prm,dist);
183 if (ok && (nbarc != PrevIndex) ) {
184 if (dist<distmin || okinter) {
188 if(okinter && (PrevIndex==0) ) break;
196 //=======================================================================
197 //function : BRepBlend_SurfRstLineBuilder
199 //=======================================================================
201 BRepBlend_SurfRstLineBuilder::BRepBlend_SurfRstLineBuilder
202 (const Handle(Adaptor3d_HSurface)& Surf1,
203 const Handle(Adaptor3d_TopolTool)& Domain1,
204 const Handle(Adaptor3d_HSurface)& Surf2,
205 const Handle(Adaptor2d_HCurve2d)& Rst,
206 const Handle(Adaptor3d_TopolTool)& Domain2):
207 sol(1,3),surf1(Surf1), domain1(Domain1),
208 surf2(Surf2), rst(Rst), domain2(Domain2)
212 //=======================================================================
215 //=======================================================================
217 void BRepBlend_SurfRstLineBuilder::Perform(Blend_SurfRstFunction& Func,
219 Blend_SurfPointFuncInv& FinvP,
220 Blend_SurfCurvFuncInv& FinvC,
221 const Standard_Real Pdep,
222 const Standard_Real Pmax,
223 const Standard_Real MaxStep,
224 const Standard_Real TolGuide,
225 const math_Vector& ParDep,
226 const Standard_Real Tolesp,
227 const Standard_Real Fleche,
228 const Standard_Boolean Appro)
230 done = Standard_False;
231 iscomplete = Standard_False;
232 comptra = Standard_False;
233 line = new BRepBlend_Line();
234 tolesp = Abs(Tolesp);
235 tolgui = Abs(TolGuide);
236 fleche = Abs(Fleche);
237 rebrou = Standard_False;
238 pasmax = Abs(MaxStep);
240 if (Pmax-Pdep >= 0.) {
253 TopAbs_State siturst,situs;
254 Standard_Boolean decroch;
255 math_Vector tolerance(1,3),infbound(1,3),supbound(1,3);
256 Func.GetTolerance(tolerance,tolesp);
257 Func.GetBounds(infbound,supbound);
258 math_FunctionSetRoot rsnld(Func,tolerance,30);
260 rsnld.Perform(Func,ParDep,infbound,supbound);
262 if (!rsnld.IsDone()) {
266 if (!CheckInside(Func,siturst,situs,decroch)) {
274 State = TestArret(Func,Standard_False,Blend_OK);
275 if (State!=Blend_OK) {
279 if (Blend_GettraceDRAWSECT()){
280 Drawsect(param,Func);
284 line->Append(previousP);
286 previousP.ParametersOnS(U,V);
287 // W = previousP.ParameterOnC();
289 BRepBlend_Extremity ptf1(previousP.PointOnS(),
290 U,V,previousP.Parameter(),tolesp);
291 BRepBlend_Extremity ptf2(previousP.PointOnC(),
292 U,V,previousP.Parameter(),tolesp);
293 if (!previousP.IsTangencyPoint()) {
294 ptf1.SetTangent(previousP.TangentOnS());
295 ptf2.SetTangent(previousP.TangentOnC());
298 line->SetStartPoints(ptf1, ptf2);
301 line->SetEndPoints(ptf1, ptf2);
304 InternalPerform(Func,Finv,FinvP,FinvC,Pmax);
305 done = Standard_True;
308 //=======================================================================
309 //function : PerformFirstSection
311 //=======================================================================
313 Standard_Boolean BRepBlend_SurfRstLineBuilder::PerformFirstSection
314 (Blend_SurfRstFunction& Func,
316 Blend_SurfPointFuncInv& FinvP,
317 Blend_SurfCurvFuncInv& FinvC,
318 const Standard_Real Pdep,
319 const Standard_Real Pmax,
320 const math_Vector& ParDep,
321 const Standard_Real Tolesp,
322 const Standard_Real TolGuide,
323 const Standard_Boolean RecRst,
324 const Standard_Boolean RecP,
325 const Standard_Boolean RecS,
329 done = Standard_False;
330 iscomplete = Standard_False;
331 comptra = Standard_False;
332 line = new BRepBlend_Line();
333 tolesp = Abs(Tolesp);
334 tolgui = Abs(TolGuide);
335 rebrou = Standard_False;
337 if (Pmax-Pdep >= 0.) {
343 Blend_Status State = Blend_OnRst12;
344 Standard_Real trst = 0.;
345 Standard_Boolean recadp,recadrst,recads;
346 Standard_Real wp,wrst,ws;
348 math_Vector infbound(1,3),supbound(1,3),tolerance(1,3);
349 math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
350 Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
351 Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
352 Handle(Adaptor2d_HCurve2d) Arc;
353 wp = wrst = ws = Pmax;
356 Func.GetTolerance(tolerance,tolesp);
357 Func.GetBounds(infbound,supbound);
359 math_FunctionSetRoot rsnld(Func,tolerance,30);
360 rsnld.Perform(Func,ParDep,infbound,supbound);
361 if (!rsnld.IsDone()) return Standard_False;
364 recads = RecS && Recadre(FinvC,solinvs,Arc,IsVtxs,Vtxs);
368 recadp = RecP && Recadre(FinvP,solinvp,IsVtxp,Vtxp);
372 recadrst = RecRst && Recadre(Func,Finv,solinvrst,IsVtxrst,Vtxrst);
376 if (!recads && !recadp && !recadrst) return Standard_False;
377 if (recadp && recadrst) {
378 if(sens*(wrst-wp) > tolgui){ //first one leaves the domain
382 trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
396 trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
399 recadrst = Standard_True;
406 if(recads && recadrst){
407 if(Abs(ws - wrst) < tolgui){
408 State = Blend_OnRst12;
409 param = 0.5*(ws+wrst);
414 else if(sens*(ws-wrst)<0){
416 State = Blend_OnRst1;
418 Arc->Value(solinvs(3)).Coord(U,V);
425 State = Blend_OnRst2;
435 State = Blend_OnRst1;
437 Arc->Value(solinvs(3)).Coord(U,V);
445 State = Blend_OnRst2;
452 State = TestArret(Func,Standard_False,State);
455 return Standard_True;
458 //=======================================================================
459 //function : Complete
461 //=======================================================================
463 Standard_Boolean BRepBlend_SurfRstLineBuilder::Complete(Blend_SurfRstFunction& Func,
465 Blend_SurfPointFuncInv& FinvP,
466 Blend_SurfCurvFuncInv& FinvC,
467 const Standard_Real Pmin)
469 if (!done) {StdFail_NotDone::Raise();}
470 if (iscomplete) {return Standard_True;}
472 previousP = line->Point(1);
475 previousP = line->Point(line->NbPoints());
478 param = previousP.Parameter();
479 previousP.ParametersOnS(sol(1),sol(2));
480 sol(3) = previousP.ParameterOnC();
482 InternalPerform(Func,Finv,FinvP,FinvC,Pmin);
483 iscomplete = Standard_True;
484 return Standard_True;
487 //=======================================================================
488 //function : InternalPerform
490 //=======================================================================
492 void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction& Func,
494 Blend_SurfPointFuncInv& FinvP,
495 Blend_SurfCurvFuncInv& FinvC,
496 const Standard_Real Bound)
498 Standard_Real stepw = pasmax;
499 Standard_Integer nbp = line->NbPoints();
500 if(nbp >= 2){ //The last step is reproduced if it is not too small.
502 stepw = (line->Point(2).Parameter() - line->Point(1).Parameter());
505 stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter());
507 stepw = Max(stepw,100.*tolgui);
509 Standard_Real parprec = param;
510 if (sens*(parprec - Bound) >= -tolgui) {
513 Blend_Status State = Blend_OnRst12;
514 TopAbs_State situonc,situons;
515 Standard_Boolean decroch;
516 Standard_Boolean Arrive,recadp,recadrst,recads,echecrecad;
517 Standard_Real wp,wrst,ws;
519 Standard_Real trst = 0.;
520 math_Vector infbound(1,3),supbound(1,3);
521 math_Vector parinit(1,3),tolerance(1,3);
522 math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
523 Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
524 Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
525 BRepBlend_Extremity Extrst,Exts;
526 Handle(Adaptor2d_HCurve2d) Arc;
528 //IntSurf_Transition Tline,Tarc;
530 Func.GetTolerance(tolerance,tolesp);
531 Func.GetBounds(infbound,supbound);
533 math_FunctionSetRoot rsnld(Func,tolerance,30);
536 Arrive = Standard_False;
537 param = parprec + sens*stepw;
538 if(sens *(param - Bound) > 0.) {
539 stepw = sens*(Bound - parprec)*0.5;
540 param = parprec + sens*stepw;
544 Standard_Boolean bonpoint = 1;
548 rsnld.Perform(Func,parinit,infbound,supbound);
549 if (rsnld.IsDone()) {
552 if(BBPP(param,Func,sol,tolesp,bp1)){
553 Standard_Real dw = 1.e-10;
555 rsnld.Perform(Func,parinit,infbound,supbound);
556 if (rsnld.IsDone()) {
559 if(BBPP(param+dw,Func,sol,tolesp,bp2)){
560 tracederiv(Func,bp1,bp2);
568 rsnld.Perform(Func,parinit,infbound,supbound);
570 if (rsnld.IsDone()) {
572 if(!CheckInside(Func,situonc,situons,decroch) && line->NbPoints() == 1){
573 State = Blend_StepTooLarge;
578 State = Blend_StepTooLarge;
582 wp = wrst = ws = Bound;
583 recadp = recadrst = recads = Standard_False;
584 echecrecad = Standard_False;
585 if (situons == TopAbs_OUT || situons == TopAbs_ON) {
586 // pb inverse rst/rst
587 recads = Recadre(FinvC,solinvs,Arc,IsVtxs,Vtxs);
590 // It is necessary to reevaluate the deviation (BUC60360)
593 Arc->Value(solinvs(3)).Coord(U,V);
597 decroch = Func.Decroch(sol, t, n);
600 echecrecad = Standard_True;
603 if (situonc == TopAbs_OUT || situonc == TopAbs_ON) {
604 // pb inverse point/surf
605 recadp = Recadre(FinvP,solinvp,IsVtxp,Vtxp);
610 echecrecad = Standard_True;
614 // pb inverse rst/surf
615 recadrst = Recadre(Func,Finv,solinvrst,IsVtxrst,Vtxrst);
620 echecrecad = Standard_True;
624 if(recadp || recads || recadrst) echecrecad = Standard_False;
626 if (recadp && recadrst) {
627 if(sens*(wrst-wp) > tolgui){ //first one leaves the domain
631 trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
646 trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
649 recadrst = Standard_True;
657 if(recads && recadrst){
658 if(Abs(ws - wrst) < tolgui){
659 State = Blend_OnRst12;
660 param = 0.5*(ws+wrst);
665 else if(sens*(ws-wrst)<0){
668 State = Blend_OnRst1;
670 Arc->Value(solinvs(3)).Coord(U,V);
677 State = Blend_OnRst2;
687 State = Blend_OnRst1;
689 Arc->Value(solinvs(3)).Coord(U,V);
697 State = Blend_OnRst2;
707 State = TestArret(Func,Standard_True,State);
710 // Failed reframing. Leave with PointsConfondus
712 cout<<"SurfRstLineBuilder : failed reframing"<<endl;
714 State = Blend_SamePoints;
722 if (Blend_GettraceDRAWSECT()){
723 Drawsect(param,Func);
728 line->Append(previousP);
731 line->Prepend(previousP);
736 if (param == Bound) {
737 Arrive = Standard_True;
738 Exts.SetValue(previousP.PointOnS(),
740 previousP.Parameter(),tolesp);
741 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
742 // Indicate end on Bound.
745 param = param + sens*stepw;
746 if (sens*(param - Bound) > - tolgui) {
753 case Blend_StepTooLarge :
756 if (Abs(stepw) < tolgui) {
757 previousP.ParametersOnS(U,V);
758 Exts.SetValue(previousP.PointOnS(),U,V,
759 previousP.Parameter(),tolesp);
760 Extrst.SetValue(previousP.PointOnC(),
761 previousP.ParameterOnC(),
762 previousP.Parameter(),tolesp);
763 Arrive = Standard_True;
764 if (line->NbPoints()>=2) {
765 // Indicate that one stops during the processing
767 cout<<"SurfRstLineBuilder : No advancement in the processing"<<endl;
772 param = parprec + sens*stepw; // no risk to exceed Bound.
777 case Blend_StepTooSmall :
780 if (Blend_GettraceDRAWSECT()){
781 Drawsect(param,Func);
786 line->Append(previousP);
789 line->Prepend(previousP);
794 stepw = Min(1.5*stepw,pasmax);
795 if (param == Bound) {
796 Arrive = Standard_True;
797 Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),
798 previousP.Parameter(),tolesp);
799 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
800 // Indicate end on Bound.
803 param = param + sens*stepw;
804 if (sens*(param - Bound) > - tolgui) {
814 if (Blend_GettraceDRAWSECT()){
815 Drawsect(param,Func);
819 line->Append(previousP);
822 line->Prepend(previousP);
824 MakeExtremity(Exts,Standard_True,Arc,solinvs(3),IsVtxs,Vtxs);
825 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
826 Arrive = Standard_True;
833 if (Blend_GettraceDRAWSECT()){
834 Drawsect(param,Func);
838 line->Append(previousP);
841 line->Prepend(previousP);
843 Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),
844 previousP.Parameter(),tolesp);
845 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
846 Arrive = Standard_True;
853 if (Blend_GettraceDRAWSECT()){
854 Drawsect(param,Func);
858 line->Append(previousP);
861 line->Prepend(previousP);
863 MakeExtremity(Exts,Standard_True,Arc,solinvs(1),IsVtxs,Vtxs);
864 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
865 Arrive = Standard_True;
869 case Blend_SamePoints :
873 cout << "SurfRstLineBuilder Points mixed in the processing" << endl;
875 previousP.ParametersOnS(U,V);
876 Exts.SetValue(previousP.PointOnS(),U,V,
877 previousP.Parameter(),tolesp);
878 Extrst.SetValue(previousP.PointOnC(),
879 previousP.ParameterOnC(),
880 previousP.Parameter(),tolesp);
881 Arrive = Standard_True;
889 line->SetEndPoints(Exts,Extrst);
890 decrochfin = decroch;
893 line->SetStartPoints(Exts,Extrst);
894 decrochdeb = decroch;
900 //=======================================================================
902 //purpose : Reframe section Surface / Restriction
903 //=======================================================================
905 Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfCurvFuncInv& FinvC,
907 Handle(Adaptor2d_HCurve2d)& Arc,
908 Standard_Boolean& IsVtx,
909 Handle(Adaptor3d_HVertex)& Vtx)
911 Standard_Boolean recadre = Standard_False;
913 gp_Pnt2d pt2d, lastpt2d;
914 Standard_Integer IndexSol, nbarc;
917 IndexSol = ArcToRecadre(sol, 0, lastpt2d, pt2d, pmin);
919 IsVtx = Standard_False;
921 return Standard_False;
926 while (nbarc < IndexSol) {
930 Arc = domain1->Value();
934 math_Vector toler(1,3),infb(1,3),supb(1,3);
935 FinvC.GetTolerance(toler,tolesp);
936 FinvC.GetBounds(infb,supb);
941 math_FunctionSetRoot rsnld(FinvC,toler,30);
942 rsnld.Perform(FinvC,Solinv,infb,supb);
944 if (!rsnld.IsDone()) {
946 cout << "SurfRstLineBuilder : RSNLD not done "<< endl << endl;
950 // It is necessary to check the value of the function
952 recadre = FinvC.IsSolution(Solinv,tolesp);
955 // In case of fail, it is checked if another arc
956 // can be useful (case of output at the proximity of a vertex)
959 IndexSol = ArcToRecadre(sol, IndexSol,
960 lastpt2d, pt2d, pmin);
962 return Standard_False; // No other solution
967 while (nbarc < IndexSol) {
972 Arc = domain1->Value();
975 FinvC.GetTolerance(toler,tolesp);
976 FinvC.GetBounds(infb,supb);
980 math_FunctionSetRoot rsnld(FinvC,toler,30);
981 rsnld.Perform(FinvC,Solinv,infb,supb);
983 if (!rsnld.IsDone()) {
985 cout << "SurfRstLineBuilder : RSNLD not done "<< endl << endl;
989 // It is necessary to check the value of the function
991 recadre = FinvC.IsSolution(Solinv,tolesp);
996 Standard_Real w = Solinv(2);
997 if(w < rst->FirstParameter() - toler(2)||
998 w > rst->LastParameter() + toler(2)){
999 return Standard_False;
1001 domain1->Initialize(Arc);
1002 domain1->InitVertexIterator();
1003 IsVtx = !domain1->MoreVertex();
1005 Vtx = domain1->Vertex();
1006 if (Abs(BRepBlend_BlendTool::Parameter(Vtx,Arc)-Solinv(3)) <=
1007 BRepBlend_BlendTool::Tolerance(Vtx,Arc)) {
1008 IsVtx = Standard_True;
1011 domain1->NextVertex();
1012 IsVtx = !domain1->MoreVertex();
1015 if (!domain1->MoreVertex()) {
1016 IsVtx = Standard_False;
1018 return Standard_True;
1020 return Standard_False;
1023 //=======================================================================
1024 //function : Recadre
1026 //=======================================================================
1028 Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfRstFunction& Func,
1029 Blend_FuncInv& Finv,
1030 math_Vector& Solinv,
1031 Standard_Boolean& IsVtx,
1032 Handle(Adaptor3d_HVertex)& Vtx)
1034 math_Vector toler(1,4),infb(1,4),supb(1,4);
1035 Finv.GetTolerance(toler,tolesp);
1036 Finv.GetBounds(infb,supb);
1042 math_FunctionSetRoot rsnld(Finv,toler,30);
1043 rsnld.Perform(Finv,Solinv,infb,supb);
1044 if (!rsnld.IsDone()) {
1046 cout << "SurfRstLineBuilder :RSNLD not done "<< endl;
1048 return Standard_False;
1052 if(Finv.IsSolution(Solinv,tolesp)){
1053 gp_Pnt2d p2d(Solinv(3),Solinv(4));
1054 TopAbs_State situ = domain1->Classify(p2d,Min(toler(3),toler(4)),0);
1055 if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
1056 return Standard_False;
1058 domain2->Initialize(rst);
1059 domain2->InitVertexIterator();
1060 IsVtx = !domain2->MoreVertex();
1062 Vtx = domain2->Vertex();
1063 if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-Solinv(1)) <=
1064 BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
1065 IsVtx = Standard_True;
1068 domain2->NextVertex();
1069 IsVtx = !domain2->MoreVertex();
1072 if (!domain2->MoreVertex()) {
1073 IsVtx = Standard_False;
1075 // The section is recalculated by direct resolution, otherwise
1076 // incoherences between the parameter and the ground caused by yawn are returned.
1078 math_Vector infbound(1,3),supbound(1,3);
1079 math_Vector parinit(1,3),tolerance(1,3);
1080 Func.GetTolerance(tolerance,tolesp);
1081 Func.GetBounds(infbound,supbound);
1083 math_FunctionSetRoot rsnld2(Func,tolerance,30);
1084 parinit(1) = Solinv(3);
1085 parinit(2) = Solinv(4);
1086 parinit(3) = Solinv(1);
1087 Func.Set(Solinv(2));
1088 rsnld2.Perform(Func,parinit,infbound,supbound);
1089 if(!rsnld2.IsDone()) return Standard_False;
1090 rsnld2.Root(parinit);
1091 Solinv(3) = parinit(1);
1092 Solinv(4) = parinit(2);
1093 Solinv(1) = parinit(3);
1094 return Standard_True;
1096 return Standard_False;
1099 //=======================================================================
1100 //function : Recadre
1102 //=======================================================================
1104 Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfPointFuncInv& FinvP,
1105 math_Vector& Solinv,
1106 Standard_Boolean& IsVtx,
1107 Handle(Adaptor3d_HVertex)& Vtx)
1111 Standard_Real firstrst = rst->FirstParameter();
1112 Standard_Real lastrst = rst->LastParameter();
1113 Standard_Real wpoint = firstrst;
1114 if((sol(3) - firstrst) > (lastrst - sol(3))) wpoint = lastrst;
1115 p2drst = rst->Value(wpoint);
1116 gp_Pnt thepoint = surf2->Value(p2drst.X(),p2drst.Y());
1118 FinvP.Set(thepoint);
1119 math_Vector toler(1,3),infb(1,3),supb(1,3);
1120 FinvP.GetTolerance(toler,tolesp);
1121 FinvP.GetBounds(infb,supb);
1126 math_FunctionSetRoot rsnld(FinvP,toler,30);
1127 rsnld.Perform(FinvP,Solinv,infb,supb);
1128 if (!rsnld.IsDone()) {
1130 cout << "SurfRstLineBuilder :RSNLD not done "<< endl;
1132 return Standard_False;
1136 if(FinvP.IsSolution(Solinv,tolesp)){
1137 gp_Pnt2d p2d(Solinv(2),Solinv(3));
1138 TopAbs_State situ = domain1->Classify(p2d,Min(toler(2),toler(3)),0);
1139 if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
1140 return Standard_False;
1142 domain2->Initialize(rst);
1143 domain2->InitVertexIterator();
1144 IsVtx = !domain2->MoreVertex();
1146 Vtx = domain2->Vertex();
1147 if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-wpoint) <=
1148 BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
1149 IsVtx = Standard_True;
1152 domain2->NextVertex();
1153 IsVtx = !domain2->MoreVertex();
1156 if (!domain2->MoreVertex()) {
1157 IsVtx = Standard_False;
1159 return Standard_True;
1161 return Standard_False;
1164 //=======================================================================
1165 //function : Transition
1167 //=======================================================================
1169 void BRepBlend_SurfRstLineBuilder::Transition(const Standard_Boolean OnFirst,
1170 const Handle(Adaptor2d_HCurve2d)& Arc,
1171 const Standard_Real Param,
1172 IntSurf_Transition& TLine,
1173 IntSurf_Transition& TArc)
1175 Standard_Boolean computetranstionaveclacorde = 0;
1177 Blend_Point prevprev;
1179 if(previousP.IsTangencyPoint()){
1180 if(line->NbPoints() < 2) return;
1181 computetranstionaveclacorde = 1;
1183 prevprev = line->Point(2);
1186 prevprev = line->Point(line->NbPoints() - 1);
1193 gp_Vec d1u,d1v,normale,tgrst;
1195 Arc->D1(Param,p2d,dp2d);
1197 surf1->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v);
1198 if(!computetranstionaveclacorde) tgline = previousP.TangentOnS1();
1199 else tgline = gp_Vec(prevprev.PointOnS(),previousP.PointOnS());
1202 surf2->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v);
1203 if(!computetranstionaveclacorde) tgline = previousP.TangentOnS2();
1204 else tgline = gp_Vec(prevprev.PointOnC(),previousP.PointOnC());
1207 tgrst.SetLinearForm(dp2d.X(),d1u,dp2d.Y(),d1v);
1208 normale = d1u.Crossed(d1v);
1210 IntSurf::MakeTransition(tgline,tgrst,normale,TLine,TArc);
1213 //=======================================================================
1214 //function : MakeExtremity
1216 //=======================================================================
1218 void BRepBlend_SurfRstLineBuilder::MakeExtremity(BRepBlend_Extremity& Extrem,
1219 const Standard_Boolean OnFirst,
1220 const Handle(Adaptor2d_HCurve2d)& Arc,
1221 const Standard_Real Param,
1222 const Standard_Boolean IsVtx,
1223 const Handle(Adaptor3d_HVertex)& Vtx)
1225 IntSurf_Transition Tline,Tarc;
1227 Handle(Adaptor3d_TopolTool) Iter;
1229 Extrem.SetValue(previousP.PointOnS(),
1231 previousP.Parameter(),tolesp);
1232 if (!previousP.IsTangencyPoint())
1233 Extrem.SetTangent(previousP.TangentOnS());
1237 Extrem.SetValue(previousP.PointOnC(),
1239 previousP.Parameter(),tolesp);
1240 if (!previousP.IsTangencyPoint())
1241 Extrem.SetTangent(previousP.TangentOnC());
1247 Transition(OnFirst,Arc,Param,Tline,Tarc);
1248 Extrem.AddArc(Arc,Param,Tline,Tarc);
1251 Extrem.SetVertex(Vtx);
1252 while (Iter->More()) {
1253 Handle(Adaptor2d_HCurve2d) arc = Iter->Value();
1255 Iter->Initialize(arc);
1256 Iter->InitVertexIterator();
1257 while (Iter->MoreVertex()) {
1258 if (Iter->Identical(Vtx,Iter->Vertex())) {
1259 prm = BRepBlend_BlendTool::Parameter(Vtx,arc);
1260 Transition(OnFirst,arc,prm,Tline,Tarc);
1261 Extrem.AddArc(arc,prm,Tline,Tarc);
1267 Transition(OnFirst,arc,Param,Tline,Tarc);
1268 Extrem.AddArc(arc,Param,Tline,Tarc);
1275 //=======================================================================
1276 //function : CheckDeflectionOnSurf
1278 //=======================================================================
1280 Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnSurf(const Blend_Point& CurPoint)
1282 //Controls 3d of Blend_CSWalking.
1284 //rule by tests in U4 corresponds to 11.478 d
1285 const Standard_Real CosRef3D = 0.98;
1286 Standard_Real Cosi=0, Cosi2=0;
1287 Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
1288 Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
1290 gp_Pnt Psurf = CurPoint.PointOnS();
1292 if(!curpointistangent){
1293 Tgsurf = CurPoint.TangentOnS();
1295 gp_Pnt prevP = previousP.PointOnS();
1297 if(!prevpointistangent){
1298 prevTg = previousP.TangentOnS();
1300 Standard_Real Norme,prevNorme = 0.;
1301 gp_Vec Corde(prevP,Psurf);
1302 Norme = Corde.SquareMagnitude();
1303 // if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
1304 if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
1306 if (Norme <= tolesp*tolesp){
1307 // it can be necessary to force same point
1308 return Blend_SamePoints;
1310 if(!prevpointistangent){
1311 if(prevNorme <= tolesp*tolesp) {
1312 return Blend_SamePoints;
1314 Cosi = sens*Corde*prevTg;
1315 if (Cosi <0.) { // angle 3d>pi/2. --> return back
1316 return Blend_Backward;
1319 Cosi2 = Cosi * Cosi / prevNorme / Norme;
1320 if (Cosi2 < CosRef3D) {
1321 return Blend_StepTooLarge;
1325 if(!curpointistangent){
1326 // Check if it is necessary to control the sign of prevtg*Tgsurf
1327 Cosi = sens*Corde*Tgsurf;
1328 Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
1329 if (Cosi2 < CosRef3D || Cosi < 0.) {
1330 return Blend_StepTooLarge;
1334 if(!curpointistangent && !prevpointistangent){
1335 // Estimation of the current arrow
1336 Standard_Real FlecheCourante =
1337 (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.;
1339 if (FlecheCourante <= 0.25*fleche*fleche) {
1340 return Blend_StepTooSmall;
1342 if (FlecheCourante > fleche*fleche) {
1344 return Blend_StepTooLarge;
1351 //=======================================================================
1352 //function : CheckDeflectionOnRst
1354 //=======================================================================
1356 Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnRst(const Blend_Point& CurPoint)
1358 //Controls 3D of Blend_CSWalking.
1360 // rule by tests in U4 corresponds to 11.478 d
1361 const Standard_Real CosRef3D = 0.98;
1362 Standard_Real Cosi, Cosi2;
1363 Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
1364 Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
1366 gp_Pnt Psurf = CurPoint.PointOnC();
1368 if(!curpointistangent){
1369 Tgsurf = CurPoint.TangentOnC();
1371 gp_Pnt prevP = previousP.PointOnC();
1373 if(!prevpointistangent){
1374 prevTg = previousP.TangentOnC();
1376 Standard_Real Norme,prevNorme = 0.;
1377 gp_Vec Corde(prevP,Psurf);
1378 Norme = Corde.SquareMagnitude();
1379 // if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
1380 if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
1382 if (Norme <= tolesp*tolesp){
1383 // it can be necessary to force same point
1384 return Blend_SamePoints;
1386 if(!prevpointistangent){
1387 if(prevNorme <= tolesp*tolesp) {
1388 return Blend_SamePoints;
1390 Cosi = sens*Corde*prevTg;
1391 if (Cosi <0.) { // angle 3d>pi/2. --> return back
1392 return Blend_Backward;
1395 Cosi2 = Cosi * Cosi / prevNorme / Norme;
1396 if (Cosi2 < CosRef3D) {
1397 return Blend_StepTooLarge;
1401 if(!curpointistangent){
1402 // Check if it is necessary to control the sign of prevtg*Tgsurf
1403 Cosi = sens*Corde*Tgsurf;
1404 Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
1405 if (Cosi2 < CosRef3D || Cosi < 0.) {
1406 return Blend_StepTooLarge;
1410 if(!curpointistangent && !prevpointistangent){
1411 // Estimation of the current arrow
1412 Standard_Real FlecheCourante =
1413 (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.;
1415 if (FlecheCourante <= 0.25*fleche*fleche) {
1416 return Blend_StepTooSmall;
1418 if (FlecheCourante > fleche*fleche) {
1420 return Blend_StepTooLarge;
1426 static IntSurf_TypeTrans ConvOrToTra(const TopAbs_Orientation O)
1428 if(O == TopAbs_FORWARD) return IntSurf_In;
1432 //=======================================================================
1433 //function : TestArret
1435 //=======================================================================
1437 Blend_Status BRepBlend_SurfRstLineBuilder::TestArret(Blend_SurfRstFunction& Func,
1438 const Standard_Boolean TestDeflection,
1439 const Blend_Status State)
1444 gp_Vec2d tg2ds,tg2drst;
1445 Blend_Status StateS,StateRst;
1446 IntSurf_TypeTrans tras = IntSurf_Undecided, trarst = IntSurf_Undecided;
1447 Blend_Point curpoint;
1449 if (Func.IsSolution(sol,tolesp)) {
1450 Standard_Boolean curpointistangent = Func.IsTangencyPoint();
1451 pts = Func.PointOnS();
1452 ptrst = Func.PointOnRst();
1453 pt2drst = Func.Pnt2dOnRst();
1454 if(curpointistangent){
1455 curpoint.SetValue(pts,ptrst,param,sol(1),sol(2),
1456 pt2drst.X(),pt2drst.Y(),sol(3));
1459 tgs = Func.TangentOnS();
1460 tgrst = Func.TangentOnRst();
1461 tg2ds = Func.Tangent2dOnS();
1462 tg2drst = Func.Tangent2dOnRst();
1464 curpoint.SetValue(pts,ptrst,param,sol(1),sol(2),
1465 pt2drst.X(),pt2drst.Y(),sol(3),
1466 tgs,tgrst,tg2ds,tg2drst);
1468 if (TestDeflection) {
1469 StateS = CheckDeflectionOnSurf(curpoint);
1470 StateRst = CheckDeflectionOnRst(curpoint);
1473 StateS = StateRst = Blend_OK;
1475 if (StateS == Blend_Backward) {
1476 StateS = Blend_StepTooLarge;
1477 rebrou= Standard_True;
1479 if (StateRst == Blend_Backward) {
1480 StateRst = Blend_StepTooLarge;
1481 rebrou = Standard_True;
1483 if (StateS == Blend_StepTooLarge ||
1484 StateRst == Blend_StepTooLarge) {
1485 return Blend_StepTooLarge;
1488 if (!comptra && !curpointistangent) {
1490 Func.Decroch(sol,nors,tgsecs);
1492 Standard_Real testra = tgsecs.Dot(nors.Crossed(tgs));
1493 if (Abs(testra) > tolesp) {
1497 else if (testra >0.) {
1500 gp_Pnt2d p2drstref; gp_Vec2d tg2drstref;
1501 rst->D1(sol(3),p2drstref,tg2drstref);
1502 testra = tg2drst.Dot(tg2drstref);
1503 TopAbs_Orientation Or = domain2->Orientation(rst);
1504 if (Abs(testra) > 1.e-8) {
1506 trarst = ConvOrToTra(TopAbs::Reverse(Or));
1508 else if (testra >0.) {
1509 trarst = ConvOrToTra(Or);
1511 comptra = Standard_True;
1512 line->Set(tras,trarst);
1516 if (StateS == Blend_OK ||
1517 StateRst == Blend_OK ) {
1518 previousP = curpoint;
1521 if (StateS == Blend_StepTooSmall &&
1522 StateRst == Blend_StepTooSmall) {
1523 previousP = curpoint;
1524 if (State == Blend_OK) {
1525 return Blend_StepTooSmall;
1531 if (State == Blend_OK) {
1532 return Blend_SamePoints;
1538 return Blend_StepTooLarge;
1541 //=======================================================================
1542 //function : CheckInside
1544 //=======================================================================
1546 Standard_Boolean BRepBlend_SurfRstLineBuilder::CheckInside(Blend_SurfRstFunction& Func,
1547 TopAbs_State& SituOnC,
1548 TopAbs_State& SituOnS,
1549 Standard_Boolean& Decroch)
1551 math_Vector tolerance(1,3);
1552 Func.GetTolerance(tolerance,tolesp);
1554 Standard_Real w = sol(3);
1555 if(w < rst->FirstParameter() - tolerance(3)||
1556 w > rst->LastParameter() + tolerance(3)){
1557 SituOnC = TopAbs_OUT;
1559 else if (w > rst->FirstParameter() &&
1560 w < rst->LastParameter()){
1561 SituOnC = TopAbs_IN;
1563 else SituOnC = TopAbs_ON;
1566 gp_Pnt2d p2d(sol(1),sol(2));
1567 SituOnS = domain1->Classify(p2d,Min(tolerance(1),tolerance(2)),0);
1571 Decroch = Func.Decroch(sol,tgs,nors);
1573 return (SituOnC == TopAbs_IN && SituOnS == TopAbs_IN && !Decroch);