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