1 // File: GeomFill_CorrectedFrenet.cxx
2 // Created: Fri Dec 19 13:25:12 1997
3 // Author: Roman BORISOV /Philippe MANGIN
8 #include <GeomFill_CorrectedFrenet.ixx>
9 #include <GeomAbs_CurveType.hxx>
10 #include <Adaptor3d_HCurve.hxx>
11 #include <gp_Trsf.hxx>
12 #include <Precision.hxx>
13 #include <TColStd_HArray1OfReal.hxx>
14 #include <Law_Interpolate.hxx>
15 #include <TColStd_SequenceOfReal.hxx>
16 #include <gp_Vec2d.hxx>
17 #include <BndLib_Add3dCurve.hxx>
18 #include <Bnd_Box.hxx>
19 #include <GeomLib.hxx>
20 #include <Law_Composite.hxx>
21 #include <Law_Constant.hxx>
22 #include <Law_BSpFunc.hxx>
23 #include <Law_BSpline.hxx>
24 #include <GeomFill_SnglrFunc.hxx>
26 #include <Geom_Plane.hxx>
27 #include <Geom_BezierCurve.hxx>
28 #include <Geom_BSplineCurve.hxx>
29 #include <TColgp_HArray1OfPnt.hxx>
32 static Standard_Boolean Affich=0;
36 static Standard_Integer CorrNumber = 0;
37 #include <Draw_Appli.hxx>
38 #include <DrawTrSurf.hxx>
39 #include <Draw_Segment2D.hxx>
41 #include <TColgp_Array1OfPnt.hxx>
42 #include <TColStd_Array1OfReal.hxx>
43 #include <TColStd_HArray1OfInteger.hxx>
47 static void draw(const Handle(Law_Function)& law)
49 Standard_Real Step, u, v, tmin;
50 Standard_Integer NbInt, i, j, jmax;
51 NbInt = law->NbIntervals(GeomAbs_C3);
52 TColStd_Array1OfReal Int(1, NbInt+1);
53 law->Intervals(Int, GeomAbs_C3);
55 Handle(Draw_Segment2D) tg2d;
57 for(i = 1; i <= NbInt; i++){
59 Step = (Int(i+1)-Int(i))/4;
60 if (i == NbInt) jmax = 4;
62 for (j=1; j<=jmax; j++) {
63 u = tmin + (j-1)*Step;
65 gp_Pnt2d point2d(u,v);
67 tg2d = new Draw_Segment2D(old, point2d,Draw_kaki);
77 //===============================================================
78 // Function : smoothlaw
79 // Purpose : to smooth a law : Reduce the number of knots
80 //===============================================================
81 static void smoothlaw(Handle(Law_BSpline)& Law,
82 const Handle(TColStd_HArray1OfReal)& Points,
83 const Handle(TColStd_HArray1OfReal)& Param,
84 const Standard_Real Tol)
87 Standard_Integer ii, Nbk;
88 Standard_Boolean B, Ok;
89 Handle(Law_BSpline) BS = Law->Copy();
95 for (ii=Nbk-1; ii>1; ii--) { // Une premiere passe tolerance serres
96 B = BS->RemoveKnot(ii, 0, tol);
97 if (B) Ok = Standard_True;
100 if (Ok) { // controle
102 for (ii=1; ii<=Param->Length() && Ok; ii++) {
103 d = Abs(BS->Value(Param->Value(ii))-Points->Value(ii));
104 if (d > tol) tol = d;
111 cout << "smooth law echec" << endl;
123 Ok = Standard_False; // Une deuxieme passe tolerance desserre
125 for (ii=Nbk-1; ii>1; ii--) {
126 B = BS->RemoveKnot(ii, 0, tol);
127 if (B) Ok = Standard_True;
130 if (Ok) { // controle
132 for (ii=1; ii<=Param->Length() && Ok; ii++) {
133 d = Abs(BS->Value(Param->Value(ii))-Points->Value(ii));
134 if (d > tol) tol = d;
139 cout << "smooth law echec" << endl;
147 cout << "Knots Law : " << endl;
148 for (ii=1; ii<=BS->NbKnots(); ii++) {
149 cout << ii << " : " << BS->Knot(ii) << endl;
155 //===============================================================
156 // Function : FindPlane
158 //===============================================================
159 static Standard_Boolean FindPlane ( const Handle(Adaptor3d_HCurve)& c,
160 Handle( Geom_Plane )& P )
162 Standard_Boolean found = Standard_True;
163 Handle(TColgp_HArray1OfPnt) TabP;
165 switch (c->GetType()) {
169 found = Standard_False;
174 P = new Geom_Plane(gp_Ax3(c->Circle().Position()));
177 case GeomAbs_Ellipse:
178 P = new Geom_Plane(gp_Ax3(c->Ellipse().Position()));
181 case GeomAbs_Hyperbola:
182 P = new Geom_Plane(gp_Ax3(c->Hyperbola().Position()));
185 case GeomAbs_Parabola:
186 P = new Geom_Plane(gp_Ax3(c->Parabola().Position()));
189 case GeomAbs_BezierCurve:
191 Handle(Geom_BezierCurve) GC = c->Bezier();
192 Standard_Integer nbp = GC->NbPoles();
194 found = Standard_False;
195 else if ( nbp == 2) {
196 found = Standard_False;
199 TabP = new (TColgp_HArray1OfPnt) (1, nbp);
200 GC->Poles(TabP->ChangeArray1());
205 case GeomAbs_BSplineCurve:
207 Handle(Geom_BSplineCurve) GC = c->BSpline();
208 Standard_Integer nbp = GC->NbPoles();
210 found = Standard_False;
211 else if ( nbp == 2) {
212 found = Standard_False;
215 TabP = new (TColgp_HArray1OfPnt) (1, nbp);
216 GC->Poles(TabP->ChangeArray1());
222 { // On utilise un echantillonage
223 Standard_Integer nbp = 15 + c->NbIntervals(GeomAbs_C3);
224 Standard_Real f, l, t, inv;
226 f = c->FirstParameter();
227 l = c->LastParameter();
229 for (ii=1; ii<=nbp; ii++) {
230 t = ( f*(nbp-ii) + l*(ii-1));
232 TabP->SetValue(ii, c->Value(t));
237 if (! TabP.IsNull()) { // Recherche d'un plan moyen et controle
238 Standard_Boolean issingular;
240 GeomLib::AxeOfInertia(TabP->Array1(), inertia, issingular);
242 found = Standard_False;
245 P = new Geom_Plane(inertia);
249 //control = Controle(TabP->Array1(), P, myTolerance);
250 // Standard_Boolean isOnPlane;
251 Standard_Real a,b,c,d, dist;
253 P->Coefficients(a,b,c,d);
254 for (ii=1; ii<=TabP->Length() && found; ii++) {
255 const gp_XYZ& xyz = TabP->Value(ii).XYZ();
256 dist = a*xyz.X() + b*xyz.Y() + c*xyz.Z() + d;
257 found = (Abs(dist) <= Precision::Confusion());
266 //===============================================================
269 //===============================================================
270 GeomFill_CorrectedFrenet::GeomFill_CorrectedFrenet()
271 : isFrenet(Standard_False)
273 frenet = new GeomFill_Frenet();
276 Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
278 Handle(GeomFill_CorrectedFrenet) copy = new (GeomFill_CorrectedFrenet)();
279 if (!myCurve.IsNull()) copy->SetCurve(myCurve);
283 void GeomFill_CorrectedFrenet::SetCurve(const Handle(Adaptor3d_HCurve)& C)
286 GeomFill_TrihedronLaw::SetCurve(C);
290 GeomAbs_CurveType type;
294 case GeomAbs_Ellipse:
295 case GeomAbs_Hyperbola:
296 case GeomAbs_Parabola:
299 // No probleme isFrenet
300 isFrenet = Standard_True;
304 // We have to search singulaties
305 isFrenet = Standard_True;
313 //===============================================================
315 // Purpose : Compute angle's law
316 //===============================================================
317 void GeomFill_CorrectedFrenet::Init()
319 EvolAroundT = new Law_Composite();
320 Standard_Integer NbI = frenet->NbIntervals(GeomAbs_C0), i;
321 TColStd_Array1OfReal T(1, NbI + 1);
322 frenet->Intervals(T, GeomAbs_C0);
323 Handle(Law_Function) Func;
325 TColStd_SequenceOfReal SeqPoles, SeqAngle;
326 TColgp_SequenceOfVec SeqTangent, SeqNormal;
328 gp_Vec Tangent, Normal, BN;
329 frenet->D0(myTrimmed->FirstParameter(), Tangent, Normal, BN);
330 Standard_Integer NbStep;
331 // Standard_Real StartAng = 0, AvStep, Step, t;
332 Standard_Real StartAng = 0, AvStep, Step;
337 if (Affich) { // Display the curve C'^C''(t)
338 GeomFill_SnglrFunc CS(myCurve);
340 AvStep = (myTrimmed->LastParameter() -
341 myTrimmed->FirstParameter())/NbStep;
342 TColgp_Array1OfPnt TabP(1, NbStep+1);
344 TColStd_Array1OfReal TI(1, NbStep+1);
345 TColStd_Array1OfInteger M(1,NbStep+1);
347 M(1) = M(NbStep+1) = 2;
348 for (i=1; i<=NbStep+1; i++) {
349 t = (myTrimmed->FirstParameter()+ (i-1)*AvStep);
354 Standard_CString name = tname ;
355 sprintf(name,"Binorm_%d", ++CorrNumber);
356 Handle(Geom_BSplineCurve) BS = new
357 (Geom_BSplineCurve) (TabP, TI, M, 1);
358 // DrawTrSurf::Set(&name[0], BS);
359 DrawTrSurf::Set(name, BS);
365 AvStep = (myTrimmed->LastParameter() - myTrimmed->FirstParameter())/NbStep;
366 for(i = 1; i <= NbI; i++) {
367 NbStep = Max(Standard_Integer((T(i+1) - T(i))/AvStep), 3);
368 Step = (T(i+1) - T(i))/NbStep;
369 if(!InitInterval(T(i), T(i+1), Step, StartAng, Tangent, Normal, AT, AN, Func, SeqPoles, SeqAngle, SeqTangent, SeqNormal))
370 if(isFrenet) isFrenet = Standard_False;
371 Handle(Law_Composite)::DownCast(EvolAroundT)->ChangeLaws().Append(Func);
373 if(myTrimmed->IsPeriodic())
374 Handle(Law_Composite)::DownCast(EvolAroundT)->SetPeriodic();
378 Standard_Integer iEnd = SeqPoles.Length();
379 HArrPoles = new TColStd_HArray1OfReal(1, iEnd);
380 HArrAngle = new TColStd_HArray1OfReal(1, iEnd);
381 HArrTangent = new TColgp_HArray1OfVec(1, iEnd);
382 HArrNormal = new TColgp_HArray1OfVec(1, iEnd);
383 for(i = 1; i <= iEnd; i++){
384 HArrPoles->ChangeValue(i) = SeqPoles(i);
385 HArrAngle->ChangeValue(i) = SeqAngle(i);
386 HArrTangent->ChangeValue(i) = SeqTangent(i);
387 HArrNormal->ChangeValue(i) = SeqNormal(i);
397 //===============================================================
398 // Function : InitInterval
399 // Purpose : Compute the angle law on a span
400 //===============================================================
401 Standard_Boolean GeomFill_CorrectedFrenet::
402 InitInterval(const Standard_Real First, const Standard_Real Last,
403 const Standard_Real Step,
404 Standard_Real& startAng, gp_Vec& prevTangent,
405 gp_Vec& prevNormal, gp_Vec& aT, gp_Vec& aN,
406 Handle(Law_Function)& FuncInt,
407 TColStd_SequenceOfReal& SeqPoles,
408 TColStd_SequenceOfReal& SeqAngle,
409 TColgp_SequenceOfVec& SeqTangent,
410 TColgp_SequenceOfVec& SeqNormal) const
413 gp_Vec Tangent, Normal, BN, cross;
414 TColStd_SequenceOfReal parameters;
415 TColStd_SequenceOfReal EvolAT;
416 Standard_Real Param = First, LengthMin, L, norm;
417 Standard_Boolean isZero = Standard_True, isConst = Standard_True;
422 frenet->SetInterval(First, Last); //To have the rigth evaluation at bounds
423 GeomFill_SnglrFunc CS(myCurve);
424 BndLib_Add3dCurve::Add(CS, First, Last, 1.e-2, Boite);
425 LengthMin = Boite.GetGap()*1.e-4;
427 aT = gp_Vec(0, 0, 0);
428 aN = gp_Vec(0, 0, 0);
430 Standard_Real angleAT, currParam, currStep = Step;
432 Handle( Geom_Plane ) aPlane;
433 Standard_Boolean isPlanar = FindPlane( myCurve, aPlane );
437 Standard_Real DLast = Last - Precision::PConfusion();
439 while (Param < Last) {
440 if (currParam > DLast) {
441 currStep = DLast - Param;
447 frenet->D0(currParam, Tangent, Normal, BN);
448 if (prevTangent.Angle(Tangent) < M_PI/3 || i == 1) {
449 parameters.Append(currParam);
451 SeqPoles.Append(Param);
452 SeqAngle.Append(i > 1? EvolAT(i-1) : startAng);
453 SeqTangent.Append(prevTangent);
454 SeqNormal.Append(prevNormal);
455 angleAT = CalcAngleAT(Tangent,Normal,prevTangent,prevNormal);
458 if(Abs(angleAT) > Precision::PConfusion())
459 isConst = Standard_False;
461 angleAT += (i > 1) ? EvolAT(i-1) : startAng;
462 EvolAT.Append(angleAT);
466 if(Abs(angleAT) > Precision::PConfusion())
467 isZero = Standard_False;
470 cross = Tangent.Crossed(Normal);
471 aN.SetLinearForm(Sin(angleAT), cross,
472 1 - Cos(angleAT), Tangent.Crossed(cross),
474 prevTangent = Tangent;
478 //Evaluate the Next step
479 CS.D1(Param, PonC, D1);
480 L = Max(PonC.XYZ().Modulus()/2, LengthMin);
481 norm = D1.Magnitude();
482 if (norm < Precision::Confusion()) {
483 norm = Precision::Confusion();
486 if (currStep > Step) currStep = Step;//default value
489 currStep /= 2; // Step too long !
491 currParam = Param + currStep;
496 aT /= parameters.Length() - 1;
497 aN /= parameters.Length() - 1;
502 if (isConst || isPlanar) {
503 FuncInt = new Law_Constant();
504 Handle(Law_Constant)::DownCast(FuncInt)->Set( angleAT, First, Last );
508 Standard_Integer Length = parameters.Length();
509 Handle(TColStd_HArray1OfReal) pararr =
510 new TColStd_HArray1OfReal(1, Length);
511 Handle(TColStd_HArray1OfReal) angleATarr =
512 new TColStd_HArray1OfReal(1, Length);
515 for (i = 1; i <= Length; i++) {
516 pararr->ChangeValue(i) = parameters(i);
517 angleATarr->ChangeValue(i) = EvolAT(i);
522 cout<<"NormalEvolution"<<endl;
523 for (i = 1; i <= Length; i++) {
524 cout<<"("<<pararr->Value(i)<<", "<<angleATarr->Value(i)<<")" << endl;
530 Law_Interpolate lawAT(angleATarr, pararr,
531 Standard_False, Precision::PConfusion());
533 Handle(Law_BSpline) BS = lawAT.Curve();
534 smoothlaw(BS, angleATarr, pararr, 0.1);
536 FuncInt = new Law_BSpFunc(BS, First, Last);
540 //===============================================================
541 // Function : CalcAngleAT (OCC78)
542 // Purpose : Calculate angle of rotation of trihedron normal and its derivatives relative
543 // at any position on his curve
544 //===============================================================
545 Standard_Real GeomFill_CorrectedFrenet::CalcAngleAT(const gp_Vec& Tangent, const gp_Vec& Normal,
546 const gp_Vec& prevTangent, const gp_Vec& prevNormal) const
549 gp_Vec Normal_rot, cross;
550 angle = Tangent.Angle(prevTangent);
551 if (Abs(angle) > Precision::Angular()) {
552 cross = Tangent.Crossed(prevTangent).Normalized();
553 Normal_rot = Normal + sin(angle)*cross.Crossed(Normal) +
554 (1 - cos(angle))*cross.Crossed(cross.Crossed(Normal));
558 Standard_Real angleAT = Normal_rot.Angle(prevNormal);
559 if(angleAT > Precision::Angular() && M_PI - angleAT > Precision::Angular())
560 if (Normal_rot.Crossed(prevNormal).IsOpposite(prevTangent, Precision::Angular()))
564 //===============================================================
565 // Function : ... (OCC78)
566 // Purpose : This family of functions produce conversion of angle utility
567 //===============================================================
568 static Standard_Real corrPI_2PI(Standard_Real Ang){
569 return Ang = (Ang >= 0.0? Ang: 2*M_PI+Ang);
571 static Standard_Real corr2PI_PI(Standard_Real Ang){
572 return Ang = (Ang < M_PI? Ang: Ang-2*M_PI);
574 static Standard_Real diffAng(Standard_Real A, Standard_Real Ao){
575 Standard_Real dA = (A-Ao) - Floor((A-Ao)/2.0/M_PI)*2.0*M_PI;
576 return dA = dA >= 0? corr2PI_PI(dA): -corr2PI_PI(-dA);
578 //===============================================================
579 // Function : CalcAngleAT (OCC78)
580 // Purpose : Calculate angle of rotation of trihedron normal and its derivatives relative
581 // at any position on his curve
582 //===============================================================
583 Standard_Real GeomFill_CorrectedFrenet::GetAngleAT(const Standard_Real Param) const{
584 // Search index of low margin from poles of TLaw by bisection method
585 Standard_Integer iB = 1, iE = HArrPoles->Length(), iC = (iE+iB)/2;
586 if(Param == HArrPoles->Value(iB)) return TLaw->Value(Param);
587 if(Param > HArrPoles->Value(iE)) iC = iE;
589 while(!(HArrPoles->Value(iC) <= Param && Param <= HArrPoles->Value(iC+1))){
590 if(HArrPoles->Value(iC) < Param) iB = iC; else iE = iC;
593 if(HArrPoles->Value(iC) == Param || Param == HArrPoles->Value(iC+1)) return TLaw->Value(Param);
595 // Calculate differenciation between apporoximated and local values of AngleAT
596 Standard_Real AngP = TLaw->Value(Param), AngPo = HArrAngle->Value(iC), dAng = AngP - AngPo;
597 gp_Vec Tangent, Normal, BN;
598 frenet->D0(Param, Tangent, Normal, BN);
599 Standard_Real DAng = CalcAngleAT(Tangent, Normal, HArrTangent->Value(iC), HArrNormal->Value(iC));
600 Standard_Real DA = diffAng(DAng,dAng);
601 // The correction (there is core of OCC78 bug)
602 if(Abs(DA) > M_PI/2.0){
607 //===============================================================
610 //===============================================================
611 Standard_Boolean GeomFill_CorrectedFrenet::D0(const Standard_Real Param,
616 frenet->D0(Param, Tangent, Normal, BiNormal);
617 if (isFrenet) return Standard_True;
619 Standard_Real angleAT;
620 //angleAT = TLaw->Value(Param);
621 angleAT = GetAngleAT(Param); //OCC78
623 // rotation around Tangent
625 cross = Tangent.Crossed(Normal);
626 Normal.SetLinearForm(Sin(angleAT), cross,
627 (1 - Cos(angleAT)), Tangent.Crossed(cross),
629 BiNormal = Tangent.Crossed(Normal);
631 return Standard_True;
634 //===============================================================
637 //===============================================================
639 Standard_Boolean GeomFill_CorrectedFrenet::D1(const Standard_Real Param,
647 frenet->D1(Param, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal);
648 if (isFrenet) return Standard_True;
650 Standard_Real angleAT, d_angleAT;
651 Standard_Real sina, cosa;
653 TLaw->D1(Param, angleAT, d_angleAT);
654 angleAT = GetAngleAT(Param); //OCC78
656 gp_Vec cross, dcross, tcross, dtcross, aux;
660 cross = Tangent.Crossed(Normal);
661 dcross.SetLinearForm(1, DTangent.Crossed(Normal),
662 Tangent.Crossed(DNormal));
664 tcross = Tangent.Crossed(cross);
665 dtcross.SetLinearForm(1, DTangent.Crossed(cross),
666 Tangent.Crossed(dcross));
668 aux.SetLinearForm(sina, dcross,
669 cosa*d_angleAT, cross);
670 aux.SetLinearForm(1 - cosa, dtcross,
671 sina*d_angleAT, tcross,
675 Normal.SetLinearForm( sina, cross,
679 BiNormal = Tangent.Crossed(Normal);
681 DBiNormal.SetLinearForm(1, DTangent.Crossed(Normal),
682 Tangent.Crossed(DNormal));
685 /* gp_Vec FDN, Tf, Nf, BNf;
688 if (Param + h > myTrimmed->LastParameter()) h = -h;
689 D0(Param + h, Tf, Nf, BNf);
690 FDN = (Nf - Normal)/h;
691 cout<<"Param = "<<Param<<endl;
692 cout<<"DN = ("<<DNormal.X()<<", "<<DNormal.Y()<<", "<<DNormal.Z()<<")"<<endl;
693 cout<<"FDN = ("<<FDN.X()<<", "<<FDN.Y()<<", "<<FDN.Z()<<")"<<endl;
696 return Standard_True;
699 //===============================================================
702 //===============================================================
703 Standard_Boolean GeomFill_CorrectedFrenet::D2(const Standard_Real Param,
714 frenet->D2(Param, Tangent, DTangent, D2Tangent,
715 Normal, DNormal, D2Normal,
716 BiNormal, DBiNormal, D2BiNormal);
717 if (isFrenet) return Standard_True;
719 Standard_Real angleAT, d_angleAT, d2_angleAT;
720 Standard_Real sina, cosa;
721 TLaw->D2(Param, angleAT, d_angleAT, d2_angleAT);
722 angleAT = GetAngleAT(Param); //OCC78
724 gp_Vec cross, dcross, d2cross, tcross, dtcross, d2tcross, aux;
727 cross = Tangent.Crossed(Normal);
728 dcross.SetLinearForm(1, DTangent.Crossed(Normal),
729 Tangent.Crossed(DNormal));
730 d2cross.SetLinearForm(1, D2Tangent.Crossed(Normal),
731 2, DTangent.Crossed(DNormal),
732 Tangent.Crossed(D2Normal));
735 tcross = Tangent.Crossed(cross);
736 dtcross.SetLinearForm(1, DTangent.Crossed(cross),
737 Tangent.Crossed(dcross));
738 d2tcross.SetLinearForm(1, D2Tangent.Crossed(cross),
739 2, DTangent.Crossed(dcross),
740 Tangent.Crossed(d2cross));
743 aux.SetLinearForm(sina, d2cross,
744 2*cosa*d_angleAT, dcross,
745 cosa*d2_angleAT - sina*d_angleAT*d_angleAT, cross);
747 aux.SetLinearForm(1 - cosa, d2tcross,
748 2*sina*d_angleAT, dtcross,
749 cosa*d_angleAT*d_angleAT + sina*d2_angleAT, tcross,
753 /* D2Normal += sina*(D2Tangent.Crossed(Normal) + 2*DTangent.Crossed(DNormal) + Tangent.Crossed(D2Normal)) +
754 2*cosa*d_angleAT*(DTangent.Crossed(Normal) + Tangent.Crossed(DNormal)) +
755 (cosa*d2_angleAT - sina*d_angleAT*d_angleAT)*Tangent.Crossed(Normal) +
756 2*sina*d_angleAT*(DTangent.Crossed(Tangent.Crossed(Normal)) + Tangent.Crossed(DTangent.Crossed(Normal)) + Tangent.Crossed(Tangent.Crossed(DNormal))) +
757 (1 - cosa)*(D2Tangent.Crossed(Tangent.Crossed(Normal)) + Tangent.Crossed(D2Tangent.Crossed(Normal)) + Tangent.Crossed(Tangent.Crossed(D2Normal)) + 2*DTangent.Crossed(DTangent.Crossed(Normal)) + 2*DTangent.Crossed(Tangent.Crossed(DNormal)) + 2*Tangent.Crossed(DTangent.Crossed(DNormal)))
759 (cosa*d_angleAT*d_angleAT + sina*d2_angleAT)*Tangent.Crossed(Tangent.Crossed(Normal));*/
762 aux.SetLinearForm(sina, dcross,
763 cosa*d_angleAT, cross);
764 aux.SetLinearForm(1 - cosa, dtcross,
765 sina*d_angleAT, tcross,
770 Normal.SetLinearForm( sina, cross,
774 BiNormal = Tangent.Crossed(Normal);
776 DBiNormal.SetLinearForm(1, DTangent.Crossed(Normal),
777 Tangent.Crossed(DNormal));
779 D2BiNormal.SetLinearForm(1, D2Tangent.Crossed(Normal),
780 2, DTangent.Crossed(DNormal),
781 Tangent.Crossed(D2Normal));
784 /* gp_Vec FD2N, FD2T, FD2BN, Tf, DTf, Nf, DNf, BNf, DBNf;
787 if (Param + h > myTrimmed->LastParameter()) h = -h;
788 D1(Param + h, Tf, DTf, Nf, DNf, BNf, DBNf);
789 FD2N = (DNf - DNormal)/h;
790 FD2T = (DTf - DTangent)/h;
791 FD2BN = (DBNf - DBiNormal)/h;
792 cout<<"Param = "<<Param<<endl;
793 cout<<"D2N = ("<<D2Normal.X()<<", "<<D2Normal.Y()<<", "<<D2Normal.Z()<<")"<<endl;
794 cout<<"FD2N = ("<<FD2N.X()<<", "<<FD2N.Y()<<", "<<FD2N.Z()<<")"<<endl<<endl;
795 cout<<"D2T = ("<<D2Tangent.X()<<", "<<D2Tangent.Y()<<", "<<D2Tangent.Z()<<")"<<endl;
796 cout<<"FD2T = ("<<FD2T.X()<<", "<<FD2T.Y()<<", "<<FD2T.Z()<<")"<<endl<<endl;
797 cout<<"D2BN = ("<<D2BiNormal.X()<<", "<<D2BiNormal.Y()<<", "<<D2BiNormal.Z()<<")"<<endl;
798 cout<<"FD2BN = ("<<FD2BN.X()<<", "<<FD2BN.Y()<<", "<<FD2BN.Z()<<")"<<endl<<endl;
801 return Standard_True;
804 //===============================================================
805 // Function : NbIntervals
807 //===============================================================
808 Standard_Integer GeomFill_CorrectedFrenet::NbIntervals(const GeomAbs_Shape S) const
810 Standard_Integer NbFrenet, NbLaw;
811 NbFrenet = frenet->NbIntervals(S);
812 if (isFrenet) return NbFrenet;
814 NbLaw = EvolAroundT->NbIntervals(S);
818 TColStd_Array1OfReal FrenetInt(1, NbFrenet + 1);
819 TColStd_Array1OfReal LawInt(1, NbLaw + 1);
820 TColStd_SequenceOfReal Fusion;
822 frenet->Intervals(FrenetInt, S);
823 EvolAroundT->Intervals(LawInt, S);
824 GeomLib::FuseIntervals(FrenetInt, LawInt, Fusion);
826 return Fusion.Length()-1;
829 //===============================================================
830 // Function : Intervals
832 //===============================================================
833 void GeomFill_CorrectedFrenet::Intervals(TColStd_Array1OfReal& T,
834 const GeomAbs_Shape S) const
836 Standard_Integer NbFrenet, NbLaw;
838 frenet->Intervals(T, S);
842 NbFrenet = frenet->NbIntervals(S);
844 EvolAroundT->Intervals(T, S);
847 NbLaw = EvolAroundT->NbIntervals(S);
849 TColStd_Array1OfReal FrenetInt(1, NbFrenet + 1);
850 TColStd_Array1OfReal LawInt(1, NbLaw + 1);
851 TColStd_SequenceOfReal Fusion;
853 frenet->Intervals(FrenetInt, S);
854 EvolAroundT->Intervals(LawInt, S);
855 GeomLib::FuseIntervals(FrenetInt, LawInt, Fusion);
857 for(Standard_Integer i = 1; i <= Fusion.Length(); i++)
858 T.ChangeValue(i) = Fusion.Value(i);
861 //===============================================================
862 // Function : SetInterval
864 //===============================================================
865 void GeomFill_CorrectedFrenet::SetInterval(const Standard_Real First,
866 const Standard_Real Last)
868 GeomFill_TrihedronLaw::SetInterval(First, Last);
869 frenet->SetInterval(First, Last);
870 if (!isFrenet) TLaw = EvolAroundT->Trim(First, Last,
871 Precision::PConfusion()/2);
874 //===============================================================
875 // Function : GetAverageLaw
877 //===============================================================
878 void GeomFill_CorrectedFrenet::GetAverageLaw(gp_Vec& ATangent,
882 if (isFrenet) frenet->GetAverageLaw(ATangent, ANormal, ABiNormal);
886 ABiNormal = ATangent;
887 ABiNormal.Cross(ANormal);
891 //===============================================================
892 // Function : IsConstant
894 //===============================================================
895 Standard_Boolean GeomFill_CorrectedFrenet::IsConstant() const
897 return (myCurve->GetType() == GeomAbs_Line);
900 //===============================================================
901 // Function : IsOnlyBy3dCurve
903 //===============================================================
904 Standard_Boolean GeomFill_CorrectedFrenet::IsOnlyBy3dCurve() const
906 return Standard_True;