0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / BlendFunc / BlendFunc_ChAsym.cxx
1 // Created on: 1998-06-02
2 // Created by: Philippe NOUAILLE
3 // Copyright (c) 1998-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 <Adaptor3d_HCurve.hxx>
19 #include <Adaptor3d_HSurface.hxx>
20 #include <Blend_Point.hxx>
21 #include <BlendFunc.hxx>
22 #include <BlendFunc_ChAsym.hxx>
23 #include <ElCLib.hxx>
24 #include <gp_Lin.hxx>
25 #include <gp_Pnt.hxx>
26 #include <gp_Vec.hxx>
27 #include <gp_Vec2d.hxx>
28 #include <math_Gauss.hxx>
29 #include <math_Matrix.hxx>
30 #include <math_SVD.hxx>
31 #include <Precision.hxx>
32 #include <Standard_NotImplemented.hxx>
33
34 //=======================================================================
35 //function : BlendFunc_ChAsym
36 //purpose  : 
37 //=======================================================================
38 BlendFunc_ChAsym::BlendFunc_ChAsym(const Handle(Adaptor3d_HSurface)& S1,
39                                    const Handle(Adaptor3d_HSurface)& S2,
40                                    const Handle(Adaptor3d_HCurve)& C) :
41     surf1(S1),surf2(S2),
42     curv(C), tcurv(C),
43     param(0),
44     dist1(RealLast()),
45     angle(RealLast()),
46     tgang(RealLast()),
47     FX(1, 4),
48     DX(1, 4, 1, 4),
49     istangent(Standard_True),
50     choix(0),
51     distmin(RealLast())
52
53 }
54
55
56 //=======================================================================
57 //function : NbEquations
58 //purpose  : 
59 //=======================================================================
60
61 Standard_Integer BlendFunc_ChAsym::NbEquations () const
62 {
63   return 4;
64 }
65
66
67
68 //=======================================================================
69 //function : Set
70 //purpose  : 
71 //=======================================================================
72
73 void BlendFunc_ChAsym::Set(const Standard_Real Param)
74 {
75   param = Param;
76 }
77
78 //=======================================================================
79 //function : Set
80 //purpose  : Segmente la courbe a sa partie utile.
81 //           La precision est prise arbitrairement petite !?
82 //=======================================================================
83
84 void BlendFunc_ChAsym::Set(const Standard_Real First, const Standard_Real Last)
85 {
86   tcurv = curv->Trim(First, Last, 1.e-12);
87 }
88
89 //=======================================================================
90 //function : GetTolerance
91 //purpose  : 
92 //=======================================================================
93
94 void BlendFunc_ChAsym::GetTolerance(math_Vector& Tolerance, const Standard_Real Tol) const
95 {
96   Tolerance(1) = surf1->UResolution(Tol);
97   Tolerance(2) = surf1->VResolution(Tol);
98   Tolerance(3) = surf2->UResolution(Tol);
99   Tolerance(4) = surf2->VResolution(Tol);
100 }
101
102
103 //=======================================================================
104 //function : GetBounds
105 //purpose  : 
106 //=======================================================================
107
108 void BlendFunc_ChAsym::GetBounds(math_Vector& InfBound, math_Vector& SupBound) const
109 {
110   InfBound(1) = surf1->FirstUParameter();
111   InfBound(2) = surf1->FirstVParameter();
112   InfBound(3) = surf2->FirstUParameter();
113   InfBound(4) = surf2->FirstVParameter();
114   SupBound(1) = surf1->LastUParameter();
115   SupBound(2) = surf1->LastVParameter();
116   SupBound(3) = surf2->LastUParameter();
117   SupBound(4) = surf2->LastVParameter();
118
119   for(Standard_Integer i = 1; i <= 4; i++){
120     if(!Precision::IsInfinite(InfBound(i)) &&
121        !Precision::IsInfinite(SupBound(i))) {
122       const Standard_Real range = (SupBound(i) - InfBound(i));
123       InfBound(i) -= range;
124       SupBound(i) += range;
125     }
126   }
127 }
128
129
130 //=======================================================================
131 //function : IsSolution
132 //purpose  : 
133 //=======================================================================
134
135 Standard_Boolean BlendFunc_ChAsym::IsSolution(const math_Vector& Sol, const Standard_Real Tol)
136 {
137   math_Vector valsol(1, 4), secmember(1, 4);
138   math_Matrix gradsol(1, 4, 1, 4);
139
140   gp_Pnt ptgui;
141   gp_Vec np, dnp, d1gui, d2gui, Nsurf1, dwtsurf1;
142   gp_Vec d1u1, d1v1, d1u2, d1v2;  
143   Standard_Real Normg;
144
145   tcurv->D2(param, ptgui, d1gui, d2gui);
146   Normg  = d1gui.Magnitude(); 
147   np     = d1gui.Normalized();
148   dnp    = (d2gui - np.Dot(d2gui) * np) / Normg;
149
150  if (choix%2 != 0) {
151     np.Reverse();
152     dnp.Reverse();
153     Normg = -Normg;
154   }
155
156   surf1->D1(Sol(1), Sol(2), pt1, d1u1, d1v1);
157   Nsurf1   = d1u1.Crossed(d1v1);
158   tsurf1   = Nsurf1.Crossed(np);
159   dwtsurf1 = Nsurf1.Crossed(dnp);
160
161   surf2->D1(Sol(3), Sol(4), pt2, d1u2, d1v2);
162
163   gp_Vec pguis1(ptgui, pt1), pguis2(ptgui, pt2);
164   gp_Vec CrossVec, s1s2(pt1, pt2);
165   Standard_Real PScaInv = 1. / tsurf1.Dot(s1s2), F4, temp;   
166   Standard_Real maxpiv  = 1.e-9;
167   Standard_Real Nordu1 = d1u1.Magnitude(),
168                 Nordv1 = d1v1.Magnitude();
169
170   temp = 2. * (Nordu1 + Nordv1) * s1s2.Magnitude() + 2. * Nordu1 * Nordv1;
171
172   Values(Sol, valsol, gradsol);
173
174   if (Abs(valsol(1)) < Tol &&
175       Abs(valsol(2)) < Tol &&
176       Abs(valsol(3)) < 2. * dist1 * Tol  &&
177       Abs(valsol(4)) < Tol * (1. + tgang) * Abs(PScaInv) * temp) {
178
179     secmember(1) = Normg - dnp.Dot(pguis1);
180     secmember(2) = Normg - dnp.Dot(pguis2);
181     secmember(3) = - 2. * d1gui.Dot(pguis1); 
182
183     CrossVec     = tsurf1.Crossed(s1s2);
184     F4           = np.Dot(CrossVec) * PScaInv;
185     temp         = dnp.Dot(CrossVec) + np.Dot(dwtsurf1.Crossed(s1s2));
186
187     temp        -= F4 * dwtsurf1.Dot(s1s2);
188     secmember(4) = PScaInv * temp;
189
190     math_Gauss Resol(gradsol, maxpiv);
191
192     if (Resol.IsDone()) {
193       Resol.Solve(secmember);
194       istangent = Standard_False;
195     }
196     else {
197       math_SVD SingRS (gradsol);
198       if (SingRS.IsDone()) {
199         math_Vector DEDT(1,4);
200         DEDT = secmember;
201         SingRS.Solve(DEDT, secmember, 1.e-6);
202         istangent = Standard_False;
203       }
204       else istangent = Standard_True;    
205     }
206
207     if (!istangent) {
208       tg1.SetLinearForm(secmember(1), d1u1, secmember(2), d1v1);
209       tg2.SetLinearForm(secmember(3), d1u2, secmember(4), d1v2);
210       tg12d.SetCoord(secmember(1),secmember(2));
211       tg22d.SetCoord(secmember(3),secmember(4));
212     }
213
214     distmin = Min( distmin, pt1.Distance(pt2));
215
216     return Standard_True;
217   }
218
219   istangent = Standard_True;
220   return Standard_False;  
221 }
222
223
224 //=======================================================================
225 //function : GetMinimalDistance
226 //purpose  : 
227 //=======================================================================
228
229 Standard_Real BlendFunc_ChAsym::GetMinimalDistance() const
230 {
231   return distmin;
232 }
233
234 //=======================================================================
235 //function : ComputeValues
236 //purpose  : 
237 //=======================================================================
238 Standard_Boolean BlendFunc_ChAsym::ComputeValues(const math_Vector& X,
239                                                  const Standard_Integer DegF,
240                                                  const Standard_Integer DegL)
241 {
242   if (DegF > DegL) return Standard_False;
243
244   gp_Vec np, d1gui, d1u1, d1v1, d2u1, d2v1, d2uv1, d1u2, d1v2, Nsurf1;
245   gp_Pnt ptgui;  
246   Standard_Real PScaInv, F4; 
247
248   tcurv->D1(param, ptgui, d1gui);
249   nplan  = d1gui.Normalized();
250   np     = nplan;
251
252   if (choix%2 != 0) np.Reverse();
253
254   if ( (DegF == 0) && (DegL == 0) ) {
255     surf1->D1(X(1), X(2), pt1, d1u1, d1v1);
256     pt2   = surf2->Value(X(3), X(4));
257   }
258   else { 
259     surf1->D2(X(1), X(2), pt1, d1u1, d1v1, d2u1, d2v1, d2uv1);
260     surf2->D1(X(3), X(4), pt2, d1u2, d1v2);
261   }
262
263   Nsurf1 = d1u1.Crossed(d1v1);
264   tsurf1 = Nsurf1.Crossed(np);
265
266   gp_Vec nps1(ptgui, pt1), s1s2(pt1, pt2);//, tempVec;     
267   PScaInv = 1. /  tsurf1.Dot(s1s2);
268   F4      = np.Dot(tsurf1.Crossed(s1s2)) * PScaInv;
269
270   if (DegF == 0) {
271     Standard_Real Dist;
272     Dist    = ptgui.XYZ().Dot(np.XYZ());
273
274     FX(1) = pt1.XYZ().Dot(np.XYZ()) - Dist;
275     FX(2) = pt2.XYZ().Dot(np.XYZ()) - Dist;
276     FX(3) = dist1 * dist1 - nps1.SquareMagnitude(); 
277     FX(4) = tgang - F4;
278   }
279
280   if (DegL == 1) { 
281     Standard_Real temp;
282     gp_Vec tempVec;
283     gp_Vec d1utsurf1, d1vtsurf1; 
284     d1utsurf1 = (d2u1.Crossed(d1v1) + d1u1.Crossed(d2uv1)).Crossed(np);
285     d1vtsurf1 = (d2uv1.Crossed(d1v1) + d1u1.Crossed(d2v1)).Crossed(np);
286     
287     DX(1, 1) = np.Dot(d1u1);
288     DX(1, 2) = np.Dot(d1v1);
289     DX(1, 3) = 0.;
290     DX(1, 4) = 0.;
291     
292     DX(2, 1) = 0.;
293     DX(2, 2) = 0.;
294     DX(2, 3) = np.Dot(d1u2);
295     DX(2, 4) =  np.Dot(d1v2);
296     
297     tempVec  = -2. * nps1;
298     DX(3, 1) = d1u1.Dot(tempVec);
299     DX(3, 2) = d1v1.Dot(tempVec);
300     DX(3, 3) = 0.;
301     DX(3, 4) = 0.;
302  
303     temp     = F4 * (d1utsurf1.Dot(s1s2) - tsurf1.Dot(d1u1));
304     temp    += np.Dot(tsurf1.Crossed(d1u1) - d1utsurf1.Crossed(s1s2));
305     DX(4, 1) = temp * PScaInv;
306     
307     temp     = F4 * (d1vtsurf1.Dot(s1s2) - tsurf1.Dot(d1v1));
308     temp    += np.Dot(tsurf1.Crossed(d1v1) - d1vtsurf1.Crossed(s1s2));
309     DX(4, 2) = temp * PScaInv;
310     
311     temp     = F4 * tsurf1.Dot(d1u2) - np.Dot(tsurf1.Crossed(d1u2));
312     DX(4, 3) = temp * PScaInv;
313
314     temp     = F4 * tsurf1.Dot(d1v2) - np.Dot(tsurf1.Crossed(d1v2));
315     DX(4, 4) = temp * PScaInv;  
316   }
317
318   return Standard_True;
319
320 }
321
322
323 //=======================================================================
324 //function : Value
325 //purpose  : 
326 //=======================================================================
327
328 Standard_Boolean BlendFunc_ChAsym::Value(const math_Vector& X, math_Vector& F)
329 {
330   const Standard_Boolean Error = ComputeValues(X, 0, 0);
331   F = FX;
332   return Error;
333 }
334
335
336 //=======================================================================
337 //function : Derivatives
338 //purpose  : 
339 //=======================================================================
340
341 Standard_Boolean BlendFunc_ChAsym::Derivatives(const math_Vector& X, math_Matrix& D)
342 {
343   const Standard_Boolean Error =  ComputeValues(X, 1, 1);
344   D = DX;
345   return Error;
346 }
347
348
349 //=======================================================================
350 //function : Values
351 //purpose  : 
352 //=======================================================================
353
354 Standard_Boolean BlendFunc_ChAsym::Values(const math_Vector& X, math_Vector& F, math_Matrix& D)
355 {
356   const Standard_Boolean Error = ComputeValues(X, 0, 1);
357   F = FX;
358   D = DX;
359   return Error;
360 }
361
362
363 //=======================================================================
364 //function : PointOnS1
365 //purpose  : 
366 //=======================================================================
367
368 const gp_Pnt& BlendFunc_ChAsym::PointOnS1 () const
369 {
370   return pt1;
371 }
372
373
374 //=======================================================================
375 //function : PointOnS2
376 //purpose  : 
377 //=======================================================================
378
379 const gp_Pnt& BlendFunc_ChAsym::PointOnS2 () const
380 {
381   return pt2;
382 }
383
384
385 //=======================================================================
386 //function : IsTangencyPoint
387 //purpose  : 
388 //=======================================================================
389
390 Standard_Boolean BlendFunc_ChAsym::IsTangencyPoint () const
391 {
392   return istangent;
393 }
394
395
396 //=======================================================================
397 //function : TangentOnS1
398 //purpose  : 
399 //=======================================================================
400
401 const gp_Vec& BlendFunc_ChAsym::TangentOnS1 () const
402 {
403   if (istangent)
404     throw Standard_DomainError("BlendFunc_ChAsym::TangentOnS1");
405   return tg1;
406 }
407
408
409 //=======================================================================
410 //function : Tangent2dOnS1
411 //purpose  : 
412 //=======================================================================
413
414 const gp_Vec2d& BlendFunc_ChAsym::Tangent2dOnS1 () const
415 {
416   if (istangent)
417     throw Standard_DomainError("BlendFunc_ChAsym::Tangent2dOnS1");
418   return tg12d;
419 }
420
421 //=======================================================================
422 //function : TangentOnS2
423 //purpose  : 
424 //=======================================================================
425
426 const gp_Vec& BlendFunc_ChAsym::TangentOnS2 () const
427 {
428   if (istangent)
429     throw Standard_DomainError("BlendFunc_ChAsym::TangentOnS2");
430   return tg2;
431 }
432
433
434 //=======================================================================
435 //function : Tangent2dOnS2
436 //purpose  : 
437 //=======================================================================
438
439 const gp_Vec2d& BlendFunc_ChAsym::Tangent2dOnS2 () const
440 {
441   if (istangent)
442     throw Standard_DomainError("BlendFunc_ChAsym::Tangent2dOnS2");
443   return tg22d;
444 }
445
446
447 //=======================================================================
448 //function : TwistOnS1
449 //purpose  : 
450 //=======================================================================
451
452 Standard_Boolean BlendFunc_ChAsym::TwistOnS1() const
453 {
454   if (istangent)
455     throw Standard_DomainError("BlendFunc_ChAsym::TwistOnS1");
456   return tg1.Dot(nplan) < 0.;
457 }
458
459 //=======================================================================
460 //function : TwistOnS2
461 //purpose  : 
462 //=======================================================================
463
464 Standard_Boolean BlendFunc_ChAsym::TwistOnS2() const
465 {
466   if (istangent)
467     throw Standard_DomainError("BlendFunc_ChAsym::TwistOnS2");
468   return tg2.Dot(nplan) < 0.;
469 }
470
471 //=======================================================================
472 //function : Tangent
473 //purpose  : TgF,NmF et TgL,NmL les tangentes et normales respectives
474 //           aux surfaces S1 et S2 
475 //=======================================================================
476
477 void BlendFunc_ChAsym::Tangent(const Standard_Real U1,
478                                const Standard_Real V1,
479                                const Standard_Real U2,
480                                const Standard_Real V2,
481                                gp_Vec& TgF,
482                                gp_Vec& TgL,
483                                gp_Vec& NmF,
484                                gp_Vec& NmL) const
485 {
486   gp_Pnt Pt1,Pt2,ptgui;
487   gp_Vec d1u1,d1v1,d1u2,d1v2;
488   gp_Vec np, d1gui;
489   Standard_Boolean revF = Standard_False;
490   Standard_Boolean revL = Standard_False;
491
492   tcurv->D1(param, ptgui, d1gui);
493   np = d1gui.Normalized();
494
495   surf1->D1(U1,V1,Pt1,d1u1,d1v1);
496   NmF = d1u1.Crossed(d1v1);
497
498   surf2->D1(U2,V2,Pt2,d1u2,d1v2);
499   NmL = d1u2.Crossed(d1v2);
500
501   TgF = (np.Crossed(NmF)).Normalized();
502   TgL = (np.Crossed(NmL)).Normalized();
503
504   if ( (choix == 2)||(choix == 5) ){
505     revF = Standard_True;
506     revL = Standard_True;
507   }
508
509   if ( (choix == 4)||(choix == 7) )
510     revL = Standard_True;
511
512   if ( (choix == 3)||(choix == 8) )
513     revF = Standard_True;
514
515   if ( revF )
516     TgF.Reverse();
517   if ( revL )
518     TgL.Reverse();
519 }
520
521
522
523 //=======================================================================
524 //function : Section
525 //purpose  : 
526 //=======================================================================
527
528 void BlendFunc_ChAsym::Section(const Standard_Real /*Param*/,
529                                const Standard_Real U1,
530                                const Standard_Real V1,
531                                const Standard_Real U2,
532                                const Standard_Real V2,
533                                Standard_Real& Pdeb,
534                                Standard_Real& Pfin,
535                                gp_Lin& C)
536 {
537   const gp_Pnt Pt1 = surf1->Value(U1,V1);
538   const gp_Pnt Pt2 = surf2->Value(U2,V2);
539   const gp_Dir dir( gp_Vec(Pt1,Pt2) );
540
541   C.SetLocation(Pt1);
542   C.SetDirection(dir);
543
544   Pdeb = 0.;
545   Pfin = ElCLib::Parameter(C, Pt2);
546 }
547
548
549 //=======================================================================
550 //function : IsRational
551 //purpose  : 
552 //=======================================================================
553
554 Standard_Boolean BlendFunc_ChAsym::IsRational () const
555 {
556   return Standard_False; 
557 }
558
559 //=======================================================================
560 //function : GetSectionSize
561 //purpose  : 
562 //=======================================================================
563 Standard_Real BlendFunc_ChAsym::GetSectionSize() const 
564 {
565   throw Standard_NotImplemented("BlendFunc_ChAsym::GetSectionSize()");
566 }
567
568 //=======================================================================
569 //function : GetMinimalWeight
570 //purpose  : 
571 //=======================================================================
572 void BlendFunc_ChAsym::GetMinimalWeight(TColStd_Array1OfReal& Weights) const 
573 {
574   Weights.Init(1);
575 }
576
577 //=======================================================================
578 //function : NbIntervals
579 //purpose  : 
580 //=======================================================================
581
582 Standard_Integer BlendFunc_ChAsym::NbIntervals (const GeomAbs_Shape S) const
583 {
584   return curv->NbIntervals(BlendFunc::NextShape(S));
585 }
586
587
588 //=======================================================================
589 //function : Intervals
590 //purpose  : 
591 //=======================================================================
592
593 void BlendFunc_ChAsym::Intervals (TColStd_Array1OfReal& T, const GeomAbs_Shape S) const
594 {
595   curv->Intervals(T, BlendFunc::NextShape(S));
596 }
597
598 //=======================================================================
599 //function : GetShape
600 //purpose  : 
601 //=======================================================================
602
603 void BlendFunc_ChAsym::GetShape (Standard_Integer& NbPoles,
604                                  Standard_Integer& NbKnots,
605                                  Standard_Integer& Degree,
606                                  Standard_Integer& NbPoles2d)
607 {
608   NbPoles   = 2;
609   NbPoles2d = 2;
610   NbKnots   = 2;
611   Degree    = 1;
612 }
613
614 //=======================================================================
615 //function : GetTolerance
616 //purpose  : Determine les Tolerances a utiliser dans les approximations.
617 //=======================================================================
618 void BlendFunc_ChAsym::GetTolerance(const Standard_Real BoundTol, 
619                                     const Standard_Real, 
620                                     const Standard_Real, 
621                                     math_Vector& Tol3d, 
622                                     math_Vector&) const
623 {
624   Tol3d.Init(BoundTol);
625 }
626
627 //=======================================================================
628 //function : Knots
629 //purpose  : 
630 //=======================================================================
631
632 void BlendFunc_ChAsym::Knots(TColStd_Array1OfReal& TKnots)
633 {
634   TKnots(1) = 0.;
635   TKnots(2) = 1.;
636 }
637
638
639 //=======================================================================
640 //function : Mults
641 //purpose  : 
642 //=======================================================================
643
644 void BlendFunc_ChAsym::Mults(TColStd_Array1OfInteger& TMults)
645 {
646   TMults(1) = 2;
647   TMults(2) = 2;
648 }
649
650
651 //=======================================================================
652 //function : Section
653 //purpose  : 
654 //=======================================================================
655
656 void BlendFunc_ChAsym::Section(const Blend_Point& P,
657                                TColgp_Array1OfPnt& Poles,
658                                TColgp_Array1OfPnt2d& Poles2d,
659                                TColStd_Array1OfReal& Weights)
660 {
661   Standard_Real u1, v1, u2, v2, prm = P.Parameter();
662   Standard_Integer low = Poles.Lower();
663   Standard_Integer upp = Poles.Upper();
664   math_Vector X(1,4), F(1,4);
665
666   P.ParametersOnS1(u1, v1);
667   P.ParametersOnS2(u2, v2);
668   X(1) = u1;
669   X(2) = v1;
670   X(3) = u2;
671   X(4) = v2;
672   Poles2d(Poles2d.Lower()).SetCoord(u1,v1);
673   Poles2d(Poles2d.Upper()).SetCoord(u2,v2);
674
675   Set(prm);
676   Value(X,F);
677   Poles(low)   = PointOnS1();
678   Poles(upp)   = PointOnS2();
679   Weights(low) = 1.0;
680   Weights(upp) = 1.0;
681 }
682
683
684 //=======================================================================
685 //function : Section
686 //purpose  : 
687 //=======================================================================
688
689 Standard_Boolean BlendFunc_ChAsym::Section
690   (const Blend_Point& P,
691    TColgp_Array1OfPnt& Poles,
692    TColgp_Array1OfVec& DPoles,
693    TColgp_Array1OfPnt2d& Poles2d,
694    TColgp_Array1OfVec2d& DPoles2d,
695    TColStd_Array1OfReal& Weights,
696    TColStd_Array1OfReal& DWeights)
697 {
698   math_Vector Sol(1, 4), valsol(1, 4), secmember(1, 4);
699   math_Matrix gradsol(1, 4, 1, 4);
700   Standard_Real    prm = P.Parameter();
701   Standard_Integer low = Poles.Lower();
702   Standard_Integer upp = Poles.Upper();
703
704   P.ParametersOnS1(Sol(1),Sol(2));
705   P.ParametersOnS2(Sol(3),Sol(4));
706   Set(prm);
707   
708   Poles2d(Poles2d.Lower()).SetCoord(Sol(1),Sol(2));
709   Poles2d(Poles2d.Upper()).SetCoord(Sol(3),Sol(4));
710   Poles(low)   = PointOnS1();
711   Poles(upp)   = PointOnS2();
712   Weights(low) = 1.0;
713   Weights(upp) = 1.0;
714
715   gp_Pnt ptgui;
716   gp_Vec np, dnp, d1gui, d2gui, Nsurf1, dwtsurf1;
717   gp_Vec d1u1, d1v1, d1u2, d1v2;  
718   Standard_Real Normg;
719
720   tcurv->D2(param, ptgui, d1gui, d2gui);
721   Normg  = d1gui.Magnitude(); 
722   np     = d1gui.Normalized();
723   dnp    = (d2gui - np.Dot(d2gui) * np) / Normg;
724
725   if (choix%2 != 0) {
726      np.Reverse();
727      dnp.Reverse();
728      Normg = -Normg;
729   }
730
731   surf1->D1(Sol(1), Sol(2), pt1, d1u1, d1v1);
732   Nsurf1   = d1u1.Crossed(d1v1);
733   tsurf1   = Nsurf1.Crossed(np);
734   dwtsurf1 = Nsurf1.Crossed(dnp);
735
736   surf2->D1(Sol(3), Sol(4), pt2, d1u2, d1v2);
737
738   gp_Vec pguis1(ptgui, pt1), pguis2(ptgui, pt2);
739   gp_Vec CrossVec, s1s2(pt1, pt2);
740   Standard_Real PScaInv = 1. / tsurf1.Dot(s1s2), F4, temp;   
741   Standard_Real maxpiv  = 1.e-9;
742   Standard_Real Nordu1 = d1u1.Magnitude(),
743                 Nordv1 = d1v1.Magnitude();
744
745   temp = 2. * (Nordu1 + Nordv1) * s1s2.Magnitude() + 2. * Nordu1 * Nordv1;
746
747   Values(Sol, valsol, gradsol);
748
749   secmember(1) = Normg - dnp.Dot(pguis1);
750   secmember(2) = Normg - dnp.Dot(pguis2);
751   secmember(3) = - 2. * d1gui.Dot(pguis1); 
752
753   CrossVec     = tsurf1.Crossed(s1s2);
754   F4           = np.Dot(CrossVec) * PScaInv;
755   temp         = dnp.Dot(CrossVec) + np.Dot(dwtsurf1.Crossed(s1s2));
756   temp        -= F4 * dwtsurf1.Dot(s1s2);
757   secmember(4) = PScaInv * temp;
758
759   math_Gauss Resol(gradsol, maxpiv);
760
761   if (Resol.IsDone()) {
762     Resol.Solve(secmember);
763     istangent = Standard_False;
764   }
765   else {
766     math_SVD SingRS (gradsol);
767     if (SingRS.IsDone()) {
768       math_Vector DEDT(1,4);
769       DEDT = secmember;
770       SingRS.Solve(DEDT, secmember, 1.e-6);
771       istangent = Standard_False;
772     }
773     else istangent = Standard_True;    
774   }
775
776   if (!istangent) {
777     tg1.SetLinearForm(secmember(1), d1u1, secmember(2), d1v1);
778     tg2.SetLinearForm(secmember(3), d1u2, secmember(4), d1v2);
779     tg12d.SetCoord(secmember(1),secmember(2));
780     tg22d.SetCoord(secmember(3),secmember(4));
781   }
782
783   distmin = Min( distmin, pt1.Distance(pt2));
784
785   if (!istangent) {
786     DPoles2d(Poles2d.Lower()).SetCoord(Tangent2dOnS1().X(),
787                                        Tangent2dOnS1().Y());
788     DPoles2d(Poles2d.Upper()).SetCoord(Tangent2dOnS2().X(),
789                                        Tangent2dOnS2().Y());
790
791     DPoles(low)   = TangentOnS1();
792     DPoles(upp)   = TangentOnS2();
793     DWeights(low) = 0.0;
794     DWeights(upp) = 0.0;  
795   }
796
797   return (!istangent);
798
799 }
800
801
802 //=======================================================================
803 //function : Section
804 //purpose  : 
805 //=======================================================================
806
807 Standard_Boolean BlendFunc_ChAsym::Section
808   (const Blend_Point& /*P*/,
809    TColgp_Array1OfPnt& /*Poles*/,
810    TColgp_Array1OfVec& /*DPoles*/,
811    TColgp_Array1OfVec& /*D2Poles*/,
812    TColgp_Array1OfPnt2d& /*Poles2d*/,
813    TColgp_Array1OfVec2d& /*DPoles2d*/,
814    TColgp_Array1OfVec2d& /*D2Poles2d*/,
815    TColStd_Array1OfReal& /*Weights*/,
816    TColStd_Array1OfReal& /*DWeights*/,
817    TColStd_Array1OfReal& /*D2Weights*/)
818 {
819   return Standard_False;
820 }
821
822
823 //=======================================================================
824 //function : Resolution
825 //purpose  : 
826 //=======================================================================
827 void BlendFunc_ChAsym::Resolution(const Standard_Integer IC2d, const Standard_Real Tol,
828                                   Standard_Real& TolU, Standard_Real& TolV) const
829 {
830   if(IC2d == 1){
831     TolU = surf1->UResolution(Tol);
832     TolV = surf1->VResolution(Tol);
833   }
834   else {
835     TolU = surf2->UResolution(Tol);
836     TolV = surf2->VResolution(Tol);
837   }
838 }
839
840
841 //=======================================================================
842 //function : Set
843 //purpose  : 
844 //=======================================================================
845 void BlendFunc_ChAsym::Set(const Standard_Real Dist1,
846                            const Standard_Real Angle,
847                            const Standard_Integer Choix)
848 {
849   dist1 = Abs(Dist1);
850   angle = Angle;
851   tgang = Tan(Angle);
852   choix = Choix;
853 }