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