0024624: Lost word in license statement in source files
[occt.git] / src / BRepBlend / BRepBlend_SurfRstEvolRad.cxx
CommitLineData
b311480e 1// Created on: 1997-07-28
2// Created by: Jerome LEMONIER
3// Copyright (c) 1997-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <BRepBlend_SurfRstEvolRad.ixx>
18#include <math_Gauss.hxx>
19#include <math_SVD.hxx>
20
21#include <ElCLib.hxx>
22#include <gp.hxx>
23#include <BlendFunc.hxx>
24#include <GeomFill.hxx>
25#include <TColStd_SequenceOfReal.hxx>
26#include <Standard_DomainError.hxx>
27#include <Standard_NotImplemented.hxx>
28#include <Precision.hxx>
29
30#define Eps 1.e-15
31
32static void t3dto2d(Standard_Real& a,
33 Standard_Real& b,
34 const gp_Vec& A,
35 const gp_Vec& B,
36 const gp_Vec& C)
37{
38 Standard_Real AB = A.Dot(B);
39 Standard_Real AC = A.Dot(C);
40 Standard_Real BC = B.Dot(C);
41 Standard_Real BB = B.Dot(B);
42 Standard_Real CC = C.Dot(C);
43 Standard_Real deno = (BB*CC-BC*BC);
44 a = (AB*CC-AC*BC)/deno;
45 b = (AC*BB-AB*BC)/deno;
46}
47
48static void FusionneIntervalles(const TColStd_Array1OfReal& I1,
49 const TColStd_Array1OfReal& I2,
50 TColStd_SequenceOfReal& Seq)
51{
52 Standard_Integer ind1=1, ind2=1;
53 Standard_Real Epspar = Precision::PConfusion()*0.99;
81bba717 54 // it is supposed that positioning works with PConfusion()/2
7fd59977 55 Standard_Real v1, v2;
81bba717 56// Initialisation : IND1 and IND2 point at the first element
57// of each of 2 tables to be processed. INDS points at the last
58// element created by TABSOR
7fd59977 59
60
81bba717 61//--- TABSOR is filled by parsing TABLE1 and TABLE2 simultaneously ---
62//------------------ and eliminating multiple occurrencies ------------
7fd59977 63
64 while ((ind1<=I1.Upper()) && (ind2<=I2.Upper())) {
65 v1 = I1(ind1);
66 v2 = I2(ind2);
67 if (Abs(v1-v2)<= Epspar) {
81bba717 68// Here the elements of I1 and I2 fit.
7fd59977 69 Seq.Append((v1+v2)/2);
70 ind1++;
71 ind2++;
72 }
73 else if (v1 < v2) {
81bba717 74 // Here the element of I1 fits.
7fd59977 75 Seq.Append(v1);
76 ind1++;
77 }
78 else {
81bba717 79// Here the element of TABLE2 fits.
7fd59977 80 Seq.Append(v2);
81 ind2++;
82 }
83 }
84
85 if (ind1>I1.Upper()) {
81bba717 86//----- Here I1 is exhausted, completed with the end of TABLE2 -------
7fd59977 87
88 for (; ind2<=I2.Upper(); ind2++) {
89 Seq.Append(I2(ind2));
90 }
91 }
92
93 if (ind2>I2.Upper()) {
81bba717 94//----- Here I2 is exhausted, completed with the end of I1 -------
7fd59977 95
96 for (; ind1<=I1.Upper(); ind1++) {
97 Seq.Append(I1(ind1));
98 }
99 }
100}
101
102//=======================================================================
103//function : BRepBlend_SurfRstEvolRad
81bba717 104//purpose : Contructor
7fd59977 105//=======================================================================
106BRepBlend_SurfRstEvolRad::BRepBlend_SurfRstEvolRad
107(const Handle(Adaptor3d_HSurface)& Surf,
108 const Handle(Adaptor3d_HSurface)& SurfRst,
109 const Handle(Adaptor2d_HCurve2d)& Rst,
110 const Handle(Adaptor3d_HCurve)& CGuide,
111 const Handle(Law_Function)& Evol):
112 surf(Surf), surfrst(SurfRst),
113 rst(Rst), cons(Rst,SurfRst),
114 guide(CGuide), tguide(CGuide),
115 istangent(Standard_True),
116 maxang(RealFirst()), minang(RealLast()),
117 distmin(RealLast()),
118 mySShape(BlendFunc_Rational)
119
120{ tevol=Evol;
121 fevol=Evol;
122}
123
124//=======================================================================
125//function :
126//purpose :
127//=======================================================================
128Standard_Integer BRepBlend_SurfRstEvolRad::NbVariables() const
129{
130 return 3;
131}
132
133//=======================================================================
134//function :
135//purpose :
136//=======================================================================
137Standard_Integer BRepBlend_SurfRstEvolRad::NbEquations() const
138{
139 return 3;
140}
141
142//=======================================================================
143//function :
144//purpose :
145//=======================================================================
146Standard_Boolean BRepBlend_SurfRstEvolRad::Value
147(const math_Vector& X,
148 math_Vector& F)
149{
150 gp_Vec d1u1,d1v1,ns,vref;
151 Standard_Real norm;
152
153 surf->D1(X(1),X(2),pts,d1u1,d1v1);
154 ptrst = cons.Value(X(3));
155
156 F(1) = nplan.XYZ().Dot(pts.XYZ()) + theD;
157
158 F(2) = nplan.XYZ().Dot(ptrst.XYZ()) + theD;
159
160 ns = d1u1.Crossed(d1v1);
161 norm = nplan.Crossed(ns).Magnitude();
162 ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns);
163 vref.SetLinearForm(ray,ns,gp_Vec(ptrst,pts));
164 F(3) = vref.SquareMagnitude() - ray*ray;
165 return Standard_True;
166}
167
168//=======================================================================
169//function : Derivatives
170//purpose :
171//=======================================================================
172Standard_Boolean BRepBlend_SurfRstEvolRad::Derivatives
173(const math_Vector& X,
174 math_Matrix& D)
175{ gp_Vec d1u1,d1v1,d2u1,d2v1,d2uv1,d1;
176 gp_Vec ns,ncrossns,resul,temp, vref;
177
178 Standard_Real norm,ndotns,grosterme;
179
180 surf->D2(X(1),X(2),pts,d1u1,d1v1,d2u1,d2v1,d2uv1);
181 cons.D1(X(3),ptrst,d1);
182
183 D(1,1) = nplan.Dot(d1u1);
184 D(1,2) = nplan.Dot(d1v1);
185 D(1,3) = 0.;
186
187 D(2,1) = 0.;
188 D(2,2) = 0.;
189 D(2,3) = nplan.Dot(d1);
190
191
192 ns = d1u1.Crossed(d1v1);
193 ncrossns = nplan.Crossed(ns);
194 norm = ncrossns.Magnitude();
195 ndotns = nplan.Dot(ns);
196
197 vref.SetLinearForm(ndotns,nplan,-1.,ns);
198 vref.Divide(norm);
199 vref.SetLinearForm(ray,vref,gp_Vec(ptrst,pts));
200
81bba717 201 // Derivative corresponding to u1
7fd59977 202 temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
203 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
204 resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan,
205 ray*grosterme/norm,ns,
206 -ray/norm,temp,
207 d1u1);
208
209 D(3,1) = 2.*(resul.Dot(vref));
210
211
81bba717 212 // Derivative corresponding to v1
7fd59977 213 temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
214 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
215 resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan,
216 ray*grosterme/norm,ns,
217 -ray/norm,temp,
218 d1v1);
219
220 D(3,2) = 2.*(resul.Dot(vref));
221
222 D(3,3) = -2.*(d1.Dot(vref));
223
224 return Standard_True;
225
226}
227
228//=======================================================================
229//function :
230//purpose :
231//=======================================================================
232Standard_Boolean BRepBlend_SurfRstEvolRad::Values
233(const math_Vector& X,
234 math_Vector& F,
235 math_Matrix& D)
236{
237 gp_Vec d1u1,d1v1,d1;
238 gp_Vec d2u1,d2v1,d2uv1;
239 gp_Vec ns,ncrossns,resul,temp,vref;
240
241 Standard_Real norm,ndotns,grosterme;
242
243 surf->D2(X(1),X(2),pts,d1u1,d1v1,d2u1,d2v1,d2uv1);
244 cons.D1(X(3),ptrst,d1);
245
246 F(1) = nplan.XYZ().Dot(pts.XYZ()) + theD;
247 F(2) = nplan.XYZ().Dot(ptrst.XYZ()) + theD;
248
249 D(1,1) = nplan.Dot(d1u1);
250 D(1,2) = nplan.Dot(d1v1);
251 D(1,3) = 0.;
252
253 D(2,1) = 0.;
254 D(2,2) = 0.;
255 D(2,3) = nplan.Dot(d1);
256
257
258 ns = d1u1.Crossed(d1v1);
259 ncrossns = nplan.Crossed(ns);
260 norm = ncrossns.Magnitude();
261 ndotns = nplan.Dot(ns);
262
263 vref.SetLinearForm(ndotns,nplan,-1.,ns);
264 vref.Divide(norm);
265 vref.SetLinearForm(ray,vref,gp_Vec(ptrst,pts));
266
267 F(3) = vref.SquareMagnitude() - ray*ray;
268
269
81bba717 270 // Derivative corresponding to u1
7fd59977 271 temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
272 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
273 resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan,
274 ray*grosterme/norm,ns,
275 -ray/norm,temp,
276 d1u1);
277
278 D(3,1) = 2.*(resul.Dot(vref));
279
280
81bba717 281 // Derivative corresponding to v1
7fd59977 282 temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
283 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
284 resul.SetLinearForm(-ray/norm*(grosterme*ndotns-nplan.Dot(temp)),nplan,
285 ray*grosterme/norm,ns,
286 -ray/norm,temp,
287 d1v1);
288
289 D(3,2) = 2.*(resul.Dot(vref));
290
291 D(3,3) = -2.*(d1.Dot(vref));
292
293 return Standard_True;
294}
295
296//=======================================================================
297//function :
298//purpose :
299//=======================================================================
300void BRepBlend_SurfRstEvolRad::Set
301(const Handle(Adaptor3d_HSurface)& SurfRef,
302const Handle(Adaptor2d_HCurve2d)& RstRef)
303{
304 surfref = SurfRef;
305 rstref = RstRef;
306}
307
308//=======================================================================
309//function :
310//purpose :
311//=======================================================================
312void BRepBlend_SurfRstEvolRad::Set(const Standard_Real Param)
313{
314 d1gui = gp_Vec(0.,0.,0.);
315 nplan = gp_Vec(0.,0.,0.);
316 tguide->D2(Param,ptgui,d1gui,d2gui);
317 normtg = d1gui.Magnitude();
318 nplan.SetXYZ(d1gui.Normalized().XYZ());
319 gp_XYZ nplanXYZ(nplan.XYZ());
320 gp_XYZ ptguiXYZ(ptgui.XYZ());
321 theD = nplanXYZ.Dot(ptguiXYZ) ;
322 theD = theD * (-1.) ;
323 tevol->D1(Param,ray,dray);
324 ray=sg1*ray;
325 dray=sg1*dray;
326}
327
328//=======================================================================
329//function :
81bba717 330//purpose : Segments the curve in its useful part.
331// Precision is taken arbitrary small !?
7fd59977 332//=======================================================================
333 void BRepBlend_SurfRstEvolRad::Set
334(const Standard_Real First,
335const Standard_Real Last)
336{
337 tguide = guide->Trim(First,Last,1.e-12);
338 tevol = fevol->Trim(First,Last,1.e-12);
339}
340
341//=======================================================================
342//function :
343//purpose :
344//=======================================================================
345 void BRepBlend_SurfRstEvolRad::GetTolerance
346(math_Vector& Tolerance,
347const Standard_Real Tol) const
348{
349 Tolerance(1) = surf->UResolution(Tol);
350 Tolerance(2) = surf->VResolution(Tol);
351 Tolerance(3) = cons.Resolution(Tol);
352}
353
354//=======================================================================
355//function :
356//purpose :
357//=======================================================================
358 void BRepBlend_SurfRstEvolRad::GetBounds
359(math_Vector& InfBound,
360math_Vector& SupBound) const
361{
362 InfBound(1) = surf->FirstUParameter();
363 InfBound(2) = surf->FirstVParameter();
364 InfBound(3) = cons.FirstParameter();
365 SupBound(1) = surf->LastUParameter();
366 SupBound(2) = surf->LastVParameter();
367 SupBound(3) = cons.LastParameter();
368
369 if(!Precision::IsInfinite(InfBound(1)) &&
370 !Precision::IsInfinite(SupBound(1))) {
371 Standard_Real range = (SupBound(1) - InfBound(1));
372 InfBound(1) -= range;
373 SupBound(1) += range;
374 }
375 if(!Precision::IsInfinite(InfBound(2)) &&
376 !Precision::IsInfinite(SupBound(2))) {
377 Standard_Real range = (SupBound(2) - InfBound(2));
378 InfBound(2) -= range;
379 SupBound(2) += range;
380 }
381}
382
383//=======================================================================
384//function :
385//purpose :
386//=======================================================================
387 Standard_Boolean BRepBlend_SurfRstEvolRad::IsSolution
388(const math_Vector& Sol,
389const Standard_Real Tol)
390{
391 math_Vector valsol(1,3),secmember(1,3);
392 math_Matrix gradsol(1,3,1,3);
393
394 gp_Vec dnplan,d1u1,d1v1,d1urst,d1vrst,d1,temp,ns,ns2,ncrossns,resul;
395 gp_Pnt bid;
396 Standard_Real norm,ndotns,grosterme;
397 Standard_Real Cosa,Sina,Angle;
398
399 Values(Sol,valsol,gradsol);
400 if (Abs(valsol(1)) <= Tol &&
401 Abs(valsol(2)) <= Tol &&
402 Abs(valsol(3)) <= 2*Tol*Abs(ray) ) {
403
81bba717 404 // Calculation of tangents
7fd59977 405
406 pt2ds = gp_Pnt2d(Sol(1),Sol(2));
407 prmrst = Sol(3);
408 pt2drst = rst->Value(prmrst);
409 surf->D1(Sol(1),Sol(2),pts,d1u1,d1v1);
410 cons.D1(Sol(3),ptrst,d1);
411 dnplan.SetLinearForm(1./normtg,d2gui,
412 -1./normtg*(nplan.Dot(d2gui)),nplan);
413
414 temp.SetXYZ(pts.XYZ() - ptgui.XYZ());
415 secmember(1) = normtg - dnplan.Dot(temp);
416
417 temp.SetXYZ(ptrst.XYZ() - ptgui.XYZ());
418 secmember(2) = normtg - dnplan.Dot(temp);
419
420 ns = d1u1.Crossed(d1v1);
421 ncrossns = nplan.Crossed(ns);
422 ndotns = nplan.Dot(ns);
423 norm = ncrossns.Magnitude();
424
425 grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm;
426 gp_Vec dnw;
427 dnw.SetLinearForm((dnplan.Dot(ns)-grosterme*ndotns)/norm,nplan,
428 ndotns/norm,dnplan,
429 grosterme/norm,ns);
430
431 ns.SetLinearForm(ndotns/norm,nplan, -1./norm,ns);
432 resul.SetLinearForm(ray, ns, gp_Vec(ptrst,pts));
433
434 secmember(3) = -2.*ray*(dnw.Dot(resul)) - 2.*dray*(ns.Dot(resul)) + 2.*ray*dray;
435 math_Gauss Resol(gradsol);
436 if (Resol.IsDone()) {
437 Resol.Solve(secmember);
438 istangent = Standard_False;
439 }
440 else {
441 math_SVD SingRS (gradsol);
442 if (SingRS.IsDone()) {
443 math_Vector DEDT(1,3);
444 DEDT = secmember;
445 SingRS.Solve(DEDT, secmember, 1.e-6);
446 istangent = Standard_False;
447 }
448 else istangent = Standard_True;
449 }
450
451 if (!istangent) {
452 tgs.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1);
453 tgrst = secmember(3)*d1;
454 tg2ds.SetCoord(secmember(1),secmember(2));
455 surfrst->D1(pt2drst.X(),pt2drst.Y(),bid,d1urst,d1vrst);
456 Standard_Real a, b;
457 t3dto2d(a,b,tgrst,d1urst,d1vrst);
458 tg2drst.SetCoord(a,b);
459 istangent = Standard_False;
460 }
461 else {
462 istangent = Standard_True;
463 }
81bba717 464 // update of maxang
7fd59977 465 if(ray>0.) ns.Reverse();
466 ns2 = -resul.Normalized();
467
468 Cosa = ns.Dot(ns2);
469 Sina = nplan.Dot(ns.Crossed(ns2));
470 if (choix%2 != 0) {
81bba717 471 Sina = -Sina; //nplan is changed into -nplan
7fd59977 472 }
473
474 Angle = ACos(Cosa);
475 if (Sina <0.) {
c6541a0c 476 Angle = 2.*M_PI - Angle;
7fd59977 477 }
478
479 if (Angle>maxang) {maxang = Angle;}
480 if (Angle<minang) {minang = Angle;}
481 distmin = Min( distmin, pts.Distance(ptrst));
482
483 return Standard_True;
484 }
485 istangent = Standard_True;
486 return Standard_False;
487}
488
489
490//=======================================================================
491//function : GetMinimalDistance
492//purpose :
493//=======================================================================
494
495Standard_Real BRepBlend_SurfRstEvolRad::GetMinimalDistance() const
496{
497 return distmin;
498}
499
500//=======================================================================
501//function :
502//purpose :
503//=======================================================================
504const gp_Pnt& BRepBlend_SurfRstEvolRad::PointOnS() const
505{
506 return pts;
507}
508
509//=======================================================================
510//function :
511//purpose :
512//=======================================================================
513const gp_Pnt& BRepBlend_SurfRstEvolRad::PointOnRst() const
514{
515 return ptrst ;
516}
517
518//=======================================================================
519//function :
520//purpose :
521//=======================================================================
522const gp_Pnt2d& BRepBlend_SurfRstEvolRad::Pnt2dOnS() const
523{
524 return pt2ds;
525}
526
527//=======================================================================
528//function :
529//purpose :
530//=======================================================================
531const gp_Pnt2d& BRepBlend_SurfRstEvolRad::Pnt2dOnRst() const
532{
533 return pt2drst;
534}
535
536//=======================================================================
537//function :
538//purpose :
539//=======================================================================
540 Standard_Real BRepBlend_SurfRstEvolRad::ParameterOnRst() const
541{
542 return prmrst;
543}
544
545//=======================================================================
546//function :
547//purpose :
548//=======================================================================
549 Standard_Boolean BRepBlend_SurfRstEvolRad::IsTangencyPoint() const
550{
551 return istangent;
552}
553
554//=======================================================================
555//function :
556//purpose :
557//=======================================================================
558const gp_Vec& BRepBlend_SurfRstEvolRad::TangentOnS() const
559{
560 if (istangent) {Standard_DomainError::Raise();}
561 return tgs;
562}
563
564//=======================================================================
565//function :
566//purpose :
567//=======================================================================
568const gp_Vec2d& BRepBlend_SurfRstEvolRad::Tangent2dOnS() const
569{
570 if (istangent) {Standard_DomainError::Raise();}
571 return tg2ds;
572}
573
574//=======================================================================
575//function :
576//purpose :
577//=======================================================================
578const gp_Vec& BRepBlend_SurfRstEvolRad::TangentOnRst() const
579{
580 if (istangent) {Standard_DomainError::Raise();}
581 return tgrst;
582}
583
584//=======================================================================
585//function :
586//purpose :
587//=======================================================================
588const gp_Vec2d& BRepBlend_SurfRstEvolRad::Tangent2dOnRst() const
589{
590 if (istangent) {Standard_DomainError::Raise();}
591 return tg2drst;
592}
593
594//=======================================================================
595//function :
596//purpose :
597//=======================================================================
598 Standard_Boolean BRepBlend_SurfRstEvolRad::Decroch
599(const math_Vector& Sol,
600gp_Vec& NS,
601gp_Vec& TgS) const
602{
603 gp_Vec TgRst, NRst, NRstInPlane, NSInPlane;
604 gp_Pnt bid,Center;
605 gp_Vec d1u,d1v;
606 Standard_Real norm,unsurnorm;
607
608 surf->D1(Sol(1),Sol(2),bid,d1u,d1v);
609 NS = NSInPlane = d1u.Crossed(d1v);
610
611 norm = nplan.Crossed(NS).Magnitude();
612 unsurnorm = 1./norm;
613 NSInPlane.SetLinearForm(nplan.Dot(NS)*unsurnorm,nplan,-unsurnorm,NS);
614
615 Center.SetXYZ(bid.XYZ()+ray*NSInPlane.XYZ());
616 if(choix>2) NSInPlane.Reverse();
617 TgS = nplan.Crossed(gp_Vec(Center,bid));
618 if (choix%2 == 1) {
619 TgS.Reverse();
620 }
621 Standard_Real u,v;
622 rstref->Value(Sol(3)).Coord(u,v);
623 surfref->D1(u,v,bid,d1u,d1v);
624 NRst = d1u.Crossed(d1v);
625 norm = nplan.Crossed(NRst).Magnitude();
626 unsurnorm = 1./norm;
627 NRstInPlane.SetLinearForm(nplan.Dot(NRst)*unsurnorm,nplan,-unsurnorm,NRst);
628 gp_Vec centptrst(Center,bid);
629 if(centptrst.Dot(NRstInPlane) < 0.) NRstInPlane.Reverse();
630 TgRst = nplan.Crossed(centptrst);
631 if (choix%2 == 1) {
632 TgRst.Reverse();
633 }
634
635 Standard_Real dot, NT = NRstInPlane.Magnitude();
636 NT *= TgRst.Magnitude();
637 if (Abs(NT) < 1.e-7) {
81bba717 638 return Standard_False; // Singularity or Incoherence.
7fd59977 639 }
640 dot = NRstInPlane.Dot(TgRst);
641 dot /= NT;
642
643 return (dot < 1.e-10);
644}
645
646//=======================================================================
647//function :
648//purpose :
649//=======================================================================
650 void BRepBlend_SurfRstEvolRad::Set (const Standard_Integer Choix)
651{
652 choix = Choix;
653 switch (choix) {
654 case 1 :
655 case 2 :
656 sg1 = -1;
657 break;
658 case 3 :
659 case 4 :
660 sg1 = 1;
661 break;
662 default :
663 sg1 = -1;
664 break;
665 }
666}
667
668//=======================================================================
669//function :
670//purpose :
671//=======================================================================
672 void BRepBlend_SurfRstEvolRad::Set(const BlendFunc_SectionShape TypeSection)
673{
674 mySShape = TypeSection;
675}
676
677//=======================================================================
678//function :
679//purpose :
680//=======================================================================
681 void BRepBlend_SurfRstEvolRad::Section
682(const Standard_Real Param,
683const Standard_Real U,
684const Standard_Real V,
685const Standard_Real W,
686Standard_Real& Pdeb,
687Standard_Real& Pfin,
688gp_Circ& C)
689{
690 gp_Vec d1u1,d1v1;
691 gp_Vec ns, np;
692 Standard_Real norm;
693 gp_Pnt Center;
694
695 tguide->D1(Param,ptgui,d1gui);
696 np = d1gui.Normalized();
697 ray = sg1*tevol->Value(Param);
698
699 surf->D1(U,V,pts,d1u1,d1v1);
700 ptrst = cons.Value(W);
701
702 ns = d1u1.Crossed(d1v1);
703
704 norm = nplan.Crossed(ns).Magnitude();
705 ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns);
706 Center.SetXYZ(pts.XYZ()+ray*ns.XYZ());
707 C.SetRadius(Abs(ray));
708
709 if (ray > 0) {
710 ns.Reverse();
711 }
712 if (choix%2 != 0) {
713 np.Reverse();
714 }
715 C.SetPosition(gp_Ax2(Center,np,ns));
716
717 Pdeb = 0.; //ElCLib::Parameter(C,pts);
718 Pfin = ElCLib::Parameter(C,ptrst);
719
81bba717 720 // Test negative and almost null angles : Single Case
c6541a0c 721 if (Pfin>1.5*M_PI) {
7fd59977 722 np.Reverse();
723 C.SetPosition(gp_Ax2(Center,np,ns));
724 Pfin = ElCLib::Parameter(C,ptrst);
725 }
726 if (Pfin < Precision::PConfusion()) Pfin += Precision::PConfusion();
727}
728
729//=======================================================================
730//function :
731//purpose :
732//=======================================================================
733 Standard_Boolean BRepBlend_SurfRstEvolRad::IsRational() const
734{
735 return (mySShape==BlendFunc_Rational || mySShape==BlendFunc_QuasiAngular);
736}
737
738//=======================================================================
739//function :
740//purpose :
741//=======================================================================
742 Standard_Real BRepBlend_SurfRstEvolRad::GetSectionSize() const
743{
744 return maxang*Abs(ray);
745}
746
747//=======================================================================
748//function :
749//purpose :
750//=======================================================================
751 void BRepBlend_SurfRstEvolRad::GetMinimalWeight(TColStd_Array1OfReal& Weigths) const
752{
753 BlendFunc::GetMinimalWeights(mySShape, myTConv, minang, maxang, Weigths );
81bba717 754 // It is supposed that it does not depend on the Radius!
7fd59977 755}
756
757//=======================================================================
758//function :
759//purpose :
760//=======================================================================
761 Standard_Integer BRepBlend_SurfRstEvolRad::NbIntervals(const GeomAbs_Shape S) const
762{
763 Standard_Integer Nb_Int_Courbe, Nb_Int_Loi;
764 Nb_Int_Courbe = guide->NbIntervals(BlendFunc::NextShape(S));
765 Nb_Int_Loi = fevol->NbIntervals(S);
766
767 if (Nb_Int_Loi==1) {
768 return Nb_Int_Courbe;
769 }
770
771 TColStd_Array1OfReal IntC(1, Nb_Int_Courbe+1);
772 TColStd_Array1OfReal IntL(1, Nb_Int_Loi+1);
773 TColStd_SequenceOfReal Inter;
774 guide->Intervals(IntC, BlendFunc::NextShape(S));
775 fevol->Intervals(IntL, S);
776
777 FusionneIntervalles( IntC, IntL, Inter);
778 return Inter.Length()-1;
779}
780
781//=======================================================================
782//function :
783//purpose :
784//=======================================================================
785 void BRepBlend_SurfRstEvolRad::Intervals(TColStd_Array1OfReal& T,
786 const GeomAbs_Shape S) const
787{
788 Standard_Integer Nb_Int_Courbe, Nb_Int_Loi;
789 Nb_Int_Courbe = guide->NbIntervals(BlendFunc::NextShape(S));
790 Nb_Int_Loi = fevol->NbIntervals(S);
791
792 if (Nb_Int_Loi==1) {
793 guide->Intervals(T, BlendFunc::NextShape(S));
794 }
795 else {
796 TColStd_Array1OfReal IntC(1, Nb_Int_Courbe+1);
797 TColStd_Array1OfReal IntL(1, Nb_Int_Loi+1);
798 TColStd_SequenceOfReal Inter;
799 guide->Intervals(IntC, BlendFunc::NextShape(S));
800 fevol->Intervals(IntL, S);
801
802 FusionneIntervalles( IntC, IntL, Inter);
803 for (Standard_Integer ii=1; ii<=Inter.Length(); ii++) {
804 T(ii) = Inter(ii);
805 }
806 }
807}
808
809
810//=======================================================================
811//function :
812//purpose :
813//=======================================================================
814 void BRepBlend_SurfRstEvolRad::GetShape
815(Standard_Integer& NbPoles,
816Standard_Integer& NbKnots,
817Standard_Integer& Degree,
818Standard_Integer& NbPoles2d)
819{
820 NbPoles2d = 2;
821 BlendFunc::GetShape(mySShape,maxang,NbPoles,NbKnots,Degree,myTConv);
822}
823
824//=======================================================================
825//function :
826//purpose :
827//=======================================================================
828 void BRepBlend_SurfRstEvolRad::GetTolerance
829(const Standard_Real BoundTol,
830const Standard_Real SurfTol,
831const Standard_Real AngleTol,
832math_Vector& Tol3d,
833math_Vector& Tol1d) const
834{
835 Standard_Integer low = Tol3d.Lower() , up=Tol3d.Upper();
836 Standard_Real Tol;
837 Tol= GeomFill::GetTolerance(myTConv, minang, Abs(ray),
838 AngleTol, SurfTol);
839 Tol1d.Init(SurfTol);
840 Tol3d.Init(SurfTol);
841 Tol3d(low+1) = Tol3d(up-1) = Min( Tol, SurfTol);
842 Tol3d(low) = Tol3d(up) = Min( Tol, BoundTol);
843}
844
845//=======================================================================
846//function :
847//purpose :
848//=======================================================================
849 void BRepBlend_SurfRstEvolRad::Knots(TColStd_Array1OfReal& TKnots)
850{
851 GeomFill::Knots(myTConv,TKnots);
852}
853
854//=======================================================================
855//function :
856//purpose :
857//=======================================================================
858 void BRepBlend_SurfRstEvolRad::Mults(TColStd_Array1OfInteger& TMults)
859{
860 GeomFill::Mults(myTConv,TMults);
861}
862
863//=======================================================================
864//function :
865//purpose :
866//=======================================================================
867 Standard_Boolean BRepBlend_SurfRstEvolRad::Section
868(const Blend_Point& P,
869TColgp_Array1OfPnt& Poles,
870TColgp_Array1OfVec& DPoles,
871TColgp_Array1OfPnt2d& Poles2d,
872TColgp_Array1OfVec2d& DPoles2d,
873TColStd_Array1OfReal& Weigths,
874TColStd_Array1OfReal& DWeigths)
875{
876
877 gp_Vec d1u1,d1v1,d2u1,d2v1,d2uv1,d1;
878 gp_Vec ns,ns2,dnplan,dnw,dn2w;//,np2,dnp2;
879 gp_Vec ncrossns;;
880 gp_Vec resulu,resulv,temp,tgct,resul;
881 gp_Vec d1urst,d1vrst;
882 gp_Pnt Center,bid;
883
75259fc5 884 Standard_Real norm,ndotns,grosterme,aDray;
7fd59977 885
886 math_Vector sol(1,3),valsol(1,3),secmember(1,3);
887 math_Matrix gradsol(1,3,1,3);
888
889 Standard_Real prm = P.Parameter(),rayprim;
7fd59977 890 Standard_Integer low = Poles.Lower();
891 Standard_Integer upp = Poles.Upper();
892 Standard_Boolean istgt;
893
894 tguide->D2(prm,ptgui,d1gui,d2gui);
895
75259fc5 896 tevol->D1(prm,ray,aDray);
7fd59977 897 ray=sg1*ray;
75259fc5 898 aDray=sg1*aDray;
7fd59977 899 normtg = d1gui.Magnitude();
900 nplan = d1gui.Normalized();
901 dnplan.SetLinearForm(1./normtg,d2gui,
902 -1./normtg*(nplan.Dot(d2gui)),nplan);
903
904 P.ParametersOnS(sol(1),sol(2));
905 sol(3) = prmrst = P.ParameterOnC();
906 pt2drst = rst->Value(prmrst);
907
908 Values(sol,valsol,gradsol);
909
910 surf->D2(sol(1),sol(2),pts,d1u1,d1v1,d2u1,d2v1,d2uv1);
911 cons.D1(sol(3),ptrst,d1);
912
913 temp.SetXYZ(pts.XYZ()- ptgui.XYZ());
914 secmember(1) = normtg - dnplan.Dot(temp);
915
916 temp.SetXYZ(ptrst.XYZ()- ptgui.XYZ());
917 secmember(2) = normtg - dnplan.Dot(temp);
918
919 ns = d1u1.Crossed(d1v1);
920 ncrossns = nplan.Crossed(ns);
921 ndotns = nplan.Dot(ns);
922 norm = ncrossns.Magnitude();
923 if (norm < Eps) {
81bba717 924 norm = 1; // Not enough, but it is not necessary to stop
7fd59977 925#if DEB
81bba717 926 cout << " SurfRstEvolRad : Surface single " << endl;
7fd59977 927#endif
928 }
929
81bba717 930 // Derivative of n1 corresponding to w
7fd59977 931
932 grosterme = ncrossns.Dot(dnplan.Crossed(ns))/norm/norm;
933 dnw.SetLinearForm((dnplan.Dot(ns)-grosterme*ndotns)/norm,nplan,
934 ndotns/norm,dnplan,
935 grosterme/norm,ns);
936
937 temp.SetLinearForm(ndotns/norm,nplan, -1./norm,ns);
938 resul.SetLinearForm(ray,temp,gp_Vec(ptrst,pts));
939
940 //secmember(3) = -2.*ray*(dnw.Dot(resul)); // jag 950105 il manquait ray
75259fc5 941 secmember(3) = -2.*ray*(dnw.Dot(resul)) - 2.*aDray*(temp.Dot(resul)) + 2.*ray*aDray;
7fd59977 942 math_Gauss Resol(gradsol);
943
944 if (Resol.IsDone()) {
945 Resol.Solve(secmember);
946 istgt = Standard_False;
947 }
948 else {
949 math_SVD SingRS (gradsol);
950 if (SingRS.IsDone()) {
951 math_Vector DEDT(1,3);
952 DEDT = secmember;
953 SingRS.Solve(DEDT, secmember, 1.e-6);
954 istgt = Standard_False;
955 }
956 else istgt = Standard_True;
957 }
958
959 if (!istgt) {
960
961 tgs.SetLinearForm(secmember(1),d1u1,secmember(2),d1v1);
962 tgrst = secmember(3)*d1;
81bba717 963 // Derivative of n1 corresponding to u1
7fd59977 964 temp = d2u1.Crossed(d1v1).Added(d1u1.Crossed(d2uv1));
965 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
966 resulu.SetLinearForm(-(grosterme*ndotns-nplan.Dot(temp))/norm,nplan,
967 grosterme/norm,ns,
968 -1./norm,temp);
969
81bba717 970 // Derivative of n1 corresponding to v1
7fd59977 971 temp = d2uv1.Crossed(d1v1).Added(d1u1.Crossed(d2v1));
972 grosterme = ncrossns.Dot(nplan.Crossed(temp))/norm/norm;
973 resulv.SetLinearForm(-(grosterme*ndotns-nplan.Dot(temp))/norm,nplan,
974 grosterme/norm,ns,
975 -1./norm,temp);
976
977
978 dnw.SetLinearForm(secmember(1),resulu,secmember(2),resulv,dnw);
979 ns.SetLinearForm(ndotns/norm,nplan, -1./norm,ns);
980
981 dn2w.SetLinearForm(ray, dnw, -1., tgrst, tgs);
75259fc5 982 dn2w.SetLinearForm(aDray,ns,dn2w);
7fd59977 983 norm = resul.Magnitude();
984 dn2w.Divide(norm);
985 ns2 = -resul.Normalized();
986 dn2w.SetLinearForm(ns2.Dot(dn2w),ns2,-1.,dn2w);
987
988 istgt = Standard_False;
989 }
990 else {
991 ns.SetLinearForm(ndotns/norm,nplan, -1./norm,ns);
992 ns2 = -resul.Normalized();
993 istgt = Standard_True;
994 }
995
81bba717 996 // Tops 2D
7fd59977 997
998 Poles2d(Poles2d.Lower()).SetCoord(sol(1),sol(2));
999 Poles2d(Poles2d.Upper()).SetCoord(pt2drst.X(),pt2drst.Y());
1000 if (!istgt) {
1001 DPoles2d(Poles2d.Lower()).SetCoord(secmember(1),secmember(2));
1002 surfrst->D1(pt2drst.X(),pt2drst.Y(),bid,d1urst,d1vrst);
1003 Standard_Real a, b;
1004 t3dto2d(a,b,tgrst,d1urst,d1vrst);
1005 DPoles2d(Poles2d.Upper()).SetCoord(a,b);
1006 }
1007
81bba717 1008 // Linear Case
7fd59977 1009 if (mySShape == BlendFunc_Linear) {
1010 Poles(low) = pts;
1011 Poles(upp) = ptrst;
1012 Weigths(low) = 1.0;
1013 Weigths(upp) = 1.0;
1014 if (!istgt) {
1015 DPoles(low) = tgs;
1016 DPoles(upp) = tgrst;
1017 DWeigths(low) = 0.0;
1018 DWeigths(upp) = 0.0;
1019 }
1020 return (!istgt);
1021 }
1022
81bba717 1023 // Case of the circle
7fd59977 1024 Center.SetXYZ(pts.XYZ()+ray*ns.XYZ());
1025 if (!istgt) {
75259fc5 1026 tgct.SetLinearForm(ray,dnw,aDray,ns,tgs);
7fd59977 1027 }
1028
1029 if (ray > 0.) {
1030 ns.Reverse();
1031 if (!istgt) {
1032 dnw.Reverse();
1033 }
1034 }
1035 if (choix%2 != 0) {
1036 nplan.Reverse();
1037 dnplan.Reverse();
1038 }
1039 if (!istgt) {
81bba717 1040 if (ray < 0.) { // to avoid Abs(dray) some lines below
75259fc5 1041 rayprim = -aDray;
7fd59977 1042 }
75259fc5 1043 else rayprim = aDray;
7fd59977 1044
1045 return GeomFill::GetCircle(myTConv,
1046 ns, ns2,
1047 dnw, dn2w,
1048 nplan, dnplan,
1049 pts, ptrst,
1050 tgs, tgrst,
1051 Abs(ray),rayprim ,
1052 Center, tgct,
1053 Poles,
1054 DPoles,
1055 Weigths,
1056 DWeigths);
1057 }
1058 else {
1059 GeomFill::GetCircle(myTConv,
1060 ns, ns2,
1061 nplan, pts, ptrst,
1062 Abs(ray), Center,
1063 Poles, Weigths);
1064 return Standard_False;
1065 }
1066}
1067
1068//=======================================================================
1069//function :
1070//purpose :
1071//=======================================================================
35e08fe8 1072 Standard_Boolean BRepBlend_SurfRstEvolRad::Section (const Blend_Point& /*P*/,
1073 TColgp_Array1OfPnt& /*Poles*/,
1074 TColgp_Array1OfVec& /*DPoles*/,
1075 TColgp_Array1OfVec& /*D2Poles*/,
1076 TColgp_Array1OfPnt2d& /*Poles2d*/,
1077 TColgp_Array1OfVec2d& /*DPoles2d*/,
1078 TColgp_Array1OfVec2d& /*D2Poles2d*/,
1079 TColStd_Array1OfReal& /*Weigths*/,
1080 TColStd_Array1OfReal& /*DWeigths*/,
1081 TColStd_Array1OfReal& /*D2Weigths*/)
7fd59977 1082{
1083 return Standard_False;
1084}
1085
1086//=======================================================================
1087//function :
1088//purpose :
1089//=======================================================================
1090 void BRepBlend_SurfRstEvolRad::Section
1091(const Blend_Point& P,
1092TColgp_Array1OfPnt& Poles,
1093TColgp_Array1OfPnt2d& Poles2d,
1094TColStd_Array1OfReal& Weigths)
1095{
1096 gp_Vec d1u1,d1v1;//,d1;
1097 gp_Vec ns,ns2;//,temp,np2;
1098 gp_Pnt Center;
1099
1100 Standard_Real norm,u1,v1,w;
1101
1102 Standard_Real prm = P.Parameter();
1103 Standard_Integer low = Poles.Lower();
1104 Standard_Integer upp = Poles.Upper();
1105
1106 tguide->D1(prm,ptgui,d1gui);
1107 ray = tevol->Value(prm);
1108 ray=sg1*ray;
1109 nplan = d1gui.Normalized();
1110
1111 P.ParametersOnS(u1,v1);
81bba717 1112 w = P.ParameterOnC(); //jlr : point on curve not on surface
7fd59977 1113 gp_Pnt2d pt2d = rst->Value(w);
1114
1115 surf->D1(u1,v1,pts,d1u1,d1v1);
1116 ptrst = cons.Value(w);
1117
1118 distmin = Min (distmin, pts.Distance(ptrst));
1119
1120 Poles2d(Poles2d.Lower()).SetCoord(u1,v1);
1121 Poles2d(Poles2d.Upper()).SetCoord(pt2d.X(),pt2d.Y());
1122
81bba717 1123 // Linear case
7fd59977 1124 if (mySShape == BlendFunc_Linear) {
1125 Poles(low) = pts;
1126 Poles(upp) = ptrst;
1127 Weigths(low) = 1.0;
1128 Weigths(upp) = 1.0;
1129 return;
1130 }
1131
1132 ns = d1u1.Crossed(d1v1);
1133 norm = nplan.Crossed(ns).Magnitude();
1134
1135 ns.SetLinearForm(nplan.Dot(ns)/norm,nplan, -1./norm,ns);
1136
1137 Center.SetXYZ(pts.XYZ()+ray*ns.XYZ());
1138
1139 ns2 = gp_Vec(Center,ptrst).Normalized();
1140 if(ray>0) ns.Reverse();
1141 if (choix%2 != 0) {
1142 nplan.Reverse();
1143 }
1144
1145 GeomFill::GetCircle(myTConv,
1146 ns, ns2,
1147 nplan, pts, ptrst,
1148 Abs(ray), Center,
1149 Poles, Weigths);
1150}
1151
1152void BRepBlend_SurfRstEvolRad::Resolution(const Standard_Integer IC2d,
1153 const Standard_Real Tol,
1154 Standard_Real& TolU,
1155 Standard_Real& TolV) const
1156{
1157 if(IC2d == 1){
1158 TolU = surf->UResolution(Tol);
1159 TolV = surf->VResolution(Tol);
1160 }
1161 else {
1162 TolU = surfrst->UResolution(Tol);
1163 TolV = surfrst->VResolution(Tol);
1164 }
1165}
1166
1167