0028966: Coding Rules - remove Adaptor2d_HCurve2d, Adaptor3d_HCurve and Adaptor3d_HSu...
[occt.git] / src / BlendFunc / BlendFunc_Ruled.cxx
1 // Created on: 1993-12-02
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1993-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_Curve.hxx>
19 #include <Adaptor3d_Surface.hxx>
20 #include <Blend_Point.hxx>
21 #include <BlendFunc.hxx>
22 #include <BlendFunc_Ruled.hxx>
23 #include <gp_Ax1.hxx>
24 #include <gp_Pnt.hxx>
25 #include <gp_Pnt2d.hxx>
26 #include <gp_Vec.hxx>
27 #include <gp_Vec2d.hxx>
28 #include <math_Gauss.hxx>
29 #include <math_Matrix.hxx>
30 #include <Precision.hxx>
31 #include <Standard_DomainError.hxx>
32 #include <Standard_NotImplemented.hxx>
33
34 BlendFunc_Ruled::BlendFunc_Ruled(const Handle(Adaptor3d_Surface)& S1,
35                                  const Handle(Adaptor3d_Surface)& S2,
36                                  const Handle(Adaptor3d_Curve)& C) :
37
38                  surf1(S1),surf2(S2),curv(C),
39                  istangent(Standard_True),
40                  normtg(0.0), theD(0.0),
41                  distmin(RealLast())
42 {
43 }
44
45 Standard_Integer BlendFunc_Ruled::NbEquations () const
46 {
47   return 4;
48 }
49
50 void BlendFunc_Ruled::Set(const Standard_Real Param)
51 {
52   curv->D2(Param,ptgui,d1gui,d2gui);
53   normtg = d1gui.Magnitude();
54   nplan  = d1gui.Normalized();
55   theD = - (nplan.XYZ().Dot(ptgui.XYZ()));
56   istangent = Standard_True;
57 }
58
59 void BlendFunc_Ruled::Set(const Standard_Real,
60                           const Standard_Real)
61 {
62   throw Standard_NotImplemented("BlendFunc_Ruled::Set");
63 }
64
65 void BlendFunc_Ruled::GetTolerance(math_Vector& Tolerance,
66                                    const Standard_Real Tol) const
67 {
68   Tolerance(1) = surf1->UResolution(Tol);
69   Tolerance(2) = surf1->VResolution(Tol);
70   Tolerance(3) = surf2->UResolution(Tol);
71   Tolerance(4) = surf2->VResolution(Tol);
72 }
73
74 void BlendFunc_Ruled::GetBounds(math_Vector& InfBound,
75                                 math_Vector& SupBound) const
76 {
77   InfBound(1) = surf1->FirstUParameter();
78   InfBound(2) = surf1->FirstVParameter();
79   InfBound(3) = surf2->FirstUParameter();
80   InfBound(4) = surf2->FirstVParameter();
81   SupBound(1) = surf1->LastUParameter();
82   SupBound(2) = surf1->LastVParameter();
83   SupBound(3) = surf2->LastUParameter();
84   SupBound(4) = surf2->LastVParameter();
85
86   for(Standard_Integer i = 1; i <= 4; i++){
87     if(!Precision::IsInfinite(InfBound(i)) &&
88        !Precision::IsInfinite(SupBound(i))) {
89       const Standard_Real range = (SupBound(i) - InfBound(i));
90       InfBound(i) -= range;
91       SupBound(i) += range;
92     }
93   }
94 }
95
96 Standard_Boolean BlendFunc_Ruled::IsSolution(const math_Vector& Sol,
97                                              const Standard_Real Tol)
98 {
99   math_Vector valsol(1,4),secmember(1,4);
100   math_Matrix gradsol(1,4,1,4);
101
102   gp_Vec dnplan,d1u1,d1v1,d1u2,d1v2,temp,ns,ncrossns;
103   Standard_Real norm,ndotns,grosterme;
104
105   Values(Sol,valsol,gradsol);
106   if (Abs(valsol(1)) <= Tol &&
107       Abs(valsol(2)) <= Tol &&
108       Abs(valsol(3)) <= Tol &&
109       Abs(valsol(4)) <= Tol) {
110
111
112     // Calcul des tangentes
113
114     surf1->D1(Sol(1),Sol(2),pts1,d1u1,d1v1);
115     surf2->D1(Sol(3),Sol(4),pts2,d1u2,d1v2);
116     dnplan.SetLinearForm(1./normtg,d2gui,
117                          -1./normtg*(nplan.Dot(d2gui)),nplan);
118       
119     secmember(1) = normtg - dnplan.Dot(gp_Vec(ptgui,pts1));
120     secmember(2) = normtg - dnplan.Dot(gp_Vec(ptgui,pts2));
121
122     ns = d1u1.Crossed(d1v1);
123     ncrossns = nplan.Crossed(ns);
124     ndotns = nplan.Dot(ns);
125     norm = ncrossns.Magnitude();
126
127     // Derivee de nor1 par rapport au parametre sur la ligne guide
128     grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm;
129     temp.SetLinearForm((dnplan.Dot(ns)-grosterme*ndotns)/norm,nplan,
130                        ndotns/norm,dnplan,
131                        grosterme/norm,ns);
132
133
134     secmember(3) = -(temp.Dot(gp_Vec(pts1,pts2)));
135
136     ns = d1u2.Crossed(d1v2);
137     ncrossns = nplan.Crossed(ns);
138     ndotns = nplan.Dot(ns);
139     norm = ncrossns.Magnitude();
140
141     // Derivee de nor2 par rapport au parametre sur la ligne guide
142     grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm;
143     temp.SetLinearForm((dnplan.Dot(ns)-grosterme*ndotns)/norm,nplan,
144                        ndotns/norm,dnplan,
145                        grosterme/norm,ns);
146
147     secmember(4) = -(temp.Dot(gp_Vec(pts1,pts2)));
148
149     math_Gauss Resol(gradsol);
150     if (Resol.IsDone()) {
151
152       Resol.Solve(secmember);
153
154       tg1.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1);
155       tg2.SetLinearForm(secmember(3),d1u2,secmember(4),d1v2);
156       tg12d.SetCoord(secmember(1),secmember(2));
157       tg22d.SetCoord(secmember(3),secmember(4));
158       istangent = Standard_False;
159     }
160     else {
161       istangent = Standard_True;
162     }
163     return Standard_True;
164   }
165   istangent = Standard_True;
166   return Standard_False;
167 }
168
169
170 //=======================================================================
171 //function : GetMinimalDistance
172 //purpose  : 
173 //=======================================================================
174
175 Standard_Real BlendFunc_Ruled::GetMinimalDistance() const
176 {
177   return distmin;
178 }
179
180 Standard_Boolean BlendFunc_Ruled::Value(const math_Vector& X,
181                                         math_Vector& F)
182 {
183   gp_Vec d1u1,d1v1,d1u2,d1v2;
184   surf1->D1(X(1),X(2),pts1,d1u1,d1v1);
185   surf2->D1(X(3),X(4),pts2,d1u2,d1v2);
186
187   const gp_Vec temp(pts1,pts2);
188   
189   gp_Vec ns1 = d1u1.Crossed(d1v1);
190   gp_Vec ns2 = d1u2.Crossed(d1v2);
191   
192   const Standard_Real norm1 = nplan.Crossed(ns1).Magnitude();
193   const Standard_Real norm2 = nplan.Crossed(ns2).Magnitude();
194   ns1.SetLinearForm(nplan.Dot(ns1)/norm1,nplan, -1./norm1,ns1);
195   ns2.SetLinearForm(nplan.Dot(ns2)/norm2,nplan, -1./norm2,ns2);
196
197   F(1) = (nplan.XYZ().Dot(pts1.XYZ())) + theD;
198   F(2) = (nplan.XYZ().Dot(pts2.XYZ())) + theD;
199   
200   F(3) = temp.Dot(ns1);
201   F(4) = temp.Dot(ns2);
202
203   return Standard_True;
204 }
205
206 Standard_Boolean BlendFunc_Ruled::Derivatives(const math_Vector& X,
207                                               math_Matrix& D)
208 {
209   gp_Vec d1u1,d1v1,d1u2,d1v2;
210   gp_Vec d2u1,d2v1,d2uv1,d2u2,d2v2,d2uv2;
211   gp_Vec nor1,nor2,p1p2;
212   gp_Vec ns1,ns2,ncrossns1,ncrossns2,resul,temp;
213
214   Standard_Real norm1,norm2,ndotns1,ndotns2,grosterme;
215
216   surf1->D2(X(1),X(2),pts1,d1u1,d1v1,d2u1,d2v1,d2uv1);
217   surf2->D2(X(3),X(4),pts2,d1u2,d1v2,d2u2,d2v2,d2uv2);
218
219   D(1,1) = nplan.Dot(d1u1);
220   D(1,2) = nplan.Dot(d1v1);
221   D(1,3) = 0.;
222   D(1,4) = 0.;
223
224   D(2,1) = 0.;
225   D(2,2) = 0.;
226   D(2,3) = nplan.Dot(d1u2);
227   D(2,4) = nplan.Dot(d1v2);
228
229   ns1 = d1u1.Crossed(d1v1);
230   ns2 = d1u2.Crossed(d1v2);
231   ncrossns1 = nplan.Crossed(ns1);
232   ncrossns2 = nplan.Crossed(ns2);
233   norm1 = ncrossns1.Magnitude();
234   norm2 = ncrossns2.Magnitude();
235
236   ndotns1 = nplan.Dot(ns1);
237   ndotns2 = nplan.Dot(ns2);
238
239   nor1.SetLinearForm(ndotns1/norm1,nplan, -1./norm1,ns1);
240   nor2.SetLinearForm(ndotns2/norm2,nplan, -1./norm2,ns2);
241
242   p1p2 = gp_Vec(pts1,pts2);
243
244   // Derivee de nor1 par rapport a u1
245   temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
246   grosterme = ncrossns1.Dot(nplan.Crossed(temp))/norm1/norm1;
247   resul.SetLinearForm(-(grosterme*ndotns1-nplan.Dot(temp))/norm1,nplan,
248                       grosterme/norm1,ns1,
249                       -1./norm1,temp);
250
251   D(3,1) = -(d1u1.Dot(nor1)) + p1p2.Dot(resul);
252
253   // Derivee par rapport a v1
254   temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
255   grosterme = ncrossns1.Dot(nplan.Crossed(temp))/norm1/norm1;
256   resul.SetLinearForm(-(grosterme*ndotns1-nplan.Dot(temp))/norm1,nplan,
257                       grosterme/norm1,ns1,
258                       -1./norm1,temp);
259
260   D(3,2) = -(d1v1.Dot(nor1)) + p1p2.Dot(resul);
261
262   D(3,3) = d1u2.Dot(nor1);
263   D(3,4) = d1v2.Dot(nor1);
264
265
266   D(4,1) = -(d1u1.Dot(nor2));
267   D(4,2) = -(d1v1.Dot(nor2));
268
269   // Derivee de nor2 par rapport a u2
270   temp = d2u2.Crossed(d1v2).Added(d1u2.Crossed(d2uv2));
271   grosterme = ncrossns2.Dot(nplan.Crossed(temp))/norm2/norm2;
272   resul.SetLinearForm(-(grosterme*ndotns2-nplan.Dot(temp))/norm2,nplan,
273                       grosterme/norm2,ns2,
274                       -1./norm2,temp);
275
276   D(4,3) = d1u2.Dot(nor2) + p1p2.Dot(resul);
277
278   // Derivee par rapport a v2
279   temp = d2uv2.Crossed(d1v2).Added(d1u2.Crossed(d2v2));
280   grosterme = ncrossns2.Dot(nplan.Crossed(temp))/norm2/norm2;
281   resul.SetLinearForm(-(grosterme*ndotns2-nplan.Dot(temp))/norm2,nplan,
282                       grosterme/norm2,ns2,
283                       -1./norm2,temp);
284
285   D(4,4) = d1v2.Dot(nor2) + p1p2.Dot(resul);
286
287   return Standard_True;
288 }
289
290
291 Standard_Boolean BlendFunc_Ruled::Values(const math_Vector& X,
292                                          math_Vector& F,
293                                          math_Matrix& D)
294 {
295   gp_Vec d1u1,d1v1,d1u2,d1v2;
296   gp_Vec d2u1,d2v1,d2uv1,d2u2,d2v2,d2uv2;
297   gp_Vec nor1,nor2,p1p2;
298   gp_Vec ns1,ns2,ncrossns1,ncrossns2,resul,temp;
299
300   Standard_Real norm1,norm2,ndotns1,ndotns2,grosterme;
301
302   surf1->D2(X(1),X(2),pts1,d1u1,d1v1,d2u1,d2v1,d2uv1);
303   surf2->D2(X(3),X(4),pts2,d1u2,d1v2,d2u2,d2v2,d2uv2);
304
305   p1p2 = gp_Vec(pts1,pts2);
306
307   ns1 = d1u1.Crossed(d1v1);
308   ns2 = d1u2.Crossed(d1v2);
309   ncrossns1 = nplan.Crossed(ns1);
310   ncrossns2 = nplan.Crossed(ns2);
311   norm1 = ncrossns1.Magnitude();
312   norm2 = ncrossns2.Magnitude();
313
314   ndotns1 = nplan.Dot(ns1);
315   ndotns2 = nplan.Dot(ns2);
316
317   nor1.SetLinearForm(ndotns1/norm1,nplan,-1./norm1,ns1);
318   nor2.SetLinearForm(ndotns2/norm2,nplan,-1./norm2,ns2);
319
320   F(1) = (nplan.XYZ().Dot(pts1.XYZ())) + theD;
321   F(2) = (nplan.XYZ().Dot(pts2.XYZ())) + theD;
322   F(3) = p1p2.Dot(nor1);
323   F(4) = p1p2.Dot(nor2);
324
325   D(1,1) = nplan.Dot(d1u1);
326   D(1,2) = nplan.Dot(d1v1);
327   D(1,3) = 0.;
328   D(1,4) = 0.;
329
330   D(2,1) = 0.;
331   D(2,2) = 0.;
332   D(2,3) = nplan.Dot(d1u2);
333   D(2,4) = nplan.Dot(d1v2);
334
335
336   // Derivee de nor1 par rapport a u1
337   temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
338   grosterme = ncrossns1.Dot(nplan.Crossed(temp))/norm1/norm1;
339   resul.SetLinearForm(-(grosterme*ndotns1-nplan.Dot(temp))/norm1,nplan,
340                       grosterme/norm1,ns1,
341                       -1./norm1,temp);
342
343   D(3,1) = -(d1u1.Dot(nor1)) + p1p2.Dot(resul);
344
345   // Derivee par rapport a v1
346   temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
347   grosterme = ncrossns1.Dot(nplan.Crossed(temp))/norm1/norm1;
348   resul.SetLinearForm(-(grosterme*ndotns1-nplan.Dot(temp))/norm1,nplan,
349                       grosterme/norm1,ns1,
350                       -1./norm1,temp);
351
352   D(3,2) = -(d1v1.Dot(nor1)) + p1p2.Dot(resul);
353
354   D(3,3) = d1u2.Dot(nor1);
355   D(3,4) = d1v2.Dot(nor1);
356
357   D(4,1) = -(d1u1.Dot(nor2));
358   D(4,2) = -(d1v1.Dot(nor2));
359
360   // Derivee de nor2 par rapport a u2
361   temp = d2u2.Crossed(d1v2).Added(d1u2.Crossed(d2uv2));
362   grosterme = ncrossns2.Dot(nplan.Crossed(temp))/norm2/norm2;
363   resul.SetLinearForm(-(grosterme*ndotns2-nplan.Dot(temp))/norm2,nplan,
364                       grosterme/norm2,ns2,
365                       -1./norm2,temp);
366
367   D(4,3) = d1u2.Dot(nor2) + p1p2.Dot(resul);
368
369   // Derivee par rapport a v2
370   temp = d2uv2.Crossed(d1v2).Added(d1u2.Crossed(d2v2));
371   grosterme = ncrossns2.Dot(nplan.Crossed(temp))/norm2/norm2;
372   resul.SetLinearForm(-(grosterme*ndotns2-nplan.Dot(temp))/norm2,nplan,
373                       grosterme/norm2,ns2,
374                       -1./norm2,temp);
375
376   D(4,4) = d1v2.Dot(nor2) + p1p2.Dot(resul);
377
378   return Standard_True;
379 }
380
381
382 void BlendFunc_Ruled::Tangent(const Standard_Real U1,
383                               const Standard_Real V1,
384                               const Standard_Real U2,
385                               const Standard_Real V2,
386                               gp_Vec& TgF,
387                               gp_Vec& TgL,
388                               gp_Vec& NmF,
389                               gp_Vec& NmL) const
390 {
391   gp_Pnt bid;
392   gp_Vec d1u,d1v;
393   gp_Vec ns1;
394
395   surf2->D1(U2,V2,bid,d1u,d1v);
396   NmL = d1u.Crossed(d1v);
397
398   surf1->D1(U1,V1,bid,d1u,d1v);
399   NmF = ns1 = d1u.Crossed(d1v);
400
401   TgF = TgL = gp_Vec(pts1,pts2);
402 }
403
404 const gp_Pnt& BlendFunc_Ruled::PointOnS1 () const
405 {
406   return pts1;
407 }
408
409 const gp_Pnt& BlendFunc_Ruled::PointOnS2 () const
410 {
411   return pts2;
412 }
413
414 Standard_Boolean BlendFunc_Ruled::IsTangencyPoint () const
415 {
416   return istangent;
417 }
418
419 const gp_Vec& BlendFunc_Ruled::TangentOnS1 () const
420 {
421   if (istangent)
422     throw Standard_DomainError("BlendFunc_Ruled::TangentOnS1");
423   return tg1;
424 }
425
426 const gp_Vec& BlendFunc_Ruled::TangentOnS2 () const
427 {
428   if (istangent)
429     throw Standard_DomainError("BlendFunc_Ruled::TangentOnS2");
430   return tg2;
431 }
432 const gp_Vec2d& BlendFunc_Ruled::Tangent2dOnS1 () const
433 {
434   if (istangent)
435     throw Standard_DomainError("BlendFunc_Ruled::Tangent2dOnS1");
436   return tg12d;
437 }
438
439 const gp_Vec2d& BlendFunc_Ruled::Tangent2dOnS2 () const
440 {
441   if (istangent)
442     throw Standard_DomainError("BlendFunc_Ruled::Tangent2dOnS2");
443   return tg22d;
444 }
445
446 Standard_Boolean BlendFunc_Ruled::GetSection(const Standard_Real Param,
447                                              const Standard_Real U1,
448                                              const Standard_Real V1,
449                                              const Standard_Real U2,
450                                              const Standard_Real V2,
451                                              TColgp_Array1OfPnt& tabP,
452                                              TColgp_Array1OfVec& tabV)
453
454 {
455   Standard_Integer NbPoint=tabP.Length();
456   if (NbPoint != tabV.Length() || NbPoint < 2) {throw Standard_RangeError();}
457
458   Standard_Integer i, lowp = tabP.Lower(), lowv = tabV.Lower();
459
460
461   gp_Vec dnplan,d1u1,d1v1,d1u2,d1v2,temp,ns,ncrossns;
462   Standard_Real norm,ndotns,grosterme,lambda;
463
464   math_Vector sol(1,4),valsol(1,4),secmember(1,4);
465   math_Matrix gradsol(1,4,1,4);
466
467   curv->D2(Param,ptgui,d1gui,d2gui);
468   normtg = d1gui.Magnitude();
469   nplan  = d1gui.Normalized();
470   theD = - (nplan.XYZ().Dot(ptgui.XYZ()));
471
472   sol(1) = U1; sol(2) = V1; sol(3) = U2; sol(4) = V2;
473
474   Values(sol,valsol,gradsol);
475
476   surf1->D1(sol(1),sol(2),pts1,d1u1,d1v1);
477   surf2->D1(sol(3),sol(4),pts2,d1u2,d1v2);
478   dnplan.SetLinearForm(1./normtg,d2gui,
479                        -1./normtg*(nplan.Dot(d2gui)),nplan);
480       
481   secmember(1) = normtg - dnplan.Dot(gp_Vec(ptgui,pts1));
482   secmember(2) = normtg - dnplan.Dot(gp_Vec(ptgui,pts2));
483
484   ns = d1u1.Crossed(d1v1);
485   ncrossns = nplan.Crossed(ns);
486   ndotns = nplan.Dot(ns);
487   norm = ncrossns.Magnitude();
488
489   // Derivee de nor1 par rapport au parametre sur la ligne guide
490   grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm;
491   temp.SetLinearForm((dnplan.Dot(ns)-grosterme*ndotns)/norm,nplan,
492                      ndotns/norm,dnplan,
493                      grosterme/norm,ns);
494
495
496   secmember(3) = -(temp.Dot(gp_Vec(pts1,pts2)));
497
498   ns = d1u2.Crossed(d1v2);
499   ncrossns = nplan.Crossed(ns);
500   ndotns = nplan.Dot(ns);
501   norm = ncrossns.Magnitude();
502
503   // Derivee de nor2 par rapport au parametre sur la ligne guide
504   grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm;
505   temp.SetLinearForm((dnplan.Dot(ns)-grosterme*ndotns)/norm,nplan,
506                      ndotns/norm,dnplan,
507                      grosterme/norm,ns);
508
509   secmember(4) = -(temp.Dot(gp_Vec(pts1,pts2)));
510
511   math_Gauss Resol(gradsol);
512   if (Resol.IsDone()) {
513
514     Resol.Solve(secmember);
515
516     tg1.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1);
517     tg2.SetLinearForm(secmember(3),d1u2,secmember(4),d1v2);
518
519     tabP(lowp) = pts1;
520     tabP(lowp+NbPoint-1)  = pts2;
521
522     tabV(lowv) = tg1;
523     tabV(lowv+NbPoint-1)  = tg2;
524
525     for (i=2; i <= NbPoint-1; i++) {
526
527       lambda = (Standard_Real)(i-1)/(Standard_Real)(NbPoint-1);
528       tabP(lowp+i-1).SetXYZ((1.-lambda)*pts1.XYZ() + lambda*pts2.XYZ());
529       tabV(lowv+i-1).SetLinearForm(1.-lambda,tg1,lambda,tg2);
530     } 
531     return Standard_True;
532   }
533   return Standard_False;
534
535 }
536 //=======================================================================
537 //function : IsRationnal
538 //purpose  : 
539 //=======================================================================
540
541 Standard_Boolean BlendFunc_Ruled::IsRational () const
542 {
543   return Standard_False;
544 }
545
546
547 //=======================================================================
548 //function : GetSectionSize
549 //purpose  : 
550 //=======================================================================
551 Standard_Real BlendFunc_Ruled::GetSectionSize() const 
552 {
553   throw Standard_NotImplemented("BlendFunc_Ruled::GetSectionSize()");
554 }
555
556 //=======================================================================
557 //function : GetMinimalWeight
558 //purpose  : 
559 //=======================================================================
560 void BlendFunc_Ruled::GetMinimalWeight(TColStd_Array1OfReal& Weigths) const 
561 {
562   Weigths.Init(1);
563 }
564 //=======================================================================
565 //function : NbIntervals
566 //purpose  : 
567 //=======================================================================
568
569 Standard_Integer BlendFunc_Ruled::NbIntervals (const GeomAbs_Shape S) const
570 {
571   return curv->NbIntervals(BlendFunc::NextShape(S));
572 }
573
574
575 //=======================================================================
576 //function : Intervals
577 //purpose  : 
578 //=======================================================================
579
580 void BlendFunc_Ruled::Intervals (TColStd_Array1OfReal& T,
581                                  const GeomAbs_Shape S) const
582 {
583   curv->Intervals(T, BlendFunc::NextShape(S));
584 }
585
586 //=======================================================================
587 //function : GetShape
588 //purpose  : 
589 //=======================================================================
590 void BlendFunc_Ruled::GetShape(Standard_Integer& NbPoles,
591                                Standard_Integer& NbKnots,
592                                Standard_Integer& Degree,
593                                Standard_Integer& NbPoles2d)
594 {
595   NbPoles = 2;
596   NbKnots = 2;
597   Degree = 1;
598   NbPoles2d = 2;
599 }
600
601 //=======================================================================
602 //function : GetTolerance
603 //purpose  : Determine les Tolerance a utiliser dans les approximations.
604 //=======================================================================
605 void BlendFunc_Ruled::GetTolerance(const Standard_Real BoundTol, 
606                                    const Standard_Real, 
607                                    const Standard_Real, 
608                                    math_Vector& Tol3d, 
609                                    math_Vector&) const
610 {
611   Tol3d.Init(BoundTol);
612 }
613
614 void BlendFunc_Ruled::Knots(TColStd_Array1OfReal& TKnots)
615 {
616   TKnots(TKnots.Lower()) = 0.;
617   TKnots(TKnots.Upper()) = 1.;
618 }
619
620 void BlendFunc_Ruled::Mults(TColStd_Array1OfInteger& TMults)
621 {
622   TMults(TMults.Lower()) = TMults(TMults.Upper()) = 2;
623 }
624
625 Standard_Boolean BlendFunc_Ruled::Section(const Blend_Point& /*P*/,
626                                           TColgp_Array1OfPnt& /*Poles*/,
627                                           TColgp_Array1OfVec& /*DPoles*/,
628                                           TColgp_Array1OfVec& /*D2Poles*/,
629                                           TColgp_Array1OfPnt2d& /*Poles2d*/,
630                                           TColgp_Array1OfVec2d& /*DPoles2d*/,
631                                           TColgp_Array1OfVec2d& /*D2Poles2d*/,
632                                           TColStd_Array1OfReal& /*Weights*/,
633                                           TColStd_Array1OfReal& /*DWeights*/,
634                                           TColStd_Array1OfReal& /*D2Weights*/)
635 {
636   return Standard_False;
637 }
638
639 Standard_Boolean BlendFunc_Ruled::Section(const Blend_Point& P,
640                                           TColgp_Array1OfPnt& Poles,
641                                           TColgp_Array1OfVec& DPoles,
642                                           TColgp_Array1OfPnt2d& Poles2d,
643                                           TColgp_Array1OfVec2d& DPoles2d,
644                                           TColStd_Array1OfReal& Weights,
645                                           TColStd_Array1OfReal& DWeights)
646 {
647   Standard_Integer lowp = Poles.Lower(), lowp2d = Poles2d.Lower();
648   Standard_Real u,v;
649
650   Poles(lowp) = P.PointOnS1();
651   Poles(lowp+1)  = P.PointOnS2();
652   
653   P.ParametersOnS1(u,v);
654   Poles2d(lowp2d).SetCoord(u,v);
655   P.ParametersOnS2(u,v);
656   Poles2d(lowp2d+1).SetCoord(u,v);
657   
658   Weights(lowp) = 1.;
659   Weights(lowp+1) = 1.;
660   
661   if (!P.IsTangencyPoint()) {
662   
663     DPoles(lowp)= P.TangentOnS1();
664     DPoles(lowp+1)= P.TangentOnS2();
665   
666     DPoles2d(lowp2d)= P.Tangent2dOnS1();
667     DPoles2d(lowp2d+1)= P.Tangent2dOnS2();
668
669     DWeights(lowp) = 0.;
670     DWeights(lowp+1) = 0.;
671     
672     return Standard_True;
673   }
674
675   return Standard_False;
676 }
677
678
679 void BlendFunc_Ruled::Section(const Blend_Point& P,
680                               TColgp_Array1OfPnt& Poles,
681                               TColgp_Array1OfPnt2d& Poles2d,
682                               TColStd_Array1OfReal& Weights)
683 {
684   Standard_Integer lowp = Poles.Lower(), lowp2d = Poles2d.Lower();
685   Standard_Real u,v;
686
687   Poles(lowp) = P.PointOnS1();
688   Poles(lowp+1)  = P.PointOnS2();
689   
690   P.ParametersOnS1(u,v);
691   Poles2d(lowp2d).SetCoord(u,v);
692   P.ParametersOnS2(u,v);
693   Poles2d(lowp2d+1).SetCoord(u,v);
694   
695   Weights(lowp) = 1.;
696   Weights(lowp+1) = 1.;
697   
698 }
699
700
701 gp_Ax1 BlendFunc_Ruled::AxeRot (const Standard_Real Prm)
702 {
703   gp_Ax1 axrot;
704   gp_Vec dirax, dnplan;
705   gp_Pnt oriax;
706
707   curv->D2(Prm,ptgui,d1gui,d2gui);
708
709   normtg = d1gui.Magnitude();
710   nplan  = d1gui.Normalized();
711   dnplan.SetLinearForm(1./normtg,d2gui,
712                        -1./normtg*(nplan.Dot(d2gui)),nplan);
713
714   dirax = nplan.Crossed(dnplan);
715   axrot.SetDirection(dirax);
716   oriax.SetXYZ(ptgui.XYZ()+(normtg/dnplan.Magnitude())*dnplan.Normalized().XYZ());
717   axrot.SetLocation(oriax);
718   return axrot;
719 }
720
721 void BlendFunc_Ruled::Resolution(const Standard_Integer IC2d,
722                                  const Standard_Real Tol,
723                                  Standard_Real& TolU,
724                                  Standard_Real& TolV) const
725 {
726   if(IC2d == 1){
727     TolU = surf1->UResolution(Tol);
728     TolV = surf1->VResolution(Tol);
729   }
730   else {
731     TolU = surf2->UResolution(Tol);
732     TolV = surf2->VResolution(Tol);
733   }
734 }