1 // Created on: 1997-12-15
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Adaptor3d_HCurve.hxx>
19 #include <Bnd_Box.hxx>
20 #include <BndLib_Add3dCurve.hxx>
21 #include <Extrema_ExtCC.hxx>
22 #include <Extrema_POnCurv.hxx>
23 #include <Geom_BezierCurve.hxx>
24 #include <Geom_BSplineCurve.hxx>
25 #include <Geom_CartesianPoint.hxx>
26 #include <Geom_Conic.hxx>
27 #include <Geom_Curve.hxx>
28 #include <Geom_Geometry.hxx>
29 #include <Geom_Line.hxx>
30 #include <Geom_Plane.hxx>
31 #include <Geom_TrimmedCurve.hxx>
32 #include <GeomAbs_CurveType.hxx>
33 #include <GeomAdaptor_HSurface.hxx>
34 #include <GeomFill_LocationLaw.hxx>
35 #include <GeomFill_SectionPlacement.hxx>
36 #include <GeomLib.hxx>
37 #include <GeomLProp_CLProps.hxx>
44 #include <gp_Trsf.hxx>
46 #include <IntCurveSurface_HInter.hxx>
47 #include <IntCurveSurface_IntersectionPoint.hxx>
48 #include <Precision.hxx>
49 #include <StdFail_NotDone.hxx>
50 #include <TColgp_HArray1OfPnt.hxx>
52 //===============================================================
55 //===============================================================
56 static void Tangente(const Adaptor3d_Curve& Path,
57 const Standard_Real Param,
61 Path.D1(Param, P, Tang);
62 Standard_Real Norm = Tang.Magnitude();
64 for (Standard_Integer ii=2; (ii<12) && (Norm < Precision::Confusion());
66 Tang = Path.DN(Param, ii);
67 Norm = Tang.Magnitude();
70 if (Norm > 100*gp::Resolution()) Tang /= Norm;
74 static Standard_Real Penalite(const Standard_Real angle,
75 const Standard_Real dist)
87 penal += 1./angle -2./M_PI;
96 static Standard_Real EvalAngle(const gp_Vec& V1,
100 angle = V1.Angle(V2);
101 if (angle > M_PI/2) angle = M_PI - angle;
105 static Standard_Integer NbSamples(const Handle(Geom_Curve)& aCurve)
107 Standard_Real nbs = 100.; //on default
109 Handle(Geom_Curve) theCurve = aCurve;
110 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
111 theCurve = (Handle(Geom_TrimmedCurve)::DownCast(aCurve))->BasisCurve();
113 if (theCurve->IsInstance(STANDARD_TYPE(Geom_Line)))
115 else if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
117 else if (theCurve->IsInstance(STANDARD_TYPE(Geom_BezierCurve)))
119 Handle(Geom_BezierCurve) BC = Handle(Geom_BezierCurve)::DownCast(theCurve);
120 nbs = 3 + BC->NbPoles();
122 else if (theCurve->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)))
124 Handle(Geom_BSplineCurve) BC = Handle(Geom_BSplineCurve)::DownCast(theCurve);
127 Standard_Real ratio =
128 (aCurve->LastParameter() - aCurve->FirstParameter())/(BC->LastParameter() - BC->FirstParameter());
137 return ((Standard_Integer)nbs);
140 //===============================================================
141 // Function :DistMini
142 // Purpose : Examine un extrema pour updater <Dist> & <Param>
143 //===============================================================
144 static void DistMini(const Extrema_ExtPC& Ext,
145 const Adaptor3d_Curve& C,
147 Standard_Real& Param)
149 Standard_Real dist1, dist2;
152 Standard_Real Dist2 = RealLast();
154 Ext.TrimmedSquareDistances(dist1, dist2, P1, P2);
155 if ( (dist1<Dist2) || (dist2<Dist2) ) {
158 Param = C.FirstParameter();
162 Param = C.LastParameter();
168 for (ii=1; ii<= Ext.NbExt(); ii++) {
169 if (Ext.SquareDistance(ii) < Dist2) {
170 Dist2 = Ext.SquareDistance(ii);
171 Param = Ext.Point(ii).Parameter();
179 //===============================================================
180 // Function : Constructeur
182 //===============================================================
183 GeomFill_SectionPlacement::
184 GeomFill_SectionPlacement(const Handle(GeomFill_LocationLaw)& L,
185 const Handle(Geom_Geometry)& Section) :
186 myLaw(L), /* myAdpSection(Section), mySection(Section), */
187 Dist(RealLast()), AngleMax(0.)
190 done = Standard_False;
191 isplan = Standard_False;
192 myIsPoint = Standard_False;
194 if (Section->IsInstance(STANDARD_TYPE(Geom_CartesianPoint)))
196 myIsPoint = Standard_True;
197 myPoint = Handle(Geom_CartesianPoint)::DownCast(Section)->Pnt();
198 isplan = Standard_True;
202 Handle(Geom_Curve) CurveSection = Handle(Geom_Curve)::DownCast(Section);
203 myAdpSection.Load(CurveSection);
204 mySection = CurveSection;
207 Standard_Integer i, j, NbPoles=0;
208 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
210 // Boite d'encombrement de la section pour en deduire le gabarit
215 BndLib_Add3dCurve::Add(myAdpSection, 1.e-4, box);
216 box.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
218 Standard_Real DX = aXmax - aXmin ;
219 Standard_Real DY = aYmax - aYmin ;
220 Standard_Real DZ = aZmax - aZmin ;
221 Gabarit = Sqrt( DX*DX+ DY*DY + DZ*DZ )/2. ;
223 Gabarit += Precision::Confusion(); // Cas des toute petite
226 // Initialisation de TheAxe pour les cas singulier
231 Tangente(myAdpSection,
232 (myAdpSection.FirstParameter()+myAdpSection.LastParameter())/2,
234 TheAxe.SetLocation(P);
235 TheAxe.SetDirection(V);
237 // y a t'il un Plan moyen ?
238 GeomAbs_CurveType TheType = myAdpSection.GetType();
242 isplan = Standard_True;
243 TheAxe = myAdpSection.Circle().Axis();
246 case GeomAbs_Ellipse:
248 isplan = Standard_True;
249 TheAxe = myAdpSection.Ellipse().Axis();
252 case GeomAbs_Hyperbola:
254 isplan = Standard_True;
255 TheAxe = myAdpSection.Hyperbola().Axis();
258 case GeomAbs_Parabola:
260 isplan = Standard_True;
261 TheAxe = myAdpSection.Parabola().Axis();
266 NbPoles = 0; // Pas de Plan !!
269 case GeomAbs_BezierCurve:
270 case GeomAbs_BSplineCurve:
272 NbPoles = myAdpSection.NbPoles();
280 if (!isplan && NbPoles>2)
282 // Calcul d'un plan moyen.
283 Handle(TColgp_HArray1OfPnt) Pnts;
284 Standard_Real first = myAdpSection.FirstParameter();
285 Standard_Real last = myAdpSection.LastParameter();
286 Standard_Real t, delta;
287 if (myAdpSection.GetType() == GeomAbs_BSplineCurve)
289 Handle(Geom_BSplineCurve) BC =
290 Handle(Geom_BSplineCurve)::DownCast(myAdpSection.Curve());
291 Standard_Integer I1, I2, I3, I4;
292 BC->LocateU( first, Precision::Confusion(), I1, I2 );
293 BC->LocateU( last, Precision::Confusion(), I3, I4 );
294 Standard_Integer NbKnots = I3 - I2 + 1;
296 Standard_Integer NbLocalPnts = 10;
297 Standard_Integer NbPnts = (NbKnots-1) * NbLocalPnts;
299 NbPnts += NbLocalPnts;
300 if (I3 != I4 && first < BC->Knot(I3))
301 NbPnts += NbLocalPnts;
302 if (!myAdpSection.IsClosed())
304 Pnts = new TColgp_HArray1OfPnt(1, NbPnts);
305 Standard_Integer nb = 1;
308 Standard_Real locallast = (BC->Knot(I2) < last)? BC->Knot(I2) : last;
309 delta = (locallast - first) / NbLocalPnts;
310 for (j = 0; j < NbLocalPnts; j++)
313 Pnts->SetValue( nb++, myAdpSection.Value(t) );
316 for (i = I2; i < I3; i++)
319 delta = (BC->Knot(i+1) - t) / NbLocalPnts;
320 for (j = 0; j < NbLocalPnts; j++)
322 Pnts->SetValue( nb++, myAdpSection.Value(t) );
326 if (I3 != I4 && first < BC->Knot(I3))
329 delta = (last - t) / NbLocalPnts;
330 for (j = 0; j < NbLocalPnts; j++)
332 Pnts->SetValue( nb++, myAdpSection.Value(t) );
336 if (!myAdpSection.IsClosed())
337 Pnts->SetValue( nb, myAdpSection.Value(last) );
341 Standard_Integer NbPnts = NbPoles-1;
342 if (!myAdpSection.IsClosed())
344 Pnts = new TColgp_HArray1OfPnt(1, NbPnts);
345 delta = (last - first) / (NbPoles-1);
346 for (i = 0; i < NbPoles-1; i++)
349 Pnts->SetValue( i+1, myAdpSection.Value(t) );
351 if (!myAdpSection.IsClosed())
352 Pnts->SetValue( NbPnts, myAdpSection.Value(last) );
355 Standard_Boolean issing;
357 GeomLib::AxeOfInertia(Pnts->Array1(), axe, issing, Precision::Confusion());
359 isplan = Standard_True;
360 TheAxe.SetLocation(axe.Location());
361 TheAxe.SetDirection(axe.Direction());
366 myExt.Initialize(myAdpSection,
367 myAdpSection.FirstParameter(),
368 myAdpSection.LastParameter(),
369 Precision::Confusion());
373 //===============================================================
374 // Function :SetLocation
376 //===============================================================
377 void GeomFill_SectionPlacement::
378 SetLocation(const Handle(GeomFill_LocationLaw)& L)
383 //===============================================================
384 // Function : Perform
385 // Purpose : Le plus simple
386 //===============================================================
387 void GeomFill_SectionPlacement::Perform(const Standard_Real Tol)
389 Handle(Adaptor3d_HCurve) Path;
390 Path = myLaw->GetCurve();
394 //===============================================================
396 // Purpose : Recherche automatique
397 //===============================================================
398 void GeomFill_SectionPlacement::Perform(const Handle(Adaptor3d_HCurve)& Path,
399 const Standard_Real Tol)
401 Standard_Real IntTol = 1.e-5;
402 Standard_Real DistCenter = Precision::Infinite();
406 Extrema_ExtPC Projector(myPoint, Path->Curve(), Precision::Confusion());
407 DistMini( Projector, Path->Curve(), Dist, PathParam );
412 PathParam = Path->FirstParameter();
413 SecParam = myAdpSection.FirstParameter();
415 Standard_Real distaux, taux, alpha;
416 gp_Pnt PonPath, PonSec, P;
418 VRef.SetXYZ(TheAxe.Direction().XYZ());
420 Tangente( Path->Curve(), PathParam, PonPath, dp1);
421 PonSec = myAdpSection.Value(SecParam);
422 Dist = PonPath.Distance(PonSec);
423 if (Dist > Tol) { // On Cherche un meilleur point sur la section
424 myExt.Perform(PonPath);
425 if ( myExt.IsDone() ) {
426 DistMini(myExt, myAdpSection, Dist, SecParam);
427 PonSec = myAdpSection.Value(SecParam);
430 AngleMax = EvalAngle(VRef, dp1);
431 if (isplan) AngleMax = M_PI/2 - AngleMax;
433 Standard_Boolean Trouve = Standard_False;
437 // (1.1) Distances Point-Plan
438 Standard_Real DistPlan;
439 gp_Vec V1 (PonPath, TheAxe.Location());
440 DistPlan = Abs(V1.Dot(VRef));
441 if (DistPlan <= IntTol)
442 DistCenter = V1.Magnitude();
444 gp_Pnt Plast = Path->Value( Path->LastParameter() );
445 V1.SetXYZ( TheAxe.Location().XYZ() - Plast.XYZ() );
446 DistPlan = Abs(V1.Dot(VRef));
447 if (DistPlan <= IntTol)
449 Standard_Real aDist = V1.Magnitude();
450 if (aDist < DistCenter)
454 PathParam = Path->LastParameter();
458 // (1.2) Intersection Plan-courbe
459 gp_Ax3 axe (TheAxe.Location(), TheAxe.Direction());
460 Handle(Geom_Plane) plan = new (Geom_Plane)(axe);
461 Handle(GeomAdaptor_HSurface) adplan =
462 new (GeomAdaptor_HSurface)(plan);
463 IntCurveSurface_HInter Intersector;
464 Intersector.Perform(Path, adplan);
465 if (Intersector.IsDone())
469 for (ii=1; ii<=Intersector.NbPoints(); ii++)
471 w = Intersector.Point(ii).W();
472 P = Path->Value( w );
473 aDist = P.Distance( TheAxe.Location() );
474 if (aDist < DistCenter)
482 if (!Intersector.IsDone() || Intersector.NbPoints() == 0)
484 Standard_Integer NbPnts = NbSamples( mySection );
485 TColgp_Array1OfPnt Pnts( 1, NbPnts+1 );
486 Standard_Real delta = (mySection->LastParameter()-mySection->FirstParameter())/NbPnts;
487 for (ii = 0; ii <= NbPnts; ii++)
488 Pnts(ii+1) = mySection->Value( mySection->FirstParameter() + ii*delta );
492 Standard_Real Xgap, Ygap, Zgap;
493 GeomLib::Inertia( Pnts, BaryCenter, Xdir, Ydir, Xgap, Ygap, Zgap );
495 gp_Pnt Pfirst = Path->Value( Path->FirstParameter() );
496 if (Pfirst.Distance(BaryCenter) < Plast.Distance(BaryCenter))
497 PathParam = Path->FirstParameter();
500 PathParam = Path->LastParameter();
501 Tangente( Path->Curve(), PathParam, PonPath, dp1);
502 PonSec = myAdpSection.Value(SecParam);
503 Dist = PonPath.Distance(PonSec);
504 if (Dist > Tol) { // On Cherche un meilleur point sur la section
505 myExt.Perform(PonPath);
506 if ( myExt.IsDone() ) {
507 DistMini(myExt, myAdpSection, Dist, SecParam);
508 PonSec = myAdpSection.Value(SecParam);
511 AngleMax = EvalAngle(VRef, dp1);
512 AngleMax = M_PI/2 - AngleMax;
517 // (1.1) Distances Point-Plan
518 Standard_Real DistPlan;
519 gp_Vec V1 (PonPath, TheAxe.Location());
520 DistPlan = Abs(V1.Dot(VRef));
522 // On examine l'autre extremite
524 Tangente(Path->Curve(), Path->LastParameter(), P, dp1);
525 V1.SetXYZ(TheAxe.Location().XYZ()-P.XYZ());
526 if (Abs(V1.Dot(VRef)) <= DistPlan ) { // On prend l'autre extremite
527 alpha = M_PI/2 - EvalAngle(VRef, dp1);
528 distaux = PonPath.Distance(PonSec);
531 if ( myExt.IsDone() )
532 DistMini(myExt, myAdpSection, distaux, taux);
537 if (Choix(distaux, alpha)) {
541 PathParam = Path->LastParameter();
545 // (1.2) Intersection Plan-courbe
546 gp_Ax3 axe (TheAxe.Location(), TheAxe.Direction());
547 Handle(Geom_Plane) plan = new (Geom_Plane)(axe);
548 Handle(GeomAdaptor_HSurface) adplan =
549 new (GeomAdaptor_HSurface)(plan);
550 IntCurveSurface_HInter Intersector;
551 Intersector.Perform(Path, adplan);
552 if (Intersector.IsDone()) {
555 for (ii=1; ii<=Intersector.NbPoints(); ii++) {
556 w = Intersector.Point(ii).W();
558 Tangente( Path->Curve(), w, P, V);
559 alpha = M_PI/2 - EvalAngle(V, VRef);
560 //(1.4) Test de distance Point-Courbe
562 if ( myExt.IsDone() ) {
563 DistMini(myExt, myAdpSection, distaux, taux);
564 if (Choix(distaux, alpha)) {
570 PonSec = myAdpSection.Value(SecParam);
574 distaux = P.Distance(PonSec);
575 if (Choix(distaux, alpha)) {
586 if (Intersector.NbPoints() == 0) {
594 // (2.1) Distance avec les extremites ...
595 myExt.Perform(PonPath);
596 if ( myExt.IsDone() ) {
597 DistMini(myExt, myAdpSection, distaux, taux);
598 if (distaux < Dist) {
603 Trouve = (Dist <= Tol);
605 Tangente( Path->Curve(), Path->LastParameter(), P, dp1);
606 alpha = EvalAngle(VRef, dp1);
608 if ( myExt.IsDone() ) {
609 if ( myExt.IsDone() ) {
610 DistMini(myExt, myAdpSection, distaux, taux);
611 if (Choix(distaux, alpha)) {
616 PathParam = Path->LastParameter();
620 Trouve = (Dist <= Tol);
623 // (2.2) Distance courbe-courbe
625 Extrema_ExtCC Ext(Path->Curve(), myAdpSection,
626 Path->FirstParameter(), Path->LastParameter(),
627 myAdpSection.FirstParameter(),
628 myAdpSection.LastParameter(),
629 Path->Resolution(Tol/100),
630 myAdpSection.Resolution(Tol/100));
632 Extrema_POnCurv P1, P2;
633 for (ii=1; ii<=Ext.NbExt(); ii++) {
634 distaux = sqrt (Ext.SquareDistance(ii));
635 Ext.Points(ii, P1, P2);
636 Tangente(Path->Curve(), P1.Parameter(), P, dp1);
637 alpha = EvalAngle(VRef, dp1);
638 if (Choix(distaux, alpha)) {
639 Trouve = Standard_True;
641 PathParam = P1.Parameter();
642 SecParam = P2.Parameter();
650 // Si l'on a toujours rien, on essai une distance point/path
651 // c'est la derniere chance.
653 PExt.Initialize(Path->Curve(),
654 Path->FirstParameter(),
655 Path->LastParameter(),
656 Precision::Confusion());
657 PExt.Perform(PonSec);
658 if ( PExt.IsDone() ) {
659 // modified for OCC13595 Tue Oct 17 15:00:08 2006.BEGIN
660 // DistMini(PExt, myAdpSection, distaux, taux);
661 DistMini(PExt, Path->Curve(), distaux, taux);
662 // modified for OCC13595 Tue Oct 17 15:00:11 2006.END
663 Tangente(Path->Curve(), taux, P, dp1);
664 alpha = EvalAngle(VRef, dp1);
665 if (Choix(distaux, alpha)) {
677 done = Standard_True;
681 //===============================================================
682 // Function : Perform
683 // Purpose : Calcul le placement pour un parametre donne.
684 //===============================================================
685 void GeomFill_SectionPlacement::Perform(const Standard_Real Param,
686 const Standard_Real Tol)
688 done = Standard_True;
689 Handle(Adaptor3d_HCurve) Path;
690 Path = myLaw->GetCurve();
695 gp_Pnt PonPath = Path->Value( PathParam );
696 Dist = PonPath.Distance(myPoint);
701 SecParam = myAdpSection.FirstParameter();
703 // Standard_Real distaux, taux, alpha;
704 // gp_Pnt PonPath, PonSec, P;
705 gp_Pnt PonPath, PonSec;
707 VRef.SetXYZ(TheAxe.Direction().XYZ());
709 Tangente( Path->Curve(), PathParam, PonPath, dp1);
710 PonSec = myAdpSection.Value(SecParam);
711 Dist = PonPath.Distance(PonSec);
712 if (Dist > Tol) { // On Cherche un meilleur point sur la section
713 myExt.Perform(PonPath);
714 if ( myExt.IsDone() ) {
715 DistMini(myExt, myAdpSection, Dist, SecParam);
716 PonSec = myAdpSection.Value(SecParam);
719 AngleMax = EvalAngle(VRef, dp1);
720 if (isplan) AngleMax = M_PI/2 - AngleMax;
723 done = Standard_True;
726 //===============================================================
729 //===============================================================
730 Standard_Boolean GeomFill_SectionPlacement::IsDone() const
735 //===============================================================
736 // Function : ParameterOnPath
738 //===============================================================
739 Standard_Real GeomFill_SectionPlacement::ParameterOnPath() const
744 //===============================================================
745 // Function : ParameterOnSection
747 //===============================================================
748 Standard_Real GeomFill_SectionPlacement::ParameterOnSection() const
753 //===============================================================
754 // Function : Distance
756 //===============================================================
757 Standard_Real GeomFill_SectionPlacement::Distance() const
762 //===============================================================
765 //===============================================================
766 Standard_Real GeomFill_SectionPlacement::Angle() const
771 //===============================================================
772 // Function : Transformation
774 //===============================================================
775 gp_Trsf GeomFill_SectionPlacement::Transformation(
776 const Standard_Boolean WithTranslation,
777 const Standard_Boolean WithCorrection) const
782 // modified by NIZHNY-MKK Fri Oct 17 15:27:07 2003
783 gp_Pnt P(0., 0., 0.), PSection(0., 0., 0.);
785 // Calcul des reperes
786 myLaw->D0(PathParam, M, V);
789 D.SetXYZ (M.Column(3));
790 DN.SetXYZ(M.Column(1));
791 gp_Ax3 Paxe(P, D, DN);
794 if (WithTranslation || WithCorrection) {
798 PSection = mySection->Value(SecParam);
800 // modified by NIZHNY-MKK Wed Oct 8 15:03:19 2003.BEGIN
803 if (WithCorrection && !myIsPoint) {
807 Standard_Failure::Raise("Illegal usage: can't rotate non-planar profile");
809 gp_Dir ProfileNormal = TheAxe.Direction();
810 gp_Dir SpineStartDir = Paxe.Direction();
812 if (! ProfileNormal.IsParallel( SpineStartDir, Precision::Angular() )) {
813 gp_Dir DirAxeOfRotation = ProfileNormal ^ SpineStartDir;
814 angle = ProfileNormal.AngleWithRef( SpineStartDir, DirAxeOfRotation );
815 gp_Ax1 AxeOfRotation( TheAxe.Location(), DirAxeOfRotation );
816 Rot.SetRotation( AxeOfRotation, angle );
818 PSection.Transform(Rot);
820 // modified by NIZHNY-MKK Wed Oct 8 15:03:21 2003.END
822 if (WithTranslation) {
823 P.ChangeCoord().SetLinearForm(-1,PSection.XYZ(),
827 P.SetCoord(0., 0., 0.);
830 gp_Ax3 Saxe(P, gp::DZ(), gp::DX());
834 Tf.SetTransformation(Saxe, Paxe);
836 if (WithCorrection) {
837 // modified by NIZHNY-MKK Fri Oct 17 15:26:36 2003.BEGIN
838 // Standard_Real angle;
842 // Standard_Failure::Raise("Illegal usage: can't rotate non-planar profile");
844 // gp_Dir ProfileNormal = TheAxe.Direction();
845 // gp_Dir SpineStartDir = Paxe.Direction();
846 // if (! ProfileNormal.IsParallel( SpineStartDir, Precision::Angular() ))
848 // gp_Dir DirAxeOfRotation = ProfileNormal ^ SpineStartDir;
849 // angle = ProfileNormal.AngleWithRef( SpineStartDir, DirAxeOfRotation );
850 // gp_Ax1 AxeOfRotation( TheAxe.Location(), DirAxeOfRotation );
851 // Rot.SetRotation( AxeOfRotation, angle );
853 // modified by NIZHNY-MKK Fri Oct 17 15:26:42 2003.END
861 //===============================================================
862 // Function : Section
864 //===============================================================
865 Handle(Geom_Curve) GeomFill_SectionPlacement::
866 Section(const Standard_Boolean WithTranslation) const
868 Handle(Geom_Curve) TheSection =
869 Handle(Geom_Curve)::DownCast(mySection->Copy());
870 TheSection->Transform(Transformation(WithTranslation, Standard_False));
875 //===============================================================
878 //===============================================================
879 Handle(Geom_Curve) GeomFill_SectionPlacement::
880 ModifiedSection(const Standard_Boolean WithTranslation) const
882 Handle(Geom_Curve) TheSection =
883 Handle(Geom_Curve)::DownCast(mySection->Copy());
884 TheSection->Transform(Transformation(WithTranslation, Standard_True));
888 //===============================================================
889 // Function :SectionAxis
891 //===============================================================
892 void GeomFill_SectionPlacement::SectionAxis(const gp_Mat& M,
897 Standard_Real Eps = 1.e-10;
900 GeomLProp_CLProps CP(mySection, SecParam, 2, Eps);
901 if (CP.IsTangentDefined()) {
905 if (CP.Curvature() > Eps) {
910 // Cas ambigu, on essai de recuperer la normal a la trajectoire
911 // Reste le probleme des points d'inflexions, qui n'est pas
912 // bien traiter par LProp (pas de recuperation de la normal) :
914 PathNormal.SetXYZ(M.Column(1));
915 PathNormal.Normalize();
917 if (BN.Magnitude() > Eps) {
924 else { // Cas indefinie, on prend le triedre
925 // complet sur la trajectoire
926 T.SetXYZ(M.Column(3));
927 N.SetXYZ(M.Column(2));
933 //===============================================================
935 // Purpose : Decide si le couple (dist, angle) est "meilleur" que
937 //===============================================================
938 Standard_Boolean GeomFill_SectionPlacement::Choix(const Standard_Real dist,
939 const Standard_Real angle) const
941 Standard_Real evoldist, evolangle;
942 evoldist = dist - Dist;
943 evolangle = angle - AngleMax;
944 // (1) Si la gain en distance est > que le gabarit, on prend
945 if (evoldist < - Gabarit)
946 return Standard_True;
948 // (2) si l'ecart en distance est de l'ordre du gabarit
949 if (Abs(evoldist) < Gabarit) {
950 // (2.1) si le gain en angle est important on garde
952 return Standard_True;
953 // (2.2) si la variation d'angle est moderee on evalue
954 // une fonction de penalite
955 if (Penalite(angle, dist/Gabarit) < Penalite(AngleMax, Dist/Gabarit) )
956 return Standard_True;
959 return Standard_False;