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