0025266: Debug statements in the source are getting flushed on to the console
[occt.git] / src / BlendFunc / BlendFunc_CSCircular.cxx
CommitLineData
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
40BlendFunc_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
58Standard_Integer BlendFunc_CSCircular::NbVariables () const
59{
60 return 2;
61}
62
63
64//=======================================================================
65//function : NbEquations
66//purpose :
67//=======================================================================
68
69Standard_Integer BlendFunc_CSCircular::NbEquations () const
70{
71 return 2;
72}
73
74
75//=======================================================================
76//function : Set
77//purpose :
78//=======================================================================
79
80void 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
101void BlendFunc_CSCircular::Set(const BlendFunc_SectionShape TypeSection)
102{
103 mySShape = TypeSection;
104}
105
106
107//=======================================================================
108//function : Set
109//purpose :
110//=======================================================================
111
112void 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 127void 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
137void 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
149void 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
176Standard_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
266Standard_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
297Standard_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
352Standard_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
410const gp_Pnt& BlendFunc_CSCircular::PointOnS () const
411{
412 return pts;
413}
414
415//=======================================================================
416//function : PointOnC
417//purpose :
418//=======================================================================
419
420const gp_Pnt& BlendFunc_CSCircular::PointOnC () const
421{
422 return ptc;
423}
424
425//=======================================================================
426//function : Pnt2d
427//purpose :
428//=======================================================================
429
430const gp_Pnt2d& BlendFunc_CSCircular::Pnt2d () const
431{
432 return pt2d;
433}
434
435//=======================================================================
436//function : ParameterOnC
437//purpose :
438//=======================================================================
439
440Standard_Real BlendFunc_CSCircular::ParameterOnC () const
441{
442 return prmc;
443}
444
445
446//=======================================================================
447//function : IsTangencyPoint
448//purpose :
449//=======================================================================
450
451Standard_Boolean BlendFunc_CSCircular::IsTangencyPoint () const
452{
453 return istangent;
454}
455
456//=======================================================================
457//function : TangentOnS
458//purpose :
459//=======================================================================
460
461const 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
473const 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
485const 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
498void 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
520void 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
560Standard_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
579Standard_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
719Standard_Boolean BlendFunc_CSCircular::IsRational() const
720{
721 return (mySShape==BlendFunc_Rational || mySShape==BlendFunc_QuasiAngular);
722}
723
724//=======================================================================
725//function : GetSectionSize
726//purpose :
727//=======================================================================
728
729Standard_Real BlendFunc_CSCircular::GetSectionSize() const
730{
731 return maxang*Abs(ray);
732}
733
734//=======================================================================
735//function : GetMinimalWeight
736//purpose :
737//=======================================================================
738void 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
749Standard_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
760void 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
770void 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//=======================================================================
784void 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
805void BlendFunc_CSCircular::Knots(TColStd_Array1OfReal& TKnots)
806{
807 GeomFill::Knots(myTConv,TKnots);
808}
809
810//=======================================================================
811//function : Mults
812//purpose :
813//=======================================================================
814
815void BlendFunc_CSCircular::Mults(TColStd_Array1OfInteger& TMults)
816{
817 GeomFill::Mults(myTConv,TMults);
818}
819
820
821//=======================================================================
822//function : Section
823//purpose :
824//=======================================================================
825
826void 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
885Standard_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
1044void 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}