b311480e |
1 | // Created on: 1997-01-24 |
2 | // Created by: Laurent BOURESCHE |
3 | // Copyright (c) 1997-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
7fd59977 |
17 | |
42cf5bc1 |
18 | #include <Adaptor2d_HCurve2d.hxx> |
19 | #include <Adaptor3d_HSurface.hxx> |
20 | #include <Adaptor3d_HVertex.hxx> |
21 | #include <Adaptor3d_TopolTool.hxx> |
22 | #include <Blend_FuncInv.hxx> |
23 | #include <Blend_Point.hxx> |
24 | #include <Blend_SurfCurvFuncInv.hxx> |
25 | #include <Blend_SurfPointFuncInv.hxx> |
26 | #include <Blend_SurfRstFunction.hxx> |
7fd59977 |
27 | #include <BRepBlend_BlendTool.hxx> |
42cf5bc1 |
28 | #include <BRepBlend_Extremity.hxx> |
29 | #include <BRepBlend_Line.hxx> |
30 | #include <BRepBlend_SurfRstLineBuilder.hxx> |
7fd59977 |
31 | #include <gp_Pnt.hxx> |
42cf5bc1 |
32 | #include <gp_Pnt2d.hxx> |
7fd59977 |
33 | #include <gp_Vec.hxx> |
42cf5bc1 |
34 | #include <gp_Vec2d.hxx> |
35 | #include <IntSurf.hxx> |
36 | #include <IntSurf_Transition.hxx> |
37 | #include <math_FunctionSetRoot.hxx> |
38 | #include <TopAbs.hxx> |
7fd59977 |
39 | |
42cf5bc1 |
40 | #include <stdio.h> |
0797d9d3 |
41 | #ifdef OCCT_DEBUG |
7fd59977 |
42 | #include <TColStd_Array1OfInteger.hxx> |
43 | #include <TColStd_Array1OfReal.hxx> |
44 | #include <TColgp_Array1OfPnt2d.hxx> |
45 | #include <TColgp_Array1OfVec.hxx> |
46 | #include <TColgp_Array1OfVec2d.hxx> |
47 | #include <TColgp_Array1OfPnt.hxx> |
48 | #include <Geom_BSplineCurve.hxx> |
49 | #ifdef DRAW |
50 | #include <DrawTrSurf.hxx> |
51 | #endif |
52 | static Standard_Integer IndexOfSection = 0; |
53 | extern Standard_Boolean Blend_GettraceDRAWSECT(); |
0797d9d3 |
54 | #ifdef OCCT_DEBUG_BBPP_N_TRDERIV |
81bba717 |
55 | // for debug : visualisation of the section |
7fd59977 |
56 | static Standard_Boolean BBPP(const Standard_Real param, |
57 | Blend_SurfRstFunction& Func, |
58 | const math_Vector& sol, |
59 | const Standard_Real tol, |
60 | Blend_Point& BP) |
61 | { |
62 | if(!Func.IsSolution(sol,tol)) return 0; |
63 | gp_Pnt pnts = Func.PointOnS(); |
64 | gp_Pnt pntrst = Func.PointOnRst(); |
65 | gp_Pnt2d p2ds = Func.Pnt2dOnS(); |
66 | gp_Pnt2d p2drst = Func.Pnt2dOnRst(); |
67 | Standard_Real w = Func.ParameterOnRst(); |
68 | BP = Blend_Point(pnts,pntrst,param, |
69 | p2ds.X(),p2ds.Y(), |
70 | p2drst.X(),p2drst.Y(),w); |
71 | return 1; |
72 | } |
73 | static void tracederiv(Blend_SurfRstFunction& Func, |
74 | const Blend_Point& BP1, |
75 | const Blend_Point& BP2) |
76 | { |
77 | Standard_Integer hp,hk,hd,hp2d,i; |
78 | Func.GetShape(hp,hk,hd,hp2d); |
79 | TColgp_Array1OfPnt TP1(1,hp); |
80 | TColgp_Array1OfVec TDP1(1,hp); |
81 | TColgp_Array1OfPnt2d TP2d1(1,hp2d); |
82 | TColgp_Array1OfVec2d TDP2d1(1,hp2d); |
83 | TColStd_Array1OfReal TW1(1,hp); |
84 | TColStd_Array1OfReal TDW1(1,hp); |
85 | Func.Section(BP1,TP1,TDP1,TP2d1,TDP2d1,TW1,TDW1); |
86 | |
87 | TColgp_Array1OfPnt TP2(1,hp); |
88 | TColgp_Array1OfVec TDP2(1,hp); |
89 | TColgp_Array1OfPnt2d TP2d2(1,hp2d); |
90 | TColgp_Array1OfVec2d TDP2d2(1,hp2d); |
91 | TColStd_Array1OfReal TW2(1,hp); |
92 | TColStd_Array1OfReal TDW2(1,hp); |
93 | Func.Section(BP2,TP2,TDP2,TP2d2,TDP2d2,TW2,TDW2); |
94 | |
95 | Standard_Real param1 = BP1.Parameter(); |
96 | Standard_Real param2 = BP2.Parameter(); |
97 | Standard_Real scal = 1./(param1-param2); |
98 | |
04232180 |
99 | std::cout<<std::endl; |
100 | std::cout<<"control derivatives at point : "<<param1<<std::endl; |
7fd59977 |
101 | |
102 | for(i = 1; i <= hp; i++){ |
04232180 |
103 | std::cout<<std::endl; |
104 | std::cout<<"point : "<<i<<std::endl; |
105 | std::cout<<"dx calculated : "<<TDP1(i).X()<<std::endl; |
106 | std::cout<<"dx estimated : "<<scal*(TP1(i).X()-TP2(i).X())<<std::endl; |
107 | std::cout<<"dy calculated : "<<TDP1(i).Y()<<std::endl; |
108 | std::cout<<"dy estimated : "<<scal*(TP1(i).Y()-TP2(i).Y())<<std::endl; |
109 | std::cout<<"dz calculated : "<<TDP1(i).Z()<<std::endl; |
110 | std::cout<<"dz estimated : "<<scal*(TP1(i).Z()-TP2(i).Z())<<std::endl; |
111 | std::cout<<"dw calculated : "<<TDW1(i)<<std::endl; |
112 | std::cout<<"dw estimated : "<<scal*(TW1(i)-TW2(i))<<std::endl; |
7fd59977 |
113 | } |
114 | for(i = 1; i <= hp2d; i++){ |
04232180 |
115 | std::cout<<std::endl; |
116 | std::cout<<"point 2d : "<<i<<std::endl; |
117 | std::cout<<"dx calculated : "<<TDP2d1(i).X()<<std::endl; |
118 | std::cout<<"dx estimated : "<<scal*(TP2d1(i).X()-TP2d2(i).X())<<std::endl; |
119 | std::cout<<"dy calculated : "<<TDP2d1(i).Y()<<std::endl; |
120 | std::cout<<"dy estimated : "<<scal*(TP2d1(i).Y()-TP2d2(i).Y())<<std::endl; |
7fd59977 |
121 | } |
122 | } |
4e18e72a |
123 | #endif |
7fd59977 |
124 | static void Drawsect(const Standard_Real param, |
125 | Blend_SurfRstFunction& Func) |
126 | { |
127 | gp_Pnt pnts = Func.PointOnS(); |
128 | gp_Pnt pntrst = Func.PointOnRst(); |
129 | gp_Pnt2d p2ds = Func.Pnt2dOnS(); |
130 | gp_Pnt2d p2drst = Func.Pnt2dOnRst(); |
131 | Standard_Real w = Func.ParameterOnRst(); |
132 | Blend_Point BP(pnts,pntrst,param, |
133 | p2ds.X(),p2ds.Y(), |
134 | p2drst.X(),p2drst.Y(),w); |
135 | Standard_Integer hp,hk,hd,hp2d; |
136 | Func.GetShape(hp,hk,hd,hp2d); |
137 | TColStd_Array1OfReal TK(1,hk); |
138 | Func.Knots(TK); |
139 | TColStd_Array1OfInteger TMul(1,hk); |
140 | Func.Mults(TMul); |
141 | TColgp_Array1OfPnt TP(1,hp); |
142 | TColgp_Array1OfPnt2d TP2d(1,hp2d); |
143 | TColStd_Array1OfReal TW(1,hp); |
144 | Func.Section(BP,TP,TP2d,TW); |
145 | Handle(Geom_BSplineCurve) sect = new Geom_BSplineCurve |
146 | (TP,TW,TK,TMul,hd); |
147 | IndexOfSection++; |
148 | #ifdef DRAW |
149 | char tname[100]; |
150 | Standard_CString name = tname ; |
151 | sprintf(name,"%s_%d","Section",IndexOfSection); |
152 | DrawTrSurf::Set(name,sect); |
153 | #endif |
154 | } |
155 | #endif |
156 | |
157 | //======================================================================= |
158 | //function : ArcToRecadre |
81bba717 |
159 | //purpose : Find a suitable arc |
160 | // PrevIndex is used to reject an already tested arc |
7fd59977 |
161 | //======================================================================= |
162 | |
163 | Standard_Integer BRepBlend_SurfRstLineBuilder:: |
75259fc5 |
164 | ArcToRecadre(const math_Vector& theSol, |
7fd59977 |
165 | const Standard_Integer PrevIndex, |
166 | gp_Pnt2d& lastpt2d, |
167 | gp_Pnt2d& pt2d, |
168 | Standard_Real& ponarc) |
169 | { |
170 | Standard_Integer IndexSol = 0, nbarc = 0; |
171 | Standard_Boolean ok = Standard_False; |
172 | Standard_Boolean byinter = (line->NbPoints() != 0), okinter = 0; |
173 | Standard_Real distmin = RealLast(); |
1d47d8d0 |
174 | Standard_Real uprev = 0.,vprev = 0., prm = 0., dist = 0.; |
7fd59977 |
175 | |
176 | if(byinter) previousP.ParametersOnS(uprev,vprev); |
75259fc5 |
177 | pt2d.SetCoord(theSol(1),theSol(2)); |
7fd59977 |
178 | lastpt2d.SetCoord(uprev,vprev); |
179 | domain1->Init(); |
180 | |
181 | while (domain1->More()) { |
182 | nbarc++; ok = 0; |
183 | if(byinter) { |
184 | ok = okinter = BRepBlend_BlendTool::Inters(pt2d,lastpt2d, |
185 | surf1, |
186 | domain1->Value(),prm,dist); |
187 | } |
188 | if(!ok) ok = BRepBlend_BlendTool::Project(pt2d,surf1, |
189 | domain1->Value(),prm,dist); |
190 | |
191 | if (ok && (nbarc != PrevIndex) ) { |
192 | if (dist<distmin || okinter) { |
193 | distmin = dist; |
194 | ponarc = prm; |
195 | IndexSol = nbarc; |
196 | if(okinter && (PrevIndex==0) ) break; |
197 | } |
198 | } |
199 | domain1->Next(); |
200 | } |
201 | return IndexSol; |
202 | } |
203 | |
204 | //======================================================================= |
205 | //function : BRepBlend_SurfRstLineBuilder |
206 | //purpose : |
207 | //======================================================================= |
208 | |
209 | BRepBlend_SurfRstLineBuilder::BRepBlend_SurfRstLineBuilder |
210 | (const Handle(Adaptor3d_HSurface)& Surf1, |
211 | const Handle(Adaptor3d_TopolTool)& Domain1, |
212 | const Handle(Adaptor3d_HSurface)& Surf2, |
213 | const Handle(Adaptor2d_HCurve2d)& Rst, |
214 | const Handle(Adaptor3d_TopolTool)& Domain2): |
d533dafb |
215 | done(Standard_False), sol(1, 3), surf1(Surf1), |
216 | domain1(Domain1), surf2(Surf2), rst(Rst), |
217 | domain2(Domain2), tolesp(0.0), tolgui(0.0), |
218 | pasmax(0.0), fleche(0.0), param(0.0), |
219 | rebrou(Standard_False), iscomplete(Standard_False), |
220 | comptra(Standard_False), sens(0.0), |
221 | decrochdeb(Standard_False), decrochfin(Standard_False) |
7fd59977 |
222 | { |
223 | } |
224 | |
225 | //======================================================================= |
226 | //function : Perform |
227 | //purpose : |
228 | //======================================================================= |
229 | |
230 | void BRepBlend_SurfRstLineBuilder::Perform(Blend_SurfRstFunction& Func, |
231 | Blend_FuncInv& Finv, |
232 | Blend_SurfPointFuncInv& FinvP, |
233 | Blend_SurfCurvFuncInv& FinvC, |
234 | const Standard_Real Pdep, |
235 | const Standard_Real Pmax, |
236 | const Standard_Real MaxStep, |
237 | const Standard_Real TolGuide, |
238 | const math_Vector& ParDep, |
239 | const Standard_Real Tolesp, |
240 | const Standard_Real Fleche, |
241 | const Standard_Boolean Appro) |
242 | { |
243 | done = Standard_False; |
244 | iscomplete = Standard_False; |
245 | comptra = Standard_False; |
246 | line = new BRepBlend_Line(); |
247 | tolesp = Abs(Tolesp); |
248 | tolgui = Abs(TolGuide); |
249 | fleche = Abs(Fleche); |
250 | rebrou = Standard_False; |
251 | pasmax = Abs(MaxStep); |
252 | |
253 | if (Pmax-Pdep >= 0.) { |
254 | sens = 1.; |
255 | } |
256 | else { |
257 | sens = -1.; |
258 | } |
259 | |
260 | Blend_Status State; |
261 | |
262 | param = Pdep; |
263 | Func.Set(param); |
264 | |
265 | if (Appro) { |
266 | TopAbs_State siturst,situs; |
267 | Standard_Boolean decroch; |
268 | math_Vector tolerance(1,3),infbound(1,3),supbound(1,3); |
269 | Func.GetTolerance(tolerance,tolesp); |
270 | Func.GetBounds(infbound,supbound); |
271 | math_FunctionSetRoot rsnld(Func,tolerance,30); |
272 | |
273 | rsnld.Perform(Func,ParDep,infbound,supbound); |
274 | |
275 | if (!rsnld.IsDone()) { |
276 | return; |
277 | } |
278 | rsnld.Root(sol); |
279 | if (!CheckInside(Func,siturst,situs,decroch)) { |
280 | return; |
281 | } |
282 | } |
283 | else { |
284 | sol = ParDep; |
285 | } |
286 | |
287 | State = TestArret(Func,Standard_False,Blend_OK); |
288 | if (State!=Blend_OK) { |
289 | return; |
290 | } |
0797d9d3 |
291 | #ifdef OCCT_DEBUG |
7fd59977 |
292 | if (Blend_GettraceDRAWSECT()){ |
293 | Drawsect(param,Func); |
294 | } |
295 | #endif |
81bba717 |
296 | // Update the line. |
7fd59977 |
297 | line->Append(previousP); |
298 | Standard_Real U,V; |
299 | previousP.ParametersOnS(U,V); |
300 | // W = previousP.ParameterOnC(); |
301 | |
302 | BRepBlend_Extremity ptf1(previousP.PointOnS(), |
303 | U,V,previousP.Parameter(),tolesp); |
304 | BRepBlend_Extremity ptf2(previousP.PointOnC(), |
305 | U,V,previousP.Parameter(),tolesp); |
306 | if (!previousP.IsTangencyPoint()) { |
307 | ptf1.SetTangent(previousP.TangentOnS()); |
308 | ptf2.SetTangent(previousP.TangentOnC()); |
309 | } |
310 | if (sens>0.) { |
311 | line->SetStartPoints(ptf1, ptf2); |
312 | } |
313 | else { |
314 | line->SetEndPoints(ptf1, ptf2); |
315 | |
316 | } |
317 | InternalPerform(Func,Finv,FinvP,FinvC,Pmax); |
318 | done = Standard_True; |
319 | } |
320 | |
321 | //======================================================================= |
322 | //function : PerformFirstSection |
323 | //purpose : |
324 | //======================================================================= |
325 | |
326 | Standard_Boolean BRepBlend_SurfRstLineBuilder::PerformFirstSection |
327 | (Blend_SurfRstFunction& Func, |
328 | Blend_FuncInv& Finv, |
329 | Blend_SurfPointFuncInv& FinvP, |
330 | Blend_SurfCurvFuncInv& FinvC, |
331 | const Standard_Real Pdep, |
332 | const Standard_Real Pmax, |
333 | const math_Vector& ParDep, |
334 | const Standard_Real Tolesp, |
335 | const Standard_Real TolGuide, |
336 | const Standard_Boolean RecRst, |
337 | const Standard_Boolean RecP, |
338 | const Standard_Boolean RecS, |
339 | Standard_Real& Psol, |
340 | math_Vector& ParSol) |
341 | { |
342 | done = Standard_False; |
343 | iscomplete = Standard_False; |
344 | comptra = Standard_False; |
345 | line = new BRepBlend_Line(); |
346 | tolesp = Abs(Tolesp); |
347 | tolgui = Abs(TolGuide); |
348 | rebrou = Standard_False; |
349 | |
350 | if (Pmax-Pdep >= 0.) { |
351 | sens = 1.; |
352 | } |
353 | else { |
354 | sens = -1.; |
355 | } |
7fd59977 |
356 | Blend_Status State = Blend_OnRst12; |
357 | Standard_Real trst = 0.; |
7fd59977 |
358 | Standard_Boolean recadp,recadrst,recads; |
359 | Standard_Real wp,wrst,ws; |
1d47d8d0 |
360 | Standard_Real U = 0.,V = 0.; |
7fd59977 |
361 | math_Vector infbound(1,3),supbound(1,3),tolerance(1,3); |
362 | math_Vector solinvp(1,3),solinvrst(1,4),solinvs(1,3); |
363 | Handle(Adaptor3d_HVertex) Vtxp,Vtxrst,Vtxs,Vtxc; |
364 | Standard_Boolean IsVtxp = 0,IsVtxrst = 0,IsVtxs = 0; |
365 | Handle(Adaptor2d_HCurve2d) Arc; |
366 | wp = wrst = ws = Pmax; |
367 | param = Pdep; |
368 | Func.Set(param); |
369 | Func.GetTolerance(tolerance,tolesp); |
370 | Func.GetBounds(infbound,supbound); |
371 | |
372 | math_FunctionSetRoot rsnld(Func,tolerance,30); |
373 | rsnld.Perform(Func,ParDep,infbound,supbound); |
374 | if (!rsnld.IsDone()) return Standard_False; |
375 | rsnld.Root(sol); |
376 | |
377 | recads = RecS && Recadre(FinvC,solinvs,Arc,IsVtxs,Vtxs); |
378 | if (recads) { |
379 | ws = solinvs(1); |
380 | } |
381 | recadp = RecP && Recadre(FinvP,solinvp,IsVtxp,Vtxp); |
382 | if (recadp) { |
383 | wp = solinvp(1); |
384 | } |
385 | recadrst = RecRst && Recadre(Func,Finv,solinvrst,IsVtxrst,Vtxrst); |
386 | if (recadrst) { |
387 | wrst = solinvrst(2); |
388 | } |
389 | if (!recads && !recadp && !recadrst) return Standard_False; |
390 | if (recadp && recadrst) { |
81bba717 |
391 | if(sens*(wrst-wp) > tolgui){ //first one leaves the domain |
7fd59977 |
392 | wrst = wp; |
393 | U = solinvp(2); |
394 | V = solinvp(3); |
395 | trst = BRepBlend_BlendTool::Parameter(Vtxp,rst); |
396 | IsVtxrst = IsVtxp; |
397 | Vtxrst = Vtxp; |
398 | } |
399 | else{ |
400 | U = solinvrst(3); |
401 | V = solinvrst(4); |
402 | trst = solinvrst(1); |
403 | } |
404 | } |
405 | else if(recadp){ |
406 | wrst = wp; |
407 | U = solinvp(2); |
408 | V = solinvp(3); |
409 | trst = BRepBlend_BlendTool::Parameter(Vtxp,rst); |
410 | IsVtxrst = IsVtxp; |
411 | Vtxrst = Vtxp; |
412 | recadrst = Standard_True; |
413 | } |
414 | else if(recadrst){ |
415 | U = solinvrst(3); |
416 | V = solinvrst(4); |
417 | trst = solinvrst(1); |
418 | } |
419 | if(recads && recadrst){ |
420 | if(Abs(ws - wrst) < tolgui){ |
421 | State = Blend_OnRst12; |
422 | param = 0.5*(ws+wrst); |
423 | sol(1) = U; |
424 | sol(2) = V; |
425 | sol(3) = solinvs(2); |
426 | } |
427 | else if(sens*(ws-wrst)<0){ |
81bba717 |
428 | // ground on surf |
7fd59977 |
429 | State = Blend_OnRst1; |
430 | param = ws; |
431 | Arc->Value(solinvs(3)).Coord(U,V); |
432 | sol(1) = U; |
433 | sol(2) = V; |
434 | sol(3) = solinvs(2); |
435 | } |
436 | else{ |
81bba717 |
437 | // ground on rst |
7fd59977 |
438 | State = Blend_OnRst2; |
439 | param = wrst; |
440 | sol(1) = U; |
441 | sol(2) = V; |
442 | sol(3) = trst; |
443 | } |
444 | Func.Set(param); |
445 | } |
446 | else if(recads){ |
81bba717 |
447 | // ground on surf |
7fd59977 |
448 | State = Blend_OnRst1; |
449 | param = ws; |
450 | Arc->Value(solinvs(3)).Coord(U,V); |
451 | sol(1) = U; |
452 | sol(2) = V; |
453 | sol(3) = solinvs(2); |
454 | Func.Set(param); |
455 | } |
456 | else if(recadrst){ |
81bba717 |
457 | // ground on rst |
7fd59977 |
458 | State = Blend_OnRst2; |
459 | param = wrst; |
460 | sol(1) = U; |
461 | sol(2) = V; |
462 | sol(3) = trst; |
463 | Func.Set(param); |
464 | } |
465 | State = TestArret(Func,Standard_False,State); |
466 | Psol = param; |
467 | ParSol = sol; |
468 | return Standard_True; |
469 | } |
470 | |
471 | //======================================================================= |
472 | //function : Complete |
473 | //purpose : |
474 | //======================================================================= |
475 | |
476 | Standard_Boolean BRepBlend_SurfRstLineBuilder::Complete(Blend_SurfRstFunction& Func, |
477 | Blend_FuncInv& Finv, |
478 | Blend_SurfPointFuncInv& FinvP, |
479 | Blend_SurfCurvFuncInv& FinvC, |
480 | const Standard_Real Pmin) |
481 | { |
9775fa61 |
482 | if (!done) {throw StdFail_NotDone();} |
7fd59977 |
483 | if (iscomplete) {return Standard_True;} |
484 | if (sens >0.) { |
485 | previousP = line->Point(1); |
486 | } |
487 | else { |
488 | previousP = line->Point(line->NbPoints()); |
489 | } |
490 | sens = -sens; |
491 | param = previousP.Parameter(); |
492 | previousP.ParametersOnS(sol(1),sol(2)); |
493 | sol(3) = previousP.ParameterOnC(); |
494 | |
495 | InternalPerform(Func,Finv,FinvP,FinvC,Pmin); |
496 | iscomplete = Standard_True; |
497 | return Standard_True; |
498 | } |
499 | |
500 | //======================================================================= |
501 | //function : InternalPerform |
502 | //purpose : |
503 | //======================================================================= |
504 | |
505 | void BRepBlend_SurfRstLineBuilder::InternalPerform(Blend_SurfRstFunction& Func, |
506 | Blend_FuncInv& Finv, |
507 | Blend_SurfPointFuncInv& FinvP, |
508 | Blend_SurfCurvFuncInv& FinvC, |
509 | const Standard_Real Bound) |
510 | { |
511 | Standard_Real stepw = pasmax; |
512 | Standard_Integer nbp = line->NbPoints(); |
81bba717 |
513 | if(nbp >= 2){ //The last step is reproduced if it is not too small. |
7fd59977 |
514 | if(sens < 0.){ |
515 | stepw = (line->Point(2).Parameter() - line->Point(1).Parameter()); |
516 | } |
517 | else{ |
518 | stepw = (line->Point(nbp).Parameter() - line->Point(nbp - 1).Parameter()); |
519 | } |
520 | stepw = Max(stepw,100.*tolgui); |
521 | } |
522 | Standard_Real parprec = param; |
523 | if (sens*(parprec - Bound) >= -tolgui) { |
524 | return; |
525 | } |
7fd59977 |
526 | Blend_Status State = Blend_OnRst12; |
1d47d8d0 |
527 | TopAbs_State situonc = TopAbs_UNKNOWN, situons = TopAbs_UNKNOWN; |
528 | Standard_Boolean decroch = Standard_False; |
7fd59977 |
529 | Standard_Boolean Arrive,recadp,recadrst,recads,echecrecad; |
530 | Standard_Real wp,wrst,ws; |
1d47d8d0 |
531 | Standard_Real U = 0.,V = 0.; |
532 | Standard_Real trst = 0.; |
7fd59977 |
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; |
0797d9d3 |
558 | #ifdef OCCT_DEBUG_BBPP_N_TRDERIV |
7fd59977 |
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 |
0797d9d3 |
724 | #ifdef OCCT_DEBUG |
04232180 |
725 | std::cout<<"SurfRstLineBuilder : failed reframing"<<std::endl; |
7fd59977 |
726 | #endif |
727 | State = Blend_SamePoints; |
728 | } |
729 | } |
730 | |
731 | switch (State) { |
732 | case Blend_OK : |
733 | { |
0797d9d3 |
734 | #ifdef OCCT_DEBUG |
7fd59977 |
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 |
0797d9d3 |
779 | #ifdef OCCT_DEBUG |
04232180 |
780 | std::cout<<"SurfRstLineBuilder : No advancement in the processing"<<std::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 | { |
0797d9d3 |
792 | #ifdef OCCT_DEBUG |
7fd59977 |
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 | { |
0797d9d3 |
826 | #ifdef OCCT_DEBUG |
7fd59977 |
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 | { |
0797d9d3 |
845 | #ifdef OCCT_DEBUG |
7fd59977 |
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 | { |
0797d9d3 |
865 | #ifdef OCCT_DEBUG |
7fd59977 |
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 |
0797d9d3 |
885 | #ifdef OCCT_DEBUG |
04232180 |
886 | std::cout << "SurfRstLineBuilder Points mixed in the processing" << std::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; |
7fd59977 |
897 | default: |
898 | break; |
7fd59977 |
899 | } |
900 | if (Arrive) { |
901 | if (sens > 0.) { |
902 | line->SetEndPoints(Exts,Extrst); |
903 | decrochfin = decroch; |
904 | } |
905 | else { |
906 | line->SetStartPoints(Exts,Extrst); |
907 | decrochdeb = decroch; |
908 | } |
909 | } |
910 | } |
911 | } |
912 | |
913 | //======================================================================= |
914 | //function : Recadre |
81bba717 |
915 | //purpose : Reframe section Surface / Restriction |
7fd59977 |
916 | //======================================================================= |
917 | |
918 | Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfCurvFuncInv& FinvC, |
919 | math_Vector& Solinv, |
920 | Handle(Adaptor2d_HCurve2d)& Arc, |
921 | Standard_Boolean& IsVtx, |
922 | Handle(Adaptor3d_HVertex)& Vtx) |
923 | { |
924 | Standard_Boolean recadre = Standard_False; |
6e6cd5d9 |
925 | |
7fd59977 |
926 | gp_Pnt2d pt2d, lastpt2d; |
927 | Standard_Integer IndexSol, nbarc; |
928 | Standard_Real pmin; |
929 | |
930 | IndexSol = ArcToRecadre(sol, 0, lastpt2d, pt2d, pmin); |
931 | |
932 | IsVtx = Standard_False; |
933 | if (IndexSol == 0) { |
934 | return Standard_False; |
935 | } |
936 | |
937 | domain1->Init(); |
938 | nbarc = 1; |
939 | while (nbarc < IndexSol) { |
940 | nbarc++; |
941 | domain1->Next(); |
942 | } |
943 | Arc = domain1->Value(); |
944 | |
945 | FinvC.Set(Arc); |
946 | |
947 | math_Vector toler(1,3),infb(1,3),supb(1,3); |
948 | FinvC.GetTolerance(toler,tolesp); |
949 | FinvC.GetBounds(infb,supb); |
950 | Solinv(1) = param; |
951 | Solinv(2) = sol(3); |
952 | Solinv(3) = pmin; |
953 | |
954 | math_FunctionSetRoot rsnld(FinvC,toler,30); |
955 | rsnld.Perform(FinvC,Solinv,infb,supb); |
956 | |
957 | if (!rsnld.IsDone()) { |
0797d9d3 |
958 | #ifdef OCCT_DEBUG |
04232180 |
959 | std::cout << "SurfRstLineBuilder : RSNLD not done "<< std::endl << std::endl; |
7fd59977 |
960 | #endif |
961 | } |
962 | else { |
81bba717 |
963 | // It is necessary to check the value of the function |
7fd59977 |
964 | rsnld.Root(Solinv); |
965 | recadre = FinvC.IsSolution(Solinv,tolesp); |
966 | } |
967 | |
81bba717 |
968 | // In case of fail, it is checked if another arc |
969 | // can be useful (case of output at the proximity of a vertex) |
7fd59977 |
970 | if (!recadre) { |
971 | |
972 | IndexSol = ArcToRecadre(sol, IndexSol, |
973 | lastpt2d, pt2d, pmin); |
974 | if (IndexSol == 0) { |
81bba717 |
975 | return Standard_False; // No other solution |
7fd59977 |
976 | } |
977 | |
978 | domain1->Init(); |
979 | nbarc = 1; |
980 | while (nbarc < IndexSol) { |
981 | nbarc++; |
982 | domain1->Next(); |
983 | } |
984 | |
985 | Arc = domain1->Value(); |
986 | FinvC.Set(Arc); |
987 | |
988 | FinvC.GetTolerance(toler,tolesp); |
989 | FinvC.GetBounds(infb,supb); |
990 | |
991 | Solinv(3) = pmin; |
992 | |
51740958 |
993 | math_FunctionSetRoot aRsnld(FinvC,toler,30); |
994 | aRsnld.Perform(FinvC,Solinv,infb,supb); |
7fd59977 |
995 | |
51740958 |
996 | if (!aRsnld.IsDone()) { |
0797d9d3 |
997 | #ifdef OCCT_DEBUG |
04232180 |
998 | std::cout << "SurfRstLineBuilder : RSNLD not done "<< std::endl << std::endl; |
7fd59977 |
999 | #endif |
1000 | } |
1001 | else { |
81bba717 |
1002 | // It is necessary to check the value of the function |
51740958 |
1003 | aRsnld.Root(Solinv); |
7fd59977 |
1004 | recadre = FinvC.IsSolution(Solinv,tolesp); |
1005 | } |
1006 | } |
1007 | |
1008 | if (recadre) { |
1009 | Standard_Real w = Solinv(2); |
1010 | if(w < rst->FirstParameter() - toler(2)|| |
1011 | w > rst->LastParameter() + toler(2)){ |
1012 | return Standard_False; |
1013 | } |
1014 | domain1->Initialize(Arc); |
1015 | domain1->InitVertexIterator(); |
1016 | IsVtx = !domain1->MoreVertex(); |
1017 | while (!IsVtx) { |
1018 | Vtx = domain1->Vertex(); |
1019 | if (Abs(BRepBlend_BlendTool::Parameter(Vtx,Arc)-Solinv(3)) <= |
1020 | BRepBlend_BlendTool::Tolerance(Vtx,Arc)) { |
1021 | IsVtx = Standard_True; |
1022 | } |
1023 | else { |
1024 | domain1->NextVertex(); |
1025 | IsVtx = !domain1->MoreVertex(); |
1026 | } |
1027 | } |
1028 | if (!domain1->MoreVertex()) { |
1029 | IsVtx = Standard_False; |
1030 | } |
1031 | return Standard_True; |
1032 | } |
1033 | return Standard_False; |
1034 | } |
1035 | |
1036 | //======================================================================= |
1037 | //function : Recadre |
1038 | //purpose : |
1039 | //======================================================================= |
1040 | |
1041 | Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfRstFunction& Func, |
1042 | Blend_FuncInv& Finv, |
1043 | math_Vector& Solinv, |
1044 | Standard_Boolean& IsVtx, |
1045 | Handle(Adaptor3d_HVertex)& Vtx) |
1046 | { |
1047 | math_Vector toler(1,4),infb(1,4),supb(1,4); |
1048 | Finv.GetTolerance(toler,tolesp); |
1049 | Finv.GetBounds(infb,supb); |
1050 | Solinv(1) = sol(3); |
1051 | Solinv(2) = param; |
1052 | Solinv(3) = sol(1); |
1053 | Solinv(4) = sol(2); |
1054 | |
1055 | math_FunctionSetRoot rsnld(Finv,toler,30); |
1056 | rsnld.Perform(Finv,Solinv,infb,supb); |
1057 | if (!rsnld.IsDone()) { |
0797d9d3 |
1058 | #ifdef OCCT_DEBUG |
04232180 |
1059 | std::cout << "SurfRstLineBuilder :RSNLD not done "<< std::endl; |
7fd59977 |
1060 | #endif |
1061 | return Standard_False; |
1062 | } |
1063 | rsnld.Root(Solinv); |
1064 | |
1065 | if(Finv.IsSolution(Solinv,tolesp)){ |
1066 | gp_Pnt2d p2d(Solinv(3),Solinv(4)); |
1067 | TopAbs_State situ = domain1->Classify(p2d,Min(toler(3),toler(4)),0); |
1068 | if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) { |
1069 | return Standard_False; |
1070 | } |
1071 | domain2->Initialize(rst); |
1072 | domain2->InitVertexIterator(); |
1073 | IsVtx = !domain2->MoreVertex(); |
1074 | while (!IsVtx) { |
1075 | Vtx = domain2->Vertex(); |
1076 | if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-Solinv(1)) <= |
1077 | BRepBlend_BlendTool::Tolerance(Vtx,rst)) { |
1078 | IsVtx = Standard_True; |
1079 | } |
1080 | else { |
1081 | domain2->NextVertex(); |
1082 | IsVtx = !domain2->MoreVertex(); |
1083 | } |
1084 | } |
1085 | if (!domain2->MoreVertex()) { |
1086 | IsVtx = Standard_False; |
1087 | } |
81bba717 |
1088 | // The section is recalculated by direct resolution, otherwise |
1089 | // incoherences between the parameter and the ground caused by yawn are returned. |
7fd59977 |
1090 | |
1091 | math_Vector infbound(1,3),supbound(1,3); |
1092 | math_Vector parinit(1,3),tolerance(1,3); |
1093 | Func.GetTolerance(tolerance,tolesp); |
1094 | Func.GetBounds(infbound,supbound); |
1095 | |
1096 | math_FunctionSetRoot rsnld2(Func,tolerance,30); |
1097 | parinit(1) = Solinv(3); |
1098 | parinit(2) = Solinv(4); |
1099 | parinit(3) = Solinv(1); |
1100 | Func.Set(Solinv(2)); |
1101 | rsnld2.Perform(Func,parinit,infbound,supbound); |
1102 | if(!rsnld2.IsDone()) return Standard_False; |
1103 | rsnld2.Root(parinit); |
1104 | Solinv(3) = parinit(1); |
1105 | Solinv(4) = parinit(2); |
1106 | Solinv(1) = parinit(3); |
1107 | return Standard_True; |
1108 | } |
1109 | return Standard_False; |
1110 | } |
1111 | |
1112 | //======================================================================= |
1113 | //function : Recadre |
1114 | //purpose : |
1115 | //======================================================================= |
1116 | |
1117 | Standard_Boolean BRepBlend_SurfRstLineBuilder::Recadre(Blend_SurfPointFuncInv& FinvP, |
1118 | math_Vector& Solinv, |
1119 | Standard_Boolean& IsVtx, |
1120 | Handle(Adaptor3d_HVertex)& Vtx) |
1121 | { |
1122 | // Le point. |
1123 | gp_Pnt2d p2drst; |
1124 | Standard_Real firstrst = rst->FirstParameter(); |
1125 | Standard_Real lastrst = rst->LastParameter(); |
1126 | Standard_Real wpoint = firstrst; |
1127 | if((sol(3) - firstrst) > (lastrst - sol(3))) wpoint = lastrst; |
1128 | p2drst = rst->Value(wpoint); |
1129 | gp_Pnt thepoint = surf2->Value(p2drst.X(),p2drst.Y()); |
1130 | |
1131 | FinvP.Set(thepoint); |
1132 | math_Vector toler(1,3),infb(1,3),supb(1,3); |
1133 | FinvP.GetTolerance(toler,tolesp); |
1134 | FinvP.GetBounds(infb,supb); |
1135 | Solinv(1) = param; |
1136 | Solinv(2) = sol(1); |
1137 | Solinv(3) = sol(2); |
1138 | |
1139 | math_FunctionSetRoot rsnld(FinvP,toler,30); |
1140 | rsnld.Perform(FinvP,Solinv,infb,supb); |
1141 | if (!rsnld.IsDone()) { |
0797d9d3 |
1142 | #ifdef OCCT_DEBUG |
04232180 |
1143 | std::cout << "SurfRstLineBuilder :RSNLD not done "<< std::endl; |
7fd59977 |
1144 | #endif |
1145 | return Standard_False; |
1146 | } |
1147 | rsnld.Root(Solinv); |
1148 | |
1149 | if(FinvP.IsSolution(Solinv,tolesp)){ |
1150 | gp_Pnt2d p2d(Solinv(2),Solinv(3)); |
1151 | TopAbs_State situ = domain1->Classify(p2d,Min(toler(2),toler(3)),0); |
1152 | if ((situ != TopAbs_IN) && (situ != TopAbs_ON)) { |
1153 | return Standard_False; |
1154 | } |
1155 | domain2->Initialize(rst); |
1156 | domain2->InitVertexIterator(); |
1157 | IsVtx = !domain2->MoreVertex(); |
1158 | while (!IsVtx) { |
1159 | Vtx = domain2->Vertex(); |
1160 | if (Abs(BRepBlend_BlendTool::Parameter(Vtx,rst)-wpoint) <= |
1161 | BRepBlend_BlendTool::Tolerance(Vtx,rst)) { |
1162 | IsVtx = Standard_True; |
1163 | } |
1164 | else { |
1165 | domain2->NextVertex(); |
1166 | IsVtx = !domain2->MoreVertex(); |
1167 | } |
1168 | } |
1169 | if (!domain2->MoreVertex()) { |
1170 | IsVtx = Standard_False; |
1171 | } |
1172 | return Standard_True; |
1173 | } |
1174 | return Standard_False; |
1175 | } |
1176 | |
1177 | //======================================================================= |
1178 | //function : Transition |
1179 | //purpose : |
1180 | //======================================================================= |
1181 | |
1182 | void BRepBlend_SurfRstLineBuilder::Transition(const Standard_Boolean OnFirst, |
1183 | const Handle(Adaptor2d_HCurve2d)& Arc, |
1184 | const Standard_Real Param, |
1185 | IntSurf_Transition& TLine, |
1186 | IntSurf_Transition& TArc) |
1187 | { |
1188 | Standard_Boolean computetranstionaveclacorde = 0; |
1189 | gp_Vec tgline; |
1190 | Blend_Point prevprev; |
1191 | |
1192 | if(previousP.IsTangencyPoint()){ |
1193 | if(line->NbPoints() < 2) return; |
1194 | computetranstionaveclacorde = 1; |
1195 | if(sens < 0){ |
1196 | prevprev = line->Point(2); |
1197 | } |
1198 | else { |
1199 | prevprev = line->Point(line->NbPoints() - 1); |
1200 | } |
1201 | } |
1202 | gp_Pnt2d p2d; |
1203 | gp_Vec2d dp2d; |
1204 | |
1205 | gp_Pnt pbid; |
1206 | gp_Vec d1u,d1v,normale,tgrst; |
1207 | |
1208 | Arc->D1(Param,p2d,dp2d); |
1209 | if (OnFirst) { |
1210 | surf1->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v); |
1211 | if(!computetranstionaveclacorde) tgline = previousP.TangentOnS1(); |
1212 | else tgline = gp_Vec(prevprev.PointOnS(),previousP.PointOnS()); |
1213 | } |
1214 | else { |
1215 | surf2->D1(p2d.X(),p2d.Y(),pbid,d1u,d1v); |
1216 | if(!computetranstionaveclacorde) tgline = previousP.TangentOnS2(); |
1217 | else tgline = gp_Vec(prevprev.PointOnC(),previousP.PointOnC()); |
1218 | } |
1219 | |
1220 | tgrst.SetLinearForm(dp2d.X(),d1u,dp2d.Y(),d1v); |
1221 | normale = d1u.Crossed(d1v); |
1222 | |
1223 | IntSurf::MakeTransition(tgline,tgrst,normale,TLine,TArc); |
1224 | } |
1225 | |
1226 | //======================================================================= |
1227 | //function : MakeExtremity |
1228 | //purpose : |
1229 | //======================================================================= |
1230 | |
1231 | void BRepBlend_SurfRstLineBuilder::MakeExtremity(BRepBlend_Extremity& Extrem, |
1232 | const Standard_Boolean OnFirst, |
1233 | const Handle(Adaptor2d_HCurve2d)& Arc, |
1234 | const Standard_Real Param, |
1235 | const Standard_Boolean IsVtx, |
1236 | const Handle(Adaptor3d_HVertex)& Vtx) |
1237 | { |
1238 | IntSurf_Transition Tline,Tarc; |
1239 | Standard_Real prm; |
1240 | Handle(Adaptor3d_TopolTool) Iter; |
1241 | if (OnFirst) { |
1242 | Extrem.SetValue(previousP.PointOnS(), |
1243 | sol(1),sol(2), |
1244 | previousP.Parameter(),tolesp); |
1245 | if (!previousP.IsTangencyPoint()) |
1246 | Extrem.SetTangent(previousP.TangentOnS()); |
1247 | Iter = domain1; |
1248 | } |
1249 | else { |
1250 | Extrem.SetValue(previousP.PointOnC(), |
1251 | sol(3), |
1252 | previousP.Parameter(),tolesp); |
1253 | if (!previousP.IsTangencyPoint()) |
1254 | Extrem.SetTangent(previousP.TangentOnC()); |
1255 | Iter = domain2; |
1256 | } |
1257 | |
1258 | Iter->Init(); |
1259 | if (!IsVtx) { |
1260 | Transition(OnFirst,Arc,Param,Tline,Tarc); |
1261 | Extrem.AddArc(Arc,Param,Tline,Tarc); |
1262 | } |
1263 | else { |
1264 | Extrem.SetVertex(Vtx); |
1265 | while (Iter->More()) { |
7fd59977 |
1266 | Handle(Adaptor2d_HCurve2d) arc = Iter->Value(); |
7fd59977 |
1267 | if (arc != Arc) { |
1268 | Iter->Initialize(arc); |
1269 | Iter->InitVertexIterator(); |
1270 | while (Iter->MoreVertex()) { |
1271 | if (Iter->Identical(Vtx,Iter->Vertex())) { |
1272 | prm = BRepBlend_BlendTool::Parameter(Vtx,arc); |
1273 | Transition(OnFirst,arc,prm,Tline,Tarc); |
1274 | Extrem.AddArc(arc,prm,Tline,Tarc); |
1275 | } |
1276 | Iter->NextVertex(); |
1277 | } |
1278 | } |
1279 | else { |
1280 | Transition(OnFirst,arc,Param,Tline,Tarc); |
1281 | Extrem.AddArc(arc,Param,Tline,Tarc); |
1282 | } |
1283 | Iter->Next(); |
1284 | } |
1285 | } |
1286 | } |
1287 | |
1288 | //======================================================================= |
1289 | //function : CheckDeflectionOnSurf |
1290 | //purpose : |
1291 | //======================================================================= |
1292 | |
1293 | Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnSurf(const Blend_Point& CurPoint) |
1294 | { |
81bba717 |
1295 | //Controls 3d of Blend_CSWalking. |
7fd59977 |
1296 | |
0d969553 |
1297 | //rule by tests in U4 corresponds to 11.478 d |
7fd59977 |
1298 | const Standard_Real CosRef3D = 0.98; |
1299 | Standard_Real Cosi=0, Cosi2=0; |
1300 | Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint(); |
1301 | Standard_Boolean prevpointistangent = previousP.IsTangencyPoint(); |
1302 | |
1303 | gp_Pnt Psurf = CurPoint.PointOnS(); |
1304 | gp_Vec Tgsurf; |
1305 | if(!curpointistangent){ |
1306 | Tgsurf = CurPoint.TangentOnS(); |
1307 | } |
1308 | gp_Pnt prevP = previousP.PointOnS(); |
1309 | gp_Vec prevTg; |
1310 | if(!prevpointistangent){ |
1311 | prevTg = previousP.TangentOnS(); |
1312 | } |
7fd59977 |
1313 | Standard_Real Norme,prevNorme = 0.; |
7fd59977 |
1314 | gp_Vec Corde(prevP,Psurf); |
1315 | Norme = Corde.SquareMagnitude(); |
1316 | // if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude(); |
1317 | if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude(); |
1318 | |
1319 | if (Norme <= tolesp*tolesp){ |
81bba717 |
1320 | // it can be necessary to force same point |
7fd59977 |
1321 | return Blend_SamePoints; |
1322 | } |
1323 | if(!prevpointistangent){ |
1324 | if(prevNorme <= tolesp*tolesp) { |
1325 | return Blend_SamePoints; |
1326 | } |
1327 | Cosi = sens*Corde*prevTg; |
81bba717 |
1328 | if (Cosi <0.) { // angle 3d>pi/2. --> return back |
7fd59977 |
1329 | return Blend_Backward; |
1330 | } |
1331 | |
1332 | Cosi2 = Cosi * Cosi / prevNorme / Norme; |
1333 | if (Cosi2 < CosRef3D) { |
1334 | return Blend_StepTooLarge; |
1335 | } |
1336 | } |
1337 | |
1338 | if(!curpointistangent){ |
81bba717 |
1339 | // Check if it is necessary to control the sign of prevtg*Tgsurf |
7fd59977 |
1340 | Cosi = sens*Corde*Tgsurf; |
1341 | Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme; |
1342 | if (Cosi2 < CosRef3D || Cosi < 0.) { |
1343 | return Blend_StepTooLarge; |
1344 | } |
1345 | } |
1346 | |
1347 | if(!curpointistangent && !prevpointistangent){ |
81bba717 |
1348 | // Estimation of the current arrow |
7fd59977 |
1349 | Standard_Real FlecheCourante = |
1350 | (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.; |
1351 | |
1352 | if (FlecheCourante <= 0.25*fleche*fleche) { |
1353 | return Blend_StepTooSmall; |
1354 | } |
1355 | if (FlecheCourante > fleche*fleche) { |
81bba717 |
1356 | // not too great : |
7fd59977 |
1357 | return Blend_StepTooLarge; |
1358 | } |
1359 | } |
1360 | return Blend_OK; |
1361 | } |
1362 | |
1363 | |
1364 | //======================================================================= |
1365 | //function : CheckDeflectionOnRst |
1366 | //purpose : |
1367 | //======================================================================= |
1368 | |
1369 | Blend_Status BRepBlend_SurfRstLineBuilder::CheckDeflectionOnRst(const Blend_Point& CurPoint) |
1370 | { |
81bba717 |
1371 | //Controls 3D of Blend_CSWalking. |
7fd59977 |
1372 | |
81bba717 |
1373 | // rule by tests in U4 corresponds to 11.478 d |
7fd59977 |
1374 | const Standard_Real CosRef3D = 0.98; |
1375 | Standard_Real Cosi, Cosi2; |
1376 | Standard_Boolean curpointistangent = CurPoint.IsTangencyPoint(); |
1377 | Standard_Boolean prevpointistangent = previousP.IsTangencyPoint(); |
1378 | |
1379 | gp_Pnt Psurf = CurPoint.PointOnC(); |
1380 | gp_Vec Tgsurf; |
1381 | if(!curpointistangent){ |
1382 | Tgsurf = CurPoint.TangentOnC(); |
1383 | } |
1384 | gp_Pnt prevP = previousP.PointOnC(); |
1385 | gp_Vec prevTg; |
1386 | if(!prevpointistangent){ |
1387 | prevTg = previousP.TangentOnC(); |
1388 | } |
7fd59977 |
1389 | Standard_Real Norme,prevNorme = 0.; |
7fd59977 |
1390 | gp_Vec Corde(prevP,Psurf); |
1391 | Norme = Corde.SquareMagnitude(); |
1392 | // if(!curpointistangent) curNorme = Tgsurf.SquareMagnitude(); |
1393 | if(!prevpointistangent) prevNorme = prevTg.SquareMagnitude(); |
1394 | |
1395 | if (Norme <= tolesp*tolesp){ |
81bba717 |
1396 | // it can be necessary to force same point |
7fd59977 |
1397 | return Blend_SamePoints; |
1398 | } |
1399 | if(!prevpointistangent){ |
1400 | if(prevNorme <= tolesp*tolesp) { |
1401 | return Blend_SamePoints; |
1402 | } |
1403 | Cosi = sens*Corde*prevTg; |
81bba717 |
1404 | if (Cosi <0.) { // angle 3d>pi/2. --> return back |
7fd59977 |
1405 | return Blend_Backward; |
1406 | } |
1407 | |
1408 | Cosi2 = Cosi * Cosi / prevNorme / Norme; |
1409 | if (Cosi2 < CosRef3D) { |
1410 | return Blend_StepTooLarge; |
1411 | } |
1412 | } |
1413 | |
1414 | if(!curpointistangent){ |
81bba717 |
1415 | // Check if it is necessary to control the sign of prevtg*Tgsurf |
7fd59977 |
1416 | Cosi = sens*Corde*Tgsurf; |
1417 | Cosi2 = Cosi * Cosi / Tgsurf.SquareMagnitude() / Norme; |
1418 | if (Cosi2 < CosRef3D || Cosi < 0.) { |
1419 | return Blend_StepTooLarge; |
1420 | } |
1421 | } |
1422 | |
1423 | if(!curpointistangent && !prevpointistangent){ |
81bba717 |
1424 | // Estimation of the current arrow |
7fd59977 |
1425 | Standard_Real FlecheCourante = |
1426 | (prevTg.Normalized().XYZ()-Tgsurf.Normalized().XYZ()).SquareModulus()*Norme/64.; |
1427 | |
1428 | if (FlecheCourante <= 0.25*fleche*fleche) { |
1429 | return Blend_StepTooSmall; |
1430 | } |
1431 | if (FlecheCourante > fleche*fleche) { |
81bba717 |
1432 | // not too great |
7fd59977 |
1433 | return Blend_StepTooLarge; |
1434 | } |
1435 | } |
1436 | return Blend_OK; |
1437 | } |
1438 | |
1439 | static IntSurf_TypeTrans ConvOrToTra(const TopAbs_Orientation O) |
1440 | { |
1441 | if(O == TopAbs_FORWARD) return IntSurf_In; |
1442 | return IntSurf_Out; |
1443 | } |
1444 | |
1445 | //======================================================================= |
1446 | //function : TestArret |
1447 | //purpose : |
1448 | //======================================================================= |
1449 | |
1450 | Blend_Status BRepBlend_SurfRstLineBuilder::TestArret(Blend_SurfRstFunction& Func, |
1451 | const Standard_Boolean TestDeflection, |
1452 | const Blend_Status State) |
1453 | { |
1454 | gp_Pnt pts,ptrst; |
1455 | gp_Pnt2d pt2drst; |
1456 | gp_Vec tgs,tgrst; |
1457 | gp_Vec2d tg2ds,tg2drst; |
1458 | Blend_Status StateS,StateRst; |
7fd59977 |
1459 | IntSurf_TypeTrans tras = IntSurf_Undecided, trarst = IntSurf_Undecided; |
7fd59977 |
1460 | Blend_Point curpoint; |
1461 | |
1462 | if (Func.IsSolution(sol,tolesp)) { |
1463 | Standard_Boolean curpointistangent = Func.IsTangencyPoint(); |
1464 | pts = Func.PointOnS(); |
1465 | ptrst = Func.PointOnRst(); |
1466 | pt2drst = Func.Pnt2dOnRst(); |
1467 | if(curpointistangent){ |
1468 | curpoint.SetValue(pts,ptrst,param,sol(1),sol(2), |
1469 | pt2drst.X(),pt2drst.Y(),sol(3)); |
1470 | } |
1471 | else{ |
1472 | tgs = Func.TangentOnS(); |
1473 | tgrst = Func.TangentOnRst(); |
1474 | tg2ds = Func.Tangent2dOnS(); |
1475 | tg2drst = Func.Tangent2dOnRst(); |
1476 | |
1477 | curpoint.SetValue(pts,ptrst,param,sol(1),sol(2), |
1478 | pt2drst.X(),pt2drst.Y(),sol(3), |
1479 | tgs,tgrst,tg2ds,tg2drst); |
1480 | } |
1481 | if (TestDeflection) { |
1482 | StateS = CheckDeflectionOnSurf(curpoint); |
1483 | StateRst = CheckDeflectionOnRst(curpoint); |
1484 | } |
1485 | else { |
1486 | StateS = StateRst = Blend_OK; |
1487 | } |
1488 | if (StateS == Blend_Backward) { |
1489 | StateS = Blend_StepTooLarge; |
1490 | rebrou= Standard_True; |
1491 | } |
1492 | if (StateRst == Blend_Backward) { |
1493 | StateRst = Blend_StepTooLarge; |
1494 | rebrou = Standard_True; |
1495 | } |
1496 | if (StateS == Blend_StepTooLarge || |
1497 | StateRst == Blend_StepTooLarge) { |
1498 | return Blend_StepTooLarge; |
1499 | } |
1500 | |
1501 | if (!comptra && !curpointistangent) { |
1502 | gp_Vec tgsecs,nors; |
1503 | Func.Decroch(sol,nors,tgsecs); |
1504 | nors.Normalize(); |
1505 | Standard_Real testra = tgsecs.Dot(nors.Crossed(tgs)); |
1506 | if (Abs(testra) > tolesp) { |
1507 | if (testra < 0.) { |
1508 | tras = IntSurf_In; |
1509 | } |
1510 | else if (testra >0.) { |
1511 | tras = IntSurf_Out; |
1512 | } |
1513 | gp_Pnt2d p2drstref; gp_Vec2d tg2drstref; |
1514 | rst->D1(sol(3),p2drstref,tg2drstref); |
1515 | testra = tg2drst.Dot(tg2drstref); |
1516 | TopAbs_Orientation Or = domain2->Orientation(rst); |
1517 | if (Abs(testra) > 1.e-8) { |
1518 | if (testra < 0.) { |
1519 | trarst = ConvOrToTra(TopAbs::Reverse(Or)); |
1520 | } |
1521 | else if (testra >0.) { |
1522 | trarst = ConvOrToTra(Or); |
1523 | } |
1524 | comptra = Standard_True; |
1525 | line->Set(tras,trarst); |
1526 | } |
1527 | } |
1528 | } |
1529 | if (StateS == Blend_OK || |
1530 | StateRst == Blend_OK ) { |
1531 | previousP = curpoint; |
1532 | return State; |
1533 | } |
1534 | if (StateS == Blend_StepTooSmall && |
1535 | StateRst == Blend_StepTooSmall) { |
1536 | previousP = curpoint; |
1537 | if (State == Blend_OK) { |
1538 | return Blend_StepTooSmall; |
1539 | } |
1540 | else { |
1541 | return State; |
1542 | } |
1543 | } |
1544 | if (State == Blend_OK) { |
1545 | return Blend_SamePoints; |
1546 | } |
1547 | else { |
1548 | return State; |
1549 | } |
1550 | } |
1551 | return Blend_StepTooLarge; |
1552 | } |
1553 | |
1554 | //======================================================================= |
1555 | //function : CheckInside |
1556 | //purpose : |
1557 | //======================================================================= |
1558 | |
1559 | Standard_Boolean BRepBlend_SurfRstLineBuilder::CheckInside(Blend_SurfRstFunction& Func, |
1560 | TopAbs_State& SituOnC, |
1561 | TopAbs_State& SituOnS, |
1562 | Standard_Boolean& Decroch) |
1563 | { |
1564 | math_Vector tolerance(1,3); |
1565 | Func.GetTolerance(tolerance,tolesp); |
81bba717 |
1566 | //face pcurve. |
7fd59977 |
1567 | Standard_Real w = sol(3); |
1568 | if(w < rst->FirstParameter() - tolerance(3)|| |
1569 | w > rst->LastParameter() + tolerance(3)){ |
1570 | SituOnC = TopAbs_OUT; |
1571 | } |
1572 | else if (w > rst->FirstParameter() && |
1573 | w < rst->LastParameter()){ |
1574 | SituOnC = TopAbs_IN; |
1575 | } |
1576 | else SituOnC = TopAbs_ON; |
1577 | |
81bba717 |
1578 | //face surface |
7fd59977 |
1579 | gp_Pnt2d p2d(sol(1),sol(2)); |
1580 | SituOnS = domain1->Classify(p2d,Min(tolerance(1),tolerance(2)),0); |
1581 | |
81bba717 |
1582 | //lost contact |
7fd59977 |
1583 | gp_Vec tgs,nors; |
1584 | Decroch = Func.Decroch(sol,tgs,nors); |
1585 | |
1586 | return (SituOnC == TopAbs_IN && SituOnS == TopAbs_IN && !Decroch); |
1587 | } |
1588 | |