0023024: Update headers of OCCT files
[occt.git] / src / BRepBlend / BRepBlend_RstRstConstRad.cxx
CommitLineData
b311480e 1// Created on: 1997-02-10
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1997-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
0d969553 21
7fd59977 22#include <BRepBlend_RstRstConstRad.ixx>
23#include <math_Gauss.hxx>
24#include <math_SVD.hxx>
25
26#include <ElCLib.hxx>
27#include <gp.hxx>
28#include <BlendFunc.hxx>
29#include <GeomFill.hxx>
30#include <Standard_DomainError.hxx>
31#include <Standard_NotImplemented.hxx>
32#include <Precision.hxx>
33
34#define Eps 1.e-15
35
36static void t3dto2d(Standard_Real& a,
37 Standard_Real& b,
38 const gp_Vec& A,
39 const gp_Vec& B,
40 const gp_Vec& C)
41{
42 Standard_Real AB = A.Dot(B);
43 Standard_Real AC = A.Dot(C);
44 Standard_Real BC = B.Dot(C);
45 Standard_Real BB = B.Dot(B);
46 Standard_Real CC = C.Dot(C);
47 Standard_Real deno = (BB*CC-BC*BC);
48 a = (AB*CC-AC*BC)/deno;
49 b = (AC*BB-AB*BC)/deno;
50}
51
52//=======================================================================
53//function : BRepBlend_RstRstConstRad
54//purpose :
55//=======================================================================
56
57BRepBlend_RstRstConstRad::BRepBlend_RstRstConstRad
58(const Handle(Adaptor3d_HSurface)& Surf1,
59 const Handle(Adaptor2d_HCurve2d)& Rst1,
60 const Handle(Adaptor3d_HSurface)& Surf2,
61 const Handle(Adaptor2d_HCurve2d)& Rst2,
62 const Handle(Adaptor3d_HCurve)& CGuide):
63 surf1(Surf1), surf2(Surf2), rst1(Rst1), rst2(Rst2),
64 cons1(Rst1, Surf1), cons2(Rst2, Surf2),
65 guide(CGuide), tguide(CGuide),
66 istangent(Standard_True), maxang(RealFirst()), minang(RealLast()),
67 distmin(RealLast()),
68 mySShape(BlendFunc_Rational)
69{}
70
71//=======================================================================
72//function : NbVariables
73//purpose :
74//=======================================================================
75
76Standard_Integer BRepBlend_RstRstConstRad::NbVariables() const
77{
78 return 2;
79}
80
81//=======================================================================
82//function : NbEquations
83//purpose :
84//=======================================================================
85
86Standard_Integer BRepBlend_RstRstConstRad::NbEquations() const
87{
88 return 2;
89}
90
91//=======================================================================
92//function : Value
93//purpose :
94//=======================================================================
95
96Standard_Boolean BRepBlend_RstRstConstRad::Value(const math_Vector& X,
97 math_Vector& F)
98{
99 ptrst1 = cons1.Value(X(1));
100 ptrst2 = cons2.Value(X(2));
101
102 F(1) = nplan.XYZ().Dot(ptrst1.XYZ()) + theD;
103 F(2) = nplan.XYZ().Dot(ptrst2.XYZ()) + theD;
104
105 return Standard_True;
106}
107
108//=======================================================================
109//function : Derivatives
110//purpose :
111//=======================================================================
112
113Standard_Boolean BRepBlend_RstRstConstRad::Derivatives(const math_Vector& X,
114 math_Matrix& D)
115{
116 gp_Vec d11, d21;
117
118 cons1.D1(X(1), ptrst1, d11);
119 cons2.D1(X(2), ptrst2, d21);
120
121 D(1,1) = nplan.Dot(d11);
122 D(1,2) = 0.;
123
124 D(2,1) = 0.;
125 D(2,2) = nplan.Dot(d21);
126
127 return Standard_True;
128}
129
130//=======================================================================
131//function : Values
132//purpose :
133//=======================================================================
134
135Standard_Boolean BRepBlend_RstRstConstRad::Values(const math_Vector& X,
136 math_Vector& F,
137 math_Matrix& D)
138{
139 Standard_Boolean Error;
140
141 Error = Value(X, F);
142 Error = Derivatives(X, D);
143
144 return Standard_True;
145}
146
147//=======================================================================
148//function : Set
149//purpose :
150//=======================================================================
151
152void BRepBlend_RstRstConstRad::Set(const Handle(Adaptor3d_HSurface)& SurfRef1,
153 const Handle(Adaptor2d_HCurve2d)& RstRef1,
154 const Handle(Adaptor3d_HSurface)& SurfRef2,
155 const Handle(Adaptor2d_HCurve2d)& RstRef2)
156{
157 surfref1 = SurfRef1;
158 surfref2 = SurfRef2;
159 rstref1 = RstRef1;
160 rstref2 = RstRef2;
161}
162
163//=======================================================================
164//function : Set
165//purpose :
166//=======================================================================
167
168void BRepBlend_RstRstConstRad::Set(const Standard_Real Param)
169{
170 tguide->D2(Param, ptgui, d1gui, d2gui);
171 normtg = d1gui.Magnitude();
172 nplan = d1gui.Normalized();
173 theD = - (nplan.XYZ().Dot(ptgui.XYZ()));
174}
175
176//=======================================================================
177//function : Set
178//purpose :
179//=======================================================================
180
181void BRepBlend_RstRstConstRad::Set(const Standard_Real First,
182 const Standard_Real Last)
183{
184 tguide = guide->Trim(First, Last, 1.e-12);
185}
186
187//=======================================================================
188//function : GetTolerance
189//purpose :
190//=======================================================================
191
192void BRepBlend_RstRstConstRad::GetTolerance(math_Vector& Tolerance,
193 const Standard_Real Tol) const
194{
195 Tolerance(1) = cons1.Resolution(Tol);
196 Tolerance(2) = cons2.Resolution(Tol);
197}
198
199//=======================================================================
200//function : GetBounds
201//purpose :
202//=======================================================================
203
204void BRepBlend_RstRstConstRad::GetBounds(math_Vector& InfBound,
205 math_Vector& SupBound) const
206{
207 InfBound(1) = cons1.FirstParameter();
208 InfBound(2) = cons2.FirstParameter();
209 SupBound(1) = cons1.LastParameter();
210 SupBound(2) = cons2.LastParameter();
211
212}
213
214//=======================================================================
215//function : IsSolution
216//purpose :
217//=======================================================================
218
219Standard_Boolean BRepBlend_RstRstConstRad::IsSolution(const math_Vector& Sol,
220 const Standard_Real Tol)
221
222
223{
224 math_Vector valsol(1, 2), secmember(1, 2);
225 math_Matrix gradsol(1, 2, 1, 2);
226
227 gp_Vec dnplan, d1urst1, d1vrst1, d1urst2, d1vrst2, d11, d21, temp;
228 gp_Pnt bid;
229
230 Standard_Real Cosa, Sina, Angle;
231
232 Values(Sol, valsol, gradsol);
233
234 if (Abs(valsol(1)) <= Tol &&
235 Abs(valsol(2)) <= Tol ) {
236
81bba717 237 // Calculation of tangents
7fd59977 238 prmrst1 = Sol(1);
239 pt2drst1 = rst1->Value(prmrst1);
240 prmrst2 = Sol(2);
241 pt2drst2 = rst2->Value(prmrst2);
242
243 cons1.D1(Sol(1), ptrst1, d11);
244 cons2.D1(Sol(2), ptrst2, d21);
245
246 dnplan.SetLinearForm(1./normtg, d2gui,
247 -1./normtg * (nplan.Dot(d2gui)), nplan);
248
249 temp.SetXYZ(ptrst1.XYZ() - ptgui.XYZ());
250 secmember(1) = normtg - dnplan.Dot(temp);
251
252 temp.SetXYZ(ptrst2.XYZ() - ptgui.XYZ());
253 secmember(2) = normtg - dnplan.Dot(temp);
254
255 math_Gauss Resol(gradsol);
256
257 if (Resol.IsDone()) {
258 Resol.Solve(secmember);
259 istangent = Standard_False;
260 }
261 else {
262 math_SVD SingRS (gradsol);
263 if (SingRS.IsDone()) {
264 math_Vector DEDT(1,3);
265 DEDT = secmember;
266 SingRS.Solve(DEDT, secmember, 1.e-6);
267 istangent = Standard_False;
268 }
269 else istangent = Standard_True;
270 }
271
272
273 if (!istangent) {
274 tgrst1 = secmember(1) * d11;
275 tgrst2 = secmember(2) * d21;
276
277 Standard_Real a, b;
278 surf1->D1(pt2drst1.X(), pt2drst1.Y(), bid, d1urst1, d1vrst1);
279 t3dto2d(a, b, tgrst1, d1urst1, d1vrst1);
280 tg2drst1.SetCoord(a, b);
281 surf2->D1(pt2drst2.X(), pt2drst2.Y(), bid, d1urst2, d1vrst2);
282 t3dto2d(a, b, tgrst1, d1urst2, d1vrst2);
283 tg2drst2.SetCoord(a, b);
284 }
285
286 gp_Pnt Center;
287 gp_Vec NotUsed;
288 Standard_Boolean IsCenter;
289
290 IsCenter = CenterCircleRst1Rst2(ptrst1, ptrst2, nplan, Center, NotUsed);
291
292 if (!IsCenter) return Standard_False;
293
294 gp_Vec n1(Center, ptrst1) , n2(Center, ptrst2);
295
296 n1.Normalize();
297 n2.Normalize();
298
299 Cosa = n1.Dot(n2);
300 Sina = nplan.Dot(n1.Crossed(n2));
301
302 if (choix%2 != 0) {
81bba717 303 Sina = -Sina; //nplan is changed into -nplan
7fd59977 304 }
305
306 Angle = ACos(Cosa);
307 if (Sina < 0.) {
c6541a0c 308 Angle = 2.*M_PI - Angle;
7fd59977 309 }
310
311 if (Angle > maxang) {maxang = Angle;}
312 if (Angle < minang) {minang = Angle;}
313 distmin = Min( distmin, ptrst1.Distance(ptrst2));
314
315 return Standard_True;
316 }
317 istangent = Standard_True;
318 return Standard_False;
319}
320
321//=======================================================================
322//function : GetMinimalDistance
323//purpose :
324//=======================================================================
325
326Standard_Real BRepBlend_RstRstConstRad::GetMinimalDistance() const
327{
328 return distmin;
329}
330
331//=======================================================================
332//function : PointOnRst1
333//purpose :
334//=======================================================================
335
336const gp_Pnt& BRepBlend_RstRstConstRad::PointOnRst1() const
337{
338 return ptrst1;
339}
340
341//=======================================================================
342//function : PointOnRst2
343//purpose :
344//=======================================================================
345
346const gp_Pnt& BRepBlend_RstRstConstRad::PointOnRst2() const
347{
348 return ptrst2;
349}
350
351//=======================================================================
352//function : Pnt2dOnRst1
353//purpose :
354//=======================================================================
355
356const gp_Pnt2d& BRepBlend_RstRstConstRad::Pnt2dOnRst1() const
357{
358 return pt2drst1;
359}
360
361//=======================================================================
362//function : Pnt2dOnRst2
363//purpose :
364//=======================================================================
365
366const gp_Pnt2d& BRepBlend_RstRstConstRad::Pnt2dOnRst2() const
367{
368 return pt2drst2;
369}
370
371//=======================================================================
372//function : ParameterOnRst1
373//purpose :
374//=======================================================================
375
376Standard_Real BRepBlend_RstRstConstRad::ParameterOnRst1() const
377{
378 return prmrst1;
379}
380
381//=======================================================================
382//function : ParameterOnRst2
383//purpose :
384//=======================================================================
385
386Standard_Real BRepBlend_RstRstConstRad::ParameterOnRst2() const
387{
388 return prmrst2;
389}
390//=======================================================================
391//function : IsTangencyPoint
392//purpose :
393//=======================================================================
394
395Standard_Boolean BRepBlend_RstRstConstRad::IsTangencyPoint() const
396{
397 return istangent;
398}
399
400//=======================================================================
401//function : TangentOnRst1
402//purpose :
403//=======================================================================
404
405const gp_Vec& BRepBlend_RstRstConstRad::TangentOnRst1() const
406{
407 if (istangent) {Standard_DomainError::Raise();}
408 return tgrst1;
409}
410
411//=======================================================================
412//function : Tangent2dOnRst1
413//purpose :
414//=======================================================================
415
416const gp_Vec2d& BRepBlend_RstRstConstRad::Tangent2dOnRst1() const
417{
418 if (istangent) {Standard_DomainError::Raise();}
419 return tg2drst1;
420}
421
422//=======================================================================
423//function : TangentOnRst2
424//purpose :
425//=======================================================================
426
427const gp_Vec& BRepBlend_RstRstConstRad::TangentOnRst2() const
428{
429 if (istangent) {Standard_DomainError::Raise();}
430 return tgrst2;
431}
432
433//=======================================================================
434//function : Tangent2dOnRst2
435//purpose :
436//=======================================================================
437
438const gp_Vec2d& BRepBlend_RstRstConstRad::Tangent2dOnRst2() const
439{
440 if (istangent) {Standard_DomainError::Raise();}
441 return tg2drst2;
442}
443
444//=======================================================================
445//function : Decroch
446//purpose :
447//=======================================================================
448
449Blend_DecrochStatus BRepBlend_RstRstConstRad::Decroch(const math_Vector& Sol,
450 gp_Vec& NRst1,
451 gp_Vec& TgRst1,
452 gp_Vec& NRst2,
453 gp_Vec& TgRst2)const
454{
455 gp_Vec NRst1InPlane, NRst2InPlane;
456 gp_Pnt PtTmp1, PtTmp2, Center;
457 gp_Vec d1u, d1v, centptrst, NotUsed;
458 Standard_Real norm, unsurnorm;
459 Standard_Real u,v;
460
461 rstref1->Value(Sol(1)).Coord(u, v);
462 surfref1->D1(u, v,PtTmp1,d1u,d1v);
81bba717 463 // Normal to the reference surface 1
7fd59977 464 NRst1 = d1u.Crossed(d1v);
465 rstref2->Value(Sol(2)).Coord(u, v);
466 surfref2->D1(u, v, PtTmp2, d1u, d1v);
81bba717 467 // Normal to the reference surface 2
7fd59977 468 NRst2 = d1u.Crossed(d1v);
469
470 Standard_Boolean IsCenter;
471
472 IsCenter = CenterCircleRst1Rst2(PtTmp1, PtTmp2, nplan, Center, NotUsed);
473
474 norm = nplan.Crossed(NRst1).Magnitude();
475 unsurnorm = 1. / norm;
476
477 NRst1InPlane.SetLinearForm(nplan.Dot(NRst1) * unsurnorm, nplan, -unsurnorm, NRst1);
478
479 centptrst.SetXYZ(PtTmp1.XYZ() - Center.XYZ());
480
481 if (centptrst.Dot(NRst1InPlane) < 0.) NRst1InPlane.Reverse();
482
483 TgRst1 = nplan.Crossed(centptrst);
484
485 norm = nplan.Crossed(NRst2).Magnitude();
486 unsurnorm = 1./ norm;
487 NRst2InPlane.SetLinearForm(nplan.Dot(NRst2) * unsurnorm, nplan, -unsurnorm, NRst2);
488 centptrst.SetXYZ(PtTmp2.XYZ() - Center.XYZ());
489
490
491 if (centptrst.Dot(NRst2InPlane) < 0.) NRst2InPlane.Reverse();
492
493 TgRst2 = nplan.Crossed(centptrst);
494
495 if (choix %2 != 0) {
496 TgRst1.Reverse();
497 TgRst2.Reverse();
498 }
499
81bba717 500 // The vectors are returned
7fd59977 501 if (NRst1InPlane.Dot(TgRst1) > -1.e-10) {
502 if (NRst2InPlane.Dot(TgRst2) < 1.e-10) {
503 return Blend_DecrochBoth;
504 }
505 else {
506 return Blend_DecrochRst1;
507 }
508 }
509 else {
510 if (NRst2InPlane.Dot(TgRst2) < 1.e-10) {
511 return Blend_DecrochRst2;
512 }
513 else {
514 return Blend_NoDecroch;
515 }
516 }
517
518}
519
520//=======================================================================
521//function : Set
522//purpose :
523//=======================================================================
524
525void BRepBlend_RstRstConstRad::Set(const Standard_Real Radius,
526 const Standard_Integer Choix)
527{
528 choix = Choix;
529 ray = Abs(Radius);
530
531}
532
533//=======================================================================
534//function : Set
535//purpose :
536//=======================================================================
537
538void BRepBlend_RstRstConstRad::Set(const BlendFunc_SectionShape TypeSection)
539{
540 mySShape = TypeSection;
541}
542
543
544
545//=======================================================================
546//function : CenterCircleRst1Rst2
81bba717 547//purpose : Calculate the center of the circle passing by two points of restrictions
7fd59977 548//=======================================================================
549Standard_Boolean BRepBlend_RstRstConstRad::CenterCircleRst1Rst2(const gp_Pnt& PtRst1,
550 const gp_Pnt& PtRst2,
551 const gp_Vec& np,
552 gp_Pnt& Center,
553 gp_Vec& VdMed) const
554{
555
556 gp_Vec rst1rst2(PtRst1, PtRst2);
81bba717 557 gp_Vec vdmedNor; //,NRst1; vdmedNor directong vector of the perpendicular bisector
7fd59977 558 Standard_Real norm2;
81bba717 559 Standard_Real Dist;// distance between the middle of PtRst1,PtRst2 and Center
7fd59977 560
81bba717 561 // Calculate the center of the circle
7fd59977 562 VdMed = rst1rst2.Crossed(np);
563 norm2 = rst1rst2.SquareMagnitude();
564 Dist = ray * ray - 0.25 * norm2;
565
566 if (choix > 2) {
567 VdMed.Reverse();
568 }
569
570 if (Dist < - 1.E-07) return Standard_False;
571
572 if (Dist > 1.E-07) {
573 Dist = sqrt(Dist);
574 vdmedNor = VdMed.Normalized();
575 Center.SetXYZ(0.5 * rst1rst2.XYZ() + PtRst1.XYZ() + Dist * vdmedNor.XYZ());
576 }
577 else
578 {
579 Center.SetXYZ(0.5 * rst1rst2.XYZ() + PtRst1.XYZ());
580 }
581
582 return Standard_True;
583
584}
585
586
587
588
589
590
591//=======================================================================
592//function : Section
593//purpose :
594//=======================================================================
595
596void BRepBlend_RstRstConstRad::Section(const Standard_Real Param,
597 const Standard_Real U,
598 const Standard_Real V,
599 Standard_Real& Pdeb,
600 Standard_Real& Pfin,
601 gp_Circ& C)
602{
603 gp_Vec ns, np, NotUsed;
604 gp_Pnt Center;
605
606 tguide->D1(Param, ptgui, d1gui);
607 np = d1gui.Normalized();
608 ptrst1 = cons1.Value(U);
609 ptrst2 = cons2.Value(V);
610
611 Standard_Boolean IsCenter;
612
613 IsCenter = CenterCircleRst1Rst2(ptrst1, ptrst2, np, Center, NotUsed);
614
615 C.SetRadius(Abs(ray));
616 ns = gp_Vec(Center, ptrst1).Normalized();
617
618 if (choix%2 != 0) {
619 np.Reverse();
620 }
621
622 C.SetPosition(gp_Ax2(Center, np, ns));
623 Pdeb = 0; //ElCLib::Parameter(C, pts);
624 Pfin = ElCLib::Parameter(C, ptrst2);
625
81bba717 626 // Test of angles negative and almost null : Special Case
c6541a0c 627 if (Pfin > 1.5 * M_PI) {
7fd59977 628 np.Reverse();
629 C.SetPosition(gp_Ax2(Center, np, ns));
630 Pfin = ElCLib::Parameter(C, ptrst2);
631 }
632 if (Pfin < Precision::PConfusion()) Pfin += Precision::PConfusion();
633}
634
635//=======================================================================
636//function : IsRational
637//purpose :
638//=======================================================================
639
640Standard_Boolean BRepBlend_RstRstConstRad::IsRational () const
641{
642 return (mySShape==BlendFunc_Rational || mySShape==BlendFunc_QuasiAngular);
643}
644
645//=======================================================================
646//function : GetSectionSize
647//purpose :
648//=======================================================================
649
650Standard_Real BRepBlend_RstRstConstRad::GetSectionSize() const
651{
652 return maxang * Abs(ray);
653}
654
655//=======================================================================
656//function : GetMinimalWeight
657//purpose :
658//=======================================================================
659
660void BRepBlend_RstRstConstRad::GetMinimalWeight(TColStd_Array1OfReal& Weights) const
661{
662 BlendFunc::GetMinimalWeights(mySShape, myTConv, minang, maxang, Weights );
81bba717 663 // It is supposed that it does not depend on the Radius!
7fd59977 664}
665
666//=======================================================================
667//function : NbIntervals
668//purpose :
669//=======================================================================
670
671Standard_Integer BRepBlend_RstRstConstRad::NbIntervals (const GeomAbs_Shape S) const
672{
673 return guide->NbIntervals(BlendFunc::NextShape(S));
674}
675
676//=======================================================================
677//function : Intervals
678//purpose :
679//=======================================================================
680
681void BRepBlend_RstRstConstRad::Intervals (TColStd_Array1OfReal& T,
682 const GeomAbs_Shape S) const
683{
684 guide->Intervals(T, BlendFunc::NextShape(S));
685}
686
687//=======================================================================
688//function : GetShape
689//purpose :
690//=======================================================================
691
692void BRepBlend_RstRstConstRad::GetShape (Standard_Integer& NbPoles,
693 Standard_Integer& NbKnots,
694 Standard_Integer& Degree,
695 Standard_Integer& NbPoles2d)
696{
697 NbPoles2d = 2;
698 BlendFunc::GetShape(mySShape, maxang, NbPoles, NbKnots, Degree, myTConv);
699}
700
701//=======================================================================
702//function : GetTolerance
81bba717 703//purpose : Determine Tolerances to be used in approximations.
7fd59977 704//=======================================================================
705
706void BRepBlend_RstRstConstRad::GetTolerance(const Standard_Real BoundTol,
707 const Standard_Real SurfTol,
708 const Standard_Real AngleTol,
709 math_Vector& Tol3d,
710 math_Vector& Tol1d) const
711{
712 Standard_Integer low = Tol3d.Lower(), up = Tol3d.Upper();
713 Standard_Real Tol;
714 Tol= GeomFill::GetTolerance(myTConv, minang, Abs(ray),
715 AngleTol, SurfTol);
716 Tol1d.Init(SurfTol);
717 Tol3d.Init(SurfTol);
718 Tol3d(low+1) = Tol3d(up-1) = Min(Tol, SurfTol);
719 Tol3d(low) = Tol3d(up) = Min(Tol, BoundTol);
720}
721
722//=======================================================================
723//function : Knots
724//purpose :
725//=======================================================================
726
727void BRepBlend_RstRstConstRad::Knots(TColStd_Array1OfReal& TKnots)
728{
729 GeomFill::Knots(myTConv, TKnots);
730}
731
732//=======================================================================
733//function : Mults
734//purpose :
735//=======================================================================
736
737void BRepBlend_RstRstConstRad::Mults(TColStd_Array1OfInteger& TMults)
738{
739 GeomFill::Mults(myTConv, TMults);
740}
741
742//=======================================================================
743//function : Section
744//purpose :
745//=======================================================================
746
747void BRepBlend_RstRstConstRad::Section(const Blend_Point& P,
748 TColgp_Array1OfPnt& Poles,
749 TColgp_Array1OfPnt2d& Poles2d,
750 TColStd_Array1OfReal& Weights)
751{
752 gp_Vec ns, ns2, NotUsed;
753 gp_Pnt Center;
754 Standard_Real u, v;
755
756 Standard_Real prm = P.Parameter();
757 Standard_Integer low = Poles.Lower();
758 Standard_Integer upp = Poles.Upper();
759
760 tguide->D1(prm,ptgui, d1gui);
761 nplan = d1gui.Normalized();
762
763 u = P.ParameterOnC1();
764 v = P.ParameterOnC2();
765
766 gp_Pnt2d pt2d1 = rst1->Value(u);
767 gp_Pnt2d pt2d2 = rst2->Value(v);
768
769 ptrst1 = cons1.Value(u);
770 ptrst2 = cons2.Value(v);
771 distmin = Min (distmin, ptrst1.Distance(ptrst2));
772
773 Poles2d(Poles2d.Lower()).SetCoord(pt2d1.X(),pt2d1.Y());
774 Poles2d(Poles2d.Upper()).SetCoord(pt2d2.X(),pt2d2.Y());
775
81bba717 776 // Linear case
7fd59977 777 if (mySShape == BlendFunc_Linear) {
778 Poles(low) = ptrst1;
779 Poles(upp) = ptrst2;
780 Weights(low) = 1.0;
781 Weights(upp) = 1.0;
782 return;
783 }
784
81bba717 785 // Calculate the center of the circle
7fd59977 786 Standard_Boolean IsCenter;
787 IsCenter = CenterCircleRst1Rst2(ptrst1, ptrst2, nplan, Center, NotUsed);
788
81bba717 789 // normals to the section with points
7fd59977 790 ns = gp_Vec(Center, ptrst1).Normalized();
791 ns2 = gp_Vec(Center, ptrst2).Normalized();
792
793 if (choix%2 != 0) {
794 nplan.Reverse();
795 }
796
797 GeomFill::GetCircle(myTConv,
798 ns, ns2,
799 nplan, ptrst1, ptrst2,
800 Abs(ray), Center,
801 Poles, Weights);
802}
803
804//=======================================================================
805//function : Section
806//purpose :
807//=======================================================================
808
809Standard_Boolean BRepBlend_RstRstConstRad::Section(const Blend_Point& P,
810 TColgp_Array1OfPnt& Poles,
811 TColgp_Array1OfVec& DPoles,
812 TColgp_Array1OfPnt2d& Poles2d,
813 TColgp_Array1OfVec2d& DPoles2d,
814 TColStd_Array1OfReal& Weights,
815 TColStd_Array1OfReal& DWeights)
816{
817
818 gp_Vec d11, d21;
819 gp_Vec dnplan, d1n1, d1n2;//,np2, dnp2;
820 gp_Vec temp, tgct;
821 gp_Vec d1urst, d1vrst;
822 gp_Pnt Center, NotUsed;
823
824 Standard_Real norm2, normmed, Dist;
825
826 math_Vector sol(1, 2), valsol(1, 2), secmember(1, 2);
827 math_Matrix gradsol(1, 2, 1, 2);
828
829 Standard_Real prm = P.Parameter();
7fd59977 830 Standard_Integer low = Poles.Lower();
831 Standard_Integer upp = Poles.Upper();
832 Standard_Boolean istgt;
833
834 tguide->D2(prm, ptgui, d1gui, d2gui);
835 normtg = d1gui.Magnitude();
836 nplan = d1gui.Normalized();
837 dnplan.SetLinearForm(1./normtg, d2gui,
838 -1./normtg * (nplan.Dot(d2gui)), nplan);
839
840 sol(1) = prmrst1 = P.ParameterOnC1();
841 sol(2) = prmrst2 = P.ParameterOnC2();
842 pt2drst1 = rst1->Value(prmrst1);
843 pt2drst2 = rst2->Value(prmrst2);
844
845 Values(sol, valsol, gradsol);
846
847 cons1.D1(sol(1), ptrst1, d11);
848 cons2.D1(sol(2), ptrst2, d21);
849
850 temp.SetXYZ(ptrst1.XYZ() - ptgui.XYZ());
851 secmember(1) = normtg - dnplan.Dot(temp);
852
853 temp.SetXYZ(ptrst2.XYZ() - ptgui.XYZ());
854 secmember(2) = normtg - dnplan.Dot(temp);
855
856 math_Gauss Resol(gradsol, 1.e-9);
857
858 if (Resol.IsDone()) {
859 istgt = Standard_False;
860 Resol.Solve(secmember);
861 }
862 else {
863 math_SVD SingRS (gradsol);
864 if (SingRS.IsDone()) {
865 math_Vector DEDT(1,2);
866 DEDT = secmember;
867 SingRS.Solve(DEDT, secmember, 1.e-6);
868 istgt = Standard_False;
869 }
870 else istgt = Standard_True;
871 }
872
873 gp_Vec med;
874 gp_Vec rst1rst2(ptrst1, ptrst2);
875 Standard_Boolean IsCenter;
876
877 IsCenter = CenterCircleRst1Rst2(ptrst1, ptrst2, nplan, Center, med);
878 if (!IsCenter) return Standard_False;
879
880 normmed = med.Magnitude();
881 med.Normalize();
882 gp_Vec n1(Center, ptrst1), n2(Center, ptrst2);
883 n1.Normalize();
884 n2.Normalize();
885
886 if (!istgt) {
81bba717 887 // secmember contains derivatives of parameters on curves
888 // compared to t
7fd59977 889 tgrst1 = secmember(1) * d11;
890 tgrst2 = secmember(2) * d21;
891
892 gp_Vec d1rst1rst2;
893
894 norm2 = rst1rst2.SquareMagnitude();
895 d1rst1rst2 = tgrst2 - tgrst1;
896 Dist = ray * ray - 0.25 * norm2;
897
898 if (Dist > 1.E-07) {
899 gp_Vec d1P1P2CrosNp, dmed;
900 d1P1P2CrosNp = d1rst1rst2.Crossed(nplan) + rst1rst2.Crossed(dnplan);
81bba717 901 // derivative of the perpendicular bisector
7fd59977 902 dmed = d1P1P2CrosNp - med.Dot(d1P1P2CrosNp) * med;
903 dmed /= normmed;
904 Dist = sqrt(Dist);
905 Standard_Real d1Dist = - (0.25 / Dist) * rst1rst2.Dot(d1rst1rst2);
906
907 if (choix > 2) {
908 dmed.Reverse();
909 }
910
81bba717 911 // the derivative of coefficient Dist is located in dmed
7fd59977 912 dmed.SetLinearForm(Dist, dmed, d1Dist, med);
913 d1rst1rst2 *= 0.5;
81bba717 914 // derivative of the Normal to the curve in P1
7fd59977 915 d1n1 = - (dmed + d1rst1rst2) / ray;
916
81bba717 917 // derivative of the Normal to the curve in P2
7fd59977 918 d1n2 = (d1rst1rst2 - dmed) / ray;
919 }
920 else {
921 d1rst1rst2 *= 0.5;
81bba717 922 // Normal to the curve in P1
7fd59977 923 d1n1 = - d1rst1rst2 / ray;
924
81bba717 925 // Normal to the curve in P2
7fd59977 926 d1n2 = d1rst1rst2 / ray;
927 }
928 }
929
81bba717 930 // Tops 2d
7fd59977 931
932 Poles2d(Poles2d.Lower()).SetCoord(pt2drst1.X(), pt2drst1.Y());
933 Poles2d(Poles2d.Upper()).SetCoord(pt2drst2.X(), pt2drst2.Y());
934 if (!istgt) {
935 Standard_Real a, b;
936 surf1->D1(pt2drst1.X(), pt2drst1.Y(), NotUsed, d1urst, d1vrst);
937 t3dto2d(a,b,tgrst1, d1urst, d1vrst);
938 DPoles2d(Poles2d.Lower()).SetCoord(a, b);
939
940 surf2->D1(pt2drst2.X(), pt2drst2.Y(), NotUsed, d1urst, d1vrst);
941 t3dto2d(a, b, tgrst2, d1urst, d1vrst);
942 DPoles2d(Poles2d.Upper()).SetCoord(a, b);
943 }
944
81bba717 945 // Linear case
7fd59977 946 if (mySShape == BlendFunc_Linear) {
947 Poles(low) = ptrst1;
948 Poles(upp) = ptrst2;
949 Weights(low) = 1.0;
950 Weights(upp) = 1.0;
951 if (!istgt) {
952 DPoles(low) = tgrst1;
953 DPoles(upp) = tgrst2;
954 DWeights(low) = 0.0;
955 DWeights(upp) = 0.0;
956 }
957 return (!istgt);
958 }
959
81bba717 960 // Case of the circle
961 // tangent to the center of the circle
7fd59977 962 if (!istgt) {
963 tgct.SetLinearForm(-ray, d1n1, tgrst1);
964 }
965
966
967 if (choix%2 != 0) {
968 nplan.Reverse();
969 dnplan.Reverse();
970 }
971
972 if (!istgt) {
973 return GeomFill::GetCircle(myTConv,
974 n1, n2,
975 d1n1, d1n2,
976 nplan, dnplan,
977 ptrst1, ptrst2,
978 tgrst1, tgrst2,
979 Abs(ray), 0,
980 Center, tgct,
981 Poles,
982 DPoles,
983 Weights,
984 DWeights);
985 }
986 else {
987 GeomFill::GetCircle(myTConv,
988 n1, n2,
989 nplan, ptrst1, ptrst2,
990 Abs(ray), Center,
991 Poles, Weights);
992 return Standard_False;
993 }
994}
995
996//=======================================================================
997//function : Section
998//purpose :
999//=======================================================================
1000
1001Standard_Boolean BRepBlend_RstRstConstRad::Section
1002(const Blend_Point&,
1003 TColgp_Array1OfPnt&,
1004 TColgp_Array1OfVec&,
1005 TColgp_Array1OfVec&,
1006 TColgp_Array1OfPnt2d&,
1007 TColgp_Array1OfVec2d&,
1008 TColgp_Array1OfVec2d&,
1009 TColStd_Array1OfReal&,
1010 TColStd_Array1OfReal&,
1011 TColStd_Array1OfReal&)
1012{
1013 return Standard_False;
1014}
1015
1016
1017void BRepBlend_RstRstConstRad::Resolution(const Standard_Integer IC2d,
1018 const Standard_Real Tol,
1019 Standard_Real& TolU,
1020 Standard_Real& TolV) const
1021{
1022 if(IC2d == 1){
1023 TolU = surf1->UResolution(Tol);
1024 TolV = surf1->VResolution(Tol);
1025 }
1026 else {
1027 TolU = surf2->UResolution(Tol);
1028 TolV = surf2->VResolution(Tol);
1029 }
1030}
1031