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