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 |
45 | static Standard_Integer IndexOfSection = 0; |
46 | extern Standard_Boolean Blend_GettraceDRAWSECT(); |
4e18e72a |
47 | #ifdef DEB_BBPP_N_TRDERIV |
81bba717 |
48 | // for debug : visualisation of the section |
7fd59977 |
49 | static 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 | } |
66 | static 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 |
117 | static 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 | |
156 | Standard_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 | |
202 | BRepBlend_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 | |
218 | void 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 | |
314 | Standard_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 | |
464 | Standard_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 | |
493 | void 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 | |
906 | Standard_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 | |
1029 | Standard_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 | |
1105 | Standard_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 | |
1170 | void 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 | |
1219 | void 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 | |
1281 | Blend_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 | |
1357 | Blend_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 | |
1427 | static 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 | |
1438 | Blend_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 | |
1547 | Standard_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 | |