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 
BlendFunc_Ruled(const Handle (Adaptor3d_Surface)& S1,const Handle (Adaptor3d_Surface)& S2,const Handle (Adaptor3d_Curve)& C)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 
NbEquations() const45 Standard_Integer BlendFunc_Ruled::NbEquations () const
46 {
47   return 4;
48 }
49 
Set(const Standard_Real Param)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 
Set(const Standard_Real,const Standard_Real)59 void BlendFunc_Ruled::Set(const Standard_Real,
60                           const Standard_Real)
61 {
62   throw Standard_NotImplemented("BlendFunc_Ruled::Set");
63 }
64 
GetTolerance(math_Vector & Tolerance,const Standard_Real Tol) const65 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 
GetBounds(math_Vector & InfBound,math_Vector & SupBound) const74 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 
IsSolution(const math_Vector & Sol,const Standard_Real Tol)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 
GetMinimalDistance() const175 Standard_Real BlendFunc_Ruled::GetMinimalDistance() const
176 {
177   return distmin;
178 }
179 
Value(const math_Vector & X,math_Vector & F)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 
Derivatives(const math_Vector & X,math_Matrix & D)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 
Values(const math_Vector & X,math_Vector & F,math_Matrix & D)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 
Tangent(const Standard_Real U1,const Standard_Real V1,const Standard_Real U2,const Standard_Real V2,gp_Vec & TgF,gp_Vec & TgL,gp_Vec & NmF,gp_Vec & NmL) const382 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 
PointOnS1() const404 const gp_Pnt& BlendFunc_Ruled::PointOnS1 () const
405 {
406   return pts1;
407 }
408 
PointOnS2() const409 const gp_Pnt& BlendFunc_Ruled::PointOnS2 () const
410 {
411   return pts2;
412 }
413 
IsTangencyPoint() const414 Standard_Boolean BlendFunc_Ruled::IsTangencyPoint () const
415 {
416   return istangent;
417 }
418 
TangentOnS1() const419 const gp_Vec& BlendFunc_Ruled::TangentOnS1 () const
420 {
421   if (istangent)
422     throw Standard_DomainError("BlendFunc_Ruled::TangentOnS1");
423   return tg1;
424 }
425 
TangentOnS2() const426 const gp_Vec& BlendFunc_Ruled::TangentOnS2 () const
427 {
428   if (istangent)
429     throw Standard_DomainError("BlendFunc_Ruled::TangentOnS2");
430   return tg2;
431 }
Tangent2dOnS1() const432 const gp_Vec2d& BlendFunc_Ruled::Tangent2dOnS1 () const
433 {
434   if (istangent)
435     throw Standard_DomainError("BlendFunc_Ruled::Tangent2dOnS1");
436   return tg12d;
437 }
438 
Tangent2dOnS2() const439 const gp_Vec2d& BlendFunc_Ruled::Tangent2dOnS2 () const
440 {
441   if (istangent)
442     throw Standard_DomainError("BlendFunc_Ruled::Tangent2dOnS2");
443   return tg22d;
444 }
445 
GetSection(const Standard_Real Param,const Standard_Real U1,const Standard_Real V1,const Standard_Real U2,const Standard_Real V2,TColgp_Array1OfPnt & tabP,TColgp_Array1OfVec & tabV)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 
IsRational() const541 Standard_Boolean BlendFunc_Ruled::IsRational () const
542 {
543   return Standard_False;
544 }
545 
546 
547 //=======================================================================
548 //function : GetSectionSize
549 //purpose  :
550 //=======================================================================
GetSectionSize() const551 Standard_Real BlendFunc_Ruled::GetSectionSize() const
552 {
553   throw Standard_NotImplemented("BlendFunc_Ruled::GetSectionSize()");
554 }
555 
556 //=======================================================================
557 //function : GetMinimalWeight
558 //purpose  :
559 //=======================================================================
GetMinimalWeight(TColStd_Array1OfReal & Weigths) const560 void BlendFunc_Ruled::GetMinimalWeight(TColStd_Array1OfReal& Weigths) const
561 {
562   Weigths.Init(1);
563 }
564 //=======================================================================
565 //function : NbIntervals
566 //purpose  :
567 //=======================================================================
568 
NbIntervals(const GeomAbs_Shape S) const569 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 
Intervals(TColStd_Array1OfReal & T,const GeomAbs_Shape S) const580 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 //=======================================================================
GetShape(Standard_Integer & NbPoles,Standard_Integer & NbKnots,Standard_Integer & Degree,Standard_Integer & NbPoles2d)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 //=======================================================================
GetTolerance(const Standard_Real BoundTol,const Standard_Real,const Standard_Real,math_Vector & Tol3d,math_Vector &) const605 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 
Knots(TColStd_Array1OfReal & TKnots)614 void BlendFunc_Ruled::Knots(TColStd_Array1OfReal& TKnots)
615 {
616   TKnots(TKnots.Lower()) = 0.;
617   TKnots(TKnots.Upper()) = 1.;
618 }
619 
Mults(TColStd_Array1OfInteger & TMults)620 void BlendFunc_Ruled::Mults(TColStd_Array1OfInteger& TMults)
621 {
622   TMults(TMults.Lower()) = TMults(TMults.Upper()) = 2;
623 }
624 
Section(const Blend_Point &,TColgp_Array1OfPnt &,TColgp_Array1OfVec &,TColgp_Array1OfVec &,TColgp_Array1OfPnt2d &,TColgp_Array1OfVec2d &,TColgp_Array1OfVec2d &,TColStd_Array1OfReal &,TColStd_Array1OfReal &,TColStd_Array1OfReal &)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 
Section(const Blend_Point & P,TColgp_Array1OfPnt & Poles,TColgp_Array1OfVec & DPoles,TColgp_Array1OfPnt2d & Poles2d,TColgp_Array1OfVec2d & DPoles2d,TColStd_Array1OfReal & Weights,TColStd_Array1OfReal & DWeights)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 
Section(const Blend_Point & P,TColgp_Array1OfPnt & Poles,TColgp_Array1OfPnt2d & Poles2d,TColStd_Array1OfReal & Weights)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 
AxeRot(const Standard_Real Prm)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 
Resolution(const Standard_Integer IC2d,const Standard_Real Tol,Standard_Real & TolU,Standard_Real & TolV) const721 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 }
735