1 // File: BlendFunc_ConstRad.cxx
2 // Created: Thu Dec 2 10:18:55 1993
3 // Author: Jacques GOUSSARD
4 // Copyright: OPEN CASCADE 1993
6 // Modified 09/09/1996 PMN Adde Nb(Intervalls), IsRationnal
7 // Optimisation, use of GetCircle
8 // Modified 20/02/1998 PMN Singular surfaces management
10 #include <BlendFunc_ConstRad.ixx>
12 #include <math_Gauss.hxx>
13 #include <math_SVD.hxx>
15 #include <BlendFunc.hxx>
16 #include <GeomFill.hxx>
17 #include <Standard_TypeDef.hxx>
18 #include <Standard_DomainError.hxx>
19 #include <Standard_NotImplemented.hxx>
21 #include <Precision.hxx>
26 //=======================================================================
27 //function : BlendFunc_ConstRad
29 //=======================================================================
31 BlendFunc_ConstRad::BlendFunc_ConstRad(const Handle(Adaptor3d_HSurface)& S1,
32 const Handle(Adaptor3d_HSurface)& S2,
33 const Handle(Adaptor3d_HCurve)& C)
37 istangent(Standard_True),
39 E(1,4), DEDX(1,4,1,4), DEDT(1,4),
41 D2EDXDT(1,4,1,4), D2EDT2(1,4),
42 maxang(RealFirst()), minang(RealLast()),
44 mySShape(BlendFunc_Rational)
46 // Initialisaton of cash control variables.
48 xval.Init(-9.876e100);
53 //=======================================================================
54 //function : NbEquations
56 //=======================================================================
58 Standard_Integer BlendFunc_ConstRad::NbEquations () const
64 //=======================================================================
67 //=======================================================================
69 void BlendFunc_ConstRad::Set(const Standard_Real Radius, const Standard_Integer Choix)
102 ray1 = ray2 = -Radius;
106 //=======================================================================
109 //=======================================================================
111 void BlendFunc_ConstRad::Set(const BlendFunc_SectionShape TypeSection)
113 mySShape = TypeSection;
117 //=======================================================================
118 //function : ComputeValues
119 //purpose : OBLIGATORY passage for all calculations
120 // This method manages positioning on Surfaces and Curves
121 // Calculate the equations and their partial derivates
122 // Stock certain intermediate results in fields to
123 // use in other methods.
124 //=======================================================================
126 Standard_Boolean BlendFunc_ConstRad::ComputeValues(const math_Vector& X,
127 const Standard_Integer Order,
128 const Standard_Boolean byParam,
129 const Standard_Real Param)
131 // static declaration to avoid systematic reallocation
133 static gp_Vec d3u1,d3v1,d3uuv1,d3uvv1,d3u2,d3v2,d3uuv2,d3uvv2;
134 static gp_Vec d1gui, d2gui, d3gui;
136 static Standard_Real invnormtg, dinvnormtg;
137 Standard_Real T = Param, aux;
139 // Case of implicite parameter
140 if ( !byParam) { T = param;}
142 // Is the work already done ?
143 Standard_Boolean myX_OK = (Order<=myXOrder) ;
144 for (Standard_Integer ii=1; ((ii<=X.Length()) && myX_OK); ii++) {
145 myX_OK = ( X(ii) == xval(ii) );
148 Standard_Boolean t_OK =( (T == tval)
149 && ((Order<=myTOrder)||(!byParam)) );
151 if (myX_OK && (t_OK) ) {
152 return Standard_True;
158 if (byParam) { myTOrder = Order;}
159 else { myTOrder = 0;}
160 //----- Positioning on the curve ----------------
164 tcurv->D1(T, ptgui, d1gui);
165 nplan = d1gui.Normalized();
171 tcurv->D2(T,ptgui,d1gui,d2gui);
172 nplan = d1gui.Normalized();
173 invnormtg = ((Standard_Real) 1 ) / d1gui.Magnitude();
174 dnplan.SetLinearForm(invnormtg, d2gui,
175 -invnormtg*(nplan.Dot(d2gui)), nplan);
180 tcurv->D3(T,ptgui,d1gui,d2gui,d3gui);
181 nplan = d1gui.Normalized();
182 invnormtg = ((Standard_Real) 1 ) / d1gui.Magnitude();
183 dnplan.SetLinearForm(invnormtg, d2gui,
184 -invnormtg*(nplan.Dot(d2gui)), nplan);
185 dinvnormtg = - nplan.Dot(d2gui)*invnormtg*invnormtg;
186 d2nplan.SetLinearForm(invnormtg, d3gui,
188 aux = dinvnormtg*(nplan.Dot(d2gui)) + invnormtg*( dnplan.Dot(d2gui)
189 + nplan.Dot(d3gui) );
190 d2nplan.SetLinearForm(-invnormtg*(nplan.Dot(d2gui)), dnplan,
191 -aux, nplan, d2nplan );
195 return Standard_False;
203 //-------------- Positioning on surfaces -----------------
207 surf1->D1(X(1),X(2),pts1,d1u1,d1v1);
208 nsurf1 = d1u1.Crossed(d1v1);
209 surf2->D1(X(3),X(4),pts2,d1u2,d1v2);
210 nsurf2 = d1u2.Crossed(d1v2);
215 surf1->D2(X(1),X(2),pts1,d1u1,d1v1,d2u1,d2v1,d2uv1);
216 nsurf1 = d1u1.Crossed(d1v1);
217 dns1u1 = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
218 dns1v1 = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
219 surf2->D2(X(3),X(4),pts2,d1u2,d1v2,d2u2,d2v2,d2uv2);
220 nsurf2 = d1u2.Crossed(d1v2);
221 dns1u2 = d2u2.Crossed(d1v2).Added(d1u2.Crossed(d2uv2));
222 dns1v2 = d2uv2.Crossed(d1v2).Added(d1u2.Crossed(d2v2));
227 surf1->D3(X(1),X(2),pts1,d1u1,d1v1,d2u1,d2v1,d2uv1,d3u1,d3v1,d3uuv1,d3uvv1);
228 nsurf1 = d1u1.Crossed(d1v1);
229 dns1u1 = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
230 dns1v1 = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
232 surf2->D3(X(3),X(4),pts2,d1u2,d1v2,d2u2,d2v2,d2uv2,d3u2,d3v2,d3uuv2,d3uvv2);
233 nsurf2 = d1u2.Crossed(d1v2);
234 dns1u2 = d2u2.Crossed(d1v2).Added(d1u2.Crossed(d2uv2));
235 dns1v2 = d2uv2.Crossed(d1v2).Added(d1u2.Crossed(d2v2));
239 return Standard_False;
241 // Case of degenerated surfaces
242 if (nsurf1.Magnitude() < Eps ) {
244 gp_Pnt2d P(X(1), X(2));
245 if (Order == 0) BlendFunc::ComputeNormal(surf1, P, nsurf1);
246 else BlendFunc::ComputeDNormal(surf1, P, nsurf1, dns1u1, dns1v1);
248 if (nsurf2.Magnitude() < Eps) {
250 gp_Pnt2d P(X(3), X(4));
251 if (Order==0) BlendFunc::ComputeNormal(surf2, P, nsurf2);
252 else BlendFunc::ComputeDNormal(surf2, P, nsurf2, dns1u2, dns1v2);
256 // -------------------- Positioning of order 0 ---------------------
257 Standard_Real invnorm1, invnorm2, ndotns1, ndotns2, theD;
258 gp_Vec ncrossns1,ncrossns2,resul,temp;
260 theD = - (nplan.XYZ().Dot(ptgui.XYZ()));
262 E(1) = (nplan.X() * (pts1.X() + pts2.X()) +
263 nplan.Y() * (pts1.Y() + pts2.Y()) +
264 nplan.Z() * (pts1.Z() + pts2.Z())) /2 + theD;
266 ncrossns1 = nplan.Crossed(nsurf1);
267 ncrossns2 = nplan.Crossed(nsurf2);
269 invnorm1 = ncrossns1.Magnitude();
270 invnorm2 = ncrossns2.Magnitude();
272 if (invnorm1 > Eps) invnorm1 = ((Standard_Real) 1) /invnorm1;
274 invnorm1 = 1; // Unsatisfactory, but it is not necessary to crash
276 cout << " ConstRad : Surface singuliere " << endl;
279 if (invnorm2 > Eps) invnorm2 = ((Standard_Real) 1) /invnorm2;
281 invnorm2 = 1; // Unsatisfactory, but it is not necessary to crash
283 cout << " ConstRad : Surface singuliere " << endl;
287 ndotns1 = nplan.Dot(nsurf1);
288 ndotns2 = nplan.Dot(nsurf2);
290 temp.SetLinearForm(ndotns1,nplan,-1.,nsurf1);
291 temp.Multiply(invnorm1);
293 resul.SetLinearForm(ray1,temp,gp_Vec(pts2,pts1));
294 temp.SetLinearForm(ndotns2,nplan,-1.,nsurf2);
295 temp.Multiply(invnorm2);
296 resul.Subtract(ray2*temp);
302 // -------------------- Positioning of order 1 ---------------------
304 Standard_Real grosterme, cube, carre;
307 DEDX(1,1) = nplan.Dot(d1u1)/2;
308 DEDX(1,2) = nplan.Dot(d1v1)/2;
309 DEDX(1,3) = nplan.Dot(d1u2)/2;
310 DEDX(1,4) = nplan.Dot(d1v2)/2;
312 cube =invnorm1*invnorm1*invnorm1;
313 // Derived in relation to u1
314 grosterme = - ncrossns1.Dot(nplan.Crossed(dns1u1))*cube;
315 dndu1.SetLinearForm( grosterme*ndotns1
316 + invnorm1*nplan.Dot(dns1u1), nplan,
318 - invnorm1, dns1u1 );
320 resul.SetLinearForm(ray1, dndu1, d1u1);
321 DEDX(2,1) = resul.X();
322 DEDX(3,1) = resul.Y();
323 DEDX(4,1) = resul.Z();
325 // Derived in relation to v1
327 grosterme = - ncrossns1.Dot(nplan.Crossed(dns1v1))*cube;
328 dndv1.SetLinearForm( grosterme*ndotns1
329 +invnorm1*nplan.Dot(dns1v1), nplan,
333 resul.SetLinearForm(ray1, dndv1, d1v1);
334 DEDX(2,2) = resul.X();
335 DEDX(3,2) = resul.Y();
336 DEDX(4,2) = resul.Z();
338 cube = invnorm2*invnorm2*invnorm2;
339 // Derived in relation to u2
340 grosterme = - ncrossns2.Dot(nplan.Crossed(dns1u2))*cube;
341 dndu2.SetLinearForm( grosterme*ndotns2
342 +invnorm2*nplan.Dot(dns1u2), nplan,
346 resul.SetLinearForm(-ray2, dndu2, -1, d1u2);
347 DEDX(2,3) = resul.X();
348 DEDX(3,3) = resul.Y();
349 DEDX(4,3) = resul.Z();
351 // Derived in relation to v2
352 grosterme = -ncrossns2.Dot(nplan.Crossed(dns1v2))*cube;
353 dndv2.SetLinearForm( grosterme*ndotns2
354 +invnorm2*nplan.Dot(dns1v2), nplan,
358 resul.SetLinearForm(-ray2,dndv2, -1, d1v2);
359 DEDX(2,4) = resul.X();
360 DEDX(3,4) = resul.Y();
361 DEDX(4,4) = resul.Z();
364 temp.SetXYZ( (pts1.XYZ()+pts2.XYZ())/2 - ptgui.XYZ());
365 // Derived from n1 in relation to w
366 grosterme = ncrossns1.Dot(dnplan.Crossed(nsurf1))*invnorm1*invnorm1;
367 dn1w.SetLinearForm((dnplan.Dot(nsurf1)-grosterme*ndotns1)*invnorm1, nplan,
368 ndotns1*invnorm1,dnplan,
369 grosterme*invnorm1,nsurf1);
371 // Derivee from n2 in relation to w
372 grosterme = ncrossns2.Dot(dnplan.Crossed(nsurf2))*invnorm2*invnorm2;
373 dn2w.SetLinearForm((dnplan.Dot(nsurf2)-grosterme*ndotns2)*invnorm2,nplan,
374 ndotns2*invnorm2,dnplan,
375 grosterme*invnorm2,nsurf2);
378 DEDT(1) = dnplan.Dot(temp) - 1./invnormtg ;
379 DEDT(2) = ray1*dn1w.X() - ray2*dn2w.X();
380 DEDT(3) = ray1*dn1w.Y() - ray2*dn2w.Y();
381 DEDT(4) = ray1*dn1w.Z() - ray2*dn2w.Z();
383 // ------ Positioning of order 2 -----------------------------
385 // gp_Vec d2ndu1, d2ndu2, d2ndv1, d2ndv2, d2nduv1, d2nduv2;
386 gp_Vec d2ns1u1, d2ns1u2, d2ns1v1, d2ns1v2, d2ns1uv1, d2ns1uv2;
387 Standard_Real uterm, vterm, smallterm, p1, p2, p12;
388 Standard_Real DPrim, DSecn;
391 D2EDX2(1, 1, 1) = nplan.Dot(d2u1)/2;
392 D2EDX2(1, 2, 1) = D2EDX2(1, 1, 2) = nplan.Dot(d2uv1)/2;
393 D2EDX2(1, 2, 2) = nplan.Dot(d2v1)/2;
395 D2EDX2(1, 3, 3) = nplan.Dot(d2u2)/2;
396 D2EDX2(1, 4, 3) = D2EDX2(1, 3, 4) = nplan.Dot(d2uv2)/2;
397 D2EDX2(1, 4, 4) = nplan.Dot(d2v2)/2;
401 carre = invnorm1*invnorm1;
402 cube = carre*invnorm1;
403 // Derived double compared to u1
404 // Derived from the norm
405 d2ns1u1.SetLinearForm(1, d3u1.Crossed(d1v1),
406 2, d2u1.Crossed(d2uv1),
407 1, d1u1.Crossed(d3uuv1));
408 DPrim = ncrossns1.Dot(nplan.Crossed(dns1u1));
409 smallterm = - 2*DPrim*cube;
410 DSecn = ncrossns1.Dot(nplan.Crossed(d2ns1u1))
411 + (nplan.Crossed(dns1u1)).SquareMagnitude();
412 grosterme = (3*DPrim*DPrim*carre - DSecn) * cube;
414 temp.SetLinearForm( grosterme*ndotns1, nplan,
415 -grosterme , nsurf1);
416 p1 = nplan.Dot(dns1u1);
417 p2 = nplan.Dot(d2ns1u1);
418 d2ndu1.SetLinearForm( invnorm1*p2
419 +smallterm*p1, nplan,
423 resul.SetLinearForm(ray1, d2ndu1, d2u1);
424 D2EDX2(2,1,1) = resul.X();
425 D2EDX2(3,1,1) = resul.Y();
426 D2EDX2(4,1,1) = resul.Z();
428 // Derived double compared to u1, v1
429 // Derived from the norm
430 d2ns1uv1 = (d3uuv1.Crossed(d1v1))
431 + (d2u1 .Crossed(d2v1))
432 + (d1u1 .Crossed(d3uvv1));
433 uterm = ncrossns1.Dot(nplan.Crossed(dns1u1));
434 vterm = ncrossns1.Dot(nplan.Crossed(dns1v1));
435 DSecn = (nplan.Crossed(dns1v1)).Dot(nplan.Crossed(dns1u1))
436 + ncrossns1.Dot(nplan.Crossed(d2ns1uv1));
437 grosterme = (3*uterm*vterm*carre-DSecn)*cube;
438 uterm *= -cube; //and only now
441 p1 = nplan.Dot(dns1u1);
442 p2 = nplan.Dot(dns1v1);
443 temp.SetLinearForm( grosterme*ndotns1, nplan,
445 - invnorm1, d2ns1uv1);
446 d2nduv1.SetLinearForm( invnorm1*nplan.Dot(d2ns1uv1)
453 resul.SetLinearForm(ray1, d2nduv1, d2uv1);
455 D2EDX2(2,2,1) = D2EDX2(2,1,2) = resul.X();
456 D2EDX2(3,2,1) = D2EDX2(3,1,2) = resul.Y();
457 D2EDX2(4,2,1) = D2EDX2(4,1,2) = resul.Z();
459 // Derived double compared to v1
460 // Derived from the norm
461 d2ns1v1.SetLinearForm(1, d1u1.Crossed(d3v1),
462 2, d2uv1.Crossed(d2v1),
463 1, d3uvv1.Crossed(d1v1));
464 DPrim = ncrossns1.Dot(nplan.Crossed(dns1v1));
465 smallterm = - 2*DPrim*cube;
466 DSecn = ncrossns1.Dot(nplan.Crossed(d2ns1v1))
467 + (nplan.Crossed(dns1v1)).SquareMagnitude();
468 grosterme = (3*DPrim*DPrim*carre - DSecn) * cube;
470 p1 = nplan.Dot(dns1v1);
471 p2 = nplan.Dot(d2ns1v1);
472 temp.SetLinearForm( grosterme*ndotns1, nplan,
473 -grosterme , nsurf1);
474 d2ndv1.SetLinearForm( invnorm1*p2
475 +smallterm*p1, nplan,
479 resul.SetLinearForm(ray1, d2ndv1, d2v1);
481 D2EDX2(2,2,2) = resul.X();
482 D2EDX2(3,2,2) = resul.Y();
483 D2EDX2(4,2,2) = resul.Z();
487 carre = invnorm2*invnorm2;
488 cube = carre*invnorm2;
489 // Derived double compared to u2
490 // Derived from the norm
491 d2ns1u2.SetLinearForm(1, d3u2.Crossed(d1v2),
492 2, d2u2.Crossed(d2uv2),
493 1, d1u2.Crossed(d3uuv2));
494 DPrim = ncrossns2.Dot(nplan.Crossed(dns1u2));
495 smallterm = - 2*DPrim*cube;
496 DSecn = ncrossns2.Dot(nplan.Crossed(d2ns1u2))
497 + (nplan.Crossed(dns1u2)).SquareMagnitude();
498 grosterme = (3*DPrim*DPrim*carre - DSecn) * cube;
500 temp.SetLinearForm( grosterme*ndotns2, nplan,
501 -grosterme , nsurf2);
502 p1 = nplan.Dot(dns1u2);
503 p2 = nplan.Dot(d2ns1u2);
504 d2ndu2.SetLinearForm( invnorm2*p2
505 +smallterm*p1, nplan,
509 resul.SetLinearForm(-ray2, d2ndu2, -1, d2u2);
510 D2EDX2(2,3,3) = resul.X();
511 D2EDX2(3,3,3) = resul.Y();
512 D2EDX2(4,3,3) = resul.Z();
514 // Derived double compared to u2, v2
515 // Derived from the norm
516 d2ns1uv2 = (d3uuv2.Crossed(d1v2))
517 + (d2u2 .Crossed(d2v2))
518 + (d1u2 .Crossed(d3uvv2));
519 uterm = ncrossns2.Dot(nplan.Crossed(dns1u2));
520 vterm = ncrossns2.Dot(nplan.Crossed(dns1v2));
521 DSecn = (nplan.Crossed(dns1v2)).Dot(nplan.Crossed(dns1u2))
522 + ncrossns2.Dot(nplan.Crossed(d2ns1uv2));
523 grosterme = (3*uterm*vterm*carre-DSecn)*cube;
524 uterm *= -cube; //and only now
527 p1 = nplan.Dot(dns1u2);
528 p2 = nplan.Dot(dns1v2);
529 temp.SetLinearForm( grosterme*ndotns2, nplan,
531 - invnorm2, d2ns1uv2);
532 d2nduv2.SetLinearForm( invnorm2*nplan.Dot(d2ns1uv2)
539 resul.SetLinearForm(-ray2, d2nduv2, -1, d2uv2);
541 D2EDX2(2,4,3) = D2EDX2(2,3,4) = resul.X();
542 D2EDX2(3,4,3) = D2EDX2(3,3,4) = resul.Y();
543 D2EDX2(4,4,3) = D2EDX2(4,3,4) = resul.Z();
545 // Derived double compared to v2
546 // Derived from the norm
547 d2ns1v2.SetLinearForm(1, d1u2.Crossed(d3v2),
548 2, d2uv2.Crossed(d2v2),
549 1, d3uvv2.Crossed(d1v2));
550 DPrim = ncrossns2.Dot(nplan.Crossed(dns1v2));
551 smallterm = - 2*DPrim*cube;
552 DSecn = ncrossns2.Dot(nplan.Crossed(d2ns1v2))
553 + (nplan.Crossed(dns1v2)).SquareMagnitude();
554 grosterme = (3*DPrim*DPrim*carre - DSecn) * cube;
556 p1 = nplan.Dot(dns1v2);
557 p2 = nplan.Dot(d2ns1v2);
558 temp.SetLinearForm( grosterme*ndotns2, nplan,
559 -grosterme , nsurf2);
560 d2ndv2.SetLinearForm( invnorm2*p2
561 +smallterm*p1, nplan,
565 resul.SetLinearForm(-ray2, d2ndv2, -1, d2v2);
567 D2EDX2(2,4,4) = resul.X();
568 D2EDX2(3,4,4) = resul.Y();
569 D2EDX2(4,4,4) = resul.Z();
573 // ---------- Derivation double in t, X --------------------------
574 D2EDXDT(1,1) = dnplan.Dot(d1u1)/2;
575 D2EDXDT(1,2) = dnplan.Dot(d1v1)/2;
576 D2EDXDT(1,3) = dnplan.Dot(d1u2)/2;
577 D2EDXDT(1,4) = dnplan.Dot(d1v2)/2;
579 carre = invnorm1*invnorm1;
580 cube = carre*invnorm1;
581 //--> Derived compared to u1 and t
582 tterm = ncrossns1.Dot(dnplan.Crossed(nsurf1));
583 smallterm = - tterm*cube;
584 // Derived from the norm
585 uterm = ncrossns1.Dot(nplan. Crossed(dns1u1));
586 DSecn = (nplan.Crossed(dns1u1)).Dot(dnplan.Crossed(nsurf1))
587 + ncrossns1.Dot(dnplan.Crossed(dns1u1));
588 grosterme = (3*uterm*tterm*carre - DSecn) * cube;
591 p1 = dnplan.Dot(nsurf1);
592 p2 = nplan. Dot(dns1u1);
593 p12 = dnplan.Dot(dns1u1);
595 d2ndtu1.SetLinearForm( invnorm1*p12
598 + grosterme*ndotns1, nplan,
600 + uterm*ndotns1, dnplan,
601 - smallterm, dns1u1);
602 d2ndtu1 -= grosterme*nsurf1;
604 resul = ray1*d2ndtu1;
605 D2EDXDT(2,1) = resul.X();
606 D2EDXDT(3,1) = resul.Y();
607 D2EDXDT(4,1) = resul.Z();
609 //--> Derived compared to v1 and t
610 // Derived from the norm
611 uterm = ncrossns1.Dot(nplan. Crossed(dns1v1));
612 DSecn = (nplan. Crossed(dns1v1)).Dot(dnplan.Crossed(nsurf1))
613 + ncrossns1.Dot(dnplan.Crossed(dns1v1));
614 grosterme = (3*uterm*tterm*carre - DSecn) * cube;
617 p1 = dnplan.Dot(nsurf1);
618 p2 = nplan. Dot(dns1v1);
619 p12 = dnplan.Dot(dns1v1);
620 d2ndtv1.SetLinearForm( invnorm1*p12
623 + grosterme*ndotns1, nplan,
625 + uterm*ndotns1, dnplan,
626 - smallterm , dns1v1);
627 d2ndtv1 -= grosterme*nsurf1;
629 resul = ray1* d2ndtv1;
630 D2EDXDT(2,2) = resul.X();
631 D2EDXDT(3,2) = resul.Y();
632 D2EDXDT(4,2) = resul.Z();
634 carre = invnorm2*invnorm2;
635 cube = carre*invnorm2;
636 //--> Derived compared to u2 and t
637 tterm = ncrossns2.Dot(dnplan.Crossed(nsurf2));
638 smallterm = -tterm*cube;
639 // Derived from the norm
640 uterm = ncrossns2.Dot(nplan. Crossed(dns1u2));
641 DSecn = (nplan. Crossed(dns1u2)).Dot(dnplan.Crossed(nsurf2))
642 + ncrossns2.Dot(dnplan.Crossed(dns1u2));
643 grosterme = (3*uterm*tterm*carre - DSecn) * cube;
646 p1 = dnplan.Dot(nsurf2);
647 p2 = nplan. Dot(dns1u2);
648 p12 = dnplan.Dot(dns1u2);
650 d2ndtu2.SetLinearForm( invnorm2*p12
653 + grosterme*ndotns2, nplan,
655 + uterm*ndotns2, dnplan,
656 -smallterm , dns1u2);
657 d2ndtu2 -= grosterme*nsurf2;
659 resul = - ray2*d2ndtu2;
660 D2EDXDT(2,3) = resul.X();
661 D2EDXDT(3,3) = resul.Y();
662 D2EDXDT(4,3) = resul.Z();
664 //--> Derived compared to v2 and t
665 // Derived from the norm
666 uterm = ncrossns2.Dot(nplan. Crossed(dns1v2));
667 DSecn = (nplan.Crossed(dns1v2)).Dot(dnplan.Crossed(nsurf2))
668 + ncrossns2.Dot(dnplan.Crossed(dns1v2));
669 grosterme = (3*uterm*tterm*carre - DSecn) * cube;
672 p1 = dnplan.Dot(nsurf2);
673 p2 = nplan. Dot(dns1v2);
674 p12 = dnplan.Dot(dns1v2);
676 d2ndtv2.SetLinearForm( invnorm2*p12
679 + grosterme*ndotns2, nplan,
681 + uterm*ndotns2, dnplan,
682 -smallterm , dns1v2);
683 d2ndtv2 -= grosterme*nsurf2;
685 resul = - ray2 * d2ndtv2;
686 D2EDXDT(2,4) = resul.X();
687 D2EDXDT(3,4) = resul.Y();
688 D2EDXDT(4,4) = resul.Z();
691 // ---------- Derivation double in t -----------------------------
692 // Derived from n1 compared to w
693 carre = invnorm1*invnorm1;
694 cube = carre*invnorm1;
695 // Derived from the norm
696 DPrim = ncrossns1.Dot(dnplan.Crossed(nsurf1));
697 smallterm = - 2*DPrim*cube;
698 DSecn = (dnplan.Crossed(nsurf1)).SquareMagnitude()
699 + ncrossns1.Dot(d2nplan.Crossed(nsurf1));
700 grosterme = (3*DPrim*DPrim*carre - DSecn) * cube;
702 p1 = dnplan. Dot(nsurf1);
703 p2 = d2nplan.Dot(nsurf1);
705 temp.SetLinearForm( grosterme*ndotns1, nplan,
706 -grosterme , nsurf1);
707 d2n1w.SetLinearForm( smallterm*p1
708 + invnorm1*p2, nplan,
710 + 2*invnorm1*p1, dnplan,
711 ndotns1*invnorm1, d2nplan);
714 // Derived from n2 compared to w
715 carre = invnorm2*invnorm2;
716 cube = carre*invnorm2;
717 // Derived from the norm
718 DPrim = ncrossns2.Dot(dnplan.Crossed(nsurf2));
719 smallterm = - 2*DPrim*cube;
720 DSecn = (dnplan.Crossed(nsurf2)).SquareMagnitude()
721 + ncrossns2.Dot(d2nplan.Crossed(nsurf2));
722 grosterme = (3*DPrim*DPrim*carre - DSecn) * cube;
724 p1 = dnplan. Dot(nsurf2);
725 p2 = d2nplan.Dot(nsurf2);
727 temp.SetLinearForm( grosterme*ndotns2, nplan,
728 -grosterme , nsurf2);
729 d2n2w.SetLinearForm( smallterm*p1
730 + invnorm2*p2, nplan,
732 + 2*invnorm2*p1, dnplan,
733 ndotns2*invnorm2, d2nplan);
736 temp.SetXYZ( (pts1.XYZ()+pts2.XYZ())/2 - ptgui.XYZ());
737 D2EDT2(1) = d2nplan.Dot(temp) - 2*dnplan.Dot(d1gui) - nplan.Dot(d2gui);
738 D2EDT2(2) = ray1*d2n1w.X() - ray2*d2n2w.X();
739 D2EDT2(3) = ray1*d2n1w.Y() - ray2*d2n2w.Y();
740 D2EDT2(4) = ray1*d2n1w.Z() - ray2*d2n2w.Z();
744 return Standard_True;
747 //=======================================================================
750 //=======================================================================
752 void BlendFunc_ConstRad::Set(const Standard_Real Param)
757 //=======================================================================
759 //purpose : Segmentation of the useful part of the curve
760 // Precision is taken at random and small !?
761 //=======================================================================
763 void BlendFunc_ConstRad::Set(const Standard_Real First, const Standard_Real Last)
765 tcurv = curv->Trim(First, Last, 1.e-12);
768 //=======================================================================
769 //function : GetTolerance
771 //=======================================================================
773 void BlendFunc_ConstRad::GetTolerance(math_Vector& Tolerance, const Standard_Real Tol) const
775 Tolerance(1) = surf1->UResolution(Tol);
776 Tolerance(2) = surf1->VResolution(Tol);
777 Tolerance(3) = surf2->UResolution(Tol);
778 Tolerance(4) = surf2->VResolution(Tol);
782 //=======================================================================
783 //function : GetBounds
785 //=======================================================================
787 void BlendFunc_ConstRad::GetBounds(math_Vector& InfBound, math_Vector& SupBound) const
789 InfBound(1) = surf1->FirstUParameter();
790 InfBound(2) = surf1->FirstVParameter();
791 InfBound(3) = surf2->FirstUParameter();
792 InfBound(4) = surf2->FirstVParameter();
793 SupBound(1) = surf1->LastUParameter();
794 SupBound(2) = surf1->LastVParameter();
795 SupBound(3) = surf2->LastUParameter();
796 SupBound(4) = surf2->LastVParameter();
798 for(Standard_Integer i = 1; i <= 4; i++){
799 if(!Precision::IsInfinite(InfBound(i)) &&
800 !Precision::IsInfinite(SupBound(i))) {
801 Standard_Real range = (SupBound(i) - InfBound(i));
802 InfBound(i) -= range;
803 SupBound(i) += range;
809 //=======================================================================
810 //function : IsSolution
812 //=======================================================================
814 Standard_Boolean BlendFunc_ConstRad::IsSolution(const math_Vector& Sol, const Standard_Real Tol)
816 Standard_Real norm, Cosa, Sina, Angle;
817 Standard_Boolean Ok=Standard_True;
819 Ok = ComputeValues(Sol, 1, Standard_True, param);
821 if (Abs(E(1)) <= Tol &&
822 E(2)*E(2) + E(3)*E(3) + E(4)*E(4) <= Tol*Tol) {
824 // ns1, ns2 and np are copied locally to avoid crushing the fields !
830 norm = nplan.Crossed(ns1).Magnitude();
832 norm = 1; // Unsatisfactory, but it is not necessary to stop
834 ns1.SetLinearForm(nplan.Dot(ns1)/norm,nplan, -1./norm, ns1);
836 norm = nplan.Crossed(ns2).Magnitude();
838 norm = 1; // Unsatisfactory, but it is not necessary to stop
840 ns2.SetLinearForm(nplan.Dot(ns2)/norm,nplan, -1./norm, ns2);
842 Standard_Real maxpiv = 1.e-9;
843 math_Vector controle(1,4),solution(1,4), tolerances(1,4);
844 GetTolerance(tolerances,Tol);
846 istangent = Standard_True;
847 math_Gauss Resol(DEDX,maxpiv);
848 if (Resol.IsDone()) {
849 Resol.Solve(-DEDT,solution);
850 istangent = Standard_False;
851 controle = DEDT.Added(DEDX.Multiplied(solution));
852 if(Abs(controle(1)) > tolerances(1) ||
853 Abs(controle(2)) > tolerances(2) ||
854 Abs(controle(3)) > tolerances(3) ||
855 Abs(controle(4)) > tolerances(4)){
856 istangent = Standard_True;
861 math_SVD SingRS (DEDX);
862 if (SingRS.IsDone()) {
863 SingRS.Solve(-DEDT, solution, 1.e-6);
864 istangent = Standard_False;
865 controle = DEDT.Added(DEDX.Multiplied(solution));
866 if(Abs(controle(1)) > tolerances(1) ||
867 Abs(controle(2)) > tolerances(2) ||
868 Abs(controle(3)) > tolerances(3) ||
869 Abs(controle(4)) > tolerances(4)){
871 cout<<"Cheminement : echec calcul des derivees"<<endl;
873 istangent = Standard_True;
879 tg1.SetLinearForm(solution(1),d1u1,solution(2),d1v1);
880 tg2.SetLinearForm(solution(3),d1u2,solution(4),d1v2);
881 tg12d.SetCoord(solution(1),solution(2));
882 tg22d.SetCoord(solution(3),solution(4));
894 Sina = np.Dot(ns1.Crossed(ns2));
896 Sina = -Sina; //nplan is changed in -nplan
899 if(Cosa > 1.) {Cosa = 1.; Sina = 0.;}
902 // Reframing on ]-pi/2, 3pi/2]
904 if (Cosa > 0.) Angle = -Angle;
905 else Angle = 2.*PI - Angle;
908 // cout << "Angle : " <<Angle << endl;
909 // if ((Angle < 0) || (Angle > PI)) {
910 // cout << "t = " << param << endl;
913 if (Abs(Angle)>maxang) {maxang = Abs(Angle);}
914 if (Abs(Angle)<minang) {minang = Abs(Angle);}
915 distmin = Min( distmin, pts1.Distance(pts2));
919 istangent = Standard_True;
920 return Standard_False;
923 //=======================================================================
924 //function : GetMinimalDistance
926 //=======================================================================
928 Standard_Real BlendFunc_ConstRad::GetMinimalDistance() const
933 //=======================================================================
936 //=======================================================================
938 Standard_Boolean BlendFunc_ConstRad::Value(const math_Vector& X, math_Vector& F)
940 const Standard_Boolean Ok = ComputeValues(X, 0);
947 //=======================================================================
948 //function : Derivatives
950 //=======================================================================
952 Standard_Boolean BlendFunc_ConstRad::Derivatives(const math_Vector& X, math_Matrix& D)
954 const Standard_Boolean Ok = ComputeValues(X, 1);
959 //=======================================================================
962 //=======================================================================
964 Standard_Boolean BlendFunc_ConstRad::Values(const math_Vector& X, math_Vector& F, math_Matrix& D)
966 const Standard_Boolean Ok = ComputeValues(X, 1);
972 //=======================================================================
973 //function : PointOnS1
975 //=======================================================================
977 const gp_Pnt& BlendFunc_ConstRad::PointOnS1 () const
983 //=======================================================================
984 //function : PointOnS2
986 //=======================================================================
988 const gp_Pnt& BlendFunc_ConstRad::PointOnS2 () const
994 //=======================================================================
995 //function : IsTangencyPoint
997 //=======================================================================
999 Standard_Boolean BlendFunc_ConstRad::IsTangencyPoint () const
1005 //=======================================================================
1006 //function : TangentOnS1
1008 //=======================================================================
1010 const gp_Vec& BlendFunc_ConstRad::TangentOnS1 () const
1013 Standard_DomainError::Raise("BlendFunc_ConstRad::TangentOnS1");
1018 //=======================================================================
1019 //function : TangentOnS2
1021 //=======================================================================
1023 const gp_Vec& BlendFunc_ConstRad::TangentOnS2 () const
1026 Standard_DomainError::Raise("BlendFunc_ConstRad::TangentOnS2");
1031 //=======================================================================
1032 //function : Tangent2dOnS1
1034 //=======================================================================
1036 const gp_Vec2d& BlendFunc_ConstRad::Tangent2dOnS1 () const
1039 Standard_DomainError::Raise("BlendFunc_ConstRad::Tangent2dOnS1");
1044 //=======================================================================
1045 //function : Tangent2dOnS2
1047 //=======================================================================
1049 const gp_Vec2d& BlendFunc_ConstRad::Tangent2dOnS2 () const
1052 Standard_DomainError::Raise("BlendFunc_ConstRad::Tangent2dOnS2");
1057 //=======================================================================
1058 //function : Tangent
1060 //=======================================================================
1062 void BlendFunc_ConstRad::Tangent(const Standard_Real U1,
1063 const Standard_Real V1,
1064 const Standard_Real U2,
1065 const Standard_Real V2,
1073 Standard_Real invnorm1;
1075 if ((U1!=xval(1)) || (V1!=xval(2)) ||
1076 (U2!=xval(3)) || (V2!=xval(4))) {
1080 // cout << " ConstRad::erreur de tengent !!!!!!!!!!!!!!!!!!!!" << endl;
1082 surf1->D1(U1,V1,bid,d1u,d1v);
1083 NmF = ns1 = d1u.Crossed(d1v);
1084 surf2->D1(U2,V2,bid,d1u,d1v);
1085 NmL = d1u.Crossed(d1v);
1092 invnorm1 = nplan.Crossed(ns1).Magnitude();
1093 if (invnorm1 < Eps) invnorm1 = 1;
1094 else invnorm1 = 1. / invnorm1;
1096 ns1.SetLinearForm(nplan.Dot(ns1)*invnorm1,nplan, -invnorm1,ns1);
1097 Center.SetXYZ(pts1.XYZ()+ray1*ns1.XYZ());
1099 TgF = nplan.Crossed(gp_Vec(Center,pts1));
1100 TgL = nplan.Crossed(gp_Vec(Center,pts2));
1107 //=======================================================================
1108 //function : TwistOnS1
1110 //=======================================================================
1112 Standard_Boolean BlendFunc_ConstRad::TwistOnS1() const
1115 Standard_DomainError::Raise("BlendFunc_ConstRad::TwistOnS1");
1116 return tg1.Dot(nplan) < 0.;
1119 //=======================================================================
1120 //function : TwistOnS2
1122 //=======================================================================
1124 Standard_Boolean BlendFunc_ConstRad::TwistOnS2() const
1127 Standard_DomainError::Raise("BlendFunc_ConstRad::TwistOnS2");
1128 return tg2.Dot(nplan) < 0.;
1131 //=======================================================================
1132 //function : Section
1134 //=======================================================================
1136 void BlendFunc_ConstRad::Section(const Standard_Real Param,
1137 const Standard_Real U1,
1138 const Standard_Real V1,
1139 const Standard_Real U2,
1140 const Standard_Real V2,
1141 Standard_Real& Pdeb,
1142 Standard_Real& Pfin,
1149 X(1) = U1; X(2) = V1; X(3) = U2; X(4) = V2;
1150 Standard_Real prm = Param;
1151 Standard_Boolean Ok;
1153 Ok = ComputeValues(X, 0, Standard_True, prm);
1158 Standard_Real norm1;
1159 norm1 = nplan.Crossed(ns1).Magnitude();
1161 norm1 = 1; // Unsatisfactory, but it is not necessary to stop
1163 ns1.SetLinearForm(nplan.Dot(ns1)/norm1,nplan, -1./norm1,ns1);
1164 Center.SetXYZ(pts1.XYZ()+ray1*ns1.XYZ());
1166 // ns1 is oriented from the center to pts1,
1174 C.SetRadius(Abs(ray1));
1175 C.SetPosition(gp_Ax2(Center,np,ns1));
1177 Pfin = ElCLib::Parameter(C,pts2);
1178 // Test negative and almost null angles : Singular Case
1181 C.SetPosition(gp_Ax2(Center,np,ns1));
1182 Pfin = ElCLib::Parameter(C,pts2);
1184 if (Pfin < Precision::PConfusion()) Pfin += Precision::PConfusion();
1187 //=======================================================================
1188 //function : IsRational
1190 //=======================================================================
1192 Standard_Boolean BlendFunc_ConstRad::IsRational () const
1194 return (mySShape==BlendFunc_Rational || mySShape==BlendFunc_QuasiAngular);
1197 //=======================================================================
1198 //function : GetSectionSize
1200 //=======================================================================
1201 Standard_Real BlendFunc_ConstRad::GetSectionSize() const
1203 return maxang*Abs(ray1);
1206 //=======================================================================
1207 //function : GetMinimalWeight
1209 //=======================================================================
1210 void BlendFunc_ConstRad::GetMinimalWeight(TColStd_Array1OfReal& Weigths) const
1212 BlendFunc::GetMinimalWeights(mySShape, myTConv, minang, maxang, Weigths );
1213 // It is supposed that it does not depend on the Radius!
1216 //=======================================================================
1217 //function : NbIntervals
1219 //=======================================================================
1221 Standard_Integer BlendFunc_ConstRad::NbIntervals (const GeomAbs_Shape S) const
1223 return curv->NbIntervals(BlendFunc::NextShape(S));
1227 //=======================================================================
1228 //function : Intervals
1230 //=======================================================================
1232 void BlendFunc_ConstRad::Intervals (TColStd_Array1OfReal& T,
1233 const GeomAbs_Shape S) const
1235 curv->Intervals(T, BlendFunc::NextShape(S));
1238 //=======================================================================
1239 //function : GetShape
1241 //=======================================================================
1243 void BlendFunc_ConstRad::GetShape (Standard_Integer& NbPoles,
1244 Standard_Integer& NbKnots,
1245 Standard_Integer& Degree,
1246 Standard_Integer& NbPoles2d)
1249 BlendFunc::GetShape(mySShape,maxang,NbPoles,NbKnots,Degree,myTConv);
1252 //=======================================================================
1253 //function : GetTolerance
1254 //purpose : Determine Tolerances used for approximations.
1255 //=======================================================================
1256 void BlendFunc_ConstRad::GetTolerance(const Standard_Real BoundTol,
1257 const Standard_Real SurfTol,
1258 const Standard_Real AngleTol,
1260 math_Vector& Tol1d) const
1262 Standard_Integer low = Tol3d.Lower() , up=Tol3d.Upper();
1264 Tol= GeomFill::GetTolerance(myTConv, minang, Abs(ray1),
1266 Tol1d.Init(SurfTol);
1267 Tol3d.Init(SurfTol);
1268 Tol3d(low+1) = Tol3d(up-1) = Min(Tol, SurfTol);
1269 Tol3d(low) = Tol3d(up) = Min(Tol, BoundTol);
1273 //=======================================================================
1276 //=======================================================================
1278 void BlendFunc_ConstRad::Knots(TColStd_Array1OfReal& TKnots)
1280 GeomFill::Knots(myTConv,TKnots);
1284 //=======================================================================
1287 //=======================================================================
1289 void BlendFunc_ConstRad::Mults(TColStd_Array1OfInteger& TMults)
1291 GeomFill::Mults(myTConv,TMults);
1295 //=======================================================================
1296 //function : Section
1298 //=======================================================================
1300 void BlendFunc_ConstRad::Section(const Blend_Point& P,
1301 TColgp_Array1OfPnt& Poles,
1302 TColgp_Array1OfPnt2d& Poles2d,
1303 TColStd_Array1OfReal& Weights)
1309 Standard_Real prm = P.Parameter();
1310 Standard_Boolean Ok;
1312 Standard_Integer low = Poles.Lower();
1313 Standard_Integer upp = Poles.Upper();
1315 P.ParametersOnS1(X(1), X(2));
1316 P.ParametersOnS2(X(3), X(4));
1318 Ok = ComputeValues(X, 0, Standard_True, prm);
1319 distmin = Min (distmin, pts1.Distance(pts2));
1321 // ns1, ns2, np are copied locally to avoid crushing the fields !
1327 Poles2d(Poles2d.Lower()).SetCoord(X(1), X(2));
1328 Poles2d(Poles2d.Upper()).SetCoord(X(3), X(4));
1330 if (mySShape == BlendFunc_Linear) {
1338 Standard_Real norm1, norm2;
1339 norm1 = nplan.Crossed(ns1).Magnitude();
1340 norm2 = nplan.Crossed(ns2).Magnitude();
1342 norm1 = 1; // Unsatisfactory, but it is not necessary to stop
1344 // cout << " ConstRad : Surface singuliere " << endl;
1348 norm2 = 1; // Unsatisfactory, but it is not necessary to stop
1350 // cout << " ConstRad : Surface singuliere " << endl;
1354 ns1.SetLinearForm(nplan.Dot(ns1)/norm1,nplan, -1./norm1,ns1);
1355 ns2.SetLinearForm(nplan.Dot(ns2)/norm2,nplan, -1./norm2,ns2);
1357 Center.SetXYZ(pts1.XYZ()+ray1*ns1.XYZ());
1359 // ns1 (resp. ns2) is oriented from center to pts1 (resp. pts2),
1360 // and the triedron ns1,ns2,nplan is made direct.
1372 GeomFill::GetCircle(myTConv,
1380 //=======================================================================
1381 //function : Section
1383 //=======================================================================
1385 Standard_Boolean BlendFunc_ConstRad::Section
1386 (const Blend_Point& P,
1387 TColgp_Array1OfPnt& Poles,
1388 TColgp_Array1OfVec& DPoles,
1389 TColgp_Array1OfPnt2d& Poles2d,
1390 TColgp_Array1OfVec2d& DPoles2d,
1391 TColStd_Array1OfReal& Weights,
1392 TColStd_Array1OfReal& DWeights)
1394 gp_Vec ns1, ns2, np, dnp, dnorm1w, dnorm2w, tgc;
1395 Standard_Real norm1, norm2;
1398 math_Vector sol(1,4), secmember(1,4);
1400 Standard_Real prm = P.Parameter();
1401 Standard_Integer low = Poles.Lower();
1402 Standard_Integer upp = Poles.Upper();
1403 Standard_Boolean istgt = Standard_True;
1405 P.ParametersOnS1(sol(1),sol(2));
1406 P.ParametersOnS2(sol(3),sol(4));
1408 // Calculation of equations
1409 ComputeValues(sol, 1, Standard_True, prm);
1410 distmin = Min (distmin, pts1.Distance(pts2));
1412 // ns1, ns2, np are copied locally to avoid crushing the fields !
1418 if ( ! pts1.IsEqual(pts2, 1.e-4)) {
1420 // Calculation of derivates Processing Normal
1421 math_Gauss Resol(DEDX, 1.e-9);
1423 if (Resol.IsDone()) {
1424 Resol.Solve(-DEDT, secmember);
1425 istgt = Standard_False;
1430 math_SVD SingRS (DEDX);
1431 if (SingRS.IsDone()) {
1432 SingRS.Solve(-DEDT, secmember, 1.e-6);
1433 istgt = Standard_False;
1438 tg1.SetLinearForm(secmember(1),d1u1, secmember(2),d1v1);
1439 tg2.SetLinearForm(secmember(3),d1u2, secmember(4),d1v2);
1441 dnorm1w.SetLinearForm(secmember(1),dndu1, secmember(2),dndv1, dn1w);
1442 dnorm2w.SetLinearForm(secmember(3),dndu2, secmember(4),dndv2, dn2w);
1447 Poles2d(Poles2d.Lower()).SetCoord(sol(1),sol(2));
1448 Poles2d(Poles2d.Upper()).SetCoord(sol(3),sol(4));
1450 DPoles2d(Poles2d.Lower()).SetCoord(secmember(1),secmember(2));
1451 DPoles2d(Poles2d.Upper()).SetCoord(secmember(3),secmember(4));
1454 // the linear case is processed...
1455 if (mySShape == BlendFunc_Linear) {
1463 DWeights(low) = 0.0;
1464 DWeights(upp) = 0.0;
1469 // Case of the circle
1470 norm1 = nplan.Crossed(ns1).Magnitude();
1471 norm2 = nplan.Crossed(ns2).Magnitude();
1473 norm1 = 1; // Unsatisfactory, but it is not necessary to stop
1475 cout << " ConstRad : Surface singuliere " << endl;
1479 norm2 = 1; // Unsatisfactory, but it is not necessary to stop
1481 cout << " ConstRad : Surface singuliere " << endl;
1485 ns1.SetLinearForm(nplan.Dot(ns1)/norm1,nplan, -1./norm1,ns1);
1486 ns2.SetLinearForm(nplan.Dot(ns2)/norm2,nplan, -1./norm2,ns2);
1488 Center.SetXYZ(pts1.XYZ()+ray1*ns1.XYZ());
1490 tgc.SetLinearForm(ray1,dnorm1w,tg1); // = tg1.Added(ray1*dn1w);
1493 // ns1 is oriented from the center to pts1, and ns2 from the center to pts2
1494 // and the trihedron ns1,ns2,nplan is made direct
1514 return GeomFill::GetCircle(myTConv,
1528 GeomFill::GetCircle(myTConv,
1533 return Standard_False;
1537 //=======================================================================
1538 //function : Section
1540 //=======================================================================
1542 Standard_Boolean BlendFunc_ConstRad::Section
1543 (const Blend_Point& P,
1544 TColgp_Array1OfPnt& Poles,
1545 TColgp_Array1OfVec& DPoles,
1546 TColgp_Array1OfVec& D2Poles,
1547 TColgp_Array1OfPnt2d& Poles2d,
1548 TColgp_Array1OfVec2d& DPoles2d,
1549 TColgp_Array1OfVec2d& D2Poles2d,
1550 TColStd_Array1OfReal& Weights,
1551 TColStd_Array1OfReal& DWeights,
1552 TColStd_Array1OfReal& D2Weights)
1554 gp_Vec ns1,ns2, np, dnp, d2np, dnorm1w, dnorm2w, d2norm1w, d2norm2w;
1555 gp_Vec tgc, dtgc, dtg1, dtg2, temp, tempbis;
1556 Standard_Real norm1, norm2;
1559 math_Vector X(1,4), sol(1,4), secmember(1,4);
1560 math_Matrix D2DXdSdt(1,4,1,4);
1562 Standard_Real prm = P.Parameter();
1563 Standard_Integer low = Poles.Lower();
1564 Standard_Integer upp = Poles.Upper();
1565 Standard_Boolean istgt = Standard_True;
1567 P.ParametersOnS1(X(1), X(2));
1568 P.ParametersOnS2(X(3), X(4));
1570 /* Pour debuger par des D.F
1572 Standard_Real deltat = 1.e-7;
1573 if (prm==tcurv->LastParameter()){deltat *= -1;} //Pour les discont
1574 Standard_Real deltaX = 1.e-7;
1575 Standard_Real seuil = 1.e-3;
1576 Standard_Integer ii, jj;
1577 gp_Vec d_plan, d1, d2, pdiff;
1578 math_Matrix M(1,4,1,4), MDiff(1,4,1,4);
1579 math_Matrix Mu1(1,4,1,4), Mv1(1,4,1,4);
1580 math_Matrix Mu2(1,4,1,4), Mv2(1,4,1,4);
1581 math_Vector V(1,4), VDiff(1,4),dx(1,4);
1585 ComputeValues(dx, 1, Standard_True, prm );
1590 ComputeValues(dx, 1, Standard_True, prm);
1595 ComputeValues(dx, 1, Standard_True, prm );
1600 ComputeValues(dx, 1, Standard_True, prm );
1603 ComputeValues(X, 1, Standard_True, prm+deltat);
1612 // Calculation of equations
1613 ComputeValues(X, 2, Standard_True, prm);
1614 distmin = Min (distmin, pts1.Distance(pts2));
1618 MDiff = (M - DEDX)*(1/deltat);
1619 VDiff = (V - DEDT)*(1/deltat);
1621 pdiff = (d_plan - dnplan)*(1/deltat);
1622 if ((pdiff-d2nplan).Magnitude() > seuil*(pdiff.Magnitude()+1))
1624 cout << "d2nplan = (" << d2nplan.X() << ","<< d2nplan.Y() << ","<< d2nplan.Z() << ")"<<endl;
1625 cout << "Diff fi = (" << pdiff.X() << ","<< pdiff.Y() << ","<< pdiff.Z() << ")"<<endl;
1628 pdiff = (d1 - dn1w)*(1/deltat);
1629 if ((pdiff-d2n1w).Magnitude() > seuil*(pdiff.Magnitude()+1))
1631 cout << "d2n1w = (" << d2n1w.X() << ","<< d2n1w.Y() << ","<< d2n1w.Z() << ")"<<endl;
1632 cout << "Diff fi = (" << pdiff.X() << ","<< pdiff.Y() << ","<< pdiff.Z() << ")"<<endl;
1634 pdiff = (d2 - dn2w)*(1/deltat);
1635 if ((pdiff-d2n2w).Magnitude() > seuil*(pdiff.Magnitude()+1))
1637 cout << "d2n2w = (" << d2n2w.X() << ","<< d2n2w.Y() << ","<< d2n2w.Z() << ")"<<endl;
1638 cout << "Diff fi = (" << pdiff.X() << ","<< pdiff.Y() << ","<< pdiff.Z() << ")"<<endl;
1642 for ( ii=1; ii<=4; ii++) {
1643 if (Abs(VDiff(ii)-D2EDT2(ii)) > seuil*(Abs(D2EDT2(ii))+1))
1645 cout << "erreur sur D2EDT2 : "<< ii << endl;
1646 cout << D2EDT2(ii) << " D.F = " << VDiff(ii) << endl;
1648 for (jj=1; jj<=4; jj++) {
1649 if (Abs(MDiff(ii,jj)-D2EDXDT(ii, jj)) >
1650 1.e-3*(Abs(D2EDXDT(ii, jj))+1.e-2))
1652 cout << "erreur sur D2EDXDT : "<< ii << " , " << jj << endl;
1653 cout << D2EDXDT(ii,jj) << " D.F = " << MDiff(ii,jj) << endl;
1657 // Test de D2EDX2 en u1
1658 MDiff = (Mu1 - DEDX)/deltaX;
1659 for (ii=1; ii<=4; ii++) {
1660 for (jj=1; jj<=4; jj++) {
1661 if (Abs(MDiff(ii,jj)-D2EDX2(ii, jj, 1)) >
1662 seuil*(Abs(D2EDX2(ii, jj, 1))+1))
1664 cout << "erreur sur D2EDX2 : "<< ii << " , " << jj << " , " << 1 << endl;
1665 cout << D2EDX2(ii,jj, 1) << " D.F = " << MDiff(ii,jj) << endl;
1670 // Test de D2EDX2 en v1
1671 MDiff = (Mv1 - DEDX)/deltaX;
1672 for (ii=1; ii<=4; ii++) {
1673 for (jj=1; jj<=4; jj++) {
1674 if (Abs(MDiff(ii,jj)-D2EDX2(ii, jj, 2)) >
1675 seuil*(Abs(D2EDX2(ii, jj, 2))+1))
1677 cout << "erreur sur D2EDX2 : "<< ii << " , " << jj << " , " << 2 << endl;
1678 cout << D2EDX2(ii,jj, 2) << " D.F = " << MDiff(ii,jj) << endl;
1682 // Test de D2EDX2 en u2
1683 MDiff = (Mu2 - DEDX)/deltaX;
1684 for (ii=1; ii<=4; ii++) {
1685 for (jj=1; jj<=4; jj++) {
1686 if (Abs(MDiff(ii,jj)-D2EDX2(ii, jj, 3)) >
1687 seuil*(Abs(D2EDX2(ii, jj, 3))+1))
1689 cout << "erreur sur D2EDX2 : "<< ii << " , " << jj << " , " << 3 << endl;
1690 cout << D2EDX2(ii,jj, 3) << " D.F = " << MDiff(ii,jj) << endl;
1695 // Test de D2EDX2 en v2
1696 MDiff = (Mv2 - DEDX)/deltaX;
1697 for (ii=1; ii<=4; ii++) {
1698 for (jj=1; jj<=4; jj++) {
1699 if (Abs(MDiff(ii,jj)-D2EDX2(ii, jj, 4)) >
1700 seuil*(Abs(D2EDX2(ii, jj, 4))+1))
1702 cout << "erreur sur D2EDX2 : "<< ii << " , " << jj << " , " << 4 << endl;
1703 cout << D2EDX2(ii,jj, 4) << " D.F = " << MDiff(ii,jj) << endl;
1710 // ns1, ns2, np are copied locally to avois crushing the fields !
1717 // Calculation of derivatives
1720 if ( ! pts1.IsEqual(pts2, 1.e-4)) {
1721 math_Gauss Resol(DEDX, 1.e-9); // Precise tolerance !!!!!
1722 // Calculation of derivatives Processing Normal
1723 if (Resol.IsDone()) {
1724 Resol.Solve(-DEDT, sol);
1725 D2EDX2.Multiply(sol, D2DXdSdt);
1726 secmember = - (D2EDT2 + (2*D2EDXDT+D2DXdSdt)*sol);
1727 Resol.Solve(secmember);
1728 istgt = Standard_False;
1733 math_SVD SingRS (DEDX);
1734 math_Vector Vbis(1,4);
1735 if (SingRS.IsDone()) {
1736 SingRS.Solve(-DEDT, sol, 1.e-6);
1737 D2EDX2.Multiply(sol, D2DXdSdt);
1738 Vbis = - (D2EDT2 + (2*D2EDXDT+D2DXdSdt)*sol);
1739 SingRS.Solve( Vbis, secmember, 1.e-6);
1740 istgt = Standard_False;
1745 tg1.SetLinearForm(sol(1),d1u1, sol(2),d1v1);
1746 tg2.SetLinearForm(sol(3),d1u2, sol(4),d1v2);
1748 dnorm1w.SetLinearForm(sol(1),dndu1, sol(2),dndv1, dn1w);
1749 dnorm2w.SetLinearForm(sol(3),dndu2, sol(4),dndv2, dn2w);
1750 temp.SetLinearForm(sol(1)*sol(1), d2u1,
1751 2*sol(1)*sol(2), d2uv1,
1752 sol(2)*sol(2), d2v1);
1754 dtg1.SetLinearForm(secmember(1),d1u1, secmember(2),d1v1, temp);
1756 temp.SetLinearForm(sol(3)*sol(3), d2u2,
1757 2*sol(3)*sol(4), d2uv2,
1758 sol(4)*sol(4), d2v2);
1759 dtg2.SetLinearForm(secmember(3),d1u2, secmember(4),d1v2, temp);
1761 temp.SetLinearForm(sol(1)*sol(1), d2ndu1,
1762 2*sol(1)*sol(2), d2nduv1,
1763 sol(2)*sol(2), d2ndv1);
1765 tempbis.SetLinearForm(2*sol(1), d2ndtu1,
1769 d2norm1w.SetLinearForm(secmember(1),dndu1, secmember(2),dndv1, temp);
1772 temp.SetLinearForm(sol(3)*sol(3), d2ndu2,
1773 2*sol(3)*sol(4), d2nduv2,
1774 sol(4)*sol(4), d2ndv2);
1775 tempbis.SetLinearForm(2*sol(3), d2ndtu2,
1779 d2norm2w.SetLinearForm(secmember(3),dndu2, secmember(4),dndv2, temp);
1783 Poles2d(Poles2d.Lower()).SetCoord(X(1),X(2));
1784 Poles2d(Poles2d.Upper()).SetCoord(X(3),X(4));
1786 DPoles2d(Poles2d.Lower()) .SetCoord(sol(1),sol(2));
1787 DPoles2d(Poles2d.Upper()) .SetCoord(sol(3),sol(4));
1788 D2Poles2d(Poles2d.Lower()).SetCoord(secmember(1), secmember(2));
1789 D2Poles2d(Poles2d.Upper()).SetCoord(secmember(3), secmember(4));
1792 // linear case is processed...
1793 if (mySShape == BlendFunc_Linear) {
1803 DWeights(low) = 0.0;
1804 DWeights(upp) = 0.0;
1805 D2Weights(low) = 0.0;
1806 D2Weights(upp) = 0.0;
1812 norm1 = nplan.Crossed(ns1).Magnitude();
1813 norm2 = nplan.Crossed(ns2).Magnitude();
1815 norm1 = 1; // Unsatisfactory, but it is not necessary to stop
1817 cout << " ConstRad : Surface singuliere " << endl;
1821 norm2 = 1; // Unsatisfactory, but it is not necessary to stop
1823 cout << " ConstRad : Surface singuliere " << endl;
1827 ns1.SetLinearForm(nplan.Dot(ns1)/norm1,nplan, -1./norm1, ns1);
1828 ns2.SetLinearForm(nplan.Dot(ns2)/norm2,nplan, -1./norm2, ns2);
1830 Center.SetXYZ(pts1.XYZ()+ray1*ns1.XYZ());
1832 tgc.SetLinearForm(ray1,dnorm1w,tg1);
1833 dtgc.SetLinearForm(ray1, d2norm1w, dtg1);
1836 // ns1 is oriented from the center to pts1 and ns2 from the center to pts2
1837 // trihedron ns1,ns2,nplan is made direct
1860 return GeomFill::GetCircle(myTConv,
1878 GeomFill::GetCircle(myTConv,
1883 return Standard_False;
1887 //=======================================================================
1890 //=======================================================================
1892 gp_Ax1 BlendFunc_ConstRad::AxeRot (const Standard_Real Prm)
1895 gp_Vec dirax, d1gui, d2gui, np, dnp;
1896 gp_Pnt oriax, ptgui;
1898 curv->D2(Prm,ptgui,d1gui,d2gui);
1900 Standard_Real normtg = d1gui.Magnitude();
1901 np = d1gui.Normalized();
1902 dnp.SetLinearForm(1./normtg, d2gui,
1903 -1./normtg*(np.Dot(d2gui)), np);
1905 dirax = np.Crossed(dnp);
1906 if (dirax.Magnitude() >= gp::Resolution()) {
1908 axrot.SetDirection(dirax);
1911 axrot.SetDirection(np); // To avoid stop
1913 if (dnp.Magnitude() >= gp::Resolution()) {
1914 oriax.SetXYZ(ptgui.XYZ()+
1915 (normtg/dnp.Magnitude())*dnp.Normalized().XYZ());
1918 oriax.SetXYZ(ptgui.XYZ());
1920 axrot.SetLocation(oriax);
1924 void BlendFunc_ConstRad::Resolution(const Standard_Integer IC2d,
1925 const Standard_Real Tol,
1926 Standard_Real& TolU,
1927 Standard_Real& TolV) const
1930 TolU = surf1->UResolution(Tol);
1931 TolV = surf1->VResolution(Tol);
1934 TolU = surf2->UResolution(Tol);
1935 TolV = surf2->VResolution(Tol);