1 // Created on: 1997-07-28
2 // Created by: Jerome LEMONIER
3 // Copyright (c) 1997-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 #include <BRepBlend_SurfRstEvolRad.ixx>
18 #include <math_Gauss.hxx>
19 #include <math_SVD.hxx>
23 #include <BlendFunc.hxx>
24 #include <GeomFill.hxx>
25 #include <TColStd_SequenceOfReal.hxx>
26 #include <Standard_DomainError.hxx>
27 #include <Standard_NotImplemented.hxx>
28 #include <Precision.hxx>
32 static void t3dto2d(Standard_Real& a,
38 Standard_Real AB = A.Dot(B);
39 Standard_Real AC = A.Dot(C);
40 Standard_Real BC = B.Dot(C);
41 Standard_Real BB = B.Dot(B);
42 Standard_Real CC = C.Dot(C);
43 Standard_Real deno = (BB*CC-BC*BC);
44 a = (AB*CC-AC*BC)/deno;
45 b = (AC*BB-AB*BC)/deno;
48 static void FusionneIntervalles(const TColStd_Array1OfReal& I1,
49 const TColStd_Array1OfReal& I2,
50 TColStd_SequenceOfReal& Seq)
52 Standard_Integer ind1=1, ind2=1;
53 Standard_Real Epspar = Precision::PConfusion()*0.99;
54 // it is supposed that positioning works with PConfusion()/2
56 // Initialisation : IND1 and IND2 point at the first element
57 // of each of 2 tables to be processed. INDS points at the last
58 // element created by TABSOR
61 //--- TABSOR is filled by parsing TABLE1 and TABLE2 simultaneously ---
62 //------------------ and eliminating multiple occurrencies ------------
64 while ((ind1<=I1.Upper()) && (ind2<=I2.Upper())) {
67 if (Abs(v1-v2)<= Epspar) {
68 // Here the elements of I1 and I2 fit.
69 Seq.Append((v1+v2)/2);
74 // Here the element of I1 fits.
79 // Here the element of TABLE2 fits.
85 if (ind1>I1.Upper()) {
86 //----- Here I1 is exhausted, completed with the end of TABLE2 -------
88 for (; ind2<=I2.Upper(); ind2++) {
93 if (ind2>I2.Upper()) {
94 //----- Here I2 is exhausted, completed with the end of I1 -------
96 for (; ind1<=I1.Upper(); ind1++) {
102 //=======================================================================
103 //function : BRepBlend_SurfRstEvolRad
104 //purpose : Contructor
105 //=======================================================================
106 BRepBlend_SurfRstEvolRad::BRepBlend_SurfRstEvolRad
107 (const Handle(Adaptor3d_HSurface)& Surf,
108 const Handle(Adaptor3d_HSurface)& SurfRst,
109 const Handle(Adaptor2d_HCurve2d)& Rst,
110 const Handle(Adaptor3d_HCurve)& CGuide,
111 const Handle(Law_Function)& Evol):
112 surf(Surf), surfrst(SurfRst),
113 rst(Rst), cons(Rst,SurfRst),
114 guide(CGuide), tguide(CGuide),
115 istangent(Standard_True),
116 maxang(RealFirst()), minang(RealLast()),
118 mySShape(BlendFunc_Rational)
124 //=======================================================================
127 //=======================================================================
128 Standard_Integer BRepBlend_SurfRstEvolRad::NbVariables() const
133 //=======================================================================
136 //=======================================================================
137 Standard_Integer BRepBlend_SurfRstEvolRad::NbEquations() const
142 //=======================================================================
145 //=======================================================================
146 Standard_Boolean BRepBlend_SurfRstEvolRad::Value
147 (const math_Vector& X,
150 gp_Vec d1u1,d1v1,ns,vref;
153 surf->D1(X(1),X(2),pts,d1u1,d1v1);
154 ptrst = cons.Value(X(3));
156 F(1) = nplan.XYZ().Dot(pts.XYZ()) + theD;
158 F(2) = nplan.XYZ().Dot(ptrst.XYZ()) + theD;
160 ns = d1u1.Crossed(d1v1);
161 norm = nplan.Crossed(ns).Magnitude();
162 ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns);
163 vref.SetLinearForm(ray,ns,gp_Vec(ptrst,pts));
164 F(3) = vref.SquareMagnitude() - ray*ray;
165 return Standard_True;
168 //=======================================================================
169 //function : Derivatives
171 //=======================================================================
172 Standard_Boolean BRepBlend_SurfRstEvolRad::Derivatives
173 (const math_Vector& X,
175 { gp_Vec d1u1,d1v1,d2u1,d2v1,d2uv1,d1;
176 gp_Vec ns,ncrossns,resul,temp, vref;
178 Standard_Real norm,ndotns,grosterme;
180 surf->D2(X(1),X(2),pts,d1u1,d1v1,d2u1,d2v1,d2uv1);
181 cons.D1(X(3),ptrst,d1);
183 D(1,1) = nplan.Dot(d1u1);
184 D(1,2) = nplan.Dot(d1v1);
189 D(2,3) = nplan.Dot(d1);
192 ns = d1u1.Crossed(d1v1);
193 ncrossns = nplan.Crossed(ns);
194 norm = ncrossns.Magnitude();
195 ndotns = nplan.Dot(ns);
197 vref.SetLinearForm(ndotns,nplan,-1.,ns);
199 vref.SetLinearForm(ray,vref,gp_Vec(ptrst,pts));
201 // Derivative corresponding to u1
202 temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
203 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
204 resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan,
205 ray*grosterme/norm,ns,
209 D(3,1) = 2.*(resul.Dot(vref));
212 // Derivative corresponding to v1
213 temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
214 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
215 resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan,
216 ray*grosterme/norm,ns,
220 D(3,2) = 2.*(resul.Dot(vref));
222 D(3,3) = -2.*(d1.Dot(vref));
224 return Standard_True;
228 //=======================================================================
231 //=======================================================================
232 Standard_Boolean BRepBlend_SurfRstEvolRad::Values
233 (const math_Vector& X,
238 gp_Vec d2u1,d2v1,d2uv1;
239 gp_Vec ns,ncrossns,resul,temp,vref;
241 Standard_Real norm,ndotns,grosterme;
243 surf->D2(X(1),X(2),pts,d1u1,d1v1,d2u1,d2v1,d2uv1);
244 cons.D1(X(3),ptrst,d1);
246 F(1) = nplan.XYZ().Dot(pts.XYZ()) + theD;
247 F(2) = nplan.XYZ().Dot(ptrst.XYZ()) + theD;
249 D(1,1) = nplan.Dot(d1u1);
250 D(1,2) = nplan.Dot(d1v1);
255 D(2,3) = nplan.Dot(d1);
258 ns = d1u1.Crossed(d1v1);
259 ncrossns = nplan.Crossed(ns);
260 norm = ncrossns.Magnitude();
261 ndotns = nplan.Dot(ns);
263 vref.SetLinearForm(ndotns,nplan,-1.,ns);
265 vref.SetLinearForm(ray,vref,gp_Vec(ptrst,pts));
267 F(3) = vref.SquareMagnitude() - ray*ray;
270 // Derivative corresponding to u1
271 temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
272 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
273 resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan,
274 ray*grosterme/norm,ns,
278 D(3,1) = 2.*(resul.Dot(vref));
281 // Derivative corresponding to v1
282 temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
283 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
284 resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan,
285 ray*grosterme/norm,ns,
289 D(3,2) = 2.*(resul.Dot(vref));
291 D(3,3) = -2.*(d1.Dot(vref));
293 return Standard_True;
296 //=======================================================================
299 //=======================================================================
300 void BRepBlend_SurfRstEvolRad::Set
301 (const Handle(Adaptor3d_HSurface)& SurfRef,
302 const Handle(Adaptor2d_HCurve2d)& RstRef)
308 //=======================================================================
311 //=======================================================================
312 void BRepBlend_SurfRstEvolRad::Set(const Standard_Real Param)
314 d1gui = gp_Vec(0.,0.,0.);
315 nplan = gp_Vec(0.,0.,0.);
316 tguide->D2(Param,ptgui,d1gui,d2gui);
317 normtg = d1gui.Magnitude();
318 nplan.SetXYZ(d1gui.Normalized().XYZ());
319 gp_XYZ nplanXYZ(nplan.XYZ());
320 gp_XYZ ptguiXYZ(ptgui.XYZ());
321 theD = nplanXYZ.Dot(ptguiXYZ) ;
322 theD = theD * (-1.) ;
323 tevol->D1(Param,ray,dray);
328 //=======================================================================
330 //purpose : Segments the curve in its useful part.
331 // Precision is taken arbitrary small !?
332 //=======================================================================
333 void BRepBlend_SurfRstEvolRad::Set
334 (const Standard_Real First,
335 const Standard_Real Last)
337 tguide = guide->Trim(First,Last,1.e-12);
338 tevol = fevol->Trim(First,Last,1.e-12);
341 //=======================================================================
344 //=======================================================================
345 void BRepBlend_SurfRstEvolRad::GetTolerance
346 (math_Vector& Tolerance,
347 const Standard_Real Tol) const
349 Tolerance(1) = surf->UResolution(Tol);
350 Tolerance(2) = surf->VResolution(Tol);
351 Tolerance(3) = cons.Resolution(Tol);
354 //=======================================================================
357 //=======================================================================
358 void BRepBlend_SurfRstEvolRad::GetBounds
359 (math_Vector& InfBound,
360 math_Vector& SupBound) const
362 InfBound(1) = surf->FirstUParameter();
363 InfBound(2) = surf->FirstVParameter();
364 InfBound(3) = cons.FirstParameter();
365 SupBound(1) = surf->LastUParameter();
366 SupBound(2) = surf->LastVParameter();
367 SupBound(3) = cons.LastParameter();
369 if(!Precision::IsInfinite(InfBound(1)) &&
370 !Precision::IsInfinite(SupBound(1))) {
371 Standard_Real range = (SupBound(1) - InfBound(1));
372 InfBound(1) -= range;
373 SupBound(1) += range;
375 if(!Precision::IsInfinite(InfBound(2)) &&
376 !Precision::IsInfinite(SupBound(2))) {
377 Standard_Real range = (SupBound(2) - InfBound(2));
378 InfBound(2) -= range;
379 SupBound(2) += range;
383 //=======================================================================
386 //=======================================================================
387 Standard_Boolean BRepBlend_SurfRstEvolRad::IsSolution
388 (const math_Vector& Sol,
389 const Standard_Real Tol)
391 math_Vector valsol(1,3),secmember(1,3);
392 math_Matrix gradsol(1,3,1,3);
394 gp_Vec dnplan,d1u1,d1v1,d1urst,d1vrst,d1,temp,ns,ns2,ncrossns,resul;
396 Standard_Real norm,ndotns,grosterme;
397 Standard_Real Cosa,Sina,Angle;
399 Values(Sol,valsol,gradsol);
400 if (Abs(valsol(1)) <= Tol &&
401 Abs(valsol(2)) <= Tol &&
402 Abs(valsol(3)) <= 2*Tol*Abs(ray) ) {
404 // Calculation of tangents
406 pt2ds = gp_Pnt2d(Sol(1),Sol(2));
408 pt2drst = rst->Value(prmrst);
409 surf->D1(Sol(1),Sol(2),pts,d1u1,d1v1);
410 cons.D1(Sol(3),ptrst,d1);
411 dnplan.SetLinearForm(1./normtg,d2gui,
412 -1./normtg*(nplan.Dot(d2gui)),nplan);
414 temp.SetXYZ(pts.XYZ() - ptgui.XYZ());
415 secmember(1) = normtg - dnplan.Dot(temp);
417 temp.SetXYZ(ptrst.XYZ() - ptgui.XYZ());
418 secmember(2) = normtg - dnplan.Dot(temp);
420 ns = d1u1.Crossed(d1v1);
421 ncrossns = nplan.Crossed(ns);
422 ndotns = nplan.Dot(ns);
423 norm = ncrossns.Magnitude();
425 grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm;
427 dnw.SetLinearForm((dnplan.Dot(ns)-grosterme*ndotns)/norm,nplan,
431 ns.SetLinearForm(ndotns/norm,nplan, -1./norm,ns);
432 resul.SetLinearForm(ray, ns, gp_Vec(ptrst,pts));
434 secmember(3) = -2.*ray*(dnw.Dot(resul)) - 2.*dray*(ns.Dot(resul)) + 2.*ray*dray;
435 math_Gauss Resol(gradsol);
436 if (Resol.IsDone()) {
437 Resol.Solve(secmember);
438 istangent = Standard_False;
441 math_SVD SingRS (gradsol);
442 if (SingRS.IsDone()) {
443 math_Vector DEDT(1,3);
445 SingRS.Solve(DEDT, secmember, 1.e-6);
446 istangent = Standard_False;
448 else istangent = Standard_True;
452 tgs.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1);
453 tgrst = secmember(3)*d1;
454 tg2ds.SetCoord(secmember(1),secmember(2));
455 surfrst->D1(pt2drst.X(),pt2drst.Y(),bid,d1urst,d1vrst);
457 t3dto2d(a,b,tgrst,d1urst,d1vrst);
458 tg2drst.SetCoord(a,b);
459 istangent = Standard_False;
462 istangent = Standard_True;
465 if(ray>0.) ns.Reverse();
466 ns2 = -resul.Normalized();
469 Sina = nplan.Dot(ns.Crossed(ns2));
471 Sina = -Sina; //nplan is changed into -nplan
476 Angle = 2.*M_PI - Angle;
479 if (Angle>maxang) {maxang = Angle;}
480 if (Angle<minang) {minang = Angle;}
481 distmin = Min( distmin, pts.Distance(ptrst));
483 return Standard_True;
485 istangent = Standard_True;
486 return Standard_False;
490 //=======================================================================
491 //function : GetMinimalDistance
493 //=======================================================================
495 Standard_Real BRepBlend_SurfRstEvolRad::GetMinimalDistance() const
500 //=======================================================================
503 //=======================================================================
504 const gp_Pnt& BRepBlend_SurfRstEvolRad::PointOnS() const
509 //=======================================================================
512 //=======================================================================
513 const gp_Pnt& BRepBlend_SurfRstEvolRad::PointOnRst() const
518 //=======================================================================
521 //=======================================================================
522 const gp_Pnt2d& BRepBlend_SurfRstEvolRad::Pnt2dOnS() const
527 //=======================================================================
530 //=======================================================================
531 const gp_Pnt2d& BRepBlend_SurfRstEvolRad::Pnt2dOnRst() const
536 //=======================================================================
539 //=======================================================================
540 Standard_Real BRepBlend_SurfRstEvolRad::ParameterOnRst() const
545 //=======================================================================
548 //=======================================================================
549 Standard_Boolean BRepBlend_SurfRstEvolRad::IsTangencyPoint() const
554 //=======================================================================
557 //=======================================================================
558 const gp_Vec& BRepBlend_SurfRstEvolRad::TangentOnS() const
560 if (istangent) {Standard_DomainError::Raise();}
564 //=======================================================================
567 //=======================================================================
568 const gp_Vec2d& BRepBlend_SurfRstEvolRad::Tangent2dOnS() const
570 if (istangent) {Standard_DomainError::Raise();}
574 //=======================================================================
577 //=======================================================================
578 const gp_Vec& BRepBlend_SurfRstEvolRad::TangentOnRst() const
580 if (istangent) {Standard_DomainError::Raise();}
584 //=======================================================================
587 //=======================================================================
588 const gp_Vec2d& BRepBlend_SurfRstEvolRad::Tangent2dOnRst() const
590 if (istangent) {Standard_DomainError::Raise();}
594 //=======================================================================
597 //=======================================================================
598 Standard_Boolean BRepBlend_SurfRstEvolRad::Decroch
599 (const math_Vector& Sol,
603 gp_Vec TgRst, NRst, NRstInPlane, NSInPlane;
606 Standard_Real norm,unsurnorm;
608 surf->D1(Sol(1),Sol(2),bid,d1u,d1v);
609 NS = NSInPlane = d1u.Crossed(d1v);
611 norm = nplan.Crossed(NS).Magnitude();
613 NSInPlane.SetLinearForm(nplan.Dot(NS)*unsurnorm,nplan,-unsurnorm,NS);
615 Center.SetXYZ(bid.XYZ()+ray*NSInPlane.XYZ());
616 if(choix>2) NSInPlane.Reverse();
617 TgS = nplan.Crossed(gp_Vec(Center,bid));
622 rstref->Value(Sol(3)).Coord(u,v);
623 surfref->D1(u,v,bid,d1u,d1v);
624 NRst = d1u.Crossed(d1v);
625 norm = nplan.Crossed(NRst).Magnitude();
627 NRstInPlane.SetLinearForm(nplan.Dot(NRst)*unsurnorm,nplan,-unsurnorm,NRst);
628 gp_Vec centptrst(Center,bid);
629 if(centptrst.Dot(NRstInPlane) < 0.) NRstInPlane.Reverse();
630 TgRst = nplan.Crossed(centptrst);
635 Standard_Real dot, NT = NRstInPlane.Magnitude();
636 NT *= TgRst.Magnitude();
637 if (Abs(NT) < 1.e-7) {
638 return Standard_False; // Singularity or Incoherence.
640 dot = NRstInPlane.Dot(TgRst);
643 return (dot < 1.e-10);
646 //=======================================================================
649 //=======================================================================
650 void BRepBlend_SurfRstEvolRad::Set (const Standard_Integer Choix)
668 //=======================================================================
671 //=======================================================================
672 void BRepBlend_SurfRstEvolRad::Set(const BlendFunc_SectionShape TypeSection)
674 mySShape = TypeSection;
677 //=======================================================================
680 //=======================================================================
681 void BRepBlend_SurfRstEvolRad::Section
682 (const Standard_Real Param,
683 const Standard_Real U,
684 const Standard_Real V,
685 const Standard_Real W,
695 tguide->D1(Param,ptgui,d1gui);
696 np = d1gui.Normalized();
697 ray = sg1*tevol->Value(Param);
699 surf->D1(U,V,pts,d1u1,d1v1);
700 ptrst = cons.Value(W);
702 ns = d1u1.Crossed(d1v1);
704 norm = nplan.Crossed(ns).Magnitude();
705 ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns);
706 Center.SetXYZ(pts.XYZ()+ray*ns.XYZ());
707 C.SetRadius(Abs(ray));
715 C.SetPosition(gp_Ax2(Center,np,ns));
717 Pdeb = 0.; //ElCLib::Parameter(C,pts);
718 Pfin = ElCLib::Parameter(C,ptrst);
720 // Test negative and almost null angles : Single Case
723 C.SetPosition(gp_Ax2(Center,np,ns));
724 Pfin = ElCLib::Parameter(C,ptrst);
726 if (Pfin < Precision::PConfusion()) Pfin += Precision::PConfusion();
729 //=======================================================================
732 //=======================================================================
733 Standard_Boolean BRepBlend_SurfRstEvolRad::IsRational() const
735 return (mySShape==BlendFunc_Rational || mySShape==BlendFunc_QuasiAngular);
738 //=======================================================================
741 //=======================================================================
742 Standard_Real BRepBlend_SurfRstEvolRad::GetSectionSize() const
744 return maxang*Abs(ray);
747 //=======================================================================
750 //=======================================================================
751 void BRepBlend_SurfRstEvolRad::GetMinimalWeight(TColStd_Array1OfReal& Weigths) const
753 BlendFunc::GetMinimalWeights(mySShape, myTConv, minang, maxang, Weigths );
754 // It is supposed that it does not depend on the Radius!
757 //=======================================================================
760 //=======================================================================
761 Standard_Integer BRepBlend_SurfRstEvolRad::NbIntervals(const GeomAbs_Shape S) const
763 Standard_Integer Nb_Int_Courbe, Nb_Int_Loi;
764 Nb_Int_Courbe = guide->NbIntervals(BlendFunc::NextShape(S));
765 Nb_Int_Loi = fevol->NbIntervals(S);
768 return Nb_Int_Courbe;
771 TColStd_Array1OfReal IntC(1, Nb_Int_Courbe+1);
772 TColStd_Array1OfReal IntL(1, Nb_Int_Loi+1);
773 TColStd_SequenceOfReal Inter;
774 guide->Intervals(IntC, BlendFunc::NextShape(S));
775 fevol->Intervals(IntL, S);
777 FusionneIntervalles( IntC, IntL, Inter);
778 return Inter.Length()-1;
781 //=======================================================================
784 //=======================================================================
785 void BRepBlend_SurfRstEvolRad::Intervals(TColStd_Array1OfReal& T,
786 const GeomAbs_Shape S) const
788 Standard_Integer Nb_Int_Courbe, Nb_Int_Loi;
789 Nb_Int_Courbe = guide->NbIntervals(BlendFunc::NextShape(S));
790 Nb_Int_Loi = fevol->NbIntervals(S);
793 guide->Intervals(T, BlendFunc::NextShape(S));
796 TColStd_Array1OfReal IntC(1, Nb_Int_Courbe+1);
797 TColStd_Array1OfReal IntL(1, Nb_Int_Loi+1);
798 TColStd_SequenceOfReal Inter;
799 guide->Intervals(IntC, BlendFunc::NextShape(S));
800 fevol->Intervals(IntL, S);
802 FusionneIntervalles( IntC, IntL, Inter);
803 for (Standard_Integer ii=1; ii<=Inter.Length(); ii++) {
810 //=======================================================================
813 //=======================================================================
814 void BRepBlend_SurfRstEvolRad::GetShape
815 (Standard_Integer& NbPoles,
816 Standard_Integer& NbKnots,
817 Standard_Integer& Degree,
818 Standard_Integer& NbPoles2d)
821 BlendFunc::GetShape(mySShape,maxang,NbPoles,NbKnots,Degree,myTConv);
824 //=======================================================================
827 //=======================================================================
828 void BRepBlend_SurfRstEvolRad::GetTolerance
829 (const Standard_Real BoundTol,
830 const Standard_Real SurfTol,
831 const Standard_Real AngleTol,
833 math_Vector& Tol1d) const
835 Standard_Integer low = Tol3d.Lower() , up=Tol3d.Upper();
837 Tol= GeomFill::GetTolerance(myTConv, minang, Abs(ray),
841 Tol3d(low+1) = Tol3d(up-1) = Min( Tol, SurfTol);
842 Tol3d(low) = Tol3d(up) = Min( Tol, BoundTol);
845 //=======================================================================
848 //=======================================================================
849 void BRepBlend_SurfRstEvolRad::Knots(TColStd_Array1OfReal& TKnots)
851 GeomFill::Knots(myTConv,TKnots);
854 //=======================================================================
857 //=======================================================================
858 void BRepBlend_SurfRstEvolRad::Mults(TColStd_Array1OfInteger& TMults)
860 GeomFill::Mults(myTConv,TMults);
863 //=======================================================================
866 //=======================================================================
867 Standard_Boolean BRepBlend_SurfRstEvolRad::Section
868 (const Blend_Point& P,
869 TColgp_Array1OfPnt& Poles,
870 TColgp_Array1OfVec& DPoles,
871 TColgp_Array1OfPnt2d& Poles2d,
872 TColgp_Array1OfVec2d& DPoles2d,
873 TColStd_Array1OfReal& Weigths,
874 TColStd_Array1OfReal& DWeigths)
877 gp_Vec d1u1,d1v1,d2u1,d2v1,d2uv1,d1;
878 gp_Vec ns,ns2,dnplan,dnw,dn2w;//,np2,dnp2;
880 gp_Vec resulu,resulv,temp,tgct,resul;
881 gp_Vec d1urst,d1vrst;
884 Standard_Real norm,ndotns,grosterme,aDray;
886 math_Vector sol(1,3),valsol(1,3),secmember(1,3);
887 math_Matrix gradsol(1,3,1,3);
889 Standard_Real prm = P.Parameter(),rayprim;
890 Standard_Integer low = Poles.Lower();
891 Standard_Integer upp = Poles.Upper();
892 Standard_Boolean istgt;
894 tguide->D2(prm,ptgui,d1gui,d2gui);
896 tevol->D1(prm,ray,aDray);
899 normtg = d1gui.Magnitude();
900 nplan = d1gui.Normalized();
901 dnplan.SetLinearForm(1./normtg,d2gui,
902 -1./normtg*(nplan.Dot(d2gui)),nplan);
904 P.ParametersOnS(sol(1),sol(2));
905 sol(3) = prmrst = P.ParameterOnC();
906 pt2drst = rst->Value(prmrst);
908 Values(sol,valsol,gradsol);
910 surf->D2(sol(1),sol(2),pts,d1u1,d1v1,d2u1,d2v1,d2uv1);
911 cons.D1(sol(3),ptrst,d1);
913 temp.SetXYZ(pts.XYZ()- ptgui.XYZ());
914 secmember(1) = normtg - dnplan.Dot(temp);
916 temp.SetXYZ(ptrst.XYZ()- ptgui.XYZ());
917 secmember(2) = normtg - dnplan.Dot(temp);
919 ns = d1u1.Crossed(d1v1);
920 ncrossns = nplan.Crossed(ns);
921 ndotns = nplan.Dot(ns);
922 norm = ncrossns.Magnitude();
924 norm = 1; // Not enough, but it is not necessary to stop
926 cout << " SurfRstEvolRad : Surface single " << endl;
930 // Derivative of n1 corresponding to w
932 grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm;
933 dnw.SetLinearForm((dnplan.Dot(ns)-grosterme*ndotns)/norm,nplan,
937 temp.SetLinearForm(ndotns/norm,nplan, -1./norm,ns);
938 resul.SetLinearForm(ray,temp,gp_Vec(ptrst,pts));
940 //secmember(3) = -2.*ray*(dnw.Dot(resul)); // jag 950105 il manquait ray
941 secmember(3) = -2.*ray*(dnw.Dot(resul)) - 2.*aDray*(temp.Dot(resul)) + 2.*ray*aDray;
942 math_Gauss Resol(gradsol);
944 if (Resol.IsDone()) {
945 Resol.Solve(secmember);
946 istgt = Standard_False;
949 math_SVD SingRS (gradsol);
950 if (SingRS.IsDone()) {
951 math_Vector DEDT(1,3);
953 SingRS.Solve(DEDT, secmember, 1.e-6);
954 istgt = Standard_False;
956 else istgt = Standard_True;
961 tgs.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1);
962 tgrst = secmember(3)*d1;
963 // Derivative of n1 corresponding to 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 // Derivative of n1 corresponding to 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);
979 ns.SetLinearForm(ndotns/norm,nplan, -1./norm,ns);
981 dn2w.SetLinearForm(ray, dnw, -1., tgrst, tgs);
982 dn2w.SetLinearForm(aDray,ns,dn2w);
983 norm = resul.Magnitude();
985 ns2 = -resul.Normalized();
986 dn2w.SetLinearForm(ns2.Dot(dn2w),ns2,-1.,dn2w);
988 istgt = Standard_False;
991 ns.SetLinearForm(ndotns/norm,nplan, -1./norm,ns);
992 ns2 = -resul.Normalized();
993 istgt = Standard_True;
998 Poles2d(Poles2d.Lower()).SetCoord(sol(1),sol(2));
999 Poles2d(Poles2d.Upper()).SetCoord(pt2drst.X(),pt2drst.Y());
1001 DPoles2d(Poles2d.Lower()).SetCoord(secmember(1),secmember(2));
1002 surfrst->D1(pt2drst.X(),pt2drst.Y(),bid,d1urst,d1vrst);
1004 t3dto2d(a,b,tgrst,d1urst,d1vrst);
1005 DPoles2d(Poles2d.Upper()).SetCoord(a,b);
1009 if (mySShape == BlendFunc_Linear) {
1016 DPoles(upp) = tgrst;
1017 DWeigths(low) = 0.0;
1018 DWeigths(upp) = 0.0;
1023 // Case of the circle
1024 Center.SetXYZ(pts.XYZ()+ray*ns.XYZ());
1026 tgct.SetLinearForm(ray,dnw,aDray,ns,tgs);
1040 if (ray < 0.) { // to avoid Abs(dray) some lines below
1043 else rayprim = aDray;
1045 return GeomFill::GetCircle(myTConv,
1059 GeomFill::GetCircle(myTConv,
1064 return Standard_False;
1068 //=======================================================================
1071 //=======================================================================
1072 Standard_Boolean BRepBlend_SurfRstEvolRad::Section (const Blend_Point& /*P*/,
1073 TColgp_Array1OfPnt& /*Poles*/,
1074 TColgp_Array1OfVec& /*DPoles*/,
1075 TColgp_Array1OfVec& /*D2Poles*/,
1076 TColgp_Array1OfPnt2d& /*Poles2d*/,
1077 TColgp_Array1OfVec2d& /*DPoles2d*/,
1078 TColgp_Array1OfVec2d& /*D2Poles2d*/,
1079 TColStd_Array1OfReal& /*Weigths*/,
1080 TColStd_Array1OfReal& /*DWeigths*/,
1081 TColStd_Array1OfReal& /*D2Weigths*/)
1083 return Standard_False;
1086 //=======================================================================
1089 //=======================================================================
1090 void BRepBlend_SurfRstEvolRad::Section
1091 (const Blend_Point& P,
1092 TColgp_Array1OfPnt& Poles,
1093 TColgp_Array1OfPnt2d& Poles2d,
1094 TColStd_Array1OfReal& Weigths)
1096 gp_Vec d1u1,d1v1;//,d1;
1097 gp_Vec ns,ns2;//,temp,np2;
1100 Standard_Real norm,u1,v1,w;
1102 Standard_Real prm = P.Parameter();
1103 Standard_Integer low = Poles.Lower();
1104 Standard_Integer upp = Poles.Upper();
1106 tguide->D1(prm,ptgui,d1gui);
1107 ray = tevol->Value(prm);
1109 nplan = d1gui.Normalized();
1111 P.ParametersOnS(u1,v1);
1112 w = P.ParameterOnC(); //jlr : point on curve not on surface
1113 gp_Pnt2d pt2d = rst->Value(w);
1115 surf->D1(u1,v1,pts,d1u1,d1v1);
1116 ptrst = cons.Value(w);
1118 distmin = Min (distmin, pts.Distance(ptrst));
1120 Poles2d(Poles2d.Lower()).SetCoord(u1,v1);
1121 Poles2d(Poles2d.Upper()).SetCoord(pt2d.X(),pt2d.Y());
1124 if (mySShape == BlendFunc_Linear) {
1132 ns = d1u1.Crossed(d1v1);
1133 norm = nplan.Crossed(ns).Magnitude();
1135 ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns);
1137 Center.SetXYZ(pts.XYZ()+ray*ns.XYZ());
1139 ns2 = gp_Vec(Center,ptrst).Normalized();
1140 if(ray>0) ns.Reverse();
1145 GeomFill::GetCircle(myTConv,
1152 void BRepBlend_SurfRstEvolRad::Resolution(const Standard_Integer IC2d,
1153 const Standard_Real Tol,
1154 Standard_Real& TolU,
1155 Standard_Real& TolV) const
1158 TolU = surf->UResolution(Tol);
1159 TolV = surf->VResolution(Tol);
1162 TolU = surfrst->UResolution(Tol);
1163 TolV = surfrst->VResolution(Tol);