1 // Created on: 1995-01-04
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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.
21 #include <BlendFunc_CSCircular.ixx>
23 #include <math_Gauss.hxx>
27 #include <BlendFunc.hxx>
28 #include <GeomFill.hxx>
29 #include <Standard_NotImplemented.hxx>
30 #include <Standard_DomainError.hxx>
31 #include <Precision.hxx>
35 //=======================================================================
36 //function : BlendFunc_CSCircular
38 //=======================================================================
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) :
44 surf(S),curv(C),guide(CGuide),law(L),istangent(Standard_True),
45 //prmc, dprmc, istangent, ray, choix, normtg,
46 maxang(RealFirst()),minang(RealLast()),mySShape(BlendFunc_Rational)
53 //=======================================================================
54 //function : NbVariables
56 //=======================================================================
58 Standard_Integer BlendFunc_CSCircular::NbVariables () const
64 //=======================================================================
65 //function : NbEquations
67 //=======================================================================
69 Standard_Integer BlendFunc_CSCircular::NbEquations () const
75 //=======================================================================
78 //=======================================================================
80 void BlendFunc_CSCircular::Set(const Standard_Real Radius, const Standard_Integer Choix)
96 //=======================================================================
99 //=======================================================================
101 void BlendFunc_CSCircular::Set(const BlendFunc_SectionShape TypeSection)
103 mySShape = TypeSection;
107 //=======================================================================
110 //=======================================================================
112 void BlendFunc_CSCircular::Set(const Standard_Real Param)
115 guide->D2(Param,ptgui,d1gui,d2gui);
116 law->D1(Param,prmc,dprmc);
118 normtg = d1gui.Magnitude();
119 nplan = d1gui.Normalized();
122 //=======================================================================
125 //=======================================================================
127 void BlendFunc_CSCircular::Set(const Standard_Real, const Standard_Real)
129 Standard_NotImplemented::Raise("BlendFunc_CSCircular::Set");
132 //=======================================================================
133 //function : GetTolerance
135 //=======================================================================
137 void BlendFunc_CSCircular::GetTolerance(math_Vector& Tolerance, const Standard_Real Tol) const
139 Tolerance(1) = surf->UResolution(Tol);
140 Tolerance(2) = surf->VResolution(Tol);
144 //=======================================================================
145 //function : GetBounds
147 //=======================================================================
149 void BlendFunc_CSCircular::GetBounds(math_Vector& InfBound, math_Vector& SupBound) const
151 InfBound(1) = surf->FirstUParameter();
152 InfBound(2) = surf->FirstVParameter();
153 SupBound(1) = surf->LastUParameter();
154 SupBound(2) = surf->LastVParameter();
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;
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;
171 //=======================================================================
172 //function : IsSolution
174 //=======================================================================
176 Standard_Boolean BlendFunc_CSCircular::IsSolution(const math_Vector& Sol, const Standard_Real Tol)
178 math_Vector valsol(1,2),secmember(1,2);
179 math_Matrix gradsol(1,2,1,2);
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;
185 Values(Sol,valsol,gradsol);
187 if (Abs(valsol(1)) <= Tol &&
188 Abs(valsol(2)) <= Tol*Tol) {
190 // Calcul des tangentes
192 pt2d = gp_Pnt2d(Sol(1),Sol(2));
194 surf->D1(Sol(1),Sol(2),pts,d1u1,d1v1);
195 curv->D2(prmc,ptc,d1c,d2c);
197 dnplan.SetLinearForm(1./normtg,d2gui,
198 -1./normtg*(nplan.Dot(d2gui)),nplan);
200 ns = d1u1.Crossed(d1v1);
201 ncrossns = nplan.Crossed(ns);
202 ndotns = nplan.Dot(ns);
203 norm = ncrossns.Magnitude();
207 // cout << "CSCircular : Surface singuliere !" << endl;
211 temp.SetXYZ(pts.XYZ() - ptc.XYZ());
212 secmember(1) = dprmc*(nplan.Dot(d1c)) - dnplan.Dot(temp);
214 grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm;
215 temp.SetLinearForm(ray/norm*(dnplan.Dot(ns)-grosterme*ndotns),nplan,
216 ray*ndotns/norm,dnplan,
217 ray*grosterme/norm,ns);
220 ns.SetLinearForm(ndotns/norm,nplan, -1./norm,ns);
221 resul.SetLinearForm(ray,ns,gp_Vec(ptc,pts));
223 secmember(2) = -2.*(resul.Dot(temp));
225 math_Gauss Resol(gradsol);
226 if (Resol.IsDone()) {
228 Resol.Solve(secmember);
230 tgs.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1);
232 tg2d.SetCoord(secmember(1),secmember(2));
233 istangent = Standard_False;
236 istangent = Standard_True;
238 // mise a jour de maxang
240 if(ray > 0.) ns.Reverse();
241 nc = -resul.Normalized();
244 Sina = nplan.Dot(ns.Crossed(nc));
246 Sina = -Sina; //nplan est change en -nplan
251 Angle = 2.*M_PI - Angle;
254 if (Angle>maxang) {maxang = Angle;}
255 if (Angle<minang) {minang = Angle;}
257 return Standard_True;
259 istangent = Standard_True;
260 return Standard_False;
264 //=======================================================================
267 //=======================================================================
269 Standard_Boolean BlendFunc_CSCircular::Value(const math_Vector& X, math_Vector& F)
271 gp_Vec d1u1,d1v1,d1c;
273 surf->D1(X(1),X(2),pts,d1u1,d1v1);
274 curv->D1(prmc,ptc,d1c);
276 F(1) = nplan.XYZ().Dot(pts.XYZ()-ptc.XYZ());
278 gp_Vec ns = d1u1.Crossed(d1v1);
279 Standard_Real norm = nplan.Crossed(ns).Magnitude();
283 // cout << "CSCircular : Surface singuliere !" << endl;
287 ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns);
289 vref.SetLinearForm(ray,ns,gp_Vec(ptc,pts));
291 F(2) = vref.SquareMagnitude() - ray*ray;
293 pt2d = gp_Pnt2d(X(1),X(2));
294 return Standard_True;
298 //=======================================================================
299 //function : Derivatives
301 //=======================================================================
303 Standard_Boolean BlendFunc_CSCircular::Derivatives(const math_Vector& X, math_Matrix& D)
305 gp_Vec d1u1,d1v1,d2u1,d2v1,d2uv1,d1c;
306 gp_Vec ns,ncrossns,resul,temp,nsov,vref;
308 Standard_Real norm,ndotns,grosterme;
310 surf->D2(X(1),X(2),pts,d1u1,d1v1,d2u1,d2v1,d2uv1);
311 curv->D1(prmc,ptc,d1c);
313 D(1,1) = nplan.Dot(d1u1);
314 D(1,2) = nplan.Dot(d1v1);
316 ns = d1u1.Crossed(d1v1);
317 ncrossns = nplan.Crossed(ns);
318 norm = ncrossns.Magnitude();
322 // cout << "CSCircular : Surface singuliere !" << endl;
326 ndotns = nplan.Dot(ns);
328 nsov.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns);
329 vref.SetLinearForm(ray,nsov,gp_Vec(ptc,pts));
331 // Derivee par rapport a u de Ps + ray*ns
332 temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
333 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
334 resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan,
335 ray*grosterme/norm,ns,
339 D(2,1) = 2.*(resul.Dot(vref));
341 // Derivee par rapport a v
342 temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
343 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
344 resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan,
345 ray*grosterme/norm,ns,
349 D(2,2) = 2.*(resul.Dot(vref));
351 pt2d = gp_Pnt2d(X(1),X(2));
352 return Standard_True;
356 //=======================================================================
359 //=======================================================================
361 Standard_Boolean BlendFunc_CSCircular::Values(const math_Vector& X, math_Vector& F, math_Matrix& D)
363 gp_Vec d1u1,d1v1,d1c;
364 gp_Vec d2u1,d2v1,d2uv1;
365 gp_Vec ns,ncrossns,resul,temp,vref,nsov;
367 Standard_Real norm,ndotns,grosterme;
369 surf->D2(X(1),X(2),pts,d1u1,d1v1,d2u1,d2v1,d2uv1);
370 curv->D1(prmc,ptc,d1c);
372 ns = d1u1.Crossed(d1v1);
373 ncrossns = nplan.Crossed(ns);
374 norm = ncrossns.Magnitude();
378 // cout << "CSCircular : Surface singuliere !" << endl;
382 ndotns = nplan.Dot(ns);
383 nsov.SetLinearForm(ndotns/norm,nplan,-1./norm,ns);
384 vref.SetLinearForm(ray,nsov,gp_Vec(ptc,pts));
386 F(1) = nplan.XYZ().Dot(pts.XYZ()-ptc.XYZ());
387 F(2) = vref.SquareMagnitude() - ray*ray;
389 D(1,1) = nplan.Dot(d1u1);
390 D(1,2) = nplan.Dot(d1v1);
392 // Derivee par rapport a u
393 temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
394 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
395 resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan,
396 ray*grosterme/norm,ns,
400 D(2,1) = 2.*(resul.Dot(vref));
402 // Derivee par rapport a v
403 temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
404 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
405 resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan,
406 ray*grosterme/norm,ns,
410 D(2,2) = 2.*(resul.Dot(vref));
412 pt2d = gp_Pnt2d(X(1),X(2));
413 return Standard_True;
417 //=======================================================================
418 //function : PointOnS
420 //=======================================================================
422 const gp_Pnt& BlendFunc_CSCircular::PointOnS () const
427 //=======================================================================
428 //function : PointOnC
430 //=======================================================================
432 const gp_Pnt& BlendFunc_CSCircular::PointOnC () const
437 //=======================================================================
440 //=======================================================================
442 const gp_Pnt2d& BlendFunc_CSCircular::Pnt2d () const
447 //=======================================================================
448 //function : ParameterOnC
450 //=======================================================================
452 Standard_Real BlendFunc_CSCircular::ParameterOnC () const
458 //=======================================================================
459 //function : IsTangencyPoint
461 //=======================================================================
463 Standard_Boolean BlendFunc_CSCircular::IsTangencyPoint () const
468 //=======================================================================
469 //function : TangentOnS
471 //=======================================================================
473 const gp_Vec& BlendFunc_CSCircular::TangentOnS () const
476 Standard_DomainError::Raise("BlendFunc_CSCircular::TangentOnS");
480 //=======================================================================
481 //function : TangentOnC
483 //=======================================================================
485 const gp_Vec& BlendFunc_CSCircular::TangentOnC () const
488 Standard_DomainError::Raise("BlendFunc_CSCircular::TangentOnC");
492 //=======================================================================
493 //function : Tangent2d
495 //=======================================================================
497 const gp_Vec2d& BlendFunc_CSCircular::Tangent2d () const
500 Standard_DomainError::Raise("BlendFunc_CSCircular::Tangent2d");
505 //=======================================================================
508 //=======================================================================
510 void BlendFunc_CSCircular::Tangent(const Standard_Real U, const Standard_Real V,
511 gp_Vec& TgS, gp_Vec& NmS) const
515 surf->D1(U,V,bid,d1u,d1v);
516 NmS = ns = d1u.Crossed(d1v);
518 const Standard_Real norm = nplan.Crossed(ns).Magnitude();
519 ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns);
520 if(ray > 0.) ns.Reverse();
521 TgS = nplan.Crossed(ns);
527 //=======================================================================
530 //=======================================================================
532 void BlendFunc_CSCircular::Section(const Standard_Real Param,
533 const Standard_Real U,
534 const Standard_Real V,
535 const Standard_Real W,
546 guide->D1(Param,ptgui,d1gui);
547 nplan = d1gui.Normalized();
549 surf->D1(U,V,pts,d1u1,d1v1);
550 ptc = curv->Value(W);
552 ns = d1u1.Crossed(d1v1);
553 norm = nplan.Crossed(ns).Magnitude();
554 ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns);
556 Center.SetXYZ(pts.XYZ()+ray*ns.XYZ());
557 C.SetRadius(Abs(ray));
559 if(ray > 0.) ns.Reverse();
562 C.SetPosition(gp_Ax2(Center,nplan,ns));
565 C.SetPosition(gp_Ax2(Center,nplan.Reversed(),ns));
568 Pfin = ElCLib::Parameter(C,ptc);
572 Standard_Boolean BlendFunc_CSCircular::Section(const Blend_Point& P,
573 TColgp_Array1OfPnt& Poles,
574 TColgp_Array1OfVec& DPoles,
575 TColgp_Array1OfVec& D2Poles,
576 TColgp_Array1OfPnt2d& Poles2d,
577 TColgp_Array1OfVec2d& DPoles2d,
578 TColgp_Array1OfVec2d& D2Poles2d,
579 TColStd_Array1OfReal& Weigths,
580 TColStd_Array1OfReal& DWeigths,
581 TColStd_Array1OfReal& D2Weigths)
583 return Blend_CSFunction::Section(P,Poles,DPoles,D2Poles,Poles2d,DPoles2d,D2Poles2d,Weigths,DWeigths,D2Weigths);
586 //=======================================================================
587 //function : GetSection
589 //=======================================================================
591 Standard_Boolean BlendFunc_CSCircular::GetSection(const Standard_Real Param,
592 const Standard_Real U,
593 const Standard_Real V,
594 const Standard_Real /*W*/,
595 TColgp_Array1OfPnt& tabP,
596 TColgp_Array1OfVec& tabV)
598 Standard_Integer NbPoint=tabP.Length();
599 if (NbPoint != tabV.Length() || NbPoint < 2) {Standard_RangeError::Raise();}
601 Standard_Integer i, lowp = tabP.Lower(), lowv = tabV.Lower();
603 gp_Vec d1u1,d1v1,d2u1,d2v1,d2uv1,d1c,d2c; //,d1u2,d1v2;
604 gp_Vec ns,dnplan,dnw,dn2w,ncrn,dncrn,ns2;
605 gp_Vec ncrossns,resul;
606 gp_Vec resulu,resulv,temp;
608 Standard_Real norm,ndotns,grosterme;
609 Standard_Real lambda,Cosa,Sina;
610 Standard_Real Angle = 0.,Dangle = 0.;
611 math_Vector sol(1,2),valsol(1,2),secmember(1,2);
612 math_Matrix gradsol(1,2,1,2);
615 dnplan.SetLinearForm(1./normtg,d2gui,
616 -1./normtg*(nplan.Dot(d2gui)),nplan);
618 curv->D2(prmc,ptc,d1c,d2c);
619 surf->D2(U,V,pts,d1u1,d1v1,d2u1,d2v1,d2uv1);
621 ns = d1u1.Crossed(d1v1);
622 ncrossns = nplan.Crossed(ns);
623 ndotns = nplan.Dot(ns);
624 norm = ncrossns.Magnitude();
626 temp.SetXYZ(pts.XYZ() - ptc.XYZ());
627 secmember(1) = dprmc*(nplan.Dot(d1c)) - dnplan.Dot(temp);
629 ns2.SetLinearForm(ndotns/norm,nplan, -1./norm,ns);
631 // Derivee de n1 par rapport a w (param sur ligne guide)
633 grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm;
634 dnw.SetLinearForm((dnplan.Dot(ns)-grosterme*ndotns)/norm,nplan,
638 temp.SetLinearForm(ray,dnw,-dprmc,d1c);
639 resul.SetLinearForm(ray,ns2,gp_Vec(ptc,pts));
641 secmember(2) = -2.*(resul.Dot(temp));
643 sol(1) = U; sol(2) = V;
644 Values(sol,valsol,gradsol);
645 math_Gauss Resol(gradsol);
647 if (Resol.IsDone()) {
649 Resol.Solve(secmember);
651 tgs.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1);
654 // Derivee de n1 par rapport a u1
655 temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
656 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
657 resulu.SetLinearForm(-(grosterme*ndotns-nplan.Dot(temp))/norm,nplan,
661 // Derivee de n1 par rapport a v1
662 temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
663 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
664 resulv.SetLinearForm(-(grosterme*ndotns-nplan.Dot(temp))/norm,nplan,
669 dnw.SetLinearForm(secmember(1),resulu,secmember(2),resulv,dnw);
671 dn2w.SetLinearForm(ray, dnw, -1., tgc, tgs);
672 norm = resul.Magnitude();
674 ns2 = -resul.Normalized();
675 dn2w.SetLinearForm(ns2.Dot(dn2w),ns2,-1.,dn2w);
689 tabP(lowp+NbPoint-1) = ptc;
692 tabV(lowv+NbPoint-1) = tgc;
697 Sina = nplan.Dot(ns.Crossed(ns2));
700 Angle = 2.*M_PI - Angle;
702 Dangle = -(dnw.Dot(ns2) + ns.Dot(dn2w))/Sina;
703 ncrn = nplan.Crossed(ns);
704 dncrn = dnplan.Crossed(ns).Added(nplan.Crossed(dnw));
707 for (i=2; i <= NbPoint-1; i++) {
708 lambda = (Standard_Real)(i-1)/(Standard_Real)(NbPoint-1);
709 Cosa = Cos(lambda*Angle);
710 Sina = Sin(lambda*Angle);
711 tabP(lowp+i-1).SetXYZ(pts.XYZ()
712 +Abs(ray)*((Cosa-1)*ns.XYZ() + Sina*ncrn.XYZ()));
714 temp.SetLinearForm(-Sina,ns,Cosa,ncrn);
715 temp.Multiply(lambda*Dangle);
716 temp.Add(((Cosa-1)*dnw).Added(Sina*dncrn));
717 temp.Multiply(Abs(ray));
719 tabV(lowv+i-1)= temp;
721 return Standard_True;
723 return Standard_False;
726 //=======================================================================
727 //function : IsRational
729 //=======================================================================
731 Standard_Boolean BlendFunc_CSCircular::IsRational() const
733 return (mySShape==BlendFunc_Rational || mySShape==BlendFunc_QuasiAngular);
736 //=======================================================================
737 //function : GetSectionSize
739 //=======================================================================
741 Standard_Real BlendFunc_CSCircular::GetSectionSize() const
743 return maxang*Abs(ray);
746 //=======================================================================
747 //function : GetMinimalWeight
749 //=======================================================================
750 void BlendFunc_CSCircular::GetMinimalWeight(TColStd_Array1OfReal& Weigths) const
752 BlendFunc::GetMinimalWeights(mySShape, myTConv,minang,maxang,Weigths);
753 // On suppose que cela ne depend pas du Rayon!
756 //=======================================================================
757 //function : NbIntervals
759 //=======================================================================
761 Standard_Integer BlendFunc_CSCircular::NbIntervals (const GeomAbs_Shape S) const
763 return curv->NbIntervals(BlendFunc::NextShape(S));
767 //=======================================================================
768 //function : Intervals
770 //=======================================================================
772 void BlendFunc_CSCircular::Intervals (TColStd_Array1OfReal& T, const GeomAbs_Shape S) const
774 curv->Intervals(T, BlendFunc::NextShape(S));
777 //=======================================================================
778 //function : GetShape
780 //=======================================================================
782 void BlendFunc_CSCircular::GetShape (Standard_Integer& NbPoles,
783 Standard_Integer& NbKnots,
784 Standard_Integer& Degree,
785 Standard_Integer& NbPoles2d)
788 BlendFunc::GetShape(mySShape,maxang,NbPoles,NbKnots,Degree,myTConv);
792 //=======================================================================
793 //function : GetTolerance
794 //purpose : Determine les Tolerances a utiliser dans les approximations.
795 //=======================================================================
796 void BlendFunc_CSCircular::GetTolerance(const Standard_Real BoundTol,
797 const Standard_Real SurfTol,
798 const Standard_Real AngleTol,
800 math_Vector& Tol1d) const
802 const Standard_Integer low = Tol3d.Lower();
803 const Standard_Integer up = Tol3d.Upper();
804 const Standard_Real Tol = GeomFill::GetTolerance(myTConv, minang, ray, AngleTol, SurfTol);
807 Tol3d(low+1) = Tol3d(up-1) = Min( Tol, SurfTol);
808 Tol3d(low) = Tol3d(up) = Min( Tol, BoundTol);
812 //=======================================================================
815 //=======================================================================
817 void BlendFunc_CSCircular::Knots(TColStd_Array1OfReal& TKnots)
819 GeomFill::Knots(myTConv,TKnots);
822 //=======================================================================
825 //=======================================================================
827 void BlendFunc_CSCircular::Mults(TColStd_Array1OfInteger& TMults)
829 GeomFill::Mults(myTConv,TMults);
833 //=======================================================================
836 //=======================================================================
838 void BlendFunc_CSCircular::Section(const Blend_Point& P,
839 TColgp_Array1OfPnt& Poles,
840 TColgp_Array1OfPnt2d& Poles2d,
841 TColStd_Array1OfReal& Weights)
843 gp_Vec d1u1,d1v1;//,d1;
844 gp_Vec ns,ns2;//,temp,np2;
847 Standard_Real norm,u1,v1;
849 Standard_Real prm = P.Parameter();
850 Standard_Integer low = Poles.Lower();
851 Standard_Integer upp = Poles.Upper();
855 P.ParametersOnS(u1,v1);
856 surf->D1(u1,v1,pts,d1u1,d1v1);
857 ptc = curv->Value(prmc);
859 Poles2d(Poles2d.Lower()).SetCoord(u1,v1);
862 if (mySShape == BlendFunc_Linear) {
870 ns = d1u1.Crossed(d1v1);
871 norm = nplan.Crossed(ns).Magnitude();
873 ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns);
875 Center.SetXYZ(pts.XYZ()+ray*ns.XYZ());
877 ns2 = gp_Vec(Center,ptc).Normalized();
878 if(ray > 0.) ns.Reverse();
884 GeomFill::GetCircle(myTConv,
892 //=======================================================================
895 //=======================================================================
897 Standard_Boolean BlendFunc_CSCircular::Section
898 (const Blend_Point& P,
899 TColgp_Array1OfPnt& Poles,
900 TColgp_Array1OfVec& DPoles,
901 TColgp_Array1OfPnt2d& Poles2d,
902 TColgp_Array1OfVec2d& DPoles2d,
903 TColStd_Array1OfReal& Weights,
904 TColStd_Array1OfReal& DWeights)
906 gp_Vec d1u1,d1v1,d2u1,d2v1,d2uv1,d1,d2;
907 gp_Vec ns,ns2,dnplan,dnw,dn2w; //,np2,dnp2;
909 gp_Vec resulu,resulv,temp,tgct,resul;
913 Standard_Real norm,ndotns,grosterme;;
915 math_Vector sol(1,2),valsol(1,2),secmember(1,2);
916 math_Matrix gradsol(1,2,1,2);
918 Standard_Real prm = P.Parameter();
919 Standard_Integer low = Poles.Lower();
920 Standard_Integer upp = Poles.Upper();
921 Standard_Boolean istgt;
924 dnplan.SetLinearForm(1./normtg,d2gui,
925 -1./normtg*(nplan.Dot(d2gui)),nplan);
927 curv->D2(prmc,ptc,d1,d2);
928 P.ParametersOnS(sol(1),sol(2));
929 surf->D2(sol(1),sol(2),pts,d1u1,d1v1,d2u1,d2v1,d2uv1);
931 ns = d1u1.Crossed(d1v1);
932 ncrossns = nplan.Crossed(ns);
933 ndotns = nplan.Dot(ns);
934 norm = ncrossns.Magnitude();
936 ns2.SetLinearForm(ndotns/norm,nplan, -1./norm,ns);
937 temp.SetXYZ(pts.XYZ() - ptc.XYZ());
939 secmember(1) = dprmc*(nplan.Dot(d1)) - dnplan.Dot(temp);
941 // Derivee de n1 par rapport a w
943 grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm;
944 dnw.SetLinearForm((dnplan.Dot(ns)-grosterme*ndotns)/norm,nplan,
948 temp.SetLinearForm(ray,dnw,-dprmc,d1);
949 resul.SetLinearForm(ray,ns2,gp_Vec(ptc,pts));
951 secmember(2) = -2.*(resul.Dot(temp));
953 Values(sol,valsol,gradsol);
954 math_Gauss Resol(gradsol);
956 if (Resol.IsDone()) {
958 Resol.Solve(secmember);
960 tgs.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1);
963 // Derivee de n1 par rapport a u1
964 temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
965 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
966 resulu.SetLinearForm(-(grosterme*ndotns-nplan.Dot(temp))/norm,nplan,
970 // Derivee de n1 par rapport a v1
971 temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
972 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
973 resulv.SetLinearForm(-(grosterme*ndotns-nplan.Dot(temp))/norm,nplan,
978 dnw.SetLinearForm(secmember(1),resulu,secmember(2),resulv,dnw);
980 dn2w.SetLinearForm(ray, dnw,-1., tgc, tgs);
981 norm = resul.Magnitude();
983 ns2 = -resul.Normalized();
984 dn2w.SetLinearForm(ns2.Dot(dn2w),ns2,-1.,dn2w);
986 istgt = Standard_False;
989 ns.SetLinearForm(ndotns/norm,nplan, -1./norm,ns);
990 ns2 = -resul.Normalized();
991 istgt = Standard_True;
996 Poles2d(Poles2d.Lower()).SetCoord(sol(1),sol(2));
998 DPoles2d(Poles2d.Lower()).SetCoord(secmember(1),secmember(2));
1001 if (mySShape == BlendFunc_Linear) {
1009 DWeights(low) = 0.0;
1010 DWeights(upp) = 0.0;
1017 Center.SetXYZ(pts.XYZ()+ray*ns.XYZ());
1019 tgct = tgs.Added(ray*dnw);
1024 if(!istgt) { dnw.Reverse(); }
1033 return GeomFill::GetCircle(myTConv,
1047 GeomFill::GetCircle(myTConv,
1052 return Standard_False;
1056 void BlendFunc_CSCircular::Resolution(const Standard_Integer , const Standard_Real Tol,
1057 Standard_Real& TolU, Standard_Real& TolV) const
1059 TolU = surf->UResolution(Tol);
1060 TolV = surf->VResolution(Tol);