b311480e |
1 | // Created on: 1995-01-04 |
2 | // Created by: Jacques GOUSSARD |
3 | // Copyright (c) 1995-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 | |
17 | // Modified 10/09/1996 PMN Ajout de (Nb)Intervalles, IsRationnal |
18 | // + Utilisation de GeomFill::GetCircle dans Section. |
19 | // Modified 23/06/1997 PMN : Pb de division par 0. |
20 | |
21 | #include <BlendFunc_CSCircular.ixx> |
22 | |
23 | #include <math_Gauss.hxx> |
24 | |
25 | #include <ElCLib.hxx> |
26 | #include <gp.hxx> |
27 | #include <BlendFunc.hxx> |
28 | #include <GeomFill.hxx> |
29 | #include <Standard_NotImplemented.hxx> |
30 | #include <Standard_DomainError.hxx> |
31 | #include <Precision.hxx> |
32 | |
33 | #define Eps 1.e-15 |
34 | |
35 | //======================================================================= |
36 | //function : BlendFunc_CSCircular |
37 | //purpose : |
38 | //======================================================================= |
39 | |
40 | BlendFunc_CSCircular::BlendFunc_CSCircular(const Handle(Adaptor3d_HSurface)& S, |
41 | const Handle(Adaptor3d_HCurve)& C, |
42 | const Handle(Adaptor3d_HCurve)& CGuide, |
43 | const Handle(Law_Function)& L) : |
eafb234b |
44 | surf(S),curv(C),guide(CGuide),law(L),istangent(Standard_True), |
7fd59977 |
45 | //prmc, dprmc, istangent, ray, choix, normtg, |
46 | maxang(RealFirst()),minang(RealLast()),mySShape(BlendFunc_Rational) |
47 | //myTConv |
48 | { |
49 | law = L; |
50 | } |
51 | |
52 | |
53 | //======================================================================= |
54 | //function : NbVariables |
55 | //purpose : |
56 | //======================================================================= |
57 | |
58 | Standard_Integer BlendFunc_CSCircular::NbVariables () const |
59 | { |
60 | return 2; |
61 | } |
62 | |
63 | |
64 | //======================================================================= |
65 | //function : NbEquations |
66 | //purpose : |
67 | //======================================================================= |
68 | |
69 | Standard_Integer BlendFunc_CSCircular::NbEquations () const |
70 | { |
71 | return 2; |
72 | } |
73 | |
74 | |
75 | //======================================================================= |
76 | //function : Set |
77 | //purpose : |
78 | //======================================================================= |
79 | |
80 | void BlendFunc_CSCircular::Set(const Standard_Real Radius, const Standard_Integer Choix) |
81 | { |
82 | choix = Choix; |
83 | switch (Choix) |
84 | { |
85 | case 3 : |
86 | case 4 : |
87 | ray = Abs(Radius); |
88 | break; |
89 | default : |
90 | ray = -Abs(Radius); |
91 | break; |
92 | } |
93 | } |
94 | |
95 | |
96 | //======================================================================= |
97 | //function : Set |
98 | //purpose : |
99 | //======================================================================= |
100 | |
101 | void BlendFunc_CSCircular::Set(const BlendFunc_SectionShape TypeSection) |
102 | { |
103 | mySShape = TypeSection; |
104 | } |
105 | |
106 | |
107 | //======================================================================= |
108 | //function : Set |
109 | //purpose : |
110 | //======================================================================= |
111 | |
112 | void BlendFunc_CSCircular::Set(const Standard_Real Param) |
113 | { |
114 | gp_Pnt ptgui; |
115 | guide->D2(Param,ptgui,d1gui,d2gui); |
116 | law->D1(Param,prmc,dprmc); |
117 | |
118 | normtg = d1gui.Magnitude(); |
119 | nplan = d1gui.Normalized(); |
120 | } |
121 | |
122 | //======================================================================= |
123 | //function : Set |
124 | //purpose : |
125 | //======================================================================= |
126 | |
35e08fe8 |
127 | void BlendFunc_CSCircular::Set(const Standard_Real, const Standard_Real) |
7fd59977 |
128 | { |
129 | Standard_NotImplemented::Raise("BlendFunc_CSCircular::Set"); |
130 | } |
131 | |
132 | //======================================================================= |
133 | //function : GetTolerance |
134 | //purpose : |
135 | //======================================================================= |
136 | |
137 | void BlendFunc_CSCircular::GetTolerance(math_Vector& Tolerance, const Standard_Real Tol) const |
138 | { |
139 | Tolerance(1) = surf->UResolution(Tol); |
140 | Tolerance(2) = surf->VResolution(Tol); |
141 | } |
142 | |
143 | |
144 | //======================================================================= |
145 | //function : GetBounds |
146 | //purpose : |
147 | //======================================================================= |
148 | |
149 | void BlendFunc_CSCircular::GetBounds(math_Vector& InfBound, math_Vector& SupBound) const |
150 | { |
151 | InfBound(1) = surf->FirstUParameter(); |
152 | InfBound(2) = surf->FirstVParameter(); |
153 | SupBound(1) = surf->LastUParameter(); |
154 | SupBound(2) = surf->LastVParameter(); |
155 | |
156 | if(!Precision::IsInfinite(InfBound(1)) && |
157 | !Precision::IsInfinite(SupBound(1))) { |
158 | const Standard_Real range = (SupBound(1) - InfBound(1)); |
159 | InfBound(1) -= range; |
160 | SupBound(1) += range; |
161 | } |
162 | if(!Precision::IsInfinite(InfBound(2)) && |
163 | !Precision::IsInfinite(SupBound(2))) { |
164 | const Standard_Real range = (SupBound(2) - InfBound(2)); |
165 | InfBound(2) -= range; |
166 | SupBound(2) += range; |
167 | } |
168 | } |
169 | |
170 | |
171 | //======================================================================= |
172 | //function : IsSolution |
173 | //purpose : |
174 | //======================================================================= |
175 | |
176 | Standard_Boolean BlendFunc_CSCircular::IsSolution(const math_Vector& Sol, const Standard_Real Tol) |
177 | { |
178 | math_Vector valsol(1,2),secmember(1,2); |
179 | math_Matrix gradsol(1,2,1,2); |
180 | |
181 | gp_Vec dnplan,d1u1,d1v1,d1c,d2c,temp,ns,ncrossns,resul,nc; |
182 | Standard_Real norm,ndotns,grosterme; |
183 | Standard_Real Cosa,Sina,Angle; |
184 | |
185 | Values(Sol,valsol,gradsol); |
186 | |
187 | if (Abs(valsol(1)) <= Tol && |
188 | Abs(valsol(2)) <= Tol*Tol) { |
189 | |
190 | // Calcul des tangentes |
191 | |
192 | pt2d = gp_Pnt2d(Sol(1),Sol(2)); |
193 | |
194 | surf->D1(Sol(1),Sol(2),pts,d1u1,d1v1); |
195 | curv->D2(prmc,ptc,d1c,d2c); |
196 | |
197 | dnplan.SetLinearForm(1./normtg,d2gui, |
198 | -1./normtg*(nplan.Dot(d2gui)),nplan); |
199 | |
200 | ns = d1u1.Crossed(d1v1); |
201 | ncrossns = nplan.Crossed(ns); |
202 | ndotns = nplan.Dot(ns); |
203 | norm = ncrossns.Magnitude(); |
204 | if (norm < Eps) { |
205 | norm = 1.; |
7fd59977 |
206 | } |
207 | |
208 | temp.SetXYZ(pts.XYZ() - ptc.XYZ()); |
209 | secmember(1) = dprmc*(nplan.Dot(d1c)) - dnplan.Dot(temp); |
210 | |
211 | grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm; |
212 | temp.SetLinearForm(ray/norm*(dnplan.Dot(ns)-grosterme*ndotns),nplan, |
213 | ray*ndotns/norm,dnplan, |
214 | ray*grosterme/norm,ns); |
215 | temp -= dprmc*d1c; |
216 | |
217 | ns.SetLinearForm(ndotns/norm,nplan, -1./norm,ns); |
218 | resul.SetLinearForm(ray,ns,gp_Vec(ptc,pts)); |
219 | |
220 | secmember(2) = -2.*(resul.Dot(temp)); |
221 | |
222 | math_Gauss Resol(gradsol); |
223 | if (Resol.IsDone()) { |
224 | |
225 | Resol.Solve(secmember); |
226 | |
227 | tgs.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1); |
228 | tgc = dprmc*d1c; |
229 | tg2d.SetCoord(secmember(1),secmember(2)); |
230 | istangent = Standard_False; |
231 | } |
232 | else { |
233 | istangent = Standard_True; |
234 | } |
235 | // mise a jour de maxang |
236 | |
237 | if(ray > 0.) ns.Reverse(); |
238 | nc = -resul.Normalized(); |
239 | |
240 | Cosa = ns.Dot(nc); |
241 | Sina = nplan.Dot(ns.Crossed(nc)); |
242 | if (choix%2 != 0) { |
243 | Sina = -Sina; //nplan est change en -nplan |
244 | } |
245 | |
246 | Angle = ACos(Cosa); |
247 | if (Sina <0.) { |
c6541a0c |
248 | Angle = 2.*M_PI - Angle; |
7fd59977 |
249 | } |
250 | |
251 | if (Angle>maxang) {maxang = Angle;} |
252 | if (Angle<minang) {minang = Angle;} |
253 | |
254 | return Standard_True; |
255 | } |
256 | istangent = Standard_True; |
257 | return Standard_False; |
258 | } |
259 | |
260 | |
261 | //======================================================================= |
262 | //function : Value |
263 | //purpose : |
264 | //======================================================================= |
265 | |
266 | Standard_Boolean BlendFunc_CSCircular::Value(const math_Vector& X, math_Vector& F) |
267 | { |
268 | gp_Vec d1u1,d1v1,d1c; |
269 | |
270 | surf->D1(X(1),X(2),pts,d1u1,d1v1); |
271 | curv->D1(prmc,ptc,d1c); |
272 | |
273 | F(1) = nplan.XYZ().Dot(pts.XYZ()-ptc.XYZ()); |
274 | |
275 | gp_Vec ns = d1u1.Crossed(d1v1); |
276 | Standard_Real norm = nplan.Crossed(ns).Magnitude(); |
277 | if (norm < Eps) { |
278 | norm = 1.; |
7fd59977 |
279 | } |
280 | |
281 | ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns); |
282 | gp_Vec vref; |
283 | vref.SetLinearForm(ray,ns,gp_Vec(ptc,pts)); |
284 | |
285 | F(2) = vref.SquareMagnitude() - ray*ray; |
286 | |
287 | pt2d = gp_Pnt2d(X(1),X(2)); |
288 | return Standard_True; |
289 | } |
290 | |
291 | |
292 | //======================================================================= |
293 | //function : Derivatives |
294 | //purpose : |
295 | //======================================================================= |
296 | |
297 | Standard_Boolean BlendFunc_CSCircular::Derivatives(const math_Vector& X, math_Matrix& D) |
298 | { |
299 | gp_Vec d1u1,d1v1,d2u1,d2v1,d2uv1,d1c; |
300 | gp_Vec ns,ncrossns,resul,temp,nsov,vref; |
301 | |
302 | Standard_Real norm,ndotns,grosterme; |
303 | |
304 | surf->D2(X(1),X(2),pts,d1u1,d1v1,d2u1,d2v1,d2uv1); |
305 | curv->D1(prmc,ptc,d1c); |
306 | |
307 | D(1,1) = nplan.Dot(d1u1); |
308 | D(1,2) = nplan.Dot(d1v1); |
309 | |
310 | ns = d1u1.Crossed(d1v1); |
311 | ncrossns = nplan.Crossed(ns); |
312 | norm = ncrossns.Magnitude(); |
313 | if (norm < Eps) { |
314 | norm = 1.; |
7fd59977 |
315 | } |
316 | |
317 | ndotns = nplan.Dot(ns); |
318 | |
319 | nsov.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns); |
320 | vref.SetLinearForm(ray,nsov,gp_Vec(ptc,pts)); |
321 | |
322 | // Derivee par rapport a u de Ps + ray*ns |
323 | temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1)); |
324 | grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm; |
325 | resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan, |
326 | ray*grosterme/norm,ns, |
327 | -ray/norm,temp, |
328 | d1u1); |
329 | |
330 | D(2,1) = 2.*(resul.Dot(vref)); |
331 | |
332 | // Derivee par rapport a v |
333 | temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1)); |
334 | grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm; |
335 | resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan, |
336 | ray*grosterme/norm,ns, |
337 | -ray/norm,temp, |
338 | d1v1); |
339 | |
340 | D(2,2) = 2.*(resul.Dot(vref)); |
341 | |
342 | pt2d = gp_Pnt2d(X(1),X(2)); |
343 | return Standard_True; |
344 | } |
345 | |
346 | |
347 | //======================================================================= |
348 | //function : Values |
349 | //purpose : |
350 | //======================================================================= |
351 | |
352 | Standard_Boolean BlendFunc_CSCircular::Values(const math_Vector& X, math_Vector& F, math_Matrix& D) |
353 | { |
354 | gp_Vec d1u1,d1v1,d1c; |
355 | gp_Vec d2u1,d2v1,d2uv1; |
356 | gp_Vec ns,ncrossns,resul,temp,vref,nsov; |
357 | |
358 | Standard_Real norm,ndotns,grosterme; |
359 | |
360 | surf->D2(X(1),X(2),pts,d1u1,d1v1,d2u1,d2v1,d2uv1); |
361 | curv->D1(prmc,ptc,d1c); |
362 | |
363 | ns = d1u1.Crossed(d1v1); |
364 | ncrossns = nplan.Crossed(ns); |
365 | norm = ncrossns.Magnitude(); |
366 | if (norm < Eps) { |
367 | norm = 1.; |
7fd59977 |
368 | } |
369 | |
370 | ndotns = nplan.Dot(ns); |
371 | nsov.SetLinearForm(ndotns/norm,nplan,-1./norm,ns); |
372 | vref.SetLinearForm(ray,nsov,gp_Vec(ptc,pts)); |
373 | |
374 | F(1) = nplan.XYZ().Dot(pts.XYZ()-ptc.XYZ()); |
375 | F(2) = vref.SquareMagnitude() - ray*ray; |
376 | |
377 | D(1,1) = nplan.Dot(d1u1); |
378 | D(1,2) = nplan.Dot(d1v1); |
379 | |
380 | // Derivee par rapport a u |
381 | temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1)); |
382 | grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm; |
383 | resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan, |
384 | ray*grosterme/norm,ns, |
385 | -ray/norm,temp, |
386 | d1u1); |
387 | |
388 | D(2,1) = 2.*(resul.Dot(vref)); |
389 | |
390 | // Derivee par rapport a v |
391 | temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1)); |
392 | grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm; |
393 | resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan, |
394 | ray*grosterme/norm,ns, |
395 | -ray/norm,temp, |
396 | d1v1); |
397 | |
398 | D(2,2) = 2.*(resul.Dot(vref)); |
399 | |
400 | pt2d = gp_Pnt2d(X(1),X(2)); |
401 | return Standard_True; |
402 | } |
403 | |
404 | |
405 | //======================================================================= |
406 | //function : PointOnS |
407 | //purpose : |
408 | //======================================================================= |
409 | |
410 | const gp_Pnt& BlendFunc_CSCircular::PointOnS () const |
411 | { |
412 | return pts; |
413 | } |
414 | |
415 | //======================================================================= |
416 | //function : PointOnC |
417 | //purpose : |
418 | //======================================================================= |
419 | |
420 | const gp_Pnt& BlendFunc_CSCircular::PointOnC () const |
421 | { |
422 | return ptc; |
423 | } |
424 | |
425 | //======================================================================= |
426 | //function : Pnt2d |
427 | //purpose : |
428 | //======================================================================= |
429 | |
430 | const gp_Pnt2d& BlendFunc_CSCircular::Pnt2d () const |
431 | { |
432 | return pt2d; |
433 | } |
434 | |
435 | //======================================================================= |
436 | //function : ParameterOnC |
437 | //purpose : |
438 | //======================================================================= |
439 | |
440 | Standard_Real BlendFunc_CSCircular::ParameterOnC () const |
441 | { |
442 | return prmc; |
443 | } |
444 | |
445 | |
446 | //======================================================================= |
447 | //function : IsTangencyPoint |
448 | //purpose : |
449 | //======================================================================= |
450 | |
451 | Standard_Boolean BlendFunc_CSCircular::IsTangencyPoint () const |
452 | { |
453 | return istangent; |
454 | } |
455 | |
456 | //======================================================================= |
457 | //function : TangentOnS |
458 | //purpose : |
459 | //======================================================================= |
460 | |
461 | const gp_Vec& BlendFunc_CSCircular::TangentOnS () const |
462 | { |
463 | if (istangent) |
464 | Standard_DomainError::Raise("BlendFunc_CSCircular::TangentOnS"); |
465 | return tgs; |
466 | } |
467 | |
468 | //======================================================================= |
469 | //function : TangentOnC |
470 | //purpose : |
471 | //======================================================================= |
472 | |
473 | const gp_Vec& BlendFunc_CSCircular::TangentOnC () const |
474 | { |
475 | if (istangent) |
476 | Standard_DomainError::Raise("BlendFunc_CSCircular::TangentOnC"); |
477 | return tgc; |
478 | } |
479 | |
480 | //======================================================================= |
481 | //function : Tangent2d |
482 | //purpose : |
483 | //======================================================================= |
484 | |
485 | const gp_Vec2d& BlendFunc_CSCircular::Tangent2d () const |
486 | { |
487 | if (istangent) |
488 | Standard_DomainError::Raise("BlendFunc_CSCircular::Tangent2d"); |
489 | return tg2d; |
490 | } |
491 | |
492 | |
493 | //======================================================================= |
494 | //function : Tangent |
495 | //purpose : |
496 | //======================================================================= |
497 | |
498 | void BlendFunc_CSCircular::Tangent(const Standard_Real U, const Standard_Real V, |
499 | gp_Vec& TgS, gp_Vec& NmS) const |
500 | { |
501 | gp_Pnt bid; |
502 | gp_Vec d1u,d1v,ns; |
503 | surf->D1(U,V,bid,d1u,d1v); |
504 | NmS = ns = d1u.Crossed(d1v); |
505 | |
506 | const Standard_Real norm = nplan.Crossed(ns).Magnitude(); |
507 | ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns); |
508 | if(ray > 0.) ns.Reverse(); |
509 | TgS = nplan.Crossed(ns); |
510 | if (choix%2 == 1) |
511 | TgS.Reverse(); |
512 | } |
513 | |
514 | |
515 | //======================================================================= |
516 | //function : Section |
517 | //purpose : |
518 | //======================================================================= |
519 | |
520 | void BlendFunc_CSCircular::Section(const Standard_Real Param, |
521 | const Standard_Real U, |
522 | const Standard_Real V, |
523 | const Standard_Real W, |
524 | Standard_Real& Pdeb, |
525 | Standard_Real& Pfin, |
526 | gp_Circ& C) |
527 | { |
528 | gp_Vec d1u1,d1v1; |
529 | gp_Vec ns;//,temp; |
530 | Standard_Real norm; |
531 | gp_Pnt Center; |
532 | gp_Pnt ptgui; |
533 | |
534 | guide->D1(Param,ptgui,d1gui); |
535 | nplan = d1gui.Normalized(); |
536 | |
537 | surf->D1(U,V,pts,d1u1,d1v1); |
538 | ptc = curv->Value(W); |
539 | |
540 | ns = d1u1.Crossed(d1v1); |
541 | norm = nplan.Crossed(ns).Magnitude(); |
542 | ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns); |
543 | |
544 | Center.SetXYZ(pts.XYZ()+ray*ns.XYZ()); |
545 | C.SetRadius(Abs(ray)); |
546 | |
547 | if(ray > 0.) ns.Reverse(); |
548 | |
549 | if (choix%2 == 0) { |
550 | C.SetPosition(gp_Ax2(Center,nplan,ns)); |
551 | } |
552 | else { |
553 | C.SetPosition(gp_Ax2(Center,nplan.Reversed(),ns)); |
554 | } |
555 | Pdeb = 0.; |
556 | Pfin = ElCLib::Parameter(C,ptc); |
557 | } |
558 | |
559 | |
560 | Standard_Boolean BlendFunc_CSCircular::Section(const Blend_Point& P, |
561 | TColgp_Array1OfPnt& Poles, |
562 | TColgp_Array1OfVec& DPoles, |
563 | TColgp_Array1OfVec& D2Poles, |
564 | TColgp_Array1OfPnt2d& Poles2d, |
565 | TColgp_Array1OfVec2d& DPoles2d, |
566 | TColgp_Array1OfVec2d& D2Poles2d, |
567 | TColStd_Array1OfReal& Weigths, |
568 | TColStd_Array1OfReal& DWeigths, |
569 | TColStd_Array1OfReal& D2Weigths) |
570 | { |
571 | return Blend_CSFunction::Section(P,Poles,DPoles,D2Poles,Poles2d,DPoles2d,D2Poles2d,Weigths,DWeigths,D2Weigths); |
572 | } |
573 | |
574 | //======================================================================= |
575 | //function : GetSection |
576 | //purpose : |
577 | //======================================================================= |
578 | |
579 | Standard_Boolean BlendFunc_CSCircular::GetSection(const Standard_Real Param, |
580 | const Standard_Real U, |
581 | const Standard_Real V, |
35e08fe8 |
582 | const Standard_Real /*W*/, |
7fd59977 |
583 | TColgp_Array1OfPnt& tabP, |
584 | TColgp_Array1OfVec& tabV) |
585 | { |
586 | Standard_Integer NbPoint=tabP.Length(); |
587 | if (NbPoint != tabV.Length() || NbPoint < 2) {Standard_RangeError::Raise();} |
588 | |
589 | Standard_Integer i, lowp = tabP.Lower(), lowv = tabV.Lower(); |
590 | |
591 | gp_Vec d1u1,d1v1,d2u1,d2v1,d2uv1,d1c,d2c; //,d1u2,d1v2; |
592 | gp_Vec ns,dnplan,dnw,dn2w,ncrn,dncrn,ns2; |
593 | gp_Vec ncrossns,resul; |
594 | gp_Vec resulu,resulv,temp; |
595 | |
596 | Standard_Real norm,ndotns,grosterme; |
597 | Standard_Real lambda,Cosa,Sina; |
598 | Standard_Real Angle = 0.,Dangle = 0.; |
599 | math_Vector sol(1,2),valsol(1,2),secmember(1,2); |
600 | math_Matrix gradsol(1,2,1,2); |
601 | |
602 | Set(Param); |
603 | dnplan.SetLinearForm(1./normtg,d2gui, |
604 | -1./normtg*(nplan.Dot(d2gui)),nplan); |
605 | |
606 | curv->D2(prmc,ptc,d1c,d2c); |
607 | surf->D2(U,V,pts,d1u1,d1v1,d2u1,d2v1,d2uv1); |
608 | |
609 | ns = d1u1.Crossed(d1v1); |
610 | ncrossns = nplan.Crossed(ns); |
611 | ndotns = nplan.Dot(ns); |
612 | norm = ncrossns.Magnitude(); |
613 | |
614 | temp.SetXYZ(pts.XYZ() - ptc.XYZ()); |
615 | secmember(1) = dprmc*(nplan.Dot(d1c)) - dnplan.Dot(temp); |
616 | |
617 | ns2.SetLinearForm(ndotns/norm,nplan, -1./norm,ns); |
618 | |
619 | // Derivee de n1 par rapport a w (param sur ligne guide) |
620 | |
621 | grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm; |
622 | dnw.SetLinearForm((dnplan.Dot(ns)-grosterme*ndotns)/norm,nplan, |
623 | ndotns/norm,dnplan, |
624 | grosterme/norm,ns); |
625 | |
626 | temp.SetLinearForm(ray,dnw,-dprmc,d1c); |
627 | resul.SetLinearForm(ray,ns2,gp_Vec(ptc,pts)); |
628 | |
629 | secmember(2) = -2.*(resul.Dot(temp)); |
630 | |
631 | sol(1) = U; sol(2) = V; |
632 | Values(sol,valsol,gradsol); |
633 | math_Gauss Resol(gradsol); |
634 | |
635 | if (Resol.IsDone()) { |
636 | |
637 | Resol.Solve(secmember); |
638 | |
639 | tgs.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1); |
640 | tgc = dprmc*d1c; |
641 | |
642 | // Derivee de n1 par rapport a u1 |
643 | temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1)); |
644 | grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm; |
645 | resulu.SetLinearForm(-(grosterme*ndotns-nplan.Dot(temp))/norm,nplan, |
646 | grosterme/norm,ns, |
647 | -1./norm,temp); |
648 | |
649 | // Derivee de n1 par rapport a v1 |
650 | temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1)); |
651 | grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm; |
652 | resulv.SetLinearForm(-(grosterme*ndotns-nplan.Dot(temp))/norm,nplan, |
653 | grosterme/norm,ns, |
654 | -1./norm,temp); |
655 | |
656 | |
657 | dnw.SetLinearForm(secmember(1),resulu,secmember(2),resulv,dnw); |
658 | ns = ns2; |
659 | dn2w.SetLinearForm(ray, dnw, -1., tgc, tgs); |
660 | norm = resul.Magnitude(); |
661 | dn2w.Divide(norm); |
662 | ns2 = -resul.Normalized(); |
663 | dn2w.SetLinearForm(ns2.Dot(dn2w),ns2,-1.,dn2w); |
664 | |
665 | if(ray > 0.) { |
666 | ns.Reverse(); |
667 | dnw.Reverse(); |
668 | } |
669 | |
670 | if (choix%2 != 0) { |
671 | nplan.Reverse(); |
672 | dnplan.Reverse(); |
673 | } |
674 | |
675 | |
676 | tabP(lowp) = pts; |
677 | tabP(lowp+NbPoint-1) = ptc; |
678 | |
679 | tabV(lowv) = tgs; |
680 | tabV(lowv+NbPoint-1) = tgc; |
681 | |
682 | if (NbPoint >2) { |
683 | |
684 | Cosa = ns.Dot(ns2); |
685 | Sina = nplan.Dot(ns.Crossed(ns2)); |
686 | Angle = ACos(Cosa); |
687 | if (Sina <0.) { |
c6541a0c |
688 | Angle = 2.*M_PI - Angle; |
7fd59977 |
689 | } |
690 | Dangle = -(dnw.Dot(ns2) + ns.Dot(dn2w))/Sina; |
691 | ncrn = nplan.Crossed(ns); |
692 | dncrn = dnplan.Crossed(ns).Added(nplan.Crossed(dnw)); |
693 | } |
694 | |
695 | for (i=2; i <= NbPoint-1; i++) { |
696 | lambda = (Standard_Real)(i-1)/(Standard_Real)(NbPoint-1); |
697 | Cosa = Cos(lambda*Angle); |
698 | Sina = Sin(lambda*Angle); |
699 | tabP(lowp+i-1).SetXYZ(pts.XYZ() |
700 | +Abs(ray)*((Cosa-1)*ns.XYZ() + Sina*ncrn.XYZ())); |
701 | |
702 | temp.SetLinearForm(-Sina,ns,Cosa,ncrn); |
703 | temp.Multiply(lambda*Dangle); |
704 | temp.Add(((Cosa-1)*dnw).Added(Sina*dncrn)); |
705 | temp.Multiply(Abs(ray)); |
706 | temp.Add(tgs); |
707 | tabV(lowv+i-1)= temp; |
708 | } |
709 | return Standard_True; |
710 | } |
711 | return Standard_False; |
712 | } |
713 | |
714 | //======================================================================= |
715 | //function : IsRational |
716 | //purpose : |
717 | //======================================================================= |
718 | |
719 | Standard_Boolean BlendFunc_CSCircular::IsRational() const |
720 | { |
721 | return (mySShape==BlendFunc_Rational || mySShape==BlendFunc_QuasiAngular); |
722 | } |
723 | |
724 | //======================================================================= |
725 | //function : GetSectionSize |
726 | //purpose : |
727 | //======================================================================= |
728 | |
729 | Standard_Real BlendFunc_CSCircular::GetSectionSize() const |
730 | { |
731 | return maxang*Abs(ray); |
732 | } |
733 | |
734 | //======================================================================= |
735 | //function : GetMinimalWeight |
736 | //purpose : |
737 | //======================================================================= |
738 | void BlendFunc_CSCircular::GetMinimalWeight(TColStd_Array1OfReal& Weigths) const |
739 | { |
740 | BlendFunc::GetMinimalWeights(mySShape, myTConv,minang,maxang,Weigths); |
741 | // On suppose que cela ne depend pas du Rayon! |
742 | } |
743 | |
744 | //======================================================================= |
745 | //function : NbIntervals |
746 | //purpose : |
747 | //======================================================================= |
748 | |
749 | Standard_Integer BlendFunc_CSCircular::NbIntervals (const GeomAbs_Shape S) const |
750 | { |
751 | return curv->NbIntervals(BlendFunc::NextShape(S)); |
752 | } |
753 | |
754 | |
755 | //======================================================================= |
756 | //function : Intervals |
757 | //purpose : |
758 | //======================================================================= |
759 | |
760 | void BlendFunc_CSCircular::Intervals (TColStd_Array1OfReal& T, const GeomAbs_Shape S) const |
761 | { |
762 | curv->Intervals(T, BlendFunc::NextShape(S)); |
763 | } |
764 | |
765 | //======================================================================= |
766 | //function : GetShape |
767 | //purpose : |
768 | //======================================================================= |
769 | |
770 | void BlendFunc_CSCircular::GetShape (Standard_Integer& NbPoles, |
771 | Standard_Integer& NbKnots, |
772 | Standard_Integer& Degree, |
773 | Standard_Integer& NbPoles2d) |
774 | { |
775 | NbPoles2d = 1; |
776 | BlendFunc::GetShape(mySShape,maxang,NbPoles,NbKnots,Degree,myTConv); |
777 | } |
778 | |
779 | |
780 | //======================================================================= |
781 | //function : GetTolerance |
782 | //purpose : Determine les Tolerances a utiliser dans les approximations. |
783 | //======================================================================= |
784 | void BlendFunc_CSCircular::GetTolerance(const Standard_Real BoundTol, |
785 | const Standard_Real SurfTol, |
786 | const Standard_Real AngleTol, |
787 | math_Vector& Tol3d, |
788 | math_Vector& Tol1d) const |
789 | { |
790 | const Standard_Integer low = Tol3d.Lower(); |
791 | const Standard_Integer up = Tol3d.Upper(); |
792 | const Standard_Real Tol = GeomFill::GetTolerance(myTConv, minang, ray, AngleTol, SurfTol); |
793 | Tol1d.Init(SurfTol); |
794 | Tol3d.Init(SurfTol); |
795 | Tol3d(low+1) = Tol3d(up-1) = Min( Tol, SurfTol); |
796 | Tol3d(low) = Tol3d(up) = Min( Tol, BoundTol); |
797 | } |
798 | |
799 | |
800 | //======================================================================= |
801 | //function : Knots |
802 | //purpose : |
803 | //======================================================================= |
804 | |
805 | void BlendFunc_CSCircular::Knots(TColStd_Array1OfReal& TKnots) |
806 | { |
807 | GeomFill::Knots(myTConv,TKnots); |
808 | } |
809 | |
810 | //======================================================================= |
811 | //function : Mults |
812 | //purpose : |
813 | //======================================================================= |
814 | |
815 | void BlendFunc_CSCircular::Mults(TColStd_Array1OfInteger& TMults) |
816 | { |
817 | GeomFill::Mults(myTConv,TMults); |
818 | } |
819 | |
820 | |
821 | //======================================================================= |
822 | //function : Section |
823 | //purpose : |
824 | //======================================================================= |
825 | |
826 | void BlendFunc_CSCircular::Section(const Blend_Point& P, |
827 | TColgp_Array1OfPnt& Poles, |
828 | TColgp_Array1OfPnt2d& Poles2d, |
829 | TColStd_Array1OfReal& Weights) |
830 | { |
831 | gp_Vec d1u1,d1v1;//,d1; |
832 | gp_Vec ns,ns2;//,temp,np2; |
833 | gp_Pnt Center; |
834 | |
835 | Standard_Real norm,u1,v1; |
836 | |
837 | Standard_Real prm = P.Parameter(); |
838 | Standard_Integer low = Poles.Lower(); |
839 | Standard_Integer upp = Poles.Upper(); |
840 | |
841 | Set(prm); |
842 | |
843 | P.ParametersOnS(u1,v1); |
844 | surf->D1(u1,v1,pts,d1u1,d1v1); |
845 | ptc = curv->Value(prmc); |
846 | |
847 | Poles2d(Poles2d.Lower()).SetCoord(u1,v1); |
848 | |
849 | // Cas Linear |
850 | if (mySShape == BlendFunc_Linear) { |
851 | Poles(low) = pts; |
852 | Poles(upp) = ptc; |
853 | Weights(low) = 1.0; |
854 | Weights(upp) = 1.0; |
855 | return; |
856 | } |
857 | |
858 | ns = d1u1.Crossed(d1v1); |
859 | norm = nplan.Crossed(ns).Magnitude(); |
860 | |
861 | ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns); |
862 | |
863 | Center.SetXYZ(pts.XYZ()+ray*ns.XYZ()); |
864 | |
865 | ns2 = gp_Vec(Center,ptc).Normalized(); |
866 | if(ray > 0.) ns.Reverse(); |
867 | |
868 | if (choix%2 != 0) { |
869 | nplan.Reverse(); |
870 | } |
871 | |
872 | GeomFill::GetCircle(myTConv, |
873 | ns, ns2, |
874 | nplan, pts, ptc, |
875 | Abs(ray), Center, |
876 | Poles, Weights); |
877 | } |
878 | |
879 | |
880 | //======================================================================= |
881 | //function : Section |
882 | //purpose : |
883 | //======================================================================= |
884 | |
885 | Standard_Boolean BlendFunc_CSCircular::Section |
886 | (const Blend_Point& P, |
887 | TColgp_Array1OfPnt& Poles, |
888 | TColgp_Array1OfVec& DPoles, |
889 | TColgp_Array1OfPnt2d& Poles2d, |
890 | TColgp_Array1OfVec2d& DPoles2d, |
891 | TColStd_Array1OfReal& Weights, |
892 | TColStd_Array1OfReal& DWeights) |
893 | { |
894 | gp_Vec d1u1,d1v1,d2u1,d2v1,d2uv1,d1,d2; |
895 | gp_Vec ns,ns2,dnplan,dnw,dn2w; //,np2,dnp2; |
896 | gp_Vec ncrossns;; |
897 | gp_Vec resulu,resulv,temp,tgct,resul; |
898 | |
899 | gp_Pnt Center; |
900 | |
901 | Standard_Real norm,ndotns,grosterme;; |
902 | |
903 | math_Vector sol(1,2),valsol(1,2),secmember(1,2); |
904 | math_Matrix gradsol(1,2,1,2); |
905 | |
906 | Standard_Real prm = P.Parameter(); |
907 | Standard_Integer low = Poles.Lower(); |
908 | Standard_Integer upp = Poles.Upper(); |
909 | Standard_Boolean istgt; |
910 | |
911 | Set(prm); |
912 | dnplan.SetLinearForm(1./normtg,d2gui, |
913 | -1./normtg*(nplan.Dot(d2gui)),nplan); |
914 | |
915 | curv->D2(prmc,ptc,d1,d2); |
916 | P.ParametersOnS(sol(1),sol(2)); |
917 | surf->D2(sol(1),sol(2),pts,d1u1,d1v1,d2u1,d2v1,d2uv1); |
918 | |
919 | ns = d1u1.Crossed(d1v1); |
920 | ncrossns = nplan.Crossed(ns); |
921 | ndotns = nplan.Dot(ns); |
922 | norm = ncrossns.Magnitude(); |
923 | |
924 | ns2.SetLinearForm(ndotns/norm,nplan, -1./norm,ns); |
925 | temp.SetXYZ(pts.XYZ() - ptc.XYZ()); |
926 | |
927 | secmember(1) = dprmc*(nplan.Dot(d1)) - dnplan.Dot(temp); |
928 | |
929 | // Derivee de n1 par rapport a w |
930 | |
931 | grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm; |
932 | dnw.SetLinearForm((dnplan.Dot(ns)-grosterme*ndotns)/norm,nplan, |
933 | ndotns/norm,dnplan, |
934 | grosterme/norm,ns); |
935 | |
936 | temp.SetLinearForm(ray,dnw,-dprmc,d1); |
937 | resul.SetLinearForm(ray,ns2,gp_Vec(ptc,pts)); |
938 | |
939 | secmember(2) = -2.*(resul.Dot(temp)); |
940 | |
941 | Values(sol,valsol,gradsol); |
942 | math_Gauss Resol(gradsol); |
943 | |
944 | if (Resol.IsDone()) { |
945 | |
946 | Resol.Solve(secmember); |
947 | |
948 | tgs.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1); |
949 | tgc = dprmc*d1; |
950 | |
951 | // Derivee de n1 par rapport a u1 |
952 | temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1)); |
953 | grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm; |
954 | resulu.SetLinearForm(-(grosterme*ndotns-nplan.Dot(temp))/norm,nplan, |
955 | grosterme/norm,ns, |
956 | -1./norm,temp); |
957 | |
958 | // Derivee de n1 par rapport a v1 |
959 | temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1)); |
960 | grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm; |
961 | resulv.SetLinearForm(-(grosterme*ndotns-nplan.Dot(temp))/norm,nplan, |
962 | grosterme/norm,ns, |
963 | -1./norm,temp); |
964 | |
965 | |
966 | dnw.SetLinearForm(secmember(1),resulu,secmember(2),resulv,dnw); |
967 | ns = ns2; |
968 | dn2w.SetLinearForm(ray, dnw,-1., tgc, tgs); |
969 | norm = resul.Magnitude(); |
970 | dn2w.Divide(norm); |
971 | ns2 = -resul.Normalized(); |
972 | dn2w.SetLinearForm(ns2.Dot(dn2w),ns2,-1.,dn2w); |
973 | |
974 | istgt = Standard_False; |
975 | } |
976 | else { |
977 | ns.SetLinearForm(ndotns/norm,nplan, -1./norm,ns); |
978 | ns2 = -resul.Normalized(); |
979 | istgt = Standard_True; |
980 | } |
981 | |
982 | // Les poles 2d |
983 | |
984 | Poles2d(Poles2d.Lower()).SetCoord(sol(1),sol(2)); |
985 | if (!istgt) { |
986 | DPoles2d(Poles2d.Lower()).SetCoord(secmember(1),secmember(2)); |
987 | } |
988 | |
989 | if (mySShape == BlendFunc_Linear) { |
990 | Poles(low) = pts; |
991 | Poles(upp) = ptc; |
992 | Weights(low) = 1.0; |
993 | Weights(upp) = 1.0; |
994 | if (!istgt) { |
995 | DPoles(low) = tgs; |
996 | DPoles(upp) = tgc; |
997 | DWeights(low) = 0.0; |
998 | DWeights(upp) = 0.0; |
999 | } |
1000 | return (!istgt); |
1001 | } |
1002 | |
1003 | |
1004 | // Cas du cercle |
1005 | Center.SetXYZ(pts.XYZ()+ray*ns.XYZ()); |
1006 | if (!istgt) { |
1007 | tgct = tgs.Added(ray*dnw); |
1008 | } |
1009 | |
1010 | if(ray > 0.) { |
1011 | ns.Reverse(); |
1012 | if(!istgt) { dnw.Reverse(); } |
1013 | } |
1014 | |
1015 | if (choix%2 != 0) { |
1016 | nplan.Reverse(); |
1017 | dnplan.Reverse(); |
1018 | } |
1019 | |
1020 | if (!istgt) { |
1021 | return GeomFill::GetCircle(myTConv, |
1022 | ns, ns2, |
1023 | dnw, dn2w, |
1024 | nplan, dnplan, |
1025 | pts, ptc, |
1026 | tgs, tgc, |
1027 | Abs(ray), 0, |
1028 | Center, tgct, |
1029 | Poles, |
1030 | DPoles, |
1031 | Weights, |
1032 | DWeights); |
1033 | } |
1034 | else { |
1035 | GeomFill::GetCircle(myTConv, |
1036 | ns, ns2, |
1037 | nplan, pts, ptc, |
1038 | Abs(ray), Center, |
1039 | Poles, Weights); |
1040 | return Standard_False; |
1041 | } |
1042 | } |
1043 | |
1044 | void BlendFunc_CSCircular::Resolution(const Standard_Integer , const Standard_Real Tol, |
1045 | Standard_Real& TolU, Standard_Real& TolV) const |
1046 | { |
1047 | TolU = surf->UResolution(Tol); |
1048 | TolV = surf->VResolution(Tol); |
1049 | } |