0022879: Possible bug in Opengl_togl_begin_layer_mode.cxx
[occt.git] / src / BRepBlend / BRepBlend_SurfRstLineBuilder.cxx
CommitLineData
7fd59977 1// File: BRepBlend_SurfRstLineBuilder.cxx
2// Created: Fri Jan 24 10:39:44 1997
3// Author: Jacques GOUSSARD
4// Author: Laurent BOURESCHE
5// <lbo@pomalox.paris1.matra-dtv.fr>
6
7#include <stdio.h>
8
9#include <BRepBlend_SurfRstLineBuilder.ixx>
10#include <BRepBlend_BlendTool.hxx>
11#include <TopAbs.hxx>
12#include <IntSurf.hxx>
13#include <math_FunctionSetRoot.hxx>
14#include <gp_Pnt2d.hxx>
15#include <gp_Pnt.hxx>
16#include <gp_Vec2d.hxx>
17#include <gp_Vec.hxx>
18
19#ifdef DEB
20#include <TColStd_Array1OfInteger.hxx>
21#include <TColStd_Array1OfReal.hxx>
22#include <TColgp_Array1OfPnt2d.hxx>
23#include <TColgp_Array1OfVec.hxx>
24#include <TColgp_Array1OfVec2d.hxx>
25#include <TColgp_Array1OfPnt.hxx>
26#include <Geom_BSplineCurve.hxx>
27#ifdef DRAW
28#include <DrawTrSurf.hxx>
29#endif
30static Standard_Integer IndexOfSection = 0;
31extern Standard_Boolean Blend_GettraceDRAWSECT();
81bba717 32// for debug : visualisation of the section
7fd59977 33static Standard_Boolean BBPP(const Standard_Real param,
34 Blend_SurfRstFunction& Func,
35 const math_Vector& sol,
36 const Standard_Real tol,
37 Blend_Point& BP)
38{
39 if(!Func.IsSolution(sol,tol)) return 0;
40 gp_Pnt pnts = Func.PointOnS();
41 gp_Pnt pntrst = Func.PointOnRst();
42 gp_Pnt2d p2ds = Func.Pnt2dOnS();
43 gp_Pnt2d p2drst = Func.Pnt2dOnRst();
44 Standard_Real w = Func.ParameterOnRst();
45 BP = Blend_Point(pnts,pntrst,param,
46 p2ds.X(),p2ds.Y(),
47 p2drst.X(),p2drst.Y(),w);
48 return 1;
49}
50static void tracederiv(Blend_SurfRstFunction& Func,
51 const Blend_Point& BP1,
52 const Blend_Point& BP2)
53{
54 Standard_Integer hp,hk,hd,hp2d,i;
55 Func.GetShape(hp,hk,hd,hp2d);
56 TColgp_Array1OfPnt TP1(1,hp);
57 TColgp_Array1OfVec TDP1(1,hp);
58 TColgp_Array1OfPnt2d TP2d1(1,hp2d);
59 TColgp_Array1OfVec2d TDP2d1(1,hp2d);
60 TColStd_Array1OfReal TW1(1,hp);
61 TColStd_Array1OfReal TDW1(1,hp);
62 Func.Section(BP1,TP1,TDP1,TP2d1,TDP2d1,TW1,TDW1);
63
64 TColgp_Array1OfPnt TP2(1,hp);
65 TColgp_Array1OfVec TDP2(1,hp);
66 TColgp_Array1OfPnt2d TP2d2(1,hp2d);
67 TColgp_Array1OfVec2d TDP2d2(1,hp2d);
68 TColStd_Array1OfReal TW2(1,hp);
69 TColStd_Array1OfReal TDW2(1,hp);
70 Func.Section(BP2,TP2,TDP2,TP2d2,TDP2d2,TW2,TDW2);
71
72 Standard_Real param1 = BP1.Parameter();
73 Standard_Real param2 = BP2.Parameter();
74 Standard_Real scal = 1./(param1-param2);
75
76 cout<<endl;
81bba717 77 cout<<"control derivatives at point : "<<param1<<endl;
7fd59977 78
79 for(i = 1; i <= hp; i++){
80 cout<<endl;
81 cout<<"point : "<<i<<endl;
81bba717 82 cout<<"dx calculated : "<<TDP1(i).X()<<endl;
83 cout<<"dx estimated : "<<scal*(TP1(i).X()-TP2(i).X())<<endl;
84 cout<<"dy calculated : "<<TDP1(i).Y()<<endl;
85 cout<<"dy estimated : "<<scal*(TP1(i).Y()-TP2(i).Y())<<endl;
86 cout<<"dz calculated : "<<TDP1(i).Z()<<endl;
87 cout<<"dz estimated : "<<scal*(TP1(i).Z()-TP2(i).Z())<<endl;
88 cout<<"dw calculated : "<<TDW1(i)<<endl;
89 cout<<"dw estimated : "<<scal*(TW1(i)-TW2(i))<<endl;
7fd59977 90 }
91 for(i = 1; i <= hp2d; i++){
92 cout<<endl;
93 cout<<"point 2d : "<<i<<endl;
81bba717 94 cout<<"dx calculated : "<<TDP2d1(i).X()<<endl;
95 cout<<"dx estimated : "<<scal*(TP2d1(i).X()-TP2d2(i).X())<<endl;
96 cout<<"dy calculated : "<<TDP2d1(i).Y()<<endl;
97 cout<<"dy estimated : "<<scal*(TP2d1(i).Y()-TP2d2(i).Y())<<endl;
7fd59977 98 }
99}
100
101static void Drawsect(const Standard_Real param,
102 Blend_SurfRstFunction& Func)
103{
104 gp_Pnt pnts = Func.PointOnS();
105 gp_Pnt pntrst = Func.PointOnRst();
106 gp_Pnt2d p2ds = Func.Pnt2dOnS();
107 gp_Pnt2d p2drst = Func.Pnt2dOnRst();
108 Standard_Real w = Func.ParameterOnRst();
109 Blend_Point BP(pnts,pntrst,param,
110 p2ds.X(),p2ds.Y(),
111 p2drst.X(),p2drst.Y(),w);
112 Standard_Integer hp,hk,hd,hp2d;
113 Func.GetShape(hp,hk,hd,hp2d);
114 TColStd_Array1OfReal TK(1,hk);
115 Func.Knots(TK);
116 TColStd_Array1OfInteger TMul(1,hk);
117 Func.Mults(TMul);
118 TColgp_Array1OfPnt TP(1,hp);
119 TColgp_Array1OfPnt2d TP2d(1,hp2d);
120 TColStd_Array1OfReal TW(1,hp);
121 Func.Section(BP,TP,TP2d,TW);
122 Handle(Geom_BSplineCurve) sect = new Geom_BSplineCurve
123 (TP,TW,TK,TMul,hd);
124 IndexOfSection++;
125#ifdef DRAW
126 char tname[100];
127 Standard_CString name = tname ;
128 sprintf(name,"%s_%d","Section",IndexOfSection);
129 DrawTrSurf::Set(name,sect);
130#endif
131}
132#endif
133
134//=======================================================================
135//function : ArcToRecadre
81bba717 136//purpose : Find a suitable arc
137// PrevIndex is used to reject an already tested arc
7fd59977 138//=======================================================================
139
140Standard_Integer BRepBlend_SurfRstLineBuilder::
141 ArcToRecadre(const math_Vector& sol,
142 const Standard_Integer PrevIndex,
143 gp_Pnt2d& lastpt2d,
144 gp_Pnt2d& pt2d,
145 Standard_Real& ponarc)
146{
147 Standard_Integer IndexSol = 0, nbarc = 0;
148 Standard_Boolean ok = Standard_False;
149 Standard_Boolean byinter = (line->NbPoints() != 0), okinter = 0;
150 Standard_Real distmin = RealLast();
151 Standard_Real uprev,vprev, prm, dist;
152
153 if(byinter) previousP.ParametersOnS(uprev,vprev);
154 pt2d.SetCoord(sol(1),sol(2));
155 lastpt2d.SetCoord(uprev,vprev);
156 domain1->Init();
157
158 while (domain1->More()) {
159 nbarc++; ok = 0;
160 if(byinter) {
161 ok = okinter = BRepBlend_BlendTool::Inters(pt2d,lastpt2d,
162 surf1,
163 domain1->Value(),prm,dist);
164 }
165 if(!ok) ok = BRepBlend_BlendTool::Project(pt2d,surf1,
166 domain1->Value(),prm,dist);
167
168 if (ok && (nbarc != PrevIndex) ) {
169 if (dist<distmin || okinter) {
170 distmin = dist;
171 ponarc = prm;
172 IndexSol = nbarc;
173 if(okinter && (PrevIndex==0) ) break;
174 }
175 }
176 domain1->Next();
177 }
178 return IndexSol;
179}
180
181//=======================================================================
182//function : BRepBlend_SurfRstLineBuilder
183//purpose :
184//=======================================================================
185
186BRepBlend_SurfRstLineBuilder::BRepBlend_SurfRstLineBuilder
187(const Handle(Adaptor3d_HSurface)& Surf1,
188 const Handle(Adaptor3d_TopolTool)& Domain1,
189 const Handle(Adaptor3d_HSurface)& Surf2,
190 const Handle(Adaptor2d_HCurve2d)& Rst,
191 const Handle(Adaptor3d_TopolTool)& Domain2):
192 sol(1,3),surf1(Surf1), domain1(Domain1),
193 surf2(Surf2), rst(Rst), domain2(Domain2)
194{
195}
196
197//=======================================================================
198//function : Perform
199//purpose :
200//=======================================================================
201
202void BRepBlend_SurfRstLineBuilder::Perform(Blend_SurfRstFunction& Func,
203 Blend_FuncInv& Finv,
204 Blend_SurfPointFuncInv& FinvP,
205 Blend_SurfCurvFuncInv& FinvC,
206 const Standard_Real Pdep,
207 const Standard_Real Pmax,
208 const Standard_Real MaxStep,
209 const Standard_Real TolGuide,
210 const math_Vector& ParDep,
211 const Standard_Real Tolesp,
212 const Standard_Real Fleche,
213 const Standard_Boolean Appro)
214{
215 done = Standard_False;
216 iscomplete = Standard_False;
217 comptra = Standard_False;
218 line = new BRepBlend_Line();
219 tolesp = Abs(Tolesp);
220 tolgui = Abs(TolGuide);
221 fleche = Abs(Fleche);
222 rebrou = Standard_False;
223 pasmax = Abs(MaxStep);
224
225 if (Pmax-Pdep >= 0.) {
226 sens = 1.;
227 }
228 else {
229 sens = -1.;
230 }
231
232 Blend_Status State;
233
234 param = Pdep;
235 Func.Set(param);
236
237 if (Appro) {
238 TopAbs_State siturst,situs;
239 Standard_Boolean decroch;
240 math_Vector tolerance(1,3),infbound(1,3),supbound(1,3);
241 Func.GetTolerance(tolerance,tolesp);
242 Func.GetBounds(infbound,supbound);
243 math_FunctionSetRoot rsnld(Func,tolerance,30);
244
245 rsnld.Perform(Func,ParDep,infbound,supbound);
246
247 if (!rsnld.IsDone()) {
248 return;
249 }
250 rsnld.Root(sol);
251 if (!CheckInside(Func,siturst,situs,decroch)) {
252 return;
253 }
254 }
255 else {
256 sol = ParDep;
257 }
258
259 State = TestArret(Func,Standard_False,Blend_OK);
260 if (State!=Blend_OK) {
261 return;
262 }
263#ifdef DEB
264 if (Blend_GettraceDRAWSECT()){
265 Drawsect(param,Func);
266 }
267#endif
81bba717 268 // Update the line.
7fd59977 269 line->Append(previousP);
270 Standard_Real U,V;
271 previousP.ParametersOnS(U,V);
272// W = previousP.ParameterOnC();
273
274 BRepBlend_Extremity ptf1(previousP.PointOnS(),
275 U,V,previousP.Parameter(),tolesp);
276 BRepBlend_Extremity ptf2(previousP.PointOnC(),
277 U,V,previousP.Parameter(),tolesp);
278 if (!previousP.IsTangencyPoint()) {
279 ptf1.SetTangent(previousP.TangentOnS());
280 ptf2.SetTangent(previousP.TangentOnC());
281 }
282 if (sens>0.) {
283 line->SetStartPoints(ptf1, ptf2);
284 }
285 else {
286 line->SetEndPoints(ptf1, ptf2);
287
288 }
289 InternalPerform(Func,Finv,FinvP,FinvC,Pmax);
290 done = Standard_True;
291}
292
293//=======================================================================
294//function : PerformFirstSection
295//purpose :
296//=======================================================================
297
298Standard_Boolean BRepBlend_SurfRstLineBuilder::PerformFirstSection
299(Blend_SurfRstFunction& Func,
300 Blend_FuncInv& Finv,
301 Blend_SurfPointFuncInv& FinvP,
302 Blend_SurfCurvFuncInv& FinvC,
303 const Standard_Real Pdep,
304 const Standard_Real Pmax,
305 const math_Vector& ParDep,
306 const Standard_Real Tolesp,
307 const Standard_Real TolGuide,
308 const Standard_Boolean RecRst,
309 const Standard_Boolean RecP,
310 const Standard_Boolean RecS,
311 Standard_Real& Psol,
312 math_Vector& ParSol)
313{
314 done = Standard_False;
315 iscomplete = Standard_False;
316 comptra = Standard_False;
317 line = new BRepBlend_Line();
318 tolesp = Abs(Tolesp);
319 tolgui = Abs(TolGuide);
320 rebrou = Standard_False;
321
322 if (Pmax-Pdep >= 0.) {
323 sens = 1.;
324 }
325 else {
326 sens = -1.;
327 }
328#ifndef DEB
329 Blend_Status State = Blend_OnRst12;
330 Standard_Real trst = 0.;
331#else
332 Blend_Status State;
333 Standard_Real trst;
334#endif
335 Standard_Boolean recadp,recadrst,recads;
336 Standard_Real wp,wrst,ws;
337 Standard_Real U,V;
338 math_Vector infbound(1,3),supbound(1,3),tolerance(1,3);
339 math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
340 Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
341 Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
342 Handle(Adaptor2d_HCurve2d) Arc;
343 wp = wrst = ws = Pmax;
344 param = Pdep;
345 Func.Set(param);
346 Func.GetTolerance(tolerance,tolesp);
347 Func.GetBounds(infbound,supbound);
348
349 math_FunctionSetRoot rsnld(Func,tolerance,30);
350 rsnld.Perform(Func,ParDep,infbound,supbound);
351 if (!rsnld.IsDone()) return Standard_False;
352 rsnld.Root(sol);
353
354 recads = RecS && Recadre(FinvC,solinvs,Arc,IsVtxs,Vtxs);
355 if (recads) {
356 ws = solinvs(1);
357 }
358 recadp = RecP && Recadre(FinvP,solinvp,IsVtxp,Vtxp);
359 if (recadp) {
360 wp = solinvp(1);
361 }
362 recadrst = RecRst && Recadre(Func,Finv,solinvrst,IsVtxrst,Vtxrst);
363 if (recadrst) {
364 wrst = solinvrst(2);
365 }
366 if (!recads && !recadp && !recadrst) return Standard_False;
367 if (recadp && recadrst) {
81bba717 368 if(sens*(wrst-wp) > tolgui){ //first one leaves the domain
7fd59977 369 wrst = wp;
370 U = solinvp(2);
371 V = solinvp(3);
372 trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
373 IsVtxrst = IsVtxp;
374 Vtxrst = Vtxp;
375 }
376 else{
377 U = solinvrst(3);
378 V = solinvrst(4);
379 trst = solinvrst(1);
380 }
381 }
382 else if(recadp){
383 wrst = wp;
384 U = solinvp(2);
385 V = solinvp(3);
386 trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
387 IsVtxrst = IsVtxp;
388 Vtxrst = Vtxp;
389 recadrst = Standard_True;
390 }
391 else if(recadrst){
392 U = solinvrst(3);
393 V = solinvrst(4);
394 trst = solinvrst(1);
395 }
396 if(recads && recadrst){
397 if(Abs(ws - wrst) < tolgui){
398 State = Blend_OnRst12;
399 param = 0.5*(ws+wrst);
400 sol(1) = U;
401 sol(2) = V;
402 sol(3) = solinvs(2);
403 }
404 else if(sens*(ws-wrst)<0){
81bba717 405 // ground on surf
7fd59977 406 State = Blend_OnRst1;
407 param = ws;
408 Arc->Value(solinvs(3)).Coord(U,V);
409 sol(1) = U;
410 sol(2) = V;
411 sol(3) = solinvs(2);
412 }
413 else{
81bba717 414 // ground on rst
7fd59977 415 State = Blend_OnRst2;
416 param = wrst;
417 sol(1) = U;
418 sol(2) = V;
419 sol(3) = trst;
420 }
421 Func.Set(param);
422 }
423 else if(recads){
81bba717 424 // ground on surf
7fd59977 425 State = Blend_OnRst1;
426 param = ws;
427 Arc->Value(solinvs(3)).Coord(U,V);
428 sol(1) = U;
429 sol(2) = V;
430 sol(3) = solinvs(2);
431 Func.Set(param);
432 }
433 else if(recadrst){
81bba717 434 // ground on rst
7fd59977 435 State = Blend_OnRst2;
436 param = wrst;
437 sol(1) = U;
438 sol(2) = V;
439 sol(3) = trst;
440 Func.Set(param);
441 }
442 State = TestArret(Func,Standard_False,State);
443 Psol = param;
444 ParSol = sol;
445 return Standard_True;
446}
447
448//=======================================================================
449//function : Complete
450//purpose :
451//=======================================================================
452
453Standard_Boolean BRepBlend_SurfRstLineBuilder::Complete(Blend_SurfRstFunction& Func,
454 Blend_FuncInv& Finv,
455 Blend_SurfPointFuncInv& FinvP,
456 Blend_SurfCurvFuncInv& FinvC,
457 const Standard_Real Pmin)
458{
459 if (!done) {StdFail_NotDone::Raise();}
460 if (iscomplete) {return Standard_True;}
461 if (sens >0.) {
462 previousP = line->Point(1);
463 }
464 else {
465 previousP = line->Point(line->NbPoints());
466 }
467 sens = -sens;
468 param = previousP.Parameter();
469 previousP.ParametersOnS(sol(1),sol(2));
470 sol(3) = previousP.ParameterOnC();
471
472 InternalPerform(Func,Finv,FinvP,FinvC,Pmin);
473 iscomplete = Standard_True;
474 return Standard_True;
475}
476
477//=======================================================================
478//function : InternalPerform
479//purpose :
480//=======================================================================
481
482void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction& Func,
483 Blend_FuncInv& Finv,
484 Blend_SurfPointFuncInv& FinvP,
485 Blend_SurfCurvFuncInv& FinvC,
486 const Standard_Real Bound)
487{
488 Standard_Real stepw = pasmax;
489 Standard_Integer nbp = line->NbPoints();
81bba717 490 if(nbp >= 2){ //The last step is reproduced if it is not too small.
7fd59977 491 if(sens < 0.){
492 stepw = (line->Point(2).Parameter() - line->Point(1).Parameter());
493 }
494 else{
495 stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter());
496 }
497 stepw = Max(stepw,100.*tolgui);
498 }
499 Standard_Real parprec = param;
500 if (sens*(parprec - Bound) >= -tolgui) {
501 return;
502 }
503#ifndef DEB
504 Blend_Status State = Blend_OnRst12;
505#else
506 Blend_Status State;
507#endif
508 TopAbs_State situonc,situons;
509 Standard_Boolean decroch;
510 Standard_Boolean Arrive,recadp,recadrst,recads,echecrecad;
511 Standard_Real wp,wrst,ws;
512 Standard_Real U,V;
513#ifndef DEB
514 Standard_Real trst = 0.;
515#else
516 Standard_Real trst;
517#endif
518 math_Vector infbound(1,3),supbound(1,3);
519 math_Vector parinit(1,3),tolerance(1,3);
520 math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3);
521 Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc;
522 Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0;
523 BRepBlend_Extremity Extrst,Exts;
524 Handle(Adaptor2d_HCurve2d) Arc;
525
526 //IntSurf_Transition Tline,Tarc;
527
528 Func.GetTolerance(tolerance,tolesp);
529 Func.GetBounds(infbound,supbound);
530
531 math_FunctionSetRoot rsnld(Func,tolerance,30);
532 parinit = sol;
533
534 Arrive = Standard_False;
535 param = parprec + sens*stepw;
536 if(sens *(param - Bound) > 0.) {
537 stepw = sens*(Bound - parprec)*0.5;
538 param = parprec + sens*stepw;
539 }
540
541 while (!Arrive) {
542 Standard_Boolean bonpoint = 1;
543#if 0
544 //debdebdebdebdebdeb
545 Func.Set(param);
546 rsnld.Perform(Func,parinit,infbound,supbound);
547 if (rsnld.IsDone()) {
548 rsnld.Root(sol);
549 Blend_Point bp1;
550 if(BBPP(param,Func,sol,tolesp,bp1)){
551 Standard_Real dw = 1.e-10;
552 Func.Set(param+dw);
553 rsnld.Perform(Func,parinit,infbound,supbound);
554 if (rsnld.IsDone()) {
555 rsnld.Root(sol);
556 Blend_Point bp2;
557 if(BBPP(param+dw,Func,sol,tolesp,bp2)){
558 tracederiv(Func,bp1,bp2);
559 }
560 }
561 }
562 }
563 //debdebdebdebdebdeb
564#endif
565 Func.Set(param);
566 rsnld.Perform(Func,parinit,infbound,supbound);
567
568 if (rsnld.IsDone()) {
569 rsnld.Root(sol);
570 if(!CheckInside(Func,situonc,situons,decroch) && line->NbPoints() == 1){
571 State = Blend_StepTooLarge;
572 bonpoint = 0;
573 }
574 }
575 else {
576 State = Blend_StepTooLarge;
577 bonpoint = 0;
578 }
579 if(bonpoint){
580 wp = wrst = ws = Bound;
581 recadp = recadrst = recads = Standard_False;
582 echecrecad = Standard_False;
583 if (situons == TopAbs_OUT || situons == TopAbs_ON) {
584 // pb inverse rst/rst
585 recads = Recadre(FinvC,solinvs,Arc,IsVtxs,Vtxs);
586 if (recads) {
587 ws = solinvs(1);
81bba717 588 // It is necessary to reevaluate the deviation (BUC60360)
7fd59977 589 gp_Vec t, n;
590 Func.Set(ws);
591 Arc->Value(solinvs(3)).Coord(U,V);
592 sol(1) = U;
593 sol(2) = V;
594 sol(3) = solinvs(2);
595 decroch = Func.Decroch(sol, t, n);
596 }
597 else {
598 echecrecad = Standard_True;
599 }
600 }
601 if (situonc == TopAbs_OUT || situonc == TopAbs_ON) {
602 // pb inverse point/surf
603 recadp = Recadre(FinvP,solinvp,IsVtxp,Vtxp);
604 if (recadp) {
605 wp = solinvp(1);
606 }
607 else {
608 echecrecad = Standard_True;
609 }
610 }
611 if (decroch) {
612 // pb inverse rst/surf
613 recadrst = Recadre(Func,Finv,solinvrst,IsVtxrst,Vtxrst);
614 if (recadrst) {
615 wrst = solinvrst(2);
616 }
617 else {
618 echecrecad = Standard_True;
619 }
620 }
621 decroch = 0;
622 if(recadp || recads || recadrst) echecrecad = Standard_False;
623 if (!echecrecad) {
624 if (recadp && recadrst) {
81bba717 625 if(sens*(wrst-wp) > tolgui){ //first one leaves the domain
7fd59977 626 wrst = wp;
627 U = solinvp(2);
628 V = solinvp(3);
629 trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
630 IsVtxrst = IsVtxp;
631 Vtxrst = Vtxp;
632 }
633 else{
634 decroch = 1;
635 U = solinvrst(3);
636 V = solinvrst(4);
637 trst = solinvrst(1);
638 }
639 }
640 else if(recadp){
641 wrst = wp;
642 U = solinvp(2);
643 V = solinvp(3);
644 trst = BRepBlend_BlendTool::Parameter(Vtxp,rst);
645 IsVtxrst = IsVtxp;
646 Vtxrst = Vtxp;
647 recadrst = Standard_True;
648 }
649 else if(recadrst){
650 decroch = 1;
651 U = solinvrst(3);
652 V = solinvrst(4);
653 trst = solinvrst(1);
654 }
655 if(recads && recadrst){
656 if(Abs(ws - wrst) < tolgui){
657 State = Blend_OnRst12;
658 param = 0.5*(ws+wrst);
659 sol(1) = U;
660 sol(2) = V;
661 sol(3) = solinvs(3);
662 }
663 else if(sens*(ws-wrst)<0){
81bba717 664 // ground on surf
7fd59977 665 decroch = 0;
666 State = Blend_OnRst1;
667 param = ws;
668 Arc->Value(solinvs(3)).Coord(U,V);
669 sol(1) = U;
670 sol(2) = V;
671 sol(3) = solinvs(2);
672 }
673 else{
81bba717 674 // ground on rst
7fd59977 675 State = Blend_OnRst2;
676 param = wrst;
677 sol(1) = U;
678 sol(2) = V;
679 sol(3) = trst;
680 }
681 Func.Set(param);
682 }
683 else if(recads){
81bba717 684 // ground on surf
7fd59977 685 State = Blend_OnRst1;
686 param = ws;
687 Arc->Value(solinvs(3)).Coord(U,V);
688 sol(1) = U;
689 sol(2) = V;
690 sol(3) = solinvs(2);
691 Func.Set(param);
692 }
693 else if(recadrst){
81bba717 694 // ground on rst
7fd59977 695 State = Blend_OnRst2;
696 param = wrst;
697 sol(1) = U;
698 sol(2) = V;
699 sol(3) = trst;
700 Func.Set(param);
701 }
702 else {
703 State = Blend_OK;
704 }
705 State = TestArret(Func,Standard_True,State);
706 }
707 else{
81bba717 708 // Failed reframing. Leave with PointsConfondus
7fd59977 709#if DEB
81bba717 710 cout<<"SurfRstLineBuilder : failed reframing"<<endl;
7fd59977 711#endif
712 State = Blend_SamePoints;
713 }
714 }
715
716 switch (State) {
717 case Blend_OK :
718 {
719#ifdef DEB
720 if (Blend_GettraceDRAWSECT()){
721 Drawsect(param,Func);
722 }
723#endif
81bba717 724 // Update the line.
7fd59977 725 if (sens>0.) {
726 line->Append(previousP);
727 }
728 else {
729 line->Prepend(previousP);
730 }
731 parinit = sol;
732 parprec = param;
733
734 if (param == Bound) {
735 Arrive = Standard_True;
736 Exts.SetValue(previousP.PointOnS(),
737 sol(1),sol(2),
738 previousP.Parameter(),tolesp);
739 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
81bba717 740 // Indicate end on Bound.
7fd59977 741 }
742 else {
743 param = param + sens*stepw;
744 if (sens*(param - Bound) > - tolgui) {
745 param = Bound;
746 }
747 }
748 }
749 break;
750
751 case Blend_StepTooLarge :
752 {
753 stepw = stepw/2.;
754 if (Abs(stepw) < tolgui) {
755 previousP.ParametersOnS(U,V);
756 Exts.SetValue(previousP.PointOnS(),U,V,
757 previousP.Parameter(),tolesp);
758 Extrst.SetValue(previousP.PointOnC(),
759 previousP.ParameterOnC(),
760 previousP.Parameter(),tolesp);
761 Arrive = Standard_True;
762 if (line->NbPoints()>=2) {
81bba717 763 // Indicate that one stops during the processing
7fd59977 764#if DEB
81bba717 765 cout<<"SurfRstLineBuilder : No advancement in the processing"<<endl;
7fd59977 766#endif
767 }
768 }
769 else {
81bba717 770 param = parprec + sens*stepw; // no risk to exceed Bound.
7fd59977 771 }
772 }
773 break;
774
775 case Blend_StepTooSmall :
776 {
777#ifdef DEB
778 if (Blend_GettraceDRAWSECT()){
779 Drawsect(param,Func);
780 }
781#endif
81bba717 782 // Update the line.
7fd59977 783 if (sens>0.) {
784 line->Append(previousP);
785 }
786 else {
787 line->Prepend(previousP);
788 }
789 parinit = sol;
790 parprec = param;
791
792 stepw = Min(1.5*stepw,pasmax);
793 if (param == Bound) {
794 Arrive = Standard_True;
795 Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),
796 previousP.Parameter(),tolesp);
797 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
81bba717 798 // Indicate end on Bound.
7fd59977 799 }
800 else {
801 param = param + sens*stepw;
802 if (sens*(param - Bound) > - tolgui) {
803 param = Bound;
804 }
805 }
806 }
807 break;
808
809 case Blend_OnRst1 :
810 {
811#ifdef DEB
812 if (Blend_GettraceDRAWSECT()){
813 Drawsect(param,Func);
814 }
815#endif
816 if (sens>0.) {
817 line->Append(previousP);
818 }
819 else {
820 line->Prepend(previousP);
821 }
822 MakeExtremity(Exts,Standard_True,Arc,solinvs(3),IsVtxs,Vtxs);
823 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
824 Arrive = Standard_True;
825 }
826 break;
827
828 case Blend_OnRst2 :
829 {
830#ifdef DEB
831 if (Blend_GettraceDRAWSECT()){
832 Drawsect(param,Func);
833 }
834#endif
835 if (sens>0.) {
836 line->Append(previousP);
837 }
838 else {
839 line->Prepend(previousP);
840 }
841 Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),
842 previousP.Parameter(),tolesp);
843 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
844 Arrive = Standard_True;
845 }
846 break;
847
848 case Blend_OnRst12 :
849 {
850#ifdef DEB
851 if (Blend_GettraceDRAWSECT()){
852 Drawsect(param,Func);
853 }
854#endif
855 if (sens>0.) {
856 line->Append(previousP);
857 }
858 else {
859 line->Prepend(previousP);
860 }
861 MakeExtremity(Exts,Standard_True,Arc,solinvs(1),IsVtxs,Vtxs);
862 MakeExtremity(Extrst,Standard_False,rst,sol(3),IsVtxrst,Vtxrst);
863 Arrive = Standard_True;
864 }
865 break;
866
867 case Blend_SamePoints :
868 {
81bba717 869 // Stop
7fd59977 870#if DEB
81bba717 871 cout << "SurfRstLineBuilder Points mixed in the processing" << endl;
7fd59977 872#endif
873 previousP.ParametersOnS(U,V);
874 Exts.SetValue(previousP.PointOnS(),U,V,
875 previousP.Parameter(),tolesp);
876 Extrst.SetValue(previousP.PointOnC(),
877 previousP.ParameterOnC(),
878 previousP.Parameter(),tolesp);
879 Arrive = Standard_True;
880 }
881 break;
882#ifndef DEB
883 default:
884 break;
885#endif
886 }
887 if (Arrive) {
888 if (sens > 0.) {
889 line->SetEndPoints(Exts,Extrst);
890 decrochfin = decroch;
891 }
892 else {
893 line->SetStartPoints(Exts,Extrst);
894 decrochdeb = decroch;
895 }
896 }
897 }
898}
899
900//=======================================================================
901//function : Recadre
81bba717 902//purpose : Reframe section Surface / Restriction
7fd59977 903//=======================================================================
904
905Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfCurvFuncInv& FinvC,
906 math_Vector& Solinv,
907 Handle(Adaptor2d_HCurve2d)& Arc,
908 Standard_Boolean& IsVtx,
909 Handle(Adaptor3d_HVertex)& Vtx)
910{
911 Standard_Boolean recadre = Standard_False;
912#ifdef DEB
913 Standard_Boolean byinter = (line->NbPoints() != 0);
914#endif
915 gp_Pnt2d pt2d, lastpt2d;
916 Standard_Integer IndexSol, nbarc;
917 Standard_Real pmin;
918
919 IndexSol = ArcToRecadre(sol, 0, lastpt2d, pt2d, pmin);
920
921 IsVtx = Standard_False;
922 if (IndexSol == 0) {
923 return Standard_False;
924 }
925
926 domain1->Init();
927 nbarc = 1;
928 while (nbarc < IndexSol) {
929 nbarc++;
930 domain1->Next();
931 }
932 Arc = domain1->Value();
933
934 FinvC.Set(Arc);
935
936 math_Vector toler(1,3),infb(1,3),supb(1,3);
937 FinvC.GetTolerance(toler,tolesp);
938 FinvC.GetBounds(infb,supb);
939 Solinv(1) = param;
940 Solinv(2) = sol(3);
941 Solinv(3) = pmin;
942
943 math_FunctionSetRoot rsnld(FinvC,toler,30);
944 rsnld.Perform(FinvC,Solinv,infb,supb);
945
946 if (!rsnld.IsDone()) {
947#if DEB
948 cout << "SurfRstLineBuilder : RSNLD not done "<< endl << endl;
949#endif
950 }
951 else {
81bba717 952 // It is necessary to check the value of the function
7fd59977 953 rsnld.Root(Solinv);
954 recadre = FinvC.IsSolution(Solinv,tolesp);
955 }
956
81bba717 957 // In case of fail, it is checked if another arc
958 // can be useful (case of output at the proximity of a vertex)
7fd59977 959 if (!recadre) {
960
961 IndexSol = ArcToRecadre(sol, IndexSol,
962 lastpt2d, pt2d, pmin);
963 if (IndexSol == 0) {
81bba717 964 return Standard_False; // No other solution
7fd59977 965 }
966
967 domain1->Init();
968 nbarc = 1;
969 while (nbarc < IndexSol) {
970 nbarc++;
971 domain1->Next();
972 }
973
974 Arc = domain1->Value();
975 FinvC.Set(Arc);
976
977 FinvC.GetTolerance(toler,tolesp);
978 FinvC.GetBounds(infb,supb);
979
980 Solinv(3) = pmin;
981
982 math_FunctionSetRoot rsnld(FinvC,toler,30);
983 rsnld.Perform(FinvC,Solinv,infb,supb);
984
985 if (!rsnld.IsDone()) {
986#if DEB
987 cout << "SurfRstLineBuilder : RSNLD not done "<< endl << endl;
988#endif
989 }
990 else {
81bba717 991 // It is necessary to check the value of the function
7fd59977 992 rsnld.Root(Solinv);
993 recadre = FinvC.IsSolution(Solinv,tolesp);
994 }
995 }
996
997 if (recadre) {
998 Standard_Real w = Solinv(2);
999 if(w < rst->FirstParameter() - toler(2)||
1000 w > rst->LastParameter() + toler(2)){
1001 return Standard_False;
1002 }
1003 domain1->Initialize(Arc);
1004 domain1->InitVertexIterator();
1005 IsVtx = !domain1->MoreVertex();
1006 while (!IsVtx) {
1007 Vtx = domain1->Vertex();
1008 if (Abs(BRepBlend_BlendTool::Parameter(Vtx,Arc)-Solinv(3)) <=
1009 BRepBlend_BlendTool::Tolerance(Vtx,Arc)) {
1010 IsVtx = Standard_True;
1011 }
1012 else {
1013 domain1->NextVertex();
1014 IsVtx = !domain1->MoreVertex();
1015 }
1016 }
1017 if (!domain1->MoreVertex()) {
1018 IsVtx = Standard_False;
1019 }
1020 return Standard_True;
1021 }
1022 return Standard_False;
1023}
1024
1025//=======================================================================
1026//function : Recadre
1027//purpose :
1028//=======================================================================
1029
1030Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfRstFunction& Func,
1031 Blend_FuncInv& Finv,
1032 math_Vector& Solinv,
1033 Standard_Boolean& IsVtx,
1034 Handle(Adaptor3d_HVertex)& Vtx)
1035{
1036 math_Vector toler(1,4),infb(1,4),supb(1,4);
1037 Finv.GetTolerance(toler,tolesp);
1038 Finv.GetBounds(infb,supb);
1039 Solinv(1) = sol(3);
1040 Solinv(2) = param;
1041 Solinv(3) = sol(1);
1042 Solinv(4) = sol(2);
1043
1044 math_FunctionSetRoot rsnld(Finv,toler,30);
1045 rsnld.Perform(Finv,Solinv,infb,supb);
1046 if (!rsnld.IsDone()) {
1047#if DEB
1048 cout << "SurfRstLineBuilder :RSNLD not done "<< endl;
1049#endif
1050 return Standard_False;
1051 }
1052 rsnld.Root(Solinv);
1053
1054 if(Finv.IsSolution(Solinv,tolesp)){
1055 gp_Pnt2d p2d(Solinv(3),Solinv(4));
1056 TopAbs_State situ = domain1->Classify(p2d,Min(toler(3),toler(4)),0);
1057 if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
1058 return Standard_False;
1059 }
1060 domain2->Initialize(rst);
1061 domain2->InitVertexIterator();
1062 IsVtx = !domain2->MoreVertex();
1063 while (!IsVtx) {
1064 Vtx = domain2->Vertex();
1065 if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-Solinv(1)) <=
1066 BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
1067 IsVtx = Standard_True;
1068 }
1069 else {
1070 domain2->NextVertex();
1071 IsVtx = !domain2->MoreVertex();
1072 }
1073 }
1074 if (!domain2->MoreVertex()) {
1075 IsVtx = Standard_False;
1076 }
81bba717 1077 // The section is recalculated by direct resolution, otherwise
1078 // incoherences between the parameter and the ground caused by yawn are returned.
7fd59977 1079
1080 math_Vector infbound(1,3),supbound(1,3);
1081 math_Vector parinit(1,3),tolerance(1,3);
1082 Func.GetTolerance(tolerance,tolesp);
1083 Func.GetBounds(infbound,supbound);
1084
1085 math_FunctionSetRoot rsnld2(Func,tolerance,30);
1086 parinit(1) = Solinv(3);
1087 parinit(2) = Solinv(4);
1088 parinit(3) = Solinv(1);
1089 Func.Set(Solinv(2));
1090 rsnld2.Perform(Func,parinit,infbound,supbound);
1091 if(!rsnld2.IsDone()) return Standard_False;
1092 rsnld2.Root(parinit);
1093 Solinv(3) = parinit(1);
1094 Solinv(4) = parinit(2);
1095 Solinv(1) = parinit(3);
1096 return Standard_True;
1097 }
1098 return Standard_False;
1099}
1100
1101//=======================================================================
1102//function : Recadre
1103//purpose :
1104//=======================================================================
1105
1106Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfPointFuncInv& FinvP,
1107 math_Vector& Solinv,
1108 Standard_Boolean& IsVtx,
1109 Handle(Adaptor3d_HVertex)& Vtx)
1110{
1111 // Le point.
1112 gp_Pnt2d p2drst;
1113 Standard_Real firstrst = rst->FirstParameter();
1114 Standard_Real lastrst = rst->LastParameter();
1115 Standard_Real wpoint = firstrst;
1116 if((sol(3) - firstrst) > (lastrst - sol(3))) wpoint = lastrst;
1117 p2drst = rst->Value(wpoint);
1118 gp_Pnt thepoint = surf2->Value(p2drst.X(),p2drst.Y());
1119
1120 FinvP.Set(thepoint);
1121 math_Vector toler(1,3),infb(1,3),supb(1,3);
1122 FinvP.GetTolerance(toler,tolesp);
1123 FinvP.GetBounds(infb,supb);
1124 Solinv(1) = param;
1125 Solinv(2) = sol(1);
1126 Solinv(3) = sol(2);
1127
1128 math_FunctionSetRoot rsnld(FinvP,toler,30);
1129 rsnld.Perform(FinvP,Solinv,infb,supb);
1130 if (!rsnld.IsDone()) {
1131#if DEB
1132 cout << "SurfRstLineBuilder :RSNLD not done "<< endl;
1133#endif
1134 return Standard_False;
1135 }
1136 rsnld.Root(Solinv);
1137
1138 if(FinvP.IsSolution(Solinv,tolesp)){
1139 gp_Pnt2d p2d(Solinv(2),Solinv(3));
1140 TopAbs_State situ = domain1->Classify(p2d,Min(toler(2),toler(3)),0);
1141 if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) {
1142 return Standard_False;
1143 }
1144 domain2->Initialize(rst);
1145 domain2->InitVertexIterator();
1146 IsVtx = !domain2->MoreVertex();
1147 while (!IsVtx) {
1148 Vtx = domain2->Vertex();
1149 if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-wpoint) <=
1150 BRepBlend_BlendTool::Tolerance(Vtx,rst)) {
1151 IsVtx = Standard_True;
1152 }
1153 else {
1154 domain2->NextVertex();
1155 IsVtx = !domain2->MoreVertex();
1156 }
1157 }
1158 if (!domain2->MoreVertex()) {
1159 IsVtx = Standard_False;
1160 }
1161 return Standard_True;
1162 }
1163 return Standard_False;
1164}
1165
1166//=======================================================================
1167//function : Transition
1168//purpose :
1169//=======================================================================
1170
1171void BRepBlend_SurfRstLineBuilder::Transition(const Standard_Boolean OnFirst,
1172 const Handle(Adaptor2d_HCurve2d)& Arc,
1173 const Standard_Real Param,
1174 IntSurf_Transition& TLine,
1175 IntSurf_Transition& TArc)
1176{
1177 Standard_Boolean computetranstionaveclacorde = 0;
1178 gp_Vec tgline;
1179 Blend_Point prevprev;
1180
1181 if(previousP.IsTangencyPoint()){
1182 if(line->NbPoints() < 2) return;
1183 computetranstionaveclacorde = 1;
1184 if(sens < 0){
1185 prevprev = line->Point(2);
1186 }
1187 else {
1188 prevprev = line->Point(line->NbPoints() - 1);
1189 }
1190 }
1191 gp_Pnt2d p2d;
1192 gp_Vec2d dp2d;
1193
1194 gp_Pnt pbid;
1195 gp_Vec d1u,d1v,normale,tgrst;
1196
1197 Arc->D1(Param,p2d,dp2d);
1198 if (OnFirst) {
1199 surf1->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v);
1200 if(!computetranstionaveclacorde) tgline = previousP.TangentOnS1();
1201 else tgline = gp_Vec(prevprev.PointOnS(),previousP.PointOnS());
1202 }
1203 else {
1204 surf2->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v);
1205 if(!computetranstionaveclacorde) tgline = previousP.TangentOnS2();
1206 else tgline = gp_Vec(prevprev.PointOnC(),previousP.PointOnC());
1207 }
1208
1209 tgrst.SetLinearForm(dp2d.X(),d1u,dp2d.Y(),d1v);
1210 normale = d1u.Crossed(d1v);
1211
1212 IntSurf::MakeTransition(tgline,tgrst,normale,TLine,TArc);
1213}
1214
1215//=======================================================================
1216//function : MakeExtremity
1217//purpose :
1218//=======================================================================
1219
1220void BRepBlend_SurfRstLineBuilder::MakeExtremity(BRepBlend_Extremity& Extrem,
1221 const Standard_Boolean OnFirst,
1222 const Handle(Adaptor2d_HCurve2d)& Arc,
1223 const Standard_Real Param,
1224 const Standard_Boolean IsVtx,
1225 const Handle(Adaptor3d_HVertex)& Vtx)
1226{
1227 IntSurf_Transition Tline,Tarc;
1228 Standard_Real prm;
1229 Handle(Adaptor3d_TopolTool) Iter;
1230 if (OnFirst) {
1231 Extrem.SetValue(previousP.PointOnS(),
1232 sol(1),sol(2),
1233 previousP.Parameter(),tolesp);
1234 if (!previousP.IsTangencyPoint())
1235 Extrem.SetTangent(previousP.TangentOnS());
1236 Iter = domain1;
1237 }
1238 else {
1239 Extrem.SetValue(previousP.PointOnC(),
1240 sol(3),
1241 previousP.Parameter(),tolesp);
1242 if (!previousP.IsTangencyPoint())
1243 Extrem.SetTangent(previousP.TangentOnC());
1244 Iter = domain2;
1245 }
1246
1247 Iter->Init();
1248 if (!IsVtx) {
1249 Transition(OnFirst,Arc,Param,Tline,Tarc);
1250 Extrem.AddArc(Arc,Param,Tline,Tarc);
1251 }
1252 else {
1253 Extrem.SetVertex(Vtx);
1254 while (Iter->More()) {
1255//#ifndef DEB
1256 Handle(Adaptor2d_HCurve2d) arc = Iter->Value();
1257//#else
1258// Handle(Adaptor2d_HCurve2d)& arc = Iter->Value();
1259//#endif
1260 if (arc != Arc) {
1261 Iter->Initialize(arc);
1262 Iter->InitVertexIterator();
1263 while (Iter->MoreVertex()) {
1264 if (Iter->Identical(Vtx,Iter->Vertex())) {
1265 prm = BRepBlend_BlendTool::Parameter(Vtx,arc);
1266 Transition(OnFirst,arc,prm,Tline,Tarc);
1267 Extrem.AddArc(arc,prm,Tline,Tarc);
1268 }
1269 Iter->NextVertex();
1270 }
1271 }
1272 else {
1273 Transition(OnFirst,arc,Param,Tline,Tarc);
1274 Extrem.AddArc(arc,Param,Tline,Tarc);
1275 }
1276 Iter->Next();
1277 }
1278 }
1279}
1280
1281//=======================================================================
1282//function : CheckDeflectionOnSurf
1283//purpose :
1284//=======================================================================
1285
1286Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnSurf(const Blend_Point& CurPoint)
1287{
81bba717 1288 //Controls 3d of Blend_CSWalking.
7fd59977 1289
0d969553 1290 //rule by tests in U4 corresponds to 11.478 d
7fd59977 1291 const Standard_Real CosRef3D = 0.98;
1292 Standard_Real Cosi=0, Cosi2=0;
1293 Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
1294 Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
1295
1296 gp_Pnt Psurf = CurPoint.PointOnS();
1297 gp_Vec Tgsurf;
1298 if(!curpointistangent){
1299 Tgsurf = CurPoint.TangentOnS();
1300 }
1301 gp_Pnt prevP = previousP.PointOnS();
1302 gp_Vec prevTg;
1303 if(!prevpointistangent){
1304 prevTg = previousP.TangentOnS();
1305 }
1306#ifndef DEB
1307 Standard_Real Norme,prevNorme = 0.;
1308#else
1309 Standard_Real Norme,prevNorme;
1310#endif
1311 gp_Vec Corde(prevP,Psurf);
1312 Norme = Corde.SquareMagnitude();
1313// if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
1314 if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
1315
1316 if (Norme <= tolesp*tolesp){
81bba717 1317 // it can be necessary to force same point
7fd59977 1318 return Blend_SamePoints;
1319 }
1320 if(!prevpointistangent){
1321 if(prevNorme <= tolesp*tolesp) {
1322 return Blend_SamePoints;
1323 }
1324 Cosi = sens*Corde*prevTg;
81bba717 1325 if (Cosi <0.) { // angle 3d>pi/2. --> return back
7fd59977 1326 return Blend_Backward;
1327 }
1328
1329 Cosi2 = Cosi * Cosi / prevNorme / Norme;
1330 if (Cosi2 < CosRef3D) {
1331 return Blend_StepTooLarge;
1332 }
1333 }
1334
1335 if(!curpointistangent){
81bba717 1336 // Check if it is necessary to control the sign of prevtg*Tgsurf
7fd59977 1337 Cosi = sens*Corde*Tgsurf;
1338 Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
1339 if (Cosi2 < CosRef3D || Cosi < 0.) {
1340 return Blend_StepTooLarge;
1341 }
1342 }
1343
1344 if(!curpointistangent && !prevpointistangent){
81bba717 1345 // Estimation of the current arrow
7fd59977 1346 Standard_Real FlecheCourante =
1347 (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.;
1348
1349 if (FlecheCourante <= 0.25*fleche*fleche) {
1350 return Blend_StepTooSmall;
1351 }
1352 if (FlecheCourante > fleche*fleche) {
81bba717 1353 // not too great :
7fd59977 1354 return Blend_StepTooLarge;
1355 }
1356 }
1357 return Blend_OK;
1358}
1359
1360
1361//=======================================================================
1362//function : CheckDeflectionOnRst
1363//purpose :
1364//=======================================================================
1365
1366Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnRst(const Blend_Point& CurPoint)
1367{
81bba717 1368 //Controls 3D of Blend_CSWalking.
7fd59977 1369
81bba717 1370 // rule by tests in U4 corresponds to 11.478 d
7fd59977 1371 const Standard_Real CosRef3D = 0.98;
1372 Standard_Real Cosi, Cosi2;
1373 Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint();
1374 Standard_Boolean prevpointistangent = previousP.IsTangencyPoint();
1375
1376 gp_Pnt Psurf = CurPoint.PointOnC();
1377 gp_Vec Tgsurf;
1378 if(!curpointistangent){
1379 Tgsurf = CurPoint.TangentOnC();
1380 }
1381 gp_Pnt prevP = previousP.PointOnC();
1382 gp_Vec prevTg;
1383 if(!prevpointistangent){
1384 prevTg = previousP.TangentOnC();
1385 }
1386#ifndef DEB
1387 Standard_Real Norme,prevNorme = 0.;
1388#else
1389 Standard_Real Norme,prevNorme;
1390#endif
1391 gp_Vec Corde(prevP,Psurf);
1392 Norme = Corde.SquareMagnitude();
1393// if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude();
1394 if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude();
1395
1396 if (Norme <= tolesp*tolesp){
81bba717 1397 // it can be necessary to force same point
7fd59977 1398 return Blend_SamePoints;
1399 }
1400 if(!prevpointistangent){
1401 if(prevNorme <= tolesp*tolesp) {
1402 return Blend_SamePoints;
1403 }
1404 Cosi = sens*Corde*prevTg;
81bba717 1405 if (Cosi <0.) { // angle 3d>pi/2. --> return back
7fd59977 1406 return Blend_Backward;
1407 }
1408
1409 Cosi2 = Cosi * Cosi / prevNorme / Norme;
1410 if (Cosi2 < CosRef3D) {
1411 return Blend_StepTooLarge;
1412 }
1413 }
1414
1415 if(!curpointistangent){
81bba717 1416 // Check if it is necessary to control the sign of prevtg*Tgsurf
7fd59977 1417 Cosi = sens*Corde*Tgsurf;
1418 Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme;
1419 if (Cosi2 < CosRef3D || Cosi < 0.) {
1420 return Blend_StepTooLarge;
1421 }
1422 }
1423
1424 if(!curpointistangent && !prevpointistangent){
81bba717 1425 // Estimation of the current arrow
7fd59977 1426 Standard_Real FlecheCourante =
1427 (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.;
1428
1429 if (FlecheCourante <= 0.25*fleche*fleche) {
1430 return Blend_StepTooSmall;
1431 }
1432 if (FlecheCourante > fleche*fleche) {
81bba717 1433 // not too great
7fd59977 1434 return Blend_StepTooLarge;
1435 }
1436 }
1437 return Blend_OK;
1438}
1439
1440static IntSurf_TypeTrans ConvOrToTra(const TopAbs_Orientation O)
1441{
1442 if(O == TopAbs_FORWARD) return IntSurf_In;
1443 return IntSurf_Out;
1444}
1445
1446//=======================================================================
1447//function : TestArret
1448//purpose :
1449//=======================================================================
1450
1451Blend_Status BRepBlend_SurfRstLineBuilder::TestArret(Blend_SurfRstFunction& Func,
1452 const Standard_Boolean TestDeflection,
1453 const Blend_Status State)
1454{
1455 gp_Pnt pts,ptrst;
1456 gp_Pnt2d pt2drst;
1457 gp_Vec tgs,tgrst;
1458 gp_Vec2d tg2ds,tg2drst;
1459 Blend_Status StateS,StateRst;
1460#ifndef DEB
1461 IntSurf_TypeTrans tras = IntSurf_Undecided, trarst = IntSurf_Undecided;
1462#else
1463 IntSurf_TypeTrans tras,trarst;
1464#endif
1465 Blend_Point curpoint;
1466
1467 if (Func.IsSolution(sol,tolesp)) {
1468 Standard_Boolean curpointistangent = Func.IsTangencyPoint();
1469 pts = Func.PointOnS();
1470 ptrst = Func.PointOnRst();
1471 pt2drst = Func.Pnt2dOnRst();
1472 if(curpointistangent){
1473 curpoint.SetValue(pts,ptrst,param,sol(1),sol(2),
1474 pt2drst.X(),pt2drst.Y(),sol(3));
1475 }
1476 else{
1477 tgs = Func.TangentOnS();
1478 tgrst = Func.TangentOnRst();
1479 tg2ds = Func.Tangent2dOnS();
1480 tg2drst = Func.Tangent2dOnRst();
1481
1482 curpoint.SetValue(pts,ptrst,param,sol(1),sol(2),
1483 pt2drst.X(),pt2drst.Y(),sol(3),
1484 tgs,tgrst,tg2ds,tg2drst);
1485 }
1486 if (TestDeflection) {
1487 StateS = CheckDeflectionOnSurf(curpoint);
1488 StateRst = CheckDeflectionOnRst(curpoint);
1489 }
1490 else {
1491 StateS = StateRst = Blend_OK;
1492 }
1493 if (StateS == Blend_Backward) {
1494 StateS = Blend_StepTooLarge;
1495 rebrou= Standard_True;
1496 }
1497 if (StateRst == Blend_Backward) {
1498 StateRst = Blend_StepTooLarge;
1499 rebrou = Standard_True;
1500 }
1501 if (StateS == Blend_StepTooLarge ||
1502 StateRst == Blend_StepTooLarge) {
1503 return Blend_StepTooLarge;
1504 }
1505
1506 if (!comptra && !curpointistangent) {
1507 gp_Vec tgsecs,nors;
1508 Func.Decroch(sol,nors,tgsecs);
1509 nors.Normalize();
1510 Standard_Real testra = tgsecs.Dot(nors.Crossed(tgs));
1511 if (Abs(testra) > tolesp) {
1512 if (testra < 0.) {
1513 tras = IntSurf_In;
1514 }
1515 else if (testra >0.) {
1516 tras = IntSurf_Out;
1517 }
1518 gp_Pnt2d p2drstref; gp_Vec2d tg2drstref;
1519 rst->D1(sol(3),p2drstref,tg2drstref);
1520 testra = tg2drst.Dot(tg2drstref);
1521 TopAbs_Orientation Or = domain2->Orientation(rst);
1522 if (Abs(testra) > 1.e-8) {
1523 if (testra < 0.) {
1524 trarst = ConvOrToTra(TopAbs::Reverse(Or));
1525 }
1526 else if (testra >0.) {
1527 trarst = ConvOrToTra(Or);
1528 }
1529 comptra = Standard_True;
1530 line->Set(tras,trarst);
1531 }
1532 }
1533 }
1534 if (StateS == Blend_OK ||
1535 StateRst == Blend_OK ) {
1536 previousP = curpoint;
1537 return State;
1538 }
1539 if (StateS == Blend_StepTooSmall &&
1540 StateRst == Blend_StepTooSmall) {
1541 previousP = curpoint;
1542 if (State == Blend_OK) {
1543 return Blend_StepTooSmall;
1544 }
1545 else {
1546 return State;
1547 }
1548 }
1549 if (State == Blend_OK) {
1550 return Blend_SamePoints;
1551 }
1552 else {
1553 return State;
1554 }
1555 }
1556 return Blend_StepTooLarge;
1557}
1558
1559//=======================================================================
1560//function : CheckInside
1561//purpose :
1562//=======================================================================
1563
1564Standard_Boolean BRepBlend_SurfRstLineBuilder::CheckInside(Blend_SurfRstFunction& Func,
1565 TopAbs_State& SituOnC,
1566 TopAbs_State& SituOnS,
1567 Standard_Boolean& Decroch)
1568{
1569 math_Vector tolerance(1,3);
1570 Func.GetTolerance(tolerance,tolesp);
81bba717 1571 //face pcurve.
7fd59977 1572 Standard_Real w = sol(3);
1573 if(w < rst->FirstParameter() - tolerance(3)||
1574 w > rst->LastParameter() + tolerance(3)){
1575 SituOnC = TopAbs_OUT;
1576 }
1577 else if (w > rst->FirstParameter() &&
1578 w < rst->LastParameter()){
1579 SituOnC = TopAbs_IN;
1580 }
1581 else SituOnC = TopAbs_ON;
1582
81bba717 1583 //face surface
7fd59977 1584 gp_Pnt2d p2d(sol(1),sol(2));
1585 SituOnS = domain1->Classify(p2d,Min(tolerance(1),tolerance(2)),0);
1586
81bba717 1587 //lost contact
7fd59977 1588 gp_Vec tgs,nors;
1589 Decroch = Func.Decroch(sol,tgs,nors);
1590
1591 return (SituOnC == TopAbs_IN && SituOnS == TopAbs_IN && !Decroch);
1592}
1593