1 // Created on: 1997-02-10
2 // Created by: Jacques GOUSSARD
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.
18 #include <Adaptor2d_HCurve2d.hxx>
19 #include <Adaptor3d_HCurve.hxx>
20 #include <Adaptor3d_HSurface.hxx>
21 #include <Blend_Point.hxx>
22 #include <BlendFunc.hxx>
23 #include <BRepBlend_RstRstEvolRad.hxx>
25 #include <GeomFill.hxx>
27 #include <gp_Circ.hxx>
29 #include <gp_Pnt2d.hxx>
31 #include <gp_Vec2d.hxx>
32 #include <Law_Function.hxx>
33 #include <math_Gauss.hxx>
34 #include <math_Matrix.hxx>
35 #include <math_SVD.hxx>
36 #include <Precision.hxx>
37 #include <Standard_DomainError.hxx>
38 #include <Standard_NotImplemented.hxx>
39 #include <TColStd_SequenceOfReal.hxx>
43 static void t3dto2d(Standard_Real& a,
49 Standard_Real AB = A.Dot(B);
50 Standard_Real AC = A.Dot(C);
51 Standard_Real BC = B.Dot(C);
52 Standard_Real BB = B.Dot(B);
53 Standard_Real CC = C.Dot(C);
54 Standard_Real deno = (BB*CC-BC*BC);
55 a = (AB*CC-AC*BC)/deno;
56 b = (AC*BB-AB*BC)/deno;
60 static void FusionneIntervalles(const TColStd_Array1OfReal& I1,
61 const TColStd_Array1OfReal& I2,
62 TColStd_SequenceOfReal& Seq)
64 Standard_Integer ind1=1, ind2=1;
65 Standard_Real Epspar = Precision::PConfusion()*0.99;
66 // supposed that the positioning works with PConfusion()/2
68 // Initialisations : IND1 and IND2 point the 1st element
69 // of each of 2 tables to be processed. INDS points at the last
70 // created element of TABSOR
73 //--- TABSOR is filled by parsing TABLE1 and TABLE2 simultaneously ---
74 //------------------ and removing multiple occurrencies ------------
76 while ((ind1<=I1.Upper()) && (ind2<=I2.Upper())) {
79 if (Abs(v1-v2)<= Epspar) {
80 // elements of I1 and I2 fit here
81 Seq.Append((v1+v2)/2);
86 // element of I1 fits here.
91 // element of TABLE2 fits here.
97 if (ind1>I1.Upper()) {
98 //----- Here I1 is exhausted, completed using the end of TABLE2 -------
100 for (; ind2<=I2.Upper(); ind2++) {
101 Seq.Append(I2(ind2));
105 if (ind2>I2.Upper()) {
106 //----- Here I2 is exhausted, completed using the end of I1 -------
108 for (; ind1<=I1.Upper(); ind1++) {
109 Seq.Append(I1(ind1));
116 //=======================================================================
117 //function : BRepBlend_RstRstEvolRad
119 //=======================================================================
121 BRepBlend_RstRstEvolRad::BRepBlend_RstRstEvolRad
122 (const Handle(Adaptor3d_HSurface)& Surf1,
123 const Handle(Adaptor2d_HCurve2d)& Rst1,
124 const Handle(Adaptor3d_HSurface)& Surf2,
125 const Handle(Adaptor2d_HCurve2d)& Rst2,
126 const Handle(Adaptor3d_HCurve)& CGuide,
127 const Handle(Law_Function)& Evol):
128 surf1(Surf1), surf2(Surf2), rst1(Rst1), rst2(Rst2),
129 cons1(Rst1, Surf1), cons2(Rst2, Surf2),
130 guide(CGuide), tguide(CGuide),
131 istangent(Standard_True), maxang(RealFirst()), minang(RealLast()),
133 mySShape(BlendFunc_Rational)
139 //=======================================================================
140 //function : NbVariables
142 //=======================================================================
144 Standard_Integer BRepBlend_RstRstEvolRad::NbVariables() const
149 //=======================================================================
150 //function : NbEquations
152 //=======================================================================
154 Standard_Integer BRepBlend_RstRstEvolRad::NbEquations() const
159 //=======================================================================
162 //=======================================================================
164 Standard_Boolean BRepBlend_RstRstEvolRad::Value(const math_Vector& X,
167 ptrst1 = cons1.Value(X(1));
168 ptrst2 = cons2.Value(X(2));
170 F(1) = nplan.XYZ().Dot(ptrst1.XYZ()) + theD;
171 F(2) = nplan.XYZ().Dot(ptrst2.XYZ()) + theD;
173 return Standard_True;
176 //=======================================================================
177 //function : Derivatives
179 //=======================================================================
181 Standard_Boolean BRepBlend_RstRstEvolRad::Derivatives(const math_Vector& X,
186 cons1.D1(X(1), ptrst1, d11);
187 cons2.D1(X(2), ptrst2, d21);
189 D(1,1) = nplan.Dot(d11);
193 D(2,2) = nplan.Dot(d21);
195 return Standard_True;
198 //=======================================================================
201 //=======================================================================
203 Standard_Boolean BRepBlend_RstRstEvolRad::Values(const math_Vector& X,
210 return Standard_True;
213 //=======================================================================
216 //=======================================================================
218 void BRepBlend_RstRstEvolRad::Set(const Handle(Adaptor3d_HSurface)& SurfRef1,
219 const Handle(Adaptor2d_HCurve2d)& RstRef1,
220 const Handle(Adaptor3d_HSurface)& SurfRef2,
221 const Handle(Adaptor2d_HCurve2d)& RstRef2)
229 //=======================================================================
232 //=======================================================================
234 void BRepBlend_RstRstEvolRad::Set(const Standard_Real Param)
236 d1gui = gp_Vec(0.,0.,0.);
237 nplan = gp_Vec(0.,0.,0.);
238 tguide->D2(Param, ptgui, d1gui, d2gui);
239 normtg = d1gui.Magnitude();
240 nplan.SetXYZ(d1gui.Normalized().XYZ());
241 gp_XYZ nplanXYZ(nplan.XYZ());
242 gp_XYZ ptguiXYZ(ptgui.XYZ());
243 theD = nplanXYZ.Dot(ptguiXYZ) ;
244 theD = theD * (-1.) ;
245 // theD = - (nplan.XYZ().Dot(ptgui.XYZ()));
246 tevol->D1(Param,ray,dray);
250 //=======================================================================
253 //=======================================================================
255 void BRepBlend_RstRstEvolRad::Set(const Standard_Real First,
256 const Standard_Real Last)
258 tguide = guide->Trim(First, Last, 1.e-12);
259 tevol = fevol->Trim(First,Last,1.e-12);
262 //=======================================================================
263 //function : GetTolerance
265 //=======================================================================
267 void BRepBlend_RstRstEvolRad::GetTolerance(math_Vector& Tolerance,
268 const Standard_Real Tol) const
270 Tolerance(1) = cons1.Resolution(Tol);
271 Tolerance(2) = cons2.Resolution(Tol);
274 //=======================================================================
275 //function : GetBounds
277 //=======================================================================
279 void BRepBlend_RstRstEvolRad::GetBounds(math_Vector& InfBound,
280 math_Vector& SupBound) const
282 InfBound(1) = cons1.FirstParameter();
283 InfBound(2) = cons2.FirstParameter();
284 SupBound(1) = cons1.LastParameter();
285 SupBound(2) = cons2.LastParameter();
289 //=======================================================================
290 //function : IsSolution
292 //=======================================================================
294 Standard_Boolean BRepBlend_RstRstEvolRad::IsSolution(const math_Vector& Sol,
295 const Standard_Real Tol)
299 math_Vector valsol(1, 2), secmember(1, 2);
300 math_Matrix gradsol(1, 2, 1, 2);
302 gp_Vec dnplan, d1urst1, d1vrst1, d1urst2, d1vrst2, d11, d21, temp;
305 Standard_Real Cosa, Sina, Angle;
307 Values(Sol, valsol, gradsol);
309 if (Abs(valsol(1)) <= Tol &&
310 Abs(valsol(2)) <= Tol ) {
312 // Calculation of tangents
314 pt2drst1 = rst1->Value(prmrst1);
316 pt2drst2 = rst2->Value(prmrst2);
318 cons1.D1(Sol(1), ptrst1, d11);
319 cons2.D1(Sol(2), ptrst2, d21);
321 dnplan.SetLinearForm(1./normtg, d2gui,
322 -1./normtg * (nplan.Dot(d2gui)), nplan);
324 temp.SetXYZ(ptrst1.XYZ() - ptgui.XYZ());
325 secmember(1) = normtg - dnplan.Dot(temp);
327 temp.SetXYZ(ptrst2.XYZ() - ptgui.XYZ());
328 secmember(2) = normtg - dnplan.Dot(temp);
330 math_Gauss Resol(gradsol);
332 if (Resol.IsDone()) {
333 Resol.Solve(secmember);
334 istangent = Standard_False;
337 math_SVD SingRS (gradsol);
338 if (SingRS.IsDone()) {
339 math_Vector DEDT(1,3);
341 SingRS.Solve(DEDT, secmember, 1.e-6);
342 istangent = Standard_False;
344 else istangent = Standard_True;
349 tgrst1 = secmember(1) * d11;
350 tgrst2 = secmember(2) * d21;
353 surf1->D1(pt2drst1.X(), pt2drst1.Y(), bid, d1urst1, d1vrst1);
354 t3dto2d(a, b, tgrst1, d1urst1, d1vrst1);
355 tg2drst1.SetCoord(a, b);
356 surf2->D1(pt2drst2.X(), pt2drst2.Y(), bid, d1urst2, d1vrst2);
357 t3dto2d(a, b, tgrst1, d1urst2, d1vrst2);
358 tg2drst2.SetCoord(a, b);
363 Standard_Boolean IsCenter;
365 IsCenter = CenterCircleRst1Rst2(ptrst1, ptrst2, nplan, Center, NotUsed);
367 if (!IsCenter) return Standard_False;
369 gp_Vec n1(Center, ptrst1) , n2(Center, ptrst2);
375 Sina = nplan.Dot(n1.Crossed(n2));
378 Sina = -Sina; //nplan is changed into -nplan
383 Angle = 2.*M_PI - Angle;
386 if (Angle > maxang) {maxang = Angle;}
387 if (Angle < minang) {minang = Angle;}
388 distmin = Min( distmin, ptrst1.Distance(ptrst2));
390 return Standard_True;
392 istangent = Standard_True;
393 return Standard_False;
396 //=======================================================================
397 //function : GetMinimalDistance
399 //=======================================================================
401 Standard_Real BRepBlend_RstRstEvolRad::GetMinimalDistance() const
406 //=======================================================================
407 //function : PointOnRst1
409 //=======================================================================
411 const gp_Pnt& BRepBlend_RstRstEvolRad::PointOnRst1() const
416 //=======================================================================
417 //function : PointOnRst2
419 //=======================================================================
421 const gp_Pnt& BRepBlend_RstRstEvolRad::PointOnRst2() const
426 //=======================================================================
427 //function : Pnt2dOnRst1
429 //=======================================================================
431 const gp_Pnt2d& BRepBlend_RstRstEvolRad::Pnt2dOnRst1() const
436 //=======================================================================
437 //function : Pnt2dOnRst2
439 //=======================================================================
441 const gp_Pnt2d& BRepBlend_RstRstEvolRad::Pnt2dOnRst2() const
446 //=======================================================================
447 //function : ParameterOnRst1
449 //=======================================================================
451 Standard_Real BRepBlend_RstRstEvolRad::ParameterOnRst1() const
456 //=======================================================================
457 //function : ParameterOnRst2
459 //=======================================================================
461 Standard_Real BRepBlend_RstRstEvolRad::ParameterOnRst2() const
465 //=======================================================================
466 //function : IsTangencyPoint
468 //=======================================================================
470 Standard_Boolean BRepBlend_RstRstEvolRad::IsTangencyPoint() const
475 //=======================================================================
476 //function : TangentOnRst1
478 //=======================================================================
480 const gp_Vec& BRepBlend_RstRstEvolRad::TangentOnRst1() const
482 if (istangent) {Standard_DomainError::Raise();}
486 //=======================================================================
487 //function : Tangent2dOnRst1
489 //=======================================================================
491 const gp_Vec2d& BRepBlend_RstRstEvolRad::Tangent2dOnRst1() const
493 if (istangent) {Standard_DomainError::Raise();}
497 //=======================================================================
498 //function : TangentOnRst2
500 //=======================================================================
502 const gp_Vec& BRepBlend_RstRstEvolRad::TangentOnRst2() const
504 if (istangent) {Standard_DomainError::Raise();}
508 //=======================================================================
509 //function : Tangent2dOnRst2
511 //=======================================================================
513 const gp_Vec2d& BRepBlend_RstRstEvolRad::Tangent2dOnRst2() const
515 if (istangent) {Standard_DomainError::Raise();}
519 //=======================================================================
522 //=======================================================================
524 Blend_DecrochStatus BRepBlend_RstRstEvolRad::Decroch(const math_Vector& Sol,
530 gp_Vec NRst1InPlane, NRst2InPlane;
531 gp_Pnt PtTmp1, PtTmp2, Center;
532 gp_Vec d1u, d1v, centptrst, NotUsed;
533 Standard_Real norm, unsurnorm;
536 rstref1->Value(Sol(1)).Coord(u, v);
537 surfref1->D1(u, v,PtTmp1,d1u,d1v);
538 // Normal to the reference surface 1
539 NRst1 = d1u.Crossed(d1v);
540 rstref2->Value(Sol(2)).Coord(u, v);
541 surfref2->D1(u, v, PtTmp2, d1u, d1v);
542 // Normal to the reference surface 2
543 NRst2 = d1u.Crossed(d1v);
545 CenterCircleRst1Rst2(PtTmp1, PtTmp2, nplan, Center, NotUsed);
547 norm = nplan.Crossed(NRst1).Magnitude();
548 unsurnorm = 1. / norm;
550 NRst1InPlane.SetLinearForm(nplan.Dot(NRst1) * unsurnorm, nplan, -unsurnorm, NRst1);
552 centptrst.SetXYZ(PtTmp1.XYZ() - Center.XYZ());
554 if (centptrst.Dot(NRst1InPlane) < 0.) NRst1InPlane.Reverse();
556 TgRst1 = nplan.Crossed(centptrst);
558 norm = nplan.Crossed(NRst2).Magnitude();
559 unsurnorm = 1./ norm;
560 NRst2InPlane.SetLinearForm(nplan.Dot(NRst2) * unsurnorm, nplan, -unsurnorm, NRst2);
561 centptrst.SetXYZ(PtTmp2.XYZ() - Center.XYZ());
564 if (centptrst.Dot(NRst2InPlane) < 0.) NRst2InPlane.Reverse();
566 TgRst2 = nplan.Crossed(centptrst);
573 // Vectors are returned
574 if (NRst1InPlane.Dot(TgRst1) > -1.e-10) {
575 if (NRst2InPlane.Dot(TgRst2) < 1.e-10) {
576 return Blend_DecrochBoth;
579 return Blend_DecrochRst1;
583 if (NRst2InPlane.Dot(TgRst2) < 1.e-10) {
584 return Blend_DecrochRst2;
587 return Blend_NoDecroch;
593 //=======================================================================
596 //=======================================================================
598 void BRepBlend_RstRstEvolRad::Set(const Standard_Integer Choix)
603 //=======================================================================
606 //=======================================================================
608 void BRepBlend_RstRstEvolRad::Set(const BlendFunc_SectionShape TypeSection)
610 mySShape = TypeSection;
615 //=======================================================================
616 //function : CenterCircleRst1Rst2
617 //purpose : Calculate the center of circle passing by two points of restrictions
618 //=======================================================================
619 Standard_Boolean BRepBlend_RstRstEvolRad::CenterCircleRst1Rst2(const gp_Pnt& PtRst1,
620 const gp_Pnt& PtRst2,
626 gp_Vec rst1rst2(PtRst1, PtRst2);
627 gp_Vec vdmedNor; //,NRst1; vdmedNor vector director of the perpendicular bisector
629 Standard_Real Dist;// distance between the middle of PtRst1,PtRst2 and Center
631 // Calculate the center of the circle
632 VdMed = rst1rst2.Crossed(np);
633 norm2 = rst1rst2.SquareMagnitude();
634 Dist = ray * ray - 0.25 * norm2;
640 if (Dist < - 1.E-07) return Standard_False;
644 vdmedNor = VdMed.Normalized();
645 Center.SetXYZ(0.5 * rst1rst2.XYZ() + PtRst1.XYZ() + Dist * vdmedNor.XYZ());
649 Center.SetXYZ(0.5 * rst1rst2.XYZ() + PtRst1.XYZ());
652 return Standard_True;
661 //=======================================================================
664 //=======================================================================
666 void BRepBlend_RstRstEvolRad::Section(const Standard_Real Param,
667 const Standard_Real U,
668 const Standard_Real V,
673 gp_Vec ns, np, NotUsed;
676 tguide->D1(Param, ptgui, d1gui);
677 ray = tevol->Value(Param);
678 np = d1gui.Normalized();
679 ptrst1 = cons1.Value(U);
680 ptrst2 = cons2.Value(V);
682 CenterCircleRst1Rst2(ptrst1, ptrst2, np, Center, NotUsed);
684 C.SetRadius(Abs(ray));
685 ns = gp_Vec(Center, ptrst1).Normalized();
691 C.SetPosition(gp_Ax2(Center, np, ns));
692 Pdeb = 0; //ElCLib::Parameter(C, pts);
693 Pfin = ElCLib::Parameter(C, ptrst2);
695 // Test negative and quasi null angles: Special case
696 if (Pfin > 1.5 * M_PI) {
698 C.SetPosition(gp_Ax2(Center, np, ns));
699 Pfin = ElCLib::Parameter(C, ptrst2);
701 if (Pfin < Precision::PConfusion()) Pfin += Precision::PConfusion();
704 //=======================================================================
705 //function : IsRational
707 //=======================================================================
709 Standard_Boolean BRepBlend_RstRstEvolRad::IsRational () const
711 return (mySShape==BlendFunc_Rational || mySShape==BlendFunc_QuasiAngular);
714 //=======================================================================
715 //function : GetSectionSize
717 //=======================================================================
719 Standard_Real BRepBlend_RstRstEvolRad::GetSectionSize() const
721 return maxang * Abs(ray);
724 //=======================================================================
725 //function : GetMinimalWeight
727 //=======================================================================
729 void BRepBlend_RstRstEvolRad::GetMinimalWeight(TColStd_Array1OfReal& Weights) const
731 BlendFunc::GetMinimalWeights(mySShape, myTConv, minang, maxang, Weights );
732 // It is supposed that it does not depend on the Radius!
735 //=======================================================================
736 //function : NbIntervals
738 //=======================================================================
740 Standard_Integer BRepBlend_RstRstEvolRad::NbIntervals (const GeomAbs_Shape S) const
742 Standard_Integer Nb_Int_Courbe, Nb_Int_Loi;
743 Nb_Int_Courbe = guide->NbIntervals(BlendFunc::NextShape(S));
744 Nb_Int_Loi = fevol->NbIntervals(S);
747 return Nb_Int_Courbe;
750 TColStd_Array1OfReal IntC(1, Nb_Int_Courbe+1);
751 TColStd_Array1OfReal IntL(1, Nb_Int_Loi+1);
752 TColStd_SequenceOfReal Inter;
753 guide->Intervals(IntC, BlendFunc::NextShape(S));
754 fevol->Intervals(IntL, S);
756 FusionneIntervalles( IntC, IntL, Inter);
757 return Inter.Length()-1;
760 //=======================================================================
761 //function : Intervals
763 //=======================================================================
765 void BRepBlend_RstRstEvolRad::Intervals (TColStd_Array1OfReal& T,
766 const GeomAbs_Shape S) const
768 Standard_Integer Nb_Int_Courbe, Nb_Int_Loi;
769 Nb_Int_Courbe = guide->NbIntervals(BlendFunc::NextShape(S));
770 Nb_Int_Loi = fevol->NbIntervals(S);
773 guide->Intervals(T, BlendFunc::NextShape(S));
776 TColStd_Array1OfReal IntC(1, Nb_Int_Courbe+1);
777 TColStd_Array1OfReal IntL(1, Nb_Int_Loi+1);
778 TColStd_SequenceOfReal Inter;
779 guide->Intervals(IntC, BlendFunc::NextShape(S));
780 fevol->Intervals(IntL, S);
782 FusionneIntervalles( IntC, IntL, Inter);
783 for (Standard_Integer ii=1; ii<=Inter.Length(); ii++) {
789 //=======================================================================
790 //function : GetShape
792 //=======================================================================
794 void BRepBlend_RstRstEvolRad::GetShape (Standard_Integer& NbPoles,
795 Standard_Integer& NbKnots,
796 Standard_Integer& Degree,
797 Standard_Integer& NbPoles2d)
800 BlendFunc::GetShape(mySShape, maxang, NbPoles, NbKnots, Degree, myTConv);
803 //=======================================================================
804 //function : GetTolerance
805 //purpose : Determine the Tolerance to be used in approximations.
806 //=======================================================================
808 void BRepBlend_RstRstEvolRad::GetTolerance(const Standard_Real BoundTol,
809 const Standard_Real SurfTol,
810 const Standard_Real AngleTol,
812 math_Vector& Tol1d) const
814 Standard_Integer low = Tol3d.Lower(), up = Tol3d.Upper();
816 Tol= GeomFill::GetTolerance(myTConv, minang, Abs(ray),
820 Tol3d(low+1) = Tol3d(up-1) = Min(Tol, SurfTol);
821 Tol3d(low) = Tol3d(up) = Min(Tol, BoundTol);
824 //=======================================================================
827 //=======================================================================
829 void BRepBlend_RstRstEvolRad::Knots(TColStd_Array1OfReal& TKnots)
831 GeomFill::Knots(myTConv, TKnots);
834 //=======================================================================
837 //=======================================================================
839 void BRepBlend_RstRstEvolRad::Mults(TColStd_Array1OfInteger& TMults)
841 GeomFill::Mults(myTConv, TMults);
844 //=======================================================================
847 //=======================================================================
849 void BRepBlend_RstRstEvolRad::Section(const Blend_Point& P,
850 TColgp_Array1OfPnt& Poles,
851 TColgp_Array1OfPnt2d& Poles2d,
852 TColStd_Array1OfReal& Weights)
854 gp_Vec n1, n2, NotUsed;
858 Standard_Real prm = P.Parameter();
859 Standard_Integer low = Poles.Lower();
860 Standard_Integer upp = Poles.Upper();
862 tguide->D1(prm,ptgui, d1gui);
863 ray = tevol->Value(prm);
864 nplan = d1gui.Normalized();
866 u = P.ParameterOnC1();
867 v = P.ParameterOnC2();
869 gp_Pnt2d pt2d1 = rst1->Value(u);
870 gp_Pnt2d pt2d2 = rst2->Value(v);
872 ptrst1 = cons1.Value(u);
873 ptrst2 = cons2.Value(v);
874 distmin = Min (distmin, ptrst1.Distance(ptrst2));
876 Poles2d(Poles2d.Lower()).SetCoord(pt2d1.X(),pt2d1.Y());
877 Poles2d(Poles2d.Upper()).SetCoord(pt2d2.X(),pt2d2.Y());
880 if (mySShape == BlendFunc_Linear) {
888 // Calculate the center of the circle
889 CenterCircleRst1Rst2(ptrst1, ptrst2, nplan, Center, NotUsed);
891 // normals to the section with points
892 n1 = gp_Vec(Center, ptrst1).Normalized();
893 n2 = gp_Vec(Center, ptrst2).Normalized();
899 GeomFill::GetCircle(myTConv,
901 nplan, ptrst1, ptrst2,
906 //=======================================================================
909 //=======================================================================
911 Standard_Boolean BRepBlend_RstRstEvolRad::Section(const Blend_Point& P,
912 TColgp_Array1OfPnt& Poles,
913 TColgp_Array1OfVec& DPoles,
914 TColgp_Array1OfPnt2d& Poles2d,
915 TColgp_Array1OfVec2d& DPoles2d,
916 TColStd_Array1OfReal& Weights,
917 TColStd_Array1OfReal& DWeights)
921 gp_Vec dnplan, d1n1, d1n2;//,np2, dnp2;
923 gp_Vec d1urst, d1vrst;
924 gp_Pnt Center, NotUsed;
926 Standard_Real norm2, normmed, Dist;
928 math_Vector sol(1, 2), valsol(1, 2), secmember(1, 2);
929 math_Matrix gradsol(1, 2, 1, 2);
931 Standard_Real prm = P.Parameter();
932 Standard_Integer low = Poles.Lower();
933 Standard_Integer upp = Poles.Upper();
934 Standard_Boolean istgt;
936 tguide->D2(prm, ptgui, d1gui, d2gui);
937 tevol->D1(prm,ray,dray);
938 normtg = d1gui.Magnitude();
939 nplan = d1gui.Normalized();
940 dnplan.SetLinearForm(1./normtg, d2gui,
941 -1./normtg * (nplan.Dot(d2gui)), nplan);
943 sol(1) = prmrst1 = P.ParameterOnC1();
944 sol(2) = prmrst2 = P.ParameterOnC2();
945 pt2drst1 = rst1->Value(prmrst1);
946 pt2drst2 = rst2->Value(prmrst2);
948 Values(sol, valsol, gradsol);
950 cons1.D1(sol(1), ptrst1, d11);
951 cons2.D1(sol(2), ptrst2, d21);
953 temp.SetXYZ(ptrst1.XYZ() - ptgui.XYZ());
954 secmember(1) = normtg - dnplan.Dot(temp);
956 temp.SetXYZ(ptrst2.XYZ() - ptgui.XYZ());
957 secmember(2) = normtg - dnplan.Dot(temp);
959 math_Gauss Resol(gradsol, 1.e-9);
961 if (Resol.IsDone()) {
962 istgt = Standard_False;
963 Resol.Solve(secmember);
966 math_SVD SingRS (gradsol);
967 if (SingRS.IsDone()) {
968 math_Vector DEDT(1,2);
970 SingRS.Solve(DEDT, secmember, 1.e-6);
971 istgt = Standard_False;
973 else istgt = Standard_True;
977 gp_Vec rst1rst2(ptrst1, ptrst2);
978 Standard_Boolean IsCenter;
980 IsCenter = CenterCircleRst1Rst2(ptrst1, ptrst2, nplan, Center, med);
981 if (!IsCenter) return Standard_False;
983 normmed = med.Magnitude();
985 gp_Vec n1(Center, ptrst1), n2(Center, ptrst2);
988 // secmember contains derivatives of parameters on curves
989 // corresponding to t
990 tgrst1 = secmember(1) * d11;
991 tgrst2 = secmember(2) * d21;
995 norm2 = rst1rst2.SquareMagnitude();
996 d1rst1rst2 = tgrst2 - tgrst1;
997 Dist = ray * ray - 0.25 * norm2;
998 Standard_Real Invdray = dray / ray;
1000 if (Dist > 1.E-07) {
1001 gp_Vec d1P1P2CrosNp, dmed;
1002 d1P1P2CrosNp = d1rst1rst2.Crossed(nplan) + rst1rst2.Crossed(dnplan);
1003 // derivative of the bisector
1004 dmed = d1P1P2CrosNp - med.Dot(d1P1P2CrosNp) * med;
1007 Standard_Real d1Dist;
1009 d1Dist = (ray * dray - 0.25 * rst1rst2.Dot(d1rst1rst2) ) / Dist;
1015 // derivative of the coefficient Dist is located in dmed
1016 dmed.SetLinearForm(Dist, dmed, d1Dist, med);
1018 // derivative of the Normal to the curve in P1
1019 d1n1 = - (d1rst1rst2 + dmed + Invdray * n1) / ray;
1021 // derivative of the Normal to the curve in P2
1022 d1n2 = (d1rst1rst2 - dmed - Invdray * n2) / ray;
1026 // Normal to the curve in P1
1027 d1n1 = - (d1rst1rst2 + Invdray * n1) / ray;
1029 // Normal to the curve in P2
1030 d1n2 = (d1rst1rst2 - Invdray * n2) / ray;
1039 Poles2d(Poles2d.Lower()).SetCoord(pt2drst1.X(), pt2drst1.Y());
1040 Poles2d(Poles2d.Upper()).SetCoord(pt2drst2.X(), pt2drst2.Y());
1043 surf1->D1(pt2drst1.X(), pt2drst1.Y(), NotUsed, d1urst, d1vrst);
1044 t3dto2d(a,b,tgrst1, d1urst, d1vrst);
1045 DPoles2d(Poles2d.Lower()).SetCoord(a, b);
1047 surf2->D1(pt2drst2.X(), pt2drst2.Y(), NotUsed, d1urst, d1vrst);
1048 t3dto2d(a, b, tgrst2, d1urst, d1vrst);
1049 DPoles2d(Poles2d.Upper()).SetCoord(a, b);
1053 if (mySShape == BlendFunc_Linear) {
1054 Poles(low) = ptrst1;
1055 Poles(upp) = ptrst2;
1059 DPoles(low) = tgrst1;
1060 DPoles(upp) = tgrst2;
1061 DWeights(low) = 0.0;
1062 DWeights(upp) = 0.0;
1067 // Case of the circle
1068 // tangent to the center of the circle
1070 tgct.SetLinearForm(-ray, d1n1, -dray, n1, tgrst1);
1080 return GeomFill::GetCircle(myTConv,
1094 GeomFill::GetCircle(myTConv,
1096 nplan, ptrst1, ptrst2,
1099 return Standard_False;
1103 //=======================================================================
1104 //function : Section
1106 //=======================================================================
1108 Standard_Boolean BRepBlend_RstRstEvolRad::Section
1109 (const Blend_Point&,
1110 TColgp_Array1OfPnt&,
1111 TColgp_Array1OfVec&,
1112 TColgp_Array1OfVec&,
1113 TColgp_Array1OfPnt2d&,
1114 TColgp_Array1OfVec2d&,
1115 TColgp_Array1OfVec2d&,
1116 TColStd_Array1OfReal&,
1117 TColStd_Array1OfReal&,
1118 TColStd_Array1OfReal&)
1120 return Standard_False;
1124 void BRepBlend_RstRstEvolRad::Resolution(const Standard_Integer IC2d,
1125 const Standard_Real Tol,
1126 Standard_Real& TolU,
1127 Standard_Real& TolV) const
1130 TolU = surf1->UResolution(Tol);
1131 TolV = surf1->VResolution(Tol);
1134 TolU = surf2->UResolution(Tol);
1135 TolV = surf2->VResolution(Tol);