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