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