0024511: Remove obsolete Image_PixelAddress.cxx
[occt.git] / src / GeomFill / GeomFill_LocationGuide.cxx
CommitLineData
b311480e 1// Created on: 1998-07-08
2// Created by: Stephanie HUMEAU
3// Copyright (c) 1998-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//
973c2be1 8// This library is free software; you can redistribute it and / or modify it
9// under the terms of the GNU Lesser General Public 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.
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 <GeomFill_LocationGuide.ixx>
18#include <gp.hxx>
19#include <gp_Pnt.hxx>
20#include <gp_Vec.hxx>
21#include <gp_Dir.hxx>
22#include <gp_Trsf.hxx>
23#include <gp_GTrsf.hxx>
24#include <gp_XYZ.hxx>
25#include <gp_Ax1.hxx>
26#include <gp_Pnt2d.hxx>
27
28#include <math_Vector.hxx>
29#include <math_Gauss.hxx>
30#include <math_FunctionSetRoot.hxx>
31#include <Precision.hxx>
32
33#include <Geom_SurfaceOfRevolution.hxx>
34#include <Geom_BSplineCurve.hxx>
35#include <Geom_Curve.hxx>
36
37#include <Adaptor3d_SurfaceOfRevolution.hxx>
38#include <Adaptor3d_HSurface.hxx>
39
40#include <IntCurveSurface_IntersectionPoint.hxx>
7fd59977 41#include <Adaptor3d_Surface.hxx>
42#include <GeomAdaptor.hxx>
43#include <GeomAdaptor_HSurface.hxx>
44#include <GeomAdaptor_HCurve.hxx>
45
46
47#include <GeomFill_FunctionGuide.ixx>
48#include <GeomFill_UniformSection.hxx>
49#include <GeomFill_SectionPlacement.hxx>
50#include <Geom_TrimmedCurve.hxx>
51#include <GeomLib.hxx>
52#include <ElCLib.hxx>
53
54#include <TColStd_HArray1OfInteger.hxx>
55#include <TColStd_HArray1OfReal.hxx>
56#include <TColgp_HArray1OfPnt.hxx>
57
f9032cf2 58#include <Extrema_ExtCS.hxx>
59#include <Extrema_POnSurf.hxx>
60
7fd59977 61#if DRAW
62static Standard_Integer Affich = 0;
63#include <Approx_Curve3d.hxx>
64#include <DrawTrSurf.hxx>
65#endif
66
67//=======================================================================
68//function : TraceRevol
69//purpose : Trace la surface de revolution (Debug)
70//=======================================================================
71#if DEB
72static void TraceRevol(const Standard_Real t,
73 const Standard_Real s,
74 const Handle(GeomFill_TrihedronWithGuide)& Law,
75 const Handle(GeomFill_SectionLaw)& Section,
76 const Handle(Adaptor3d_HCurve)& Curve,
77 const gp_Mat& Trans)
78
79{
80 gp_Vec T, N, B;
81 gp_Pnt P;
82 Standard_Boolean Ok;
83 gp_Ax3 Rep(gp::Origin(), gp::DZ(), gp::DX());
84
85 Curve->D0(t, P);
86 Ok = Law->D0(t, T, N, B);
87
88 gp_Mat M(N.XYZ(), B.XYZ(), T.XYZ());
89 M *= Trans;
90
91 gp_Dir D = M.Column(3);
92 gp_Ax1 Ax(P,D); // axe pour la surface de revoltuion
93
94 // calculer transfo entre triedre et Oxyz
95 gp_Dir N2 = N;
96 gp_Ax3 N3(P,D,N2);
97 gp_Trsf Transfo;
98 Transfo.SetTransformation(N3, Rep);
99
100 // transformer la section
101 Standard_Real f, l,e=1.e-7;
102 Handle (Geom_Curve) S, C;
103
104 if (Section->IsConstant(e)) {
105 C = Section->ConstantSection();
106 }
107 else {
108 Standard_Integer NbPoles, NbKnots, Deg;
109 Section->SectionShape(NbPoles, NbKnots, Deg);
110 TColStd_Array1OfInteger Mult(1,NbKnots);
111 Section->Mults( Mult);
112 TColStd_Array1OfReal Knots(1,NbKnots);
113 Section->Knots(Knots);
114 TColgp_Array1OfPnt Poles(1, NbPoles);
115 TColStd_Array1OfReal Weights(1, NbPoles);
116 Section->D0(s, Poles, Weights);
117 if (Section->IsRational())
118 C = new (Geom_BSplineCurve)
119 (Poles, Weights, Knots, Mult ,
120 Deg, Section->IsUPeriodic());
121 else
122 C = new (Geom_BSplineCurve)
123 (Poles, Knots, Mult,
124 Deg, Section->IsUPeriodic());
125
126 }
127
128 f = C->FirstParameter();
129 l = C->LastParameter();
130 S = new (Geom_TrimmedCurve) (C, f, l);
131 S->Transform(Transfo);
132
133 // Surface de revolution
134 Handle (Geom_Surface) Revol = new(Geom_SurfaceOfRevolution) (S, Ax);
135 cout << "Surf Revol at parameter t = " << t << endl;
136
137#if DRAW
138 Standard_CString aName = "TheRevol" ;
139 DrawTrSurf::Set(aName,Revol);
140#endif
141}
142#endif
143
144//==================================================================
145//Function: InGoodPeriod
146//Purpose : Recadre un paramtere
147//==================================================================
148static void InGoodPeriod(const Standard_Real Prec,
149 const Standard_Real Period,
150 Standard_Real& Current)
151{
152 Standard_Real Diff=Current-Prec;
153 Standard_Integer nb = (Standard_Integer ) IntegerPart(Diff/Period);
154 Current -= nb*Period;
155 Diff = Current-Prec;
156 if (Diff > Period/2) Current -= Period;
157 else if (Diff < -Period/2) Current += Period;
158}
159
160//==================================================================
161//Function: GeomFill_LocationGuide
162//Purpose : constructor
163//==================================================================
164 GeomFill_LocationGuide::
165 GeomFill_LocationGuide (const Handle(GeomFill_TrihedronWithGuide)& Triedre)
166 : TolRes(1,3), Inf(1,3,0.), Sup(1,3,0.),
167 X(1,3), R(1,3), myStatus(GeomFill_PipeOk)
168{
169 TolRes.Init(1.e-6);
170 myLaw = Triedre; // loi de triedre
171 mySec.Nullify(); // loi de section
172 myCurve.Nullify();
173 myFirstS = myLastS = -505e77;
174
175 myNbPts = 21; // nb points pour les calculs
176 myGuide = myLaw->Guide(); // courbe guide
177 if (!myGuide->IsPeriodic()) {
178 Standard_Real f, l, delta;
179 f = myGuide->FirstParameter();
180 l = myGuide->LastParameter();
181 delta = (l-f)/100;
182 f-=delta;
183 l+=delta;
184 myGuide = myGuide->Trim(f,l,delta*1.e-7); // courbe guide
185 }// if
186
187 myPoles2d = new (TColgp_HArray2OfPnt2d)(1, 2, 1, myNbPts);
188 rotation = Standard_False; // contact ou non
189 OrigParam1 = 0; // param pour ACR quand trajectoire
190 OrigParam2 = 1; // et guide pas meme sens de parcourt
191 Trans.SetIdentity();
192 WithTrans = Standard_False;
193
194#if DRAW
195 if (Affich) {
196 Approx_Curve3d approx(myGuide, 1.e-4,
197 GeomAbs_C1,
198 15+myGuide->NbIntervals(GeomAbs_CN),
199 14);
200 if (approx.HasResult()) {
201 Standard_CString aName = "TheGuide" ;
202 DrawTrSurf::Set(aName, approx.Curve());
203 }
204 }
205#endif
206}
207
208//==================================================================
209//Function: SetRotation
210//Purpose : init et force la Rotation
211//==================================================================
212 void GeomFill_LocationGuide::SetRotation(const Standard_Real PrecAngle,
213 Standard_Real& LastAngle)
214{
215 if (myCurve.IsNull())
216 Standard_ConstructionError::Raise(
217 "GeomFill_LocationGuide::The path is not setted !!");
218
219 //repere fixe
220 gp_Ax3 Rep(gp::Origin(), gp::DZ(), gp::DX());
221// gp_Pnt P,P1,P2;
222 gp_Pnt P;
223 gp_Vec T,N,B;
224 Standard_Integer ii, Deg;
225 Standard_Boolean isconst, israt=Standard_False;
226 Standard_Real t, v,w, OldAngle=0, Angle, DeltaG, DeltaU, Diff;
f9032cf2 227 Standard_Real CurAngle = PrecAngle, a1/*, a2*/;
7fd59977 228 gp_Pnt2d p1,p2;
229 Handle(Geom_SurfaceOfRevolution) Revol; // surface de revolution
230 Handle(GeomAdaptor_HSurface) Pl; // = Revol
231 Handle(Geom_TrimmedCurve) S;
232 IntCurveSurface_IntersectionPoint PInt; // intersection guide/Revol
7fd59977 233 Handle(TColStd_HArray1OfInteger) Mult;
234 Handle(TColStd_HArray1OfReal) Knots, Weights;
235 Handle(TColgp_HArray1OfPnt) Poles;
236
237
238 Standard_Real U=0, UPeriod=0;
239 Standard_Real f = myCurve->FirstParameter();
240 Standard_Real l = myCurve->LastParameter();
241 Standard_Boolean Ok, uperiodic = mySec->IsUPeriodic();
242
243 DeltaG = (myGuide->LastParameter() - myGuide->FirstParameter())/5;
244 Handle(Geom_Curve) mySection;
245 Standard_Real Tol =1.e-9;
246
247 Standard_Integer NbPoles, NbKnots;
248 mySec->SectionShape(NbPoles, NbKnots, Deg);
249
250
251 if (mySec->IsConstant(Tol)) {
252 mySection = mySec->ConstantSection();
253 Uf = mySection->FirstParameter();
254 Ul = mySection->LastParameter();
255
256 isconst = Standard_True;
257 }
258 else {
259 isconst = Standard_False;
260 israt = mySec->IsRational();
261 Mult = new (TColStd_HArray1OfInteger) (1, NbKnots);
262 mySec->Mults( Mult->ChangeArray1());
263 Knots = new (TColStd_HArray1OfReal) (1, NbKnots);
264 mySec->Knots(Knots->ChangeArray1());
265 Poles = new (TColgp_HArray1OfPnt) (1, NbPoles);
266 Weights = new (TColStd_HArray1OfReal) (1, NbPoles);
267 Uf = Knots->Value(1);
268 Ul = Knots->Value(NbKnots);
269 }
270
271 // Bornes de calculs
272 Standard_Real Delta;
273// Standard_Integer bid1, bid2, NbK;
274 Delta = myGuide->LastParameter() - myGuide->FirstParameter();
275 Inf(1) = myGuide->FirstParameter() - Delta/10;
276 Sup(1) = myGuide->LastParameter() + Delta/10;
277
c6541a0c
D
278 Inf(2) = -M_PI;
279 Sup(2) = 3*M_PI;
7fd59977 280
281 Delta = Ul - Uf;
282 Inf(3) = Uf - Delta/10;
283 Sup(3) = Ul + Delta/10;
284
285 // JALONNEMENT
286 DeltaU = (Ul-Uf)/(2+NbKnots);
287 if (uperiodic) UPeriod = Ul-Uf;
288
289 for (ii=1; ii<=myNbPts; ii++) {
290 t = Standard_Real(myNbPts - ii)*f + Standard_Real(ii - 1)*l;
291 t /= (myNbPts-1);
292 myCurve->D0(t, P);
293 Ok = myLaw->D0(t, T, N, B);
294 if (!Ok) {
295 myStatus = myLaw->ErrorStatus();
296 return; //Y a rien a faire.
297 }
298 gp_Dir D = T;
299 if (WithTrans) {
300 gp_Mat M(N.XYZ(), B.XYZ(), T.XYZ());
301 M *= Trans;
302 D = M.Column(3);
303 }
304 gp_Ax1 Ax(P,D); // axe pour la surface de revoltuion
305
306 // calculer transfo entre triedre et Oxyz
307 gp_Dir N2 = N;
308 gp_Ax3 N3(P,D,N2);
309 gp_Trsf Transfo;
310 Transfo.SetTransformation(N3, Rep);
311
312 // transformer la section
313 if (! isconst) {
314 U = myFirstS + (t-myCurve->FirstParameter())*ratio;
315 mySec->D0(U, Poles->ChangeArray1(), Weights->ChangeArray1());
316 if (israt)
317 mySection = new (Geom_BSplineCurve)
318 (Poles->Array1(),
319 Weights->Array1(),
320 Knots->Array1(),
321 Mult->Array1(),
322 Deg, mySec->IsUPeriodic());
323 else
324 mySection = new (Geom_BSplineCurve)
325 (Poles->Array1(),
326 Knots->Array1(),
327 Mult->Array1(),
328 Deg, mySec->IsUPeriodic());
329 S = new (Geom_TrimmedCurve) (mySection, Uf, Ul);
330 }
331 else {
332 S = new (Geom_TrimmedCurve)
333 (Handle(Geom_Curve)::DownCast(mySection->Copy()), Uf, Ul);
334 }
335 S->Transform(Transfo);
f9032cf2 336
7fd59977 337 // Surface de revolution
338 Revol = new(Geom_SurfaceOfRevolution) (S, Ax);
339
f9032cf2 340 GeomAdaptor_Surface GArevol(Revol);
341 Extrema_ExtCS DistMini(myGuide->Curve(), GArevol,
342 Precision::Confusion(), Precision::Confusion());
343 Extrema_POnCurv Pc;
344 Extrema_POnSurf Ps;
345 Standard_Real theU = 0., theV = 0.;
346
347 if (!DistMini.IsDone() || DistMini.NbExt() == 0) {
7fd59977 348#if DEB
349 cout <<"LocationGuide : Pas d'intersection"<<endl;
350 TraceRevol(t, U, myLaw, mySec, myCurve, Trans);
351#endif
352 Standard_Boolean SOS=Standard_False;
353 if (ii>1) {
354 // Intersection de secour entre surf revol et guide
355 // equation
356 X(1) = myPoles2d->Value(1,ii-1).Y();
357 X(2) = myPoles2d->Value(2,ii-1).X();
358 X(3) = myPoles2d->Value(2,ii-1).Y();
359 GeomFill_FunctionGuide E (mySec, myGuide, U);
360 E.SetParam(U, P, T.XYZ(), N.XYZ());
361 // resolution => angle
362 math_FunctionSetRoot Result(E, X, TolRes,
363 Inf, Sup);
364
365 if (Result.IsDone() &&
366 (Result.FunctionSetErrors().Norm() < TolRes(1)*TolRes(1)) ) {
367#if DEB
368 cout << "Ratrappage Reussi !" << endl;
369#endif
370 SOS = Standard_True;
371 math_Vector RR(1,3);
372 Result.Root(RR);
f9032cf2 373 PInt.SetValues(P, RR(2), RR(3), RR(1), IntCurveSurface_Out);
374 theU = PInt.U();
375 theV = PInt.V();
7fd59977 376 }
377 else {
378#if DEB
379 cout << "Echec du Ratrappage !" << endl;
380#endif
381 }
382 }
383 if (!SOS) {
384 myStatus = GeomFill_ImpossibleContact;
385 return;
386 }
387 }
388 else { // on prend le point d'intersection
389 // d'angle le plus proche de P
f9032cf2 390
391 Standard_Real MinDist = RealLast();
392 Standard_Integer jref = 0;
393 for (Standard_Integer j = 1; j <= DistMini.NbExt(); j++)
394 {
395 Standard_Real aDist = DistMini.SquareDistance(j);
396 if (aDist < MinDist)
397 {
398 MinDist = aDist;
399 jref = j;
400 }
401 }
402 MinDist = Sqrt(MinDist);
403 DistMini.Points(jref, Pc, Ps);
404
405 Ps.Parameter(theU, theV);
406 a1 = theU;
407
c6541a0c 408 InGoodPeriod (CurAngle, 2*M_PI, a1);
7fd59977 409 }//else
410
411 // Controle de w
f9032cf2 412 w = Pc.Parameter();
413
7fd59977 414 if (ii>1) {
415 Diff = w - myPoles2d->Value(1, ii-1).Y();
416 if (Abs(Diff) > DeltaG) {
417 if (myGuide->IsPeriodic()) {
418 InGoodPeriod (myPoles2d->Value(1, ii-1).Y(),
419 myGuide->Period(), w);
420 Diff = w - myPoles2d->Value(1, ii-1).Y();
421 }
422 }
423
424#if DEB
425 if (Abs(Diff) > DeltaG) {
426 cout << "Location :: Diff on Guide : " <<
427 Diff << endl;
428 }
429#endif
430 }
431 //Recadrage de l'angle.
f9032cf2 432 Angle = theU;
433
7fd59977 434 if (ii > 1) {
435 Diff = Angle - OldAngle;
c6541a0c
D
436 if (Abs(Diff) > M_PI) {
437 InGoodPeriod (OldAngle, 2*M_PI, Angle);
7fd59977 438 Diff = Angle - OldAngle;
439 }
440#if DEB
c6541a0c 441 if (Abs(Diff) > M_PI/4) {
7fd59977 442 cout << "Diff d'angle trop grand !!" << endl;
443 }
444#endif
445 }
446
447
448 //Recadrage du V
f9032cf2 449 v = theV;
450
7fd59977 451 if (ii > 1) {
452 if (uperiodic) {
453 InGoodPeriod (myPoles2d->Value(2, ii-1).Y(), UPeriod, v);
454 }
455 Diff = v - myPoles2d->Value(2, ii-1).Y();
456#if DEB
457 if (Abs(Diff) > DeltaU) {
458 cout << "Diff sur section trop grand !!" << endl;
459 }
460#endif
461 }
462
463 p1.SetCoord(t, w); // on stocke les parametres
464 p2.SetCoord(Angle , v);
465 CurAngle = Angle;
466 myPoles2d->SetValue(1, ii, p1);
467 myPoles2d->SetValue(2, ii, p2);
468 OldAngle = Angle;
469 }
470
471 LastAngle = CurAngle;
472 rotation = Standard_True; //C'est pret !
473}
474
475
476//==================================================================
477//Function: Set
478//Purpose : init loi de section et force la Rotation
479//==================================================================
480 void GeomFill_LocationGuide::Set(const Handle(GeomFill_SectionLaw)& Section,
481 const Standard_Boolean rotat,
482 const Standard_Real SFirst,
483 const Standard_Real SLast,
484 const Standard_Real PrecAngle,
485 Standard_Real& LastAngle)
486{
487 myStatus = GeomFill_PipeOk;
488 myFirstS = SFirst;
489 myLastS = SLast;
490 LastAngle = PrecAngle;
491 if (myCurve.IsNull())
492 ratio = 0.;
493 else
494 ratio = (SLast-SFirst) / (myCurve->LastParameter() -
495 myCurve->FirstParameter());
496 mySec = Section;
497
498 if (rotat) SetRotation(PrecAngle, LastAngle);
499 else rotation = Standard_False;
500}
501
502//==================================================================
503//Function: EraseRotation
504//Purpose : Supprime la Rotation
505//==================================================================
506 void GeomFill_LocationGuide:: EraseRotation()
507{
508 rotation = Standard_False;
509 if (myStatus == GeomFill_ImpossibleContact) myStatus = GeomFill_PipeOk;
510}
511
512//==================================================================
513//Function: Copy
514//Purpose :
515//==================================================================
516 Handle(GeomFill_LocationLaw) GeomFill_LocationGuide::Copy() const
517{
518 Standard_Real la;
519 Handle(GeomFill_TrihedronWithGuide) L;
520 L = Handle(GeomFill_TrihedronWithGuide)::DownCast(myLaw->Copy());
521 Handle(GeomFill_LocationGuide) copy = new
522 (GeomFill_LocationGuide) (L);
523 copy->SetOrigine(OrigParam1, OrigParam2);
524 copy->Set(mySec, rotation, myFirstS, myLastS,
525 myPoles2d->Value(1,1).X(), la);
526 copy->SetTrsf(Trans);
527
528 return copy;
529}
530
531
532//==================================================================
533//Function: SetCurve
534//Purpose : Calcul des poles sur la surface d'arret (intersection
535// courbe guide / surface de revolution en myNbPts points)
536//==================================================================
537 void GeomFill_LocationGuide::SetCurve(const Handle(Adaptor3d_HCurve)& C)
538{
539 Standard_Real LastAngle;
540 myCurve = C;
541 myTrimmed = C;
542
543 if (!myCurve.IsNull()){
544 myLaw->SetCurve(C);
545 myLaw->Origine(OrigParam1, OrigParam2);
546 myStatus = myLaw->ErrorStatus();
547
548 if (rotation) SetRotation(myPoles2d->Value(1,1).X(), LastAngle);
549 }
550}
551
552//==================================================================
553//Function: GetCurve
554//Purpose : return the trajectoire
555//==================================================================
556 const Handle(Adaptor3d_HCurve)& GeomFill_LocationGuide::GetCurve() const
557{
558 return myCurve;
559}
560
561//==================================================================
562//Function: SetTrsf
563//Purpose :
564//==================================================================
565 void GeomFill_LocationGuide::SetTrsf(const gp_Mat& Transfo)
566{
567 Trans = Transfo;
568 gp_Mat Aux;
569 Aux.SetIdentity();
570 Aux -= Trans;
571 WithTrans = Standard_False; // Au cas ou Trans = I
572 for (Standard_Integer ii=1; ii<=3 && !WithTrans ; ii++)
573 for (Standard_Integer jj=1; jj<=3 && !WithTrans; jj++)
574 if (Abs(Aux.Value(ii, jj)) > 1.e-14) WithTrans = Standard_True;
575}
576
577//==================================================================
578//Function: D0
579//Purpose :
580//==================================================================
581 Standard_Boolean GeomFill_LocationGuide::D0(const Standard_Real Param,
582 gp_Mat& M,
583 gp_Vec& V)
584{
585 Standard_Boolean Ok;
586 gp_Vec T,N,B;
587 gp_Pnt P;
588
589 myCurve->D0(Param, P);
590 V.SetXYZ(P.XYZ());
591 Ok = myLaw->D0(Param, T, N, B);
592 if (!Ok) {
593 myStatus = myLaw->ErrorStatus();
594 return Ok;
595 }
596 M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
597
598 if (WithTrans) {
599 M *= Trans;
600 }
601
602 if(rotation) {
603 Standard_Real U = myFirstS +
604 (Param-myCurve->FirstParameter())*ratio;
605 // initialisations germe
606 InitX(Param);
607
608 Standard_Integer Iter = 100;
609 gp_XYZ t,b,n;
610 t = M.Column(3);
611 b = M.Column(2);
612 n = M.Column(1);
613
614 // Intersection entre surf revol et guide
615 // equation
616 GeomFill_FunctionGuide E (mySec, myGuide, U);
617 E.SetParam(Param, P, t, n);
618 // resolution => angle
619 math_FunctionSetRoot Result(E, X, TolRes,
620 Inf, Sup, Iter);
621
622 if (Result.IsDone()) {
623 // solution
624 Result.Root(R);
625
626 // rotation
627 gp_Mat Rot;
628 Rot.SetRotation(t, R(2));
629 b *= Rot;
630 n *= Rot;
631
632 M.SetCols(n, b, t);
633 }
634 else {
635#if DEB
636 cout << "LocationGuide::D0 : No Result !"<<endl;
637 TraceRevol(Param, U, myLaw, mySec, myCurve, Trans);
638#endif
639 myStatus = GeomFill_ImpossibleContact;
640 return Standard_False;
641 }
642 }
643
644 return Standard_True;
645}
646
647//==================================================================
648//Function: D0
649//Purpose : calcul de l'intersection (C0) surface revol / guide
650//==================================================================
651 Standard_Boolean GeomFill_LocationGuide::D0(const Standard_Real Param,
652 gp_Mat& M,
653 gp_Vec& V,
654// TColgp_Array1OfPnt2d& Poles2d)
655 TColgp_Array1OfPnt2d& )
656{
657 gp_Vec T, N, B;
658 gp_Pnt P;
659 Standard_Boolean Ok;
7fd59977 660
661 myCurve->D0(Param, P);
662 V.SetXYZ(P.XYZ());
663 Ok = myLaw->D0(Param, T, N, B);
664 if (!Ok) {
665 myStatus = myLaw->ErrorStatus();
666 return Ok;
667 }
668 M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
669
670 if (WithTrans) {
671 M *= Trans;
672 }
673
674 if (rotation) {
7fd59977 675 //initialisation du germe
676 InitX(Param);
677 Standard_Integer Iter = 100;
678 gp_XYZ b, n, t;
679 t = M.Column(3);
680 b = M.Column(2);
681 n = M.Column(1);
682
683 // equation d'intersection entre surf revol et guide => angle
684 GeomFill_FunctionGuide E (mySec, myGuide, myFirstS +
685 (Param-myCurve->FirstParameter())*ratio);
686 E.SetParam(Param, P, t, n);
687
688 // resolution
689 math_FunctionSetRoot Result(E, X, TolRes,
690 Inf, Sup, Iter);
691
692 if (Result.IsDone()) {
693 // solution
694 Result.Root(R);
695
696 // rotation
697 gp_Mat Rot;
698 Rot.SetRotation(t, R(2));
699
700
701 b *= Rot;
702 n *= Rot;
703
704 M.SetCols(n, b, t);
705 }
706 else {
707#if DEB
6e6cd5d9 708 Standard_Real U = myFirstS + ratio*(Param-myCurve->FirstParameter());
7fd59977 709 cout << "LocationGuide::D0 : No Result !"<<endl;
710 TraceRevol(Param, U, myLaw, mySec, myCurve, Trans);
711#endif
712 myStatus = GeomFill_ImpossibleContact;
713 return Standard_False;
714 }
715 }
716
717 return Standard_True;
718}
719
720
721//==================================================================
722//Function: D1
723//Purpose : calcul de l'intersection (C1) surface revol / guide
724//==================================================================
725 Standard_Boolean GeomFill_LocationGuide::D1(const Standard_Real Param,
726 gp_Mat& M,
727 gp_Vec& V,
728 gp_Mat& DM,
729 gp_Vec& DV,
730// TColgp_Array1OfPnt2d& Poles2d,
731 TColgp_Array1OfPnt2d& ,
732// TColgp_Array1OfVec2d& DPoles2d)
733 TColgp_Array1OfVec2d& )
734{
735// gp_Vec T, N, B, DT, DN, DB, T0, N0, B0;
736 gp_Vec T, N, B, DT, DN, DB;
737// gp_Pnt P, P0;
738 gp_Pnt P;
739 Standard_Boolean Ok;
740
741 myCurve->D1(Param, P, DV);
742 V.SetXYZ(P.XYZ());
743 Ok = myLaw->D1(Param, T, DT, N, DN, B, DB);
744 if (!Ok) {
745 myStatus = myLaw->ErrorStatus();
746 return Ok;
747 }
748 M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
749 DM.SetCols(DN.XYZ() , DB.XYZ(), DT.XYZ());
750
751 if (WithTrans) {
752 M *= Trans;
753 DM *= Trans;
754 }
755
756 if (rotation) {
757 return Standard_False;
4e76d93b 758 /*
7fd59977 759#ifdef DEB
760 Standard_Real U = myFirstS + ratio*(Param-myCurve->FirstParameter());
761#else
762 myCurve->FirstParameter() ;
763#endif
764
765 // initialisation du germe
766 InitX(Param);
767
768 Standard_Integer Iter = 100;
769 gp_XYZ t,b,n, dt, db, dn;
770 t = M.Column(3);
771 b = M.Column(2);
772 n = M.Column(1);
773 dt = M.Column(3);
774 db = M.Column(2);
775 dn = M.Column(1);
776
777 // equation d'intersection surf revol / guide => angle
778 GeomFill_FunctionGuide E (mySec, myGuide, myFirstS +
779 (Param-myCurve->FirstParameter())*ratio);
780 E.SetParam(Param, P, t, n);
781
782 // resolution
783 math_FunctionSetRoot Result(E, X, TolRes,
784 Inf, Sup, Iter);
785
786 if (Result.IsDone())
787 {
788 // solution de la fonction
789 Result.Root(R);
790
791 // derivee de la fonction
792 math_Vector DEDT(1,3);
793 E.DerivT(R, DV.XYZ(), dt, DEDT); // dE/dt => DEDT
794
795 math_Vector DSDT (1,3,0);
796 math_Matrix DEDX (1,3,1,3,0);
797 E.Derivatives(R, DEDX); // dE/dx au point R => DEDX
798
799 // resolution du syst. : DEDX*DSDT = -DEDT
800 math_Gauss Ga(DEDX);
801 if (Ga.IsDone())
802 {
803 Ga.Solve (DEDT.Opposite(), DSDT);// resolution du syst.
804 }//if
805 else {
806#if DEB
807 cout << "DEDX = " << DEDX << endl;
808 cout << "DEDT = " << DEDT << endl;
809#endif
810 Standard_ConstructionError::Raise(
811 "LocationGuide::D1 : No Result dans la derivee");
812 }
813
814 // transformation = rotation
815 gp_Mat Rot, DRot;
816 Rot.SetRotation(t, R(2));
817
818
819
820 M.SetCols(n*Rot, b*Rot, t);
821
822 // transfo entre triedre (en Q) et Oxyz
823 gp_Ax3 Rep(gp::Origin(),gp::DZ(), gp::DX());
824 gp_Ax3 RepTriedre(gp::Origin(),t,n);
825 gp_Trsf Transfo3;
826 Transfo3.SetTransformation(Rep,RepTriedre);
827 // on se place dans Oxyz
828 Transfo3.Transforms(n);
829 Transfo3.Transforms(b);
830 Transfo3.Transforms(dn);
831 Transfo3.Transforms(db);
832
833 // matrices de rotation et derivees
834 Standard_Real A = R(2);
835 Standard_Real Aprim = DSDT(2);
836
837#ifdef DEB
838 gp_Mat M2 (Cos(A), -Sin(A),0, // rotation autour de T
839 Sin(A), Cos(A),0,
840 0,0,1);
841#endif
842
843 gp_Mat M2prim (-Sin(A), -Cos(A), 0, // derivee rotation autour de T
844 Cos(A), -Sin(A), 0,
845 0, 0, 0);
846 M2prim.Multiply(Aprim);
847
848 // transformations
849
850
851 dn *= Rot;
852 db *= Rot;
853
854 n *= DRot;
855 b *= DRot;
856
857 dn += n;
858 db += b;
859
860 // on repasse dans repere triedre
861 gp_Trsf InvTrsf;
862 InvTrsf = Transfo3.Inverted();
863 InvTrsf.Transforms(dn);
864 InvTrsf.Transforms(db);
865
866 DM.SetCols(dn , db , dt);
867 }//if_Result
868
869 else {
870#if DEB
871 cout << "LocationGuide::D1 : No Result !!"<<endl;
872 TraceRevol(Param, U, myLaw, mySec, myCurve, Trans);
873#endif
874 myStatus = GeomFill_ImpossibleContact;
875 return Standard_False;
876 }
4e76d93b 877*/
7fd59977 878 }//if_rotation
879
880
881 return Standard_True;
882
883}
884
885//==================================================================
886//Function: D2
887//Purpose : calcul de l'intersection (C2) surface revol / guide
888//==================================================================
889Standard_Boolean GeomFill_LocationGuide::D2(const Standard_Real Param,
890 gp_Mat& M,
891 gp_Vec& V,
892 gp_Mat& DM,
893 gp_Vec& DV,
894 gp_Mat& D2M,
895 gp_Vec& D2V,
896// TColgp_Array1OfPnt2d& Poles2d,
897 TColgp_Array1OfPnt2d& ,
898// TColgp_Array1OfVec2d& DPoles2d,
899 TColgp_Array1OfVec2d& ,
900// TColgp_Array1OfVec2d& D2Poles2d)
901 TColgp_Array1OfVec2d& )
902{
903 gp_Vec T, N, B, DT, DN, DB, D2T, D2N, D2B;
904// gp_Vec T0, N0, B0, T1, N1, B1;
905// gp_Pnt P, P0, P1;
906 gp_Pnt P;
907 Standard_Boolean Ok;
908
909 myCurve->D2(Param, P, DV, D2V);
910 V.SetXYZ(P.XYZ());
911 Ok = myLaw->D2(Param, T, DT, D2T, N, DN, D2N, B, DB, D2B);
912 if (!Ok) {
913 myStatus = myLaw->ErrorStatus();
914 return Ok;
915 }
916
917 if (WithTrans) {
918 M *= Trans;
919 DM *= Trans;
920 D2M *= Trans;
921 }
922
923 if (rotation)
924 {
925 return Standard_False;
926/*
927 Standard_Real U = myFirstS +
928 (Param-myCurve->FirstParameter())*ratio;
929 // rotation
930 math_Vector X(1,3,0);
931 InitX(Param,X);
932 // tolerance sur X
933
934 TolRes.Init(1.e-6);
935 // tolerance sur E
936// Standard_Real ETol = 1.e-6;
937 Standard_Integer Iter = 100;
938
939
940 // resoudre equation d'intersection entre surf revol et guide => angle
941 GeomFill_FunctionGuide E (mySec, myGuide, myFirstS +
942 (Param-myCurve->FirstParameter())*ratio);
943 E.SetParam(Param, P, T, N);
944
945 // resolution
946 math_FunctionSetRoot Result(E, X, TolRes,
947 Inf, Sup, Iter);
948
949 if (Result.IsDone())
950 {
951 Result.Root(R); // solution
952
953 //gp_Pnt2d p (R(2), R(3)); // point sur la surface (angle, v)
954 //Poles2d.SetValue(1,p);
955
956 // derivee de la fonction
957 math_Vector DEDT(1,3,0);
958 E.DerivT(Param, Param0, R, R0, DEDT); // dE/dt => DEDT
959 math_Vector DSDT (1,3,0);
960 math_Matrix DEDX (1,3,1,3,0);
961 E.Derivatives(R, DEDX); // dE/dx au point R => DEDX
962
963 // resolution du syst. lin. : DEDX*DSDT = -DEDT
964 math_Gauss Ga(DEDX);
965 if (Ga.IsDone())
966 {
967 Ga.Solve (DEDT.Opposite(), DSDT); // resolution du syst. lin.
968 //gp_Vec2d dp (DSDT(2), DSDT(3)); // surface
969 //DPoles2d.SetValue(1, dp);
970 }//if
971 else cout <<"LocationGuide::D2 : No Result dans la derivee premiere"<<endl;
972
973 // deuxieme derivee
974 GeomFill_Tensor D2EDX2(3,3,3);
975 E.Deriv2X(R, D2EDX2); // d2E/dx2
976
977 math_Vector D2EDT2(1,3,0);
978
979 // if(Param1 < Param && Param < Param0)
980 E.Deriv2T(Param1, Param, Param0, R1, R, R0, D2EDT2); // d2E/dt2
981 // else if (Param < Param0 && Param0 < Param1)
982 // E.Deriv2T(Param, Param0, Param1, R, R0, R1, D2EDT2); // d2E/dt2
983 // else
984 // E.Deriv2T(Param0, Param1, Param, R0, R1, R, D2EDT2); // d2E/dt2
985
986 math_Matrix D2EDTDX(1,3,1,3,0);
987 E.DerivTX(Param, Param0, R, R0, D2EDTDX); // d2E/dtdx
988
989 math_Vector D2SDT2(1,3,0); // d2s/dt2
990 math_Matrix M1(1,3,1,3,0);
991 D2EDX2.Multiply(DSDT,M1);
992
993 // resolution du syst. lin.
994 math_Gauss Ga1 (DEDX);
995 if (Ga1.IsDone())
996 {
997 Ga1.Solve ( - M1*DSDT - 2*D2EDTDX*DSDT - D2EDT2 , D2SDT2);
998 //gp_Vec2d d2p (D2SDT2(2), D2SDT2(3)); // surface
999 //D2Poles2d.SetValue(1, d2p);
1000 }//if
1001 else {
1002 cout <<"LocationGuide::D2 : No Result dans la derivee seconde"<<endl;
1003 myStatus = GeomFill_ImpossibleContact;
1004 }
1005
1006//------------------------------------------
1007// rotation
1008//------------------------------------------
1009
1010 gp_Trsf Tr;
1011 gp_Pnt Q (0, 0 ,0);
1012 gp_Ax1 Axe (Q, D);
1013 Tr.SetRotation(Axe, R(2));
1014
1015 gp_Vec b,b2;
1016 b = b2 = B;
1017 gp_Vec n,n2;
1018 n = n2 = N;
1019
1020 B.Transform(Tr);
1021 N.Transform(Tr);
1022
1023 M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
1024
1025//------------------------------------------
1026// derivees de la rotation
1027// A VERIFIER !!!!
1028//-----------------------------------------
1029 gp_Vec db,dn,db3,dn3;
1030 db = db3 = DB;
1031 dn = dn3 = DN;
1032
1033 gp_Vec db1,dn1,db2,dn2;
1034
1035//transfo entre triedre et Oxyz
1036 gp_Ax3 RepTriedre4(Q,D,B2);
1037 gp_Trsf Transfo3;
1038 Transfo3.SetTransformation(Rep,RepTriedre4);
1039
1040//on passe dans le repere du triedre
1041 n.Transform(Transfo3);
1042 b.Transform(Transfo3);
1043 n2.Transform(Transfo3);
1044 b2.Transform(Transfo3);
1045 dn.Transform(Transfo3);
1046 db.Transform(Transfo3);
1047 dn3.Transform(Transfo3);
1048 db3.Transform(Transfo3);
1049 D2N.Transform(Transfo3);
1050 D2B.Transform(Transfo3);
1051
1052//matrices de rotation et derivees
1053 Standard_Real A = R(2);
1054 Standard_Real Aprim = DSDT(2);
1055 Standard_Real Asec = D2SDT2(2);
1056
1057 gp_Mat M2 (Cos(A),-Sin(A),0, // rotation autour de T
1058 Sin(A), Cos(A),0,
1059 0, 0, 1);
1060
1061 gp_Mat M2prim (-Sin(A),-Cos(A),0, // derivee 1ere rotation autour de T
1062 Cos(A), -Sin(A),0,
1063 0,0,0);
1064
1065 gp_Mat M2sec (-Cos(A), Sin(A), 0, // derivee 2nde rotation autour de T
1066 -Sin(A), -Cos(A), 0,
1067 0,0,0);
1068 M2sec.Multiply(Aprim*Aprim);
1069 gp_Mat M2p = M2prim.Multiplied(Asec);
1070 M2sec.Add(M2p);
1071
1072 M2prim.Multiply(Aprim);
1073
1074// transformation
1075 gp_Trsf Rot;
1076 Rot.SetValues(M2(1,1),M2(1,2),M2(1,3),0,
1077 M2(2,1),M2(2,2),M2(2,3),0,
1078 M2(3,1),M2(3,2),M2(3,3),0,
1079 1.e-8,1.e-8);
1080 gp_Trsf DRot;
1081 DRot.SetValues(M2prim(1,1),M2prim(1,2),M2prim(1,3),0,
1082 M2prim(2,1),M2prim(2,2),M2prim(2,3),0,
1083 M2prim(3,1),M2prim(3,2),M2prim(3,3),0,
1084 1.e-8,1.e-8);
1085
1086 gp_Trsf D2Rot;
1087 D2Rot.SetValues(M2sec(1,1),M2sec(1,2),M2sec(1,3),0,
1088 M2sec(2,1),M2sec(2,2),M2sec(2,3),0,
1089 M2sec(3,1),M2sec(3,2),M2sec(3,3),0,
1090 1.e-8,1.e-8);
1091
1092
1093//derivee premiere
1094 dn.Transform(Rot);
1095 db.Transform(Rot);
1096 n.Transform(DRot);
1097 b.Transform(DRot);
1098 dn1 = dn + n;
1099 db1 = db + b;
1100 dn1.Transform(Transfo3.Inverted());
1101 db1.Transform(Transfo3.Inverted());
1102
1103 DM.SetCols(dn1.XYZ(), db1.XYZ(), DT.XYZ());
1104
1105//derivee seconde
1106 D2N.Transform(Rot);
1107 D2B.Transform(Rot);
1108 dn3.Transform(DRot);
1109 db3.Transform(DRot);
1110 n2.Transform(D2Rot);
1111 b2.Transform(D2Rot);
1112 dn2 = n2 + 2*dn3 + D2N;
1113 db2 = b2 + 2*db3 + D2B;
1114 dn2.Transform(Transfo3.Inverted());
1115 db2.Transform(Transfo3.Inverted());
1116
1117 D2M.SetCols(dn2.XYZ(), db2.XYZ(), D2T.XYZ());
1118
1119 }//if_result
1120 else {
1121#if DEB
1122 cout << "LocationGuide::D2 : No Result !!" <<endl;
1123 TraceRevol(Param, U, myLaw, mySec, myCurve, Trans);
1124#endif
1125 return Standard_False;
1126 }*/
1127 }//if_rotation
1128
1129 else
1130 {
1131 M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
1132 DM.SetCols(DN.XYZ(), DB.XYZ(), DT.XYZ());
1133 D2M.SetCols(D2N.XYZ(), D2B.XYZ(), D2T.XYZ());
1134 }
1135
1136 return Standard_True;
1137// return Standard_False;
1138}
1139
1140//==================================================================
1141//Function : HasFirstRestriction
1142//Purpose :
1143//==================================================================
1144 Standard_Boolean GeomFill_LocationGuide::HasFirstRestriction() const
1145{
1146 return Standard_False;
1147}
1148
1149//==================================================================
1150//Function : HasLastRestriction
1151//Purpose :
1152//==================================================================
1153 Standard_Boolean GeomFill_LocationGuide::HasLastRestriction() const
1154{
1155 return Standard_False;
1156}
1157
1158//==================================================================
1159//Function : TraceNumber
1160//Purpose :
1161//==================================================================
1162 Standard_Integer GeomFill_LocationGuide::TraceNumber() const
1163{
1164 return 0;
1165}
1166
1167//==================================================================
1168//Function : ErrorStatus
1169//Purpose :
1170//==================================================================
1171 GeomFill_PipeError GeomFill_LocationGuide::ErrorStatus() const
1172{
1173 return myStatus;
1174}
1175
1176//==================================================================
1177//Function:NbIntervals
1178//Purpose :
1179//==================================================================
1180 Standard_Integer GeomFill_LocationGuide::NbIntervals
1181 (const GeomAbs_Shape S) const
1182{
1183 Standard_Integer Nb_Sec, Nb_Law;
1184 Nb_Sec = myTrimmed->NbIntervals(S);
1185 Nb_Law = myLaw->NbIntervals(S);
1186
1187 if (Nb_Sec==1) {
1188 return Nb_Law;
1189 }
1190 else if (Nb_Law==1) {
1191 return Nb_Sec;
1192 }
1193
1194 TColStd_Array1OfReal IntC(1, Nb_Sec+1);
1195 TColStd_Array1OfReal IntL(1, Nb_Law+1);
1196 TColStd_SequenceOfReal Inter;
1197 myTrimmed->Intervals(IntC, S);
1198 myLaw->Intervals(IntL, S);
1199
1200 GeomLib::FuseIntervals( IntC, IntL, Inter, Precision::PConfusion()*0.99);
1201 return Inter.Length()-1;
1202
1203}
1204
1205//==================================================================
1206//Function:Intervals
1207//Purpose :
1208//==================================================================
1209 void GeomFill_LocationGuide::Intervals(TColStd_Array1OfReal& T,
1210 const GeomAbs_Shape S) const
1211{
1212 Standard_Integer Nb_Sec, Nb_Law;
1213 Nb_Sec = myTrimmed->NbIntervals(S);
1214 Nb_Law = myLaw->NbIntervals(S);
1215
1216 if (Nb_Sec==1) {
1217 myLaw->Intervals(T, S);
1218 return;
1219 }
1220 else if (Nb_Law==1) {
1221 myTrimmed->Intervals(T, S);
1222 return;
1223 }
1224
1225 TColStd_Array1OfReal IntC(1, Nb_Sec+1);
1226 TColStd_Array1OfReal IntL(1, Nb_Law+1);
1227 TColStd_SequenceOfReal Inter;
1228 myTrimmed->Intervals(IntC, S);
1229 myLaw->Intervals(IntL, S);
1230
1231 GeomLib::FuseIntervals(IntC, IntL, Inter, Precision::PConfusion()*0.99);
1232 for (Standard_Integer ii=1; ii<=Inter.Length(); ii++)
1233 T(ii) = Inter(ii);
1234}
1235
1236//==================================================================
1237//Function:SetInterval
1238//Purpose :
1239//==================================================================
1240 void GeomFill_LocationGuide::SetInterval(const Standard_Real First,
1241 const Standard_Real Last)
1242{
1243 myLaw->SetInterval(First, Last);
1244 myTrimmed = myCurve->Trim(First, Last, 0);
1245}
1246//==================================================================
1247//Function: GetInterval
1248//Purpose :
1249//==================================================================
1250 void GeomFill_LocationGuide::GetInterval(Standard_Real& First,
1251 Standard_Real& Last) const
1252{
1253 First = myTrimmed->FirstParameter();
1254 Last = myTrimmed->LastParameter();
1255}
1256
1257//==================================================================
1258//Function: GetDomain
1259//Purpose :
1260//==================================================================
1261 void GeomFill_LocationGuide::GetDomain(Standard_Real& First,
1262 Standard_Real& Last) const
1263{
1264 First = myCurve->FirstParameter();
1265 Last = myCurve->LastParameter();
1266}
1267
1268//==================================================================
1269//function : SetTolerance
1270//purpose :
1271//==================================================================
1272void GeomFill_LocationGuide::SetTolerance(const Standard_Real Tol3d,
1273 const Standard_Real )
1274{
1275 TolRes(1) = myGuide->Resolution(Tol3d);
1276 Resolution(1, Tol3d, TolRes(2), TolRes(3));
1277
1278}
1279
1280//==================================================================
1281//function : Resolution
1282//purpose : A definir
1283//==================================================================
1284//void GeomFill_LocationGuide::Resolution (const Standard_Integer Index,
1285void GeomFill_LocationGuide::Resolution (const Standard_Integer ,
1286 const Standard_Real Tol,
1287 Standard_Real& TolU,
1288 Standard_Real& TolV) const
1289{
1290 TolU = Tol/100;
1291 TolV = Tol/100;
1292}
1293
1294//==================================================================
1295//Function:GetMaximalNorm
1296//Purpose : On suppose les triedres normes => return 1
1297//==================================================================
1298 Standard_Real GeomFill_LocationGuide::GetMaximalNorm()
1299{
1300 return 1.;
1301}
1302
1303//==================================================================
1304//Function:GetAverageLaw
1305//Purpose :
1306//==================================================================
1307 void GeomFill_LocationGuide::GetAverageLaw(gp_Mat& AM,
1308 gp_Vec& AV)
1309{
1310 Standard_Integer ii;
1311 Standard_Real U, delta;
1312 gp_Vec V, V1, V2, V3;
1313
1314 myLaw->GetAverageLaw(V1, V2, V3);
1315 AM.SetCols(V1.XYZ(), V2.XYZ(), V3.XYZ());
1316
1317 AV.SetCoord(0., 0., 0.);
1318 delta = (myTrimmed->LastParameter() - myTrimmed->FirstParameter())/10;
1319 U = myTrimmed->FirstParameter();
1320 for (ii=0; ii<=myNbPts; ii++, U+=delta) {
1321 V.SetXYZ( myTrimmed->Value(U).XYZ() );
1322 AV += V;
1323 }
1324 AV = AV/(myNbPts+1);
1325}
1326
1327
1328//==================================================================
1329//Function : Section
1330//Purpose :
1331//==================================================================
1332 Handle(Geom_Curve) GeomFill_LocationGuide::Section() const
1333{
1334 return mySec->ConstantSection();
1335}
1336
1337//==================================================================
1338//Function : Guide
1339//Purpose :
1340//==================================================================
1341 Handle(Adaptor3d_HCurve) GeomFill_LocationGuide::Guide() const
1342{
1343 return myGuide;
1344}
1345
1346//==================================================================
1347//Function : IsRotation
1348//Purpose :
1349//==================================================================
1350// Standard_Boolean GeomFill_LocationGuide::IsRotation(Standard_Real& Error) const
1351 Standard_Boolean GeomFill_LocationGuide::IsRotation(Standard_Real& ) const
1352{
1353 return Standard_False;
1354}
1355
1356//==================================================================
1357//Function : Rotation
1358//Purpose :
1359//==================================================================
1360// void GeomFill_LocationGuide::Rotation(gp_Pnt& Centre) const
1361 void GeomFill_LocationGuide::Rotation(gp_Pnt& ) const
1362{
1363 Standard_NotImplemented::Raise("GeomFill_LocationGuide::Rotation");
1364}
1365
1366//==================================================================
1367//Function : IsTranslation
1368//Purpose :
1369//==================================================================
1370// Standard_Boolean GeomFill_LocationGuide::IsTranslation(Standard_Real& Error) const
1371 Standard_Boolean GeomFill_LocationGuide::IsTranslation(Standard_Real& ) const
1372{
1373 return Standard_False;
1374}
1375
1376//==================================================================
1377//Function : InitX
1378//Purpose : recherche par interpolation d'une valeur initiale
1379//==================================================================
1380void GeomFill_LocationGuide::InitX(const Standard_Real Param) const
1381{
1382
1383 Standard_Integer Ideb = 1, Ifin = myPoles2d->RowLength(), Idemi;
1384 Standard_Real Valeur, t1, t2;
1385
1386
1387 Valeur = myPoles2d->Value(1, Ideb).X();
1388 if (Param == Valeur) {
1389 Ifin = Ideb+1;
1390 }
1391
1392 Valeur = myPoles2d->Value(1, Ifin).X();
1393 if (Param == Valeur) {
1394 Ideb = Ifin-1;
1395 }
1396
1397 while ( Ideb+1 != Ifin) {
1398 Idemi = (Ideb+Ifin)/2;
1399 Valeur = myPoles2d->Value(1, Idemi).X();
1400 if (Valeur < Param) {
1401 Ideb = Idemi;
1402 }
1403 else {
1404 if ( Valeur > Param) { Ifin = Idemi;}
1405 else {
1406 Ideb = Idemi;
1407 Ifin = Ideb+1;
1408 }
1409 }
1410 }
1411
1412 t1 = myPoles2d->Value(1,Ideb).X();
1413 t2 = myPoles2d->Value(1,Ifin).X();
1414 Standard_Real diff = t2-t1;
1415
1416 Standard_Real W1, W2;
1417 W1 = myPoles2d->Value(1,Ideb).Coord(2);
1418 W2 = myPoles2d->Value(1,Ifin).Coord(2);
1419 const gp_Pnt2d& P1 = myPoles2d->Value(2, Ideb);
1420 const gp_Pnt2d& P2 = myPoles2d->Value(2, Ifin);
1421
1422 if (diff > 1.e-7) {
1423 Standard_Real b = (Param-t1) / diff,
1424 a = (t2-Param) / diff;
1425 X(1) = a * W1 + b * W2;
1426 X(2) = a * P1.Coord(1) + b * P2.Coord(1); // angle
1427 X(3) = a * P1.Coord(2) + b * P2.Coord(2); // param isov
1428 }
1429 else {
1430 X(1) = (W1+W2) /2;
1431 X(2) = (P1.Coord(1) + P2.Coord(1)) /2;
1432 X(3) = (P1.Coord(2) + P2.Coord(2)) /2;
1433 }
1434
1435 if (myGuide->IsPeriodic()) {
1436 X(1) = ElCLib::InPeriod(X(1), myGuide->FirstParameter(),
1437 myGuide->LastParameter());
1438 }
c6541a0c 1439 X(2) = ElCLib::InPeriod(X(2), 0, 2*M_PI);
7fd59977 1440 if (mySec->IsUPeriodic()) {
1441 X(3) = ElCLib::InPeriod(X(3), Uf, Ul);
1442 }
1443}
1444
1445
1446//==================================================================
1447//Function : SetOrigine
1448//Purpose : utilise pour ACR dans le cas ou la trajectoire est multi-edges
1449//==================================================================
1450void GeomFill_LocationGuide::SetOrigine(const Standard_Real Param1,
1451 const Standard_Real Param2)
1452{
1453 OrigParam1 = Param1;
1454 OrigParam2 = Param2;
1455}
1456
f9032cf2 1457//==================================================================
1458//Function : ComputeAutomaticLaw
1459//Purpose :
1460//==================================================================
1461GeomFill_PipeError GeomFill_LocationGuide::ComputeAutomaticLaw(Handle(TColgp_HArray1OfPnt2d)& ParAndRad) const
1462{
1463 gp_Pnt P;
1464 gp_Vec T,N,B;
1465 Standard_Integer ii;
1466 Standard_Real t;
1467
1468 GeomFill_PipeError theStatus = GeomFill_PipeOk;
1469
1470 Standard_Real f = myCurve->FirstParameter();
1471 Standard_Real l = myCurve->LastParameter();
1472
1473 ParAndRad = new TColgp_HArray1OfPnt2d(1, myNbPts);
1474 for (ii = 1; ii <= myNbPts; ii++)
1475 {
1476 t = Standard_Real(myNbPts - ii)*f + Standard_Real(ii - 1)*l;
1477 t /= (myNbPts-1);
1478 myCurve->D0(t, P);
1479 Standard_Boolean Ok = myLaw->D0(t, T, N, B);
1480 if (!Ok)
1481 {
1482 theStatus = myLaw->ErrorStatus();
1483 return theStatus;
1484 }
1485 gp_Pnt PointOnGuide = myLaw->CurrentPointOnGuide();
1486 Standard_Real CurWidth = P.Distance(PointOnGuide);
1487
1488 gp_Pnt2d aParamWithRadius(t, CurWidth);
1489 ParAndRad->SetValue(ii, aParamWithRadius);
1490 }
1491
1492 return theStatus;
1493}