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