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