mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-19 13:40:49 +03:00
0023824: Bad results of sweep operation when a path curve has unpredictable torsion along its way.
Adding test cases for this fix
This commit is contained in:
@@ -67,7 +67,7 @@ is
|
||||
enumeration Trihedron
|
||||
is IsCorrectedFrenet, IsFixed, IsFrenet, IsConstantNormal, IsDarboux,
|
||||
IsGuideAC, IsGuidePlan,
|
||||
IsGuideACWithContact, IsGuidePlanWithContact end;
|
||||
IsGuideACWithContact, IsGuidePlanWithContact, IsDiscreteTrihedron end;
|
||||
|
||||
class Filling;
|
||||
---Purpose: Root class for Filling;
|
||||
@@ -195,6 +195,13 @@ is
|
||||
class SequenceOfTrsf
|
||||
instantiates Sequence from TCollection (Trsf from gp);
|
||||
|
||||
class SequenceOfAx2
|
||||
instantiates Sequence from TCollection (Ax2 from gp);
|
||||
|
||||
class HSequenceOfAx2
|
||||
instantiates HSequence from TCollection (Ax2 from gp,
|
||||
SequenceOfAx2 from GeomFill);
|
||||
|
||||
--
|
||||
-- private classes
|
||||
--
|
||||
@@ -226,6 +233,7 @@ is
|
||||
class Fixed;
|
||||
class Frenet;
|
||||
class CorrectedFrenet;
|
||||
class DiscreteTrihedron;
|
||||
class ConstantBiNormal;
|
||||
class Darboux;
|
||||
class DraftTrihedron;
|
||||
|
@@ -37,7 +37,8 @@ uses
|
||||
HArray1OfReal from TColStd,
|
||||
SequenceOfReal from TColStd,
|
||||
HArray1OfVec from TColgp,
|
||||
SequenceOfVec from TColgp
|
||||
SequenceOfVec from TColgp,
|
||||
Trihedron from GeomFill
|
||||
|
||||
raises
|
||||
OutOfRange, ConstructionError
|
||||
@@ -45,11 +46,14 @@ is
|
||||
|
||||
Create returns CorrectedFrenet from GeomFill;
|
||||
|
||||
Create (ForEvaluation: Boolean)
|
||||
returns CorrectedFrenet from GeomFill;
|
||||
|
||||
Copy(me)
|
||||
returns TrihedronLaw from GeomFill
|
||||
is redefined;
|
||||
|
||||
Init(me: mutable)
|
||||
Init(me: mutable)
|
||||
is static private;
|
||||
|
||||
InitInterval(me; First, Last, Step: Real;
|
||||
@@ -59,7 +63,7 @@ is
|
||||
SeqPoles: out SequenceOfReal from TColStd;
|
||||
SeqAngle: out SequenceOfReal from TColStd;
|
||||
SeqTangent: out SequenceOfVec from TColgp;
|
||||
SeqNormal: out SequenceOfVec from TColgp)
|
||||
SeqNormal: out SequenceOfVec from TColgp)
|
||||
returns Boolean
|
||||
--- Purpose: Computes BSpline representation of Normal evolution at one
|
||||
--- interval of continuity of Frenet. Returns True if FuncInt = 0
|
||||
@@ -142,6 +146,20 @@ is
|
||||
OutOfRange from Standard
|
||||
is redefined;
|
||||
|
||||
|
||||
-- =================== To define the best trihedron mode ===============
|
||||
|
||||
EvaluateBestMode(me : mutable)
|
||||
returns Trihedron from GeomFill;
|
||||
---Purpose: Tries to define the best trihedron mode
|
||||
-- for the curve. It can be:
|
||||
-- - Frenet
|
||||
-- - CorrectedFrenet
|
||||
-- - DiscreteTrihedron
|
||||
-- Warning: the CorrectedFrenet must be constructed
|
||||
-- with option ForEvaluation = True,
|
||||
-- the curve must be set by method SetCurve.
|
||||
|
||||
|
||||
-- =================== To help computation of Tolerance ===============
|
||||
GetAverageLaw(me : mutable;
|
||||
@@ -165,11 +183,13 @@ is
|
||||
is redefined;
|
||||
|
||||
fields
|
||||
frenet : Frenet from GeomFill;
|
||||
EvolAroundT : Function from Law;
|
||||
TLaw : Function from Law;
|
||||
AT, AN : Vec from gp;
|
||||
isFrenet : Boolean;
|
||||
frenet : Frenet from GeomFill;
|
||||
EvolAroundT : Function from Law;
|
||||
TLaw : Function from Law;
|
||||
AT, AN : Vec from gp;
|
||||
isFrenet : Boolean;
|
||||
myForEvaluation : Boolean;
|
||||
|
||||
---OCC78
|
||||
HArrPoles : HArray1OfReal from TColStd;
|
||||
HArrAngle : HArray1OfReal from TColStd;
|
||||
|
@@ -44,6 +44,7 @@
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <TColgp_HArray1OfPnt.hxx>
|
||||
|
||||
|
||||
#ifdef DEB
|
||||
static Standard_Boolean Affich=0;
|
||||
#endif
|
||||
@@ -90,6 +91,30 @@ static void draw(const Handle(Law_Function)& law)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static Standard_Real ComputeTorsion(const Standard_Real Param,
|
||||
const Handle(Adaptor3d_HCurve)& aCurve)
|
||||
{
|
||||
Standard_Real Torsion;
|
||||
|
||||
gp_Pnt aPoint;
|
||||
gp_Vec DC1, DC2, DC3;
|
||||
aCurve->D3(Param, aPoint, DC1, DC2, DC3);
|
||||
gp_Vec DC1crossDC2 = DC1 ^ DC2;
|
||||
Standard_Real Norm_DC1crossDC2 = DC1crossDC2.Magnitude();
|
||||
|
||||
Standard_Real DC1DC2DC3 = DC1crossDC2 * DC3 ; //mixed product
|
||||
|
||||
Standard_Real Tol = gp::Resolution();
|
||||
Standard_Real SquareNorm_DC1crossDC2 = Norm_DC1crossDC2 * Norm_DC1crossDC2;
|
||||
if (SquareNorm_DC1crossDC2 <= Tol)
|
||||
Torsion = 0.;
|
||||
else
|
||||
Torsion = DC1DC2DC3 / SquareNorm_DC1crossDC2 ;
|
||||
|
||||
return Torsion;
|
||||
}
|
||||
|
||||
//===============================================================
|
||||
// Function : smoothlaw
|
||||
// Purpose : to smooth a law : Reduce the number of knots
|
||||
@@ -280,13 +305,25 @@ static Standard_Boolean FindPlane ( const Handle(Adaptor3d_HCurve)& c,
|
||||
}
|
||||
|
||||
//===============================================================
|
||||
// Function :
|
||||
// Function : Constructor
|
||||
// Purpose :
|
||||
//===============================================================
|
||||
GeomFill_CorrectedFrenet::GeomFill_CorrectedFrenet()
|
||||
: isFrenet(Standard_False)
|
||||
{
|
||||
frenet = new GeomFill_Frenet();
|
||||
myForEvaluation = Standard_False;
|
||||
}
|
||||
|
||||
//===============================================================
|
||||
// Function : Constructor
|
||||
// Purpose :
|
||||
//===============================================================
|
||||
GeomFill_CorrectedFrenet::GeomFill_CorrectedFrenet(const Standard_Boolean ForEvaluation)
|
||||
: isFrenet(Standard_False)
|
||||
{
|
||||
frenet = new GeomFill_Frenet();
|
||||
myForEvaluation = ForEvaluation;
|
||||
}
|
||||
|
||||
Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
|
||||
@@ -314,6 +351,7 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
|
||||
{
|
||||
// No probleme isFrenet
|
||||
isFrenet = Standard_True;
|
||||
break;
|
||||
}
|
||||
default :
|
||||
{
|
||||
@@ -382,8 +420,12 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
|
||||
for(i = 1; i <= NbI; i++) {
|
||||
NbStep = Max(Standard_Integer((T(i+1) - T(i))/AvStep), 3);
|
||||
Step = (T(i+1) - T(i))/NbStep;
|
||||
if(!InitInterval(T(i), T(i+1), Step, StartAng, Tangent, Normal, AT, AN, Func, SeqPoles, SeqAngle, SeqTangent, SeqNormal))
|
||||
if(isFrenet) isFrenet = Standard_False;
|
||||
if(!InitInterval(T(i), T(i+1), Step, StartAng, Tangent, Normal, AT, AN, Func,
|
||||
SeqPoles, SeqAngle, SeqTangent, SeqNormal))
|
||||
{
|
||||
if(isFrenet)
|
||||
isFrenet = Standard_False;
|
||||
}
|
||||
Handle(Law_Composite)::DownCast(EvolAroundT)->ChangeLaws().Append(Func);
|
||||
}
|
||||
if(myTrimmed->IsPeriodic())
|
||||
@@ -402,7 +444,7 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
|
||||
HArrTangent->ChangeValue(i) = SeqTangent(i);
|
||||
HArrNormal->ChangeValue(i) = SeqNormal(i);
|
||||
};
|
||||
|
||||
|
||||
#if DRAW
|
||||
if (Affich) {
|
||||
draw(EvolAroundT);
|
||||
@@ -431,6 +473,7 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
|
||||
TColStd_SequenceOfReal EvolAT;
|
||||
Standard_Real Param = First, LengthMin, L, norm;
|
||||
Standard_Boolean isZero = Standard_True, isConst = Standard_True;
|
||||
const Standard_Real minnorm = 1.e-16;
|
||||
Standard_Integer i;
|
||||
gp_Pnt PonC;
|
||||
gp_Vec D1;
|
||||
@@ -446,7 +489,9 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
|
||||
Standard_Real angleAT, currParam, currStep = Step;
|
||||
|
||||
Handle( Geom_Plane ) aPlane;
|
||||
Standard_Boolean isPlanar = FindPlane( myCurve, aPlane );
|
||||
Standard_Boolean isPlanar = Standard_False;
|
||||
if (!myForEvaluation)
|
||||
isPlanar = FindPlane( myCurve, aPlane );
|
||||
|
||||
i = 1;
|
||||
currParam = Param;
|
||||
@@ -493,13 +538,21 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
|
||||
|
||||
//Evaluate the Next step
|
||||
CS.D1(Param, PonC, D1);
|
||||
L = Max(PonC.XYZ().Modulus()/2, LengthMin);
|
||||
|
||||
L = PonC.XYZ().Modulus()/2;
|
||||
norm = D1.Magnitude();
|
||||
if (norm < Precision::Confusion()) {
|
||||
norm = Precision::Confusion();
|
||||
if (norm <= gp::Resolution())
|
||||
{
|
||||
//norm = 2.*gp::Resolution();
|
||||
norm = minnorm;
|
||||
}
|
||||
currStep = L / norm;
|
||||
if (currStep > Step) currStep = Step;//default value
|
||||
if (currStep <= gp::Resolution()) //L = 0 => curvature = 0, linear segment
|
||||
currStep = Step;
|
||||
if (currStep < Precision::Confusion()) //too small step
|
||||
currStep = Precision::Confusion();
|
||||
if (currStep > Step) //too big step
|
||||
currStep = Step;//default value
|
||||
}
|
||||
else
|
||||
currStep /= 2; // Step too long !
|
||||
@@ -887,6 +940,59 @@ Standard_Real GeomFill_CorrectedFrenet::GetAngleAT(const Standard_Real Param) co
|
||||
Precision::PConfusion()/2);
|
||||
}
|
||||
|
||||
//===============================================================
|
||||
// Function : EvaluateBestMode
|
||||
// Purpose :
|
||||
//===============================================================
|
||||
GeomFill_Trihedron GeomFill_CorrectedFrenet::EvaluateBestMode()
|
||||
{
|
||||
if (EvolAroundT.IsNull())
|
||||
return GeomFill_IsFrenet; //Frenet
|
||||
|
||||
const Standard_Real MaxAngle = 3.*M_PI/4.;
|
||||
const Standard_Real MaxTorsion = 100.;
|
||||
|
||||
Standard_Real Step, u, v, tmin, tmax;
|
||||
Standard_Integer NbInt, i, j, k = 1;
|
||||
NbInt = EvolAroundT->NbIntervals(GeomAbs_CN);
|
||||
TColStd_Array1OfReal Int(1, NbInt+1);
|
||||
EvolAroundT->Intervals(Int, GeomAbs_CN);
|
||||
gp_Pnt2d old;
|
||||
gp_Vec2d aVec, PrevVec;
|
||||
|
||||
Standard_Integer NbSamples = 10;
|
||||
for(i = 1; i <= NbInt; i++){
|
||||
tmin = Int(i);
|
||||
tmax = Int(i+1);
|
||||
Standard_Real Torsion = ComputeTorsion(tmin, myTrimmed);
|
||||
if (Abs(Torsion) > MaxTorsion)
|
||||
return GeomFill_IsDiscreteTrihedron; //DiscreteTrihedron
|
||||
|
||||
Handle(Law_Function) trimmedlaw = EvolAroundT->Trim(tmin, tmax, Precision::PConfusion()/2);
|
||||
Step = (Int(i+1)-Int(i))/NbSamples;
|
||||
for (j = 0; j <= NbSamples; j++) {
|
||||
u = tmin + j*Step;
|
||||
v = trimmedlaw->Value(u);
|
||||
gp_Pnt2d point2d(u,v);
|
||||
if (j != 0)
|
||||
{
|
||||
aVec.SetXY(point2d.XY() - old.XY());
|
||||
if (k > 2)
|
||||
{
|
||||
Standard_Real theAngle = PrevVec.Angle(aVec);
|
||||
if (Abs(theAngle) > MaxAngle)
|
||||
return GeomFill_IsDiscreteTrihedron; //DiscreteTrihedron
|
||||
}
|
||||
PrevVec = aVec;
|
||||
}
|
||||
old = point2d;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
return GeomFill_IsCorrectedFrenet; //CorrectedFrenet
|
||||
}
|
||||
|
||||
//===============================================================
|
||||
// Function : GetAverageLaw
|
||||
// Purpose :
|
||||
|
154
src/GeomFill/GeomFill_DiscreteTrihedron.cdl
Normal file
154
src/GeomFill/GeomFill_DiscreteTrihedron.cdl
Normal file
@@ -0,0 +1,154 @@
|
||||
-- Created on: 2013-02-05
|
||||
-- Created by: Julia GERASIMOVA
|
||||
-- Copyright (c) 2001-2013 OPEN CASCADE SAS
|
||||
--
|
||||
-- The content of this file is subject to the Open CASCADE Technology Public
|
||||
-- License Version 6.5 (the "License"). You may not use the content of this file
|
||||
-- except in compliance with the License. Please obtain a copy of the License
|
||||
-- at http://www.opencascade.org and read it completely before using this file.
|
||||
--
|
||||
-- The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
||||
-- main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
||||
--
|
||||
-- The Original Code and all software distributed under the License is
|
||||
-- distributed on an "AS IS" basis, without warranty of any kind, and the
|
||||
-- Initial Developer hereby disclaims all such warranties, including without
|
||||
-- limitation, any warranties of merchantability, fitness for a particular
|
||||
-- purpose or non-infringement. Please see the License for the specific terms
|
||||
-- and conditions governing the rights and limitations under the License.
|
||||
|
||||
|
||||
class DiscreteTrihedron from GeomFill
|
||||
inherits TrihedronLaw from GeomFill
|
||||
|
||||
---Purpose: Defined Discrete Trihedron Law.
|
||||
-- The requirement for path curve is only G1.
|
||||
-- The result is C0-continuous surface
|
||||
-- that can be later approximated to C1.
|
||||
|
||||
uses
|
||||
HCurve from Adaptor3d,
|
||||
Shape from GeomAbs,
|
||||
Pnt from gp,
|
||||
Vec from gp,
|
||||
Array1OfReal from TColStd,
|
||||
Frenet from GeomFill,
|
||||
HSequenceOfAx2 from GeomFill,
|
||||
HSequenceOfReal from TColStd
|
||||
|
||||
raises
|
||||
OutOfRange, ConstructionError
|
||||
is
|
||||
|
||||
Create
|
||||
returns DiscreteTrihedron from GeomFill
|
||||
raises ConstructionError;
|
||||
|
||||
Copy(me)
|
||||
returns TrihedronLaw from GeomFill
|
||||
is redefined;
|
||||
|
||||
Init(me: mutable)
|
||||
is static;
|
||||
|
||||
SetCurve(me : mutable; C : HCurve from Adaptor3d)
|
||||
is redefined;
|
||||
|
||||
--
|
||||
--
|
||||
--========== To compute Location and derivatives Location
|
||||
--
|
||||
D0(me : mutable;
|
||||
Param: Real;
|
||||
Tangent : out Vec from gp;
|
||||
Normal : out Vec from gp;
|
||||
BiNormal : out Vec from gp)
|
||||
---Purpose: compute Trihedron on curve at parameter <Param>
|
||||
returns Boolean is redefined;
|
||||
|
||||
D1(me : mutable;
|
||||
Param: Real;
|
||||
Tangent : out Vec from gp;
|
||||
DTangent : out Vec from gp;
|
||||
Normal : out Vec from gp;
|
||||
DNormal : out Vec from gp;
|
||||
BiNormal : out Vec from gp;
|
||||
DBiNormal : out Vec from gp)
|
||||
---Purpose: compute Trihedron and derivative Trihedron on curve
|
||||
-- at parameter <Param>
|
||||
-- Warning : It used only for C1 or C2 aproximation
|
||||
-- For the moment it returns null values for DTangent, DNormal
|
||||
-- and DBiNormal.
|
||||
returns Boolean
|
||||
is redefined;
|
||||
|
||||
D2(me : mutable;
|
||||
Param: Real;
|
||||
Tangent : out Vec from gp;
|
||||
DTangent : out Vec from gp;
|
||||
D2Tangent : out Vec from gp;
|
||||
Normal : out Vec from gp;
|
||||
DNormal : out Vec from gp;
|
||||
D2Normal : out Vec from gp;
|
||||
BiNormal : out Vec from gp;
|
||||
DBiNormal : out Vec from gp;
|
||||
D2BiNormal : out Vec from gp)
|
||||
---Purpose: compute Trihedron on curve
|
||||
-- first and seconde derivatives.
|
||||
-- Warning : It used only for C2 aproximation
|
||||
-- For the moment it returns null values for DTangent, DNormal
|
||||
-- DBiNormal, D2Tangent, D2Normal, D2BiNormal.
|
||||
returns Boolean
|
||||
is redefined;
|
||||
--
|
||||
-- =================== Management of continuity ===================
|
||||
--
|
||||
NbIntervals(me; S : Shape from GeomAbs)
|
||||
---Purpose: Returns the number of intervals for continuity
|
||||
-- <S>.
|
||||
-- May be one if Continuity(me) >= <S>
|
||||
returns Integer is redefined;
|
||||
|
||||
Intervals(me; T : in out Array1OfReal from TColStd;
|
||||
S : Shape from GeomAbs)
|
||||
---Purpose: Stores in <T> the parameters bounding the intervals
|
||||
-- of continuity <S>.
|
||||
--
|
||||
-- The array must provide enough room to accomodate
|
||||
-- for the parameters. i.e. T.Length() > NbIntervals()
|
||||
raises
|
||||
OutOfRange from Standard
|
||||
is redefined;
|
||||
|
||||
|
||||
-- =================== To help computation of Tolerance ===============
|
||||
GetAverageLaw(me : mutable;
|
||||
ATangent : out Vec from gp;
|
||||
ANormal : out Vec from gp;
|
||||
ABiNormal : out Vec from gp)
|
||||
---Purpose: Get average value of Tangent(t) and Normal(t) it is usful to
|
||||
-- make fast approximation of rational surfaces.
|
||||
is redefined;
|
||||
|
||||
-- =================== To help Particular case ===============
|
||||
|
||||
IsConstant(me)
|
||||
---Purpose: Say if the law is Constant.
|
||||
returns Boolean
|
||||
is redefined;
|
||||
|
||||
IsOnlyBy3dCurve(me)
|
||||
---Purpose: Return True.
|
||||
returns Boolean
|
||||
is redefined;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
myPoint : Pnt from gp;
|
||||
myTrihedrons : HSequenceOfAx2 from GeomFill;
|
||||
myKnots : HSequenceOfReal from TColStd;
|
||||
myFrenet : Frenet from GeomFill;
|
||||
myUseFrenet : Boolean from Standard;
|
||||
|
||||
end DiscreteTrihedron;
|
392
src/GeomFill/GeomFill_DiscreteTrihedron.cxx
Normal file
392
src/GeomFill/GeomFill_DiscreteTrihedron.cxx
Normal file
@@ -0,0 +1,392 @@
|
||||
// Created on: 2013-02-05
|
||||
// Created by: Julia GERASIMOVA
|
||||
// Copyright (c) 2001-2013 OPEN CASCADE SAS
|
||||
//
|
||||
// The content of this file is subject to the Open CASCADE Technology Public
|
||||
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||
// except in compliance with the License. Please obtain a copy of the License
|
||||
// at http://www.opencascade.org and read it completely before using this file.
|
||||
//
|
||||
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
||||
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
||||
//
|
||||
// The Original Code and all software distributed under the License is
|
||||
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
||||
// Initial Developer hereby disclaims all such warranties, including without
|
||||
// limitation, any warranties of merchantability, fitness for a particular
|
||||
// purpose or non-infringement. Please see the License for the specific terms
|
||||
// and conditions governing the rights and limitations under the License.
|
||||
|
||||
|
||||
#include <GeomFill_DiscreteTrihedron.ixx>
|
||||
#include <GeomFill_DiscreteTrihedron.hxx>
|
||||
#include <GeomFill_Frenet.hxx>
|
||||
#include <GeomAbs_CurveType.hxx>
|
||||
#include <Adaptor3d_HCurve.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_HSequenceOfReal.hxx>
|
||||
#include <GeomFill_HSequenceOfAx2.hxx>
|
||||
|
||||
|
||||
static const Standard_Real TolConf = Precision::Confusion();
|
||||
|
||||
//=======================================================================
|
||||
//function : GeomFill_DiscreteTrihedron
|
||||
//purpose : Constructor
|
||||
//=======================================================================
|
||||
|
||||
GeomFill_DiscreteTrihedron::GeomFill_DiscreteTrihedron()
|
||||
{
|
||||
myFrenet = new GeomFill_Frenet();
|
||||
myKnots = new TColStd_HSequenceOfReal();
|
||||
myTrihedrons = new GeomFill_HSequenceOfAx2();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Copy
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(GeomFill_TrihedronLaw) GeomFill_DiscreteTrihedron::Copy() const
|
||||
{
|
||||
Handle(GeomFill_DiscreteTrihedron) copy = new (GeomFill_DiscreteTrihedron)();
|
||||
if (!myCurve.IsNull()) copy->SetCurve(myCurve);
|
||||
return copy;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void GeomFill_DiscreteTrihedron::SetCurve(const Handle(Adaptor3d_HCurve)& C)
|
||||
{
|
||||
GeomFill_TrihedronLaw::SetCurve(C);
|
||||
if (! C.IsNull()) {
|
||||
GeomAbs_CurveType type;
|
||||
type = C->GetType();
|
||||
switch (type) {
|
||||
case GeomAbs_Circle:
|
||||
case GeomAbs_Ellipse:
|
||||
case GeomAbs_Hyperbola:
|
||||
case GeomAbs_Parabola:
|
||||
case GeomAbs_Line:
|
||||
{
|
||||
// No probleme
|
||||
myUseFrenet = Standard_True;
|
||||
myFrenet->SetCurve(C);
|
||||
break;
|
||||
}
|
||||
default :
|
||||
{
|
||||
myUseFrenet = Standard_False;
|
||||
// We have to fill <myKnots> and <myTrihedrons>
|
||||
Init();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Init
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void GeomFill_DiscreteTrihedron::Init()
|
||||
{
|
||||
Standard_Integer NbIntervals = myTrimmed->NbIntervals(GeomAbs_CN);
|
||||
TColStd_Array1OfReal Knots(1, NbIntervals+1);
|
||||
myTrimmed->Intervals(Knots, GeomAbs_CN);
|
||||
|
||||
//Standard_Real Tol = Precision::Confusion();
|
||||
Standard_Integer NbSamples = 10;
|
||||
|
||||
Standard_Integer i, j;
|
||||
for (i = 1; i <= NbIntervals; i++)
|
||||
{
|
||||
Standard_Real delta = (Knots(i+1) - Knots(i))/NbSamples;
|
||||
for (j = 0; j < NbSamples; j++)
|
||||
{
|
||||
Standard_Real Param = Knots(i) + j*delta;
|
||||
myKnots->Append(Param);
|
||||
}
|
||||
}
|
||||
myKnots->Append(Knots(NbIntervals+1));
|
||||
|
||||
|
||||
gp_Pnt Origin(0.,0.,0.), Pnt, SubPnt;
|
||||
gp_Vec Tangent;
|
||||
gp_Dir TangDir;
|
||||
Standard_Real norm;
|
||||
for (i = 1; i <= myKnots->Length(); i++)
|
||||
{
|
||||
Standard_Real Param = myKnots->Value(i);
|
||||
myTrimmed->D1(Param, Pnt, Tangent);
|
||||
norm = Tangent.Magnitude();
|
||||
if (norm < TolConf)
|
||||
{
|
||||
Standard_Real subdelta = (myKnots->Value(i+1) - myKnots->Value(i))/NbSamples;
|
||||
if (subdelta < Precision::PConfusion())
|
||||
subdelta = myKnots->Value(i+1) - myKnots->Value(i);
|
||||
SubPnt = myTrimmed->Value(Param + subdelta);
|
||||
Tangent.SetXYZ(SubPnt.XYZ() - Pnt.XYZ());
|
||||
}
|
||||
//Tangent.Normalize();
|
||||
TangDir = Tangent; //normalize;
|
||||
Tangent = TangDir;
|
||||
if (i == 1) //first point
|
||||
{
|
||||
gp_Ax2 FirstAxis(Origin, TangDir);
|
||||
myTrihedrons->Append(FirstAxis);
|
||||
}
|
||||
else
|
||||
{
|
||||
gp_Ax2 LastAxis = myTrihedrons->Value(myTrihedrons->Length());
|
||||
gp_Vec LastTangent = LastAxis.Direction();
|
||||
gp_Vec AxisOfRotation = LastTangent ^ Tangent;
|
||||
if (AxisOfRotation.Magnitude() <= gp::Resolution()) //tangents are equal or opposite
|
||||
{
|
||||
Standard_Real ScalarProduct = LastTangent * Tangent;
|
||||
if (ScalarProduct > 0.) //tangents are equal
|
||||
myTrihedrons->Append(LastAxis);
|
||||
else //tangents are opposite
|
||||
{
|
||||
Standard_Real NewParam = (myKnots->Value(i-1) + myKnots->Value(i))/2.;
|
||||
if (NewParam - myKnots->Value(i-1) < gp::Resolution())
|
||||
Standard_ConstructionError::Raise("GeomFill_DiscreteTrihedron : impassable singularities on path curve");
|
||||
myKnots->InsertBefore(i, NewParam);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
else //good value of angle
|
||||
{
|
||||
Standard_Real theAngle = LastTangent.AngleWithRef(Tangent, AxisOfRotation);
|
||||
gp_Ax1 theAxisOfRotation(Origin, AxisOfRotation);
|
||||
gp_Ax2 NewAxis = LastAxis.Rotated(theAxisOfRotation, theAngle);
|
||||
NewAxis.SetDirection(TangDir); //to prevent accumulation of floating computations error
|
||||
myTrihedrons->Append(NewAxis);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : D0
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean GeomFill_DiscreteTrihedron::D0(const Standard_Real Param,
|
||||
gp_Vec& Tangent,
|
||||
gp_Vec& Normal,
|
||||
gp_Vec& BiNormal)
|
||||
{
|
||||
if (myUseFrenet)
|
||||
{
|
||||
myFrenet->D0(Param, Tangent, Normal, BiNormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Locate <Param> in the sequence <myKnots>
|
||||
Standard_Integer Index = -1;
|
||||
Standard_Real TolPar = Precision::PConfusion();
|
||||
//Standard_Real TolConf = Precision::Confusion();
|
||||
Standard_Integer NbSamples = 10;
|
||||
gp_Pnt Origin(0.,0.,0.);
|
||||
|
||||
Standard_Integer i;
|
||||
//gp_Ax2 PrevAxis;
|
||||
//Standard_Real PrevParam;
|
||||
|
||||
Standard_Integer I1, I2;
|
||||
I1 = 1;
|
||||
I2 = myKnots->Length();
|
||||
for (;;)
|
||||
{
|
||||
i = (I1 + I2)/2;
|
||||
if (Param <= myKnots->Value(i))
|
||||
I2 = i;
|
||||
else
|
||||
I1 = i;
|
||||
if (I2 - I1 <= 1)
|
||||
break;
|
||||
}
|
||||
Index = I1;
|
||||
if (Abs(Param - myKnots->Value(I2)) < TolPar)
|
||||
Index = I2;
|
||||
|
||||
Standard_Real PrevParam = myKnots->Value(Index);
|
||||
gp_Ax2 PrevAxis = myTrihedrons->Value(Index);
|
||||
gp_Ax2 theAxis;
|
||||
if (Abs(Param - PrevParam) < TolPar)
|
||||
theAxis = PrevAxis;
|
||||
else //<Param> is between knots
|
||||
{
|
||||
myTrimmed->D1(Param, myPoint, Tangent);
|
||||
Standard_Real norm = Tangent.Magnitude();
|
||||
if (norm < TolConf)
|
||||
{
|
||||
Standard_Real subdelta = (myKnots->Value(Index+1) - Param)/NbSamples;
|
||||
if (subdelta < Precision::PConfusion())
|
||||
subdelta = myKnots->Value(Index+1) - Param;
|
||||
gp_Pnt SubPnt = myTrimmed->Value(Param + subdelta);
|
||||
Tangent.SetXYZ(SubPnt.XYZ() - myPoint.XYZ());
|
||||
}
|
||||
//Tangent.Normalize();
|
||||
gp_Dir TangDir(Tangent); //normalize;
|
||||
Tangent = TangDir;
|
||||
gp_Vec PrevTangent = PrevAxis.Direction();
|
||||
gp_Vec AxisOfRotation = PrevTangent ^ Tangent;
|
||||
if (AxisOfRotation.Magnitude() <= gp::Resolution()) //tangents are equal
|
||||
{
|
||||
//we assume that tangents can not be opposite
|
||||
theAxis = PrevAxis;
|
||||
}
|
||||
else //good value of angle
|
||||
{
|
||||
Standard_Real theAngle = PrevTangent.AngleWithRef(Tangent, AxisOfRotation);
|
||||
gp_Ax1 theAxisOfRotation(Origin, AxisOfRotation);
|
||||
theAxis = PrevAxis.Rotated(theAxisOfRotation, theAngle);
|
||||
}
|
||||
theAxis.SetDirection(TangDir); //to prevent accumulation of floating computations error
|
||||
} //end of else (Param is between knots)
|
||||
|
||||
Tangent = theAxis.Direction();
|
||||
Normal = theAxis.XDirection();
|
||||
BiNormal = theAxis.YDirection();
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : D1
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean GeomFill_DiscreteTrihedron::D1(const Standard_Real Param,
|
||||
gp_Vec& Tangent,
|
||||
gp_Vec& DTangent,
|
||||
gp_Vec& Normal,
|
||||
gp_Vec& DNormal,
|
||||
gp_Vec& BiNormal,
|
||||
gp_Vec& DBiNormal)
|
||||
{
|
||||
if (myUseFrenet)
|
||||
{
|
||||
myFrenet->D1(Param, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
D0(Param, Tangent, Normal, BiNormal);
|
||||
|
||||
DTangent.SetCoord(0.,0.,0.);
|
||||
DNormal.SetCoord(0.,0.,0.);
|
||||
DBiNormal.SetCoord(0.,0.,0.);
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : D2
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean GeomFill_DiscreteTrihedron::D2(const Standard_Real Param,
|
||||
gp_Vec& Tangent,
|
||||
gp_Vec& DTangent,
|
||||
gp_Vec& D2Tangent,
|
||||
gp_Vec& Normal,
|
||||
gp_Vec& DNormal,
|
||||
gp_Vec& D2Normal,
|
||||
gp_Vec& BiNormal,
|
||||
gp_Vec& DBiNormal,
|
||||
gp_Vec& D2BiNormal)
|
||||
{
|
||||
if (myUseFrenet)
|
||||
{
|
||||
myFrenet->D2(Param, Tangent, DTangent, D2Tangent,
|
||||
Normal, DNormal, D2Normal,
|
||||
BiNormal, DBiNormal, D2BiNormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
D0(Param, Tangent, Normal, BiNormal);
|
||||
|
||||
DTangent.SetCoord(0.,0.,0.);
|
||||
DNormal.SetCoord(0.,0.,0.);
|
||||
DBiNormal.SetCoord(0.,0.,0.);
|
||||
D2Tangent.SetCoord(0.,0.,0.);
|
||||
D2Normal.SetCoord(0.,0.,0.);
|
||||
D2BiNormal.SetCoord(0.,0.,0.);
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : NbIntervals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer GeomFill_DiscreteTrihedron::NbIntervals(const GeomAbs_Shape S) const
|
||||
{
|
||||
return (myTrimmed->NbIntervals(GeomAbs_CN));
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Intervals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void GeomFill_DiscreteTrihedron::Intervals(TColStd_Array1OfReal& T,
|
||||
const GeomAbs_Shape S) const
|
||||
{
|
||||
myTrimmed->Intervals(T, GeomAbs_CN);
|
||||
}
|
||||
|
||||
void GeomFill_DiscreteTrihedron::GetAverageLaw(gp_Vec& ATangent,
|
||||
gp_Vec& ANormal,
|
||||
gp_Vec& ABiNormal)
|
||||
{
|
||||
Standard_Integer Num = 20; //order of digitalization
|
||||
gp_Vec T, N, BN;
|
||||
ATangent = gp_Vec(0, 0, 0);
|
||||
ANormal = gp_Vec(0, 0, 0);
|
||||
ABiNormal = gp_Vec(0, 0, 0);
|
||||
Standard_Real Step = (myTrimmed->LastParameter() -
|
||||
myTrimmed->FirstParameter()) / Num;
|
||||
Standard_Real Param;
|
||||
for (Standard_Integer i = 0; i <= Num; i++) {
|
||||
Param = myTrimmed->FirstParameter() + i*Step;
|
||||
if (Param > myTrimmed->LastParameter()) Param = myTrimmed->LastParameter();
|
||||
D0(Param, T, N, BN);
|
||||
ATangent += T;
|
||||
ANormal += N;
|
||||
ABiNormal += BN;
|
||||
}
|
||||
ATangent /= Num + 1;
|
||||
ANormal /= Num + 1;
|
||||
|
||||
ATangent.Normalize();
|
||||
ABiNormal = ATangent.Crossed(ANormal).Normalized();
|
||||
ANormal = ABiNormal.Crossed(ATangent);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsConstant
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean GeomFill_DiscreteTrihedron::IsConstant() const
|
||||
{
|
||||
return (myCurve->GetType() == GeomAbs_Line);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsOnlyBy3dCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean GeomFill_DiscreteTrihedron::IsOnlyBy3dCurve() const
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
@@ -141,7 +141,8 @@ is
|
||||
|
||||
DoSingular(me: mutable; U: Real; Index: Integer;
|
||||
Tangent, BiNormal: out Vec from gp;
|
||||
n, k, TFlag, BNFlag: out Integer)
|
||||
n, k, TFlag, BNFlag: out Integer;
|
||||
Delta: out Real)
|
||||
returns Boolean
|
||||
is private;
|
||||
|
||||
@@ -149,7 +150,8 @@ is
|
||||
Param: Real; Index: Integer;
|
||||
Tangent : out Vec from gp;
|
||||
Normal : out Vec from gp;
|
||||
BiNormal : out Vec from gp)
|
||||
BiNormal : out Vec from gp;
|
||||
Delta : out Real)
|
||||
---Purpose: computes Triedrhon on curve at parameter <Param>
|
||||
returns Boolean
|
||||
is private;
|
||||
@@ -161,7 +163,8 @@ is
|
||||
Normal : out Vec from gp;
|
||||
DNormal : out Vec from gp;
|
||||
BiNormal : out Vec from gp;
|
||||
DBiNormal : out Vec from gp)
|
||||
DBiNormal : out Vec from gp;
|
||||
Delta : out Real)
|
||||
---Purpose: computes Triedrhon and derivative Trihedron on curve
|
||||
-- at parameter <Param>
|
||||
-- Warning : It used only for C1 or C2 aproximation
|
||||
@@ -178,7 +181,8 @@ is
|
||||
D2Normal : out Vec from gp;
|
||||
BiNormal : out Vec from gp;
|
||||
DBiNormal : out Vec from gp;
|
||||
D2BiNormal : out Vec from gp)
|
||||
D2BiNormal : out Vec from gp;
|
||||
Delta : out Real)
|
||||
---Purpose: computes Trihedron on curve
|
||||
-- first and seconde derivatives.
|
||||
-- Warning : It used only for C2 aproximation
|
||||
|
@@ -326,11 +326,13 @@ Handle(GeomFill_TrihedronLaw) GeomFill_Frenet::Copy() const
|
||||
{
|
||||
Standard_Real norm;
|
||||
Standard_Integer Index;
|
||||
Standard_Real Delta = 0.;
|
||||
if(IsSingular(Param, Index))
|
||||
if (SingularD0(Param, Index, Tangent, Normal, BiNormal))
|
||||
if (SingularD0(Param, Index, Tangent, Normal, BiNormal, Delta))
|
||||
return Standard_True;
|
||||
|
||||
myTrimmed->D2(Param, P, Tangent, BiNormal);
|
||||
Standard_Real theParam = Param + Delta;
|
||||
myTrimmed->D2(theParam, P, Tangent, BiNormal);
|
||||
Tangent.Normalize();
|
||||
BiNormal = Tangent.Crossed(BiNormal);
|
||||
norm = BiNormal.Magnitude();
|
||||
@@ -360,13 +362,15 @@ Handle(GeomFill_TrihedronLaw) GeomFill_Frenet::Copy() const
|
||||
gp_Vec& DBiNormal)
|
||||
{
|
||||
Standard_Integer Index;
|
||||
Standard_Real Delta = 0.;
|
||||
if(IsSingular(Param, Index))
|
||||
if (SingularD1(Param, Index, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal))
|
||||
if (SingularD1(Param, Index, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal, Delta))
|
||||
return Standard_True;
|
||||
|
||||
// Standard_Real Norma;
|
||||
Standard_Real theParam = Param + Delta;
|
||||
gp_Vec DC1, DC2, DC3;
|
||||
myTrimmed->D3(Param, P, DC1, DC2, DC3);
|
||||
myTrimmed->D3(theParam, P, DC1, DC2, DC3);
|
||||
Tangent = DC1.Normalized();
|
||||
|
||||
//if (DC2.Magnitude() <= NullTol || Tangent.Crossed(DC2).Magnitude() <= NullTol) {
|
||||
@@ -412,16 +416,19 @@ Handle(GeomFill_TrihedronLaw) GeomFill_Frenet::Copy() const
|
||||
gp_Vec& D2BiNormal)
|
||||
{
|
||||
Standard_Integer Index;
|
||||
Standard_Real Delta = 0.;
|
||||
if(IsSingular(Param, Index))
|
||||
if(SingularD2(Param, Index, Tangent, DTangent, D2Tangent,
|
||||
Normal, DNormal, D2Normal,
|
||||
BiNormal, DBiNormal, D2BiNormal))
|
||||
BiNormal, DBiNormal, D2BiNormal,
|
||||
Delta))
|
||||
return Standard_True;
|
||||
|
||||
// Standard_Real Norma;
|
||||
Standard_Real theParam = Param + Delta;
|
||||
gp_Vec DC1, DC2, DC3, DC4;
|
||||
myTrimmed->D3(Param, P, DC1, DC2, DC3);
|
||||
DC4 = myTrimmed->DN(Param, 4);
|
||||
myTrimmed->D3(theParam, P, DC1, DC2, DC3);
|
||||
DC4 = myTrimmed->DN(theParam, 4);
|
||||
|
||||
Tangent = DC1.Normalized();
|
||||
|
||||
@@ -604,9 +611,11 @@ Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
|
||||
Standard_Integer& n,
|
||||
Standard_Integer& k,
|
||||
Standard_Integer& TFlag,
|
||||
Standard_Integer& BNFlag)
|
||||
Standard_Integer& BNFlag,
|
||||
Standard_Real& Delta)
|
||||
{
|
||||
Standard_Integer i, MaxN = 20;
|
||||
Delta = 0.;
|
||||
Standard_Real h;
|
||||
h = 2*mySnglLen->Value(Index);
|
||||
|
||||
@@ -615,7 +624,8 @@ Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
|
||||
TFlag = 1;
|
||||
BNFlag = 1;
|
||||
GetInterval(A, B);
|
||||
if (U >= (A + B)/2) h = -h;
|
||||
if (U >= (A + B)/2)
|
||||
h = -h;
|
||||
for(i = 1; i <= MaxN; i++) {
|
||||
Tangent = myTrimmed->DN(U, i);
|
||||
if(Tangent.Magnitude() > Precision::Confusion()) break;
|
||||
@@ -641,7 +651,12 @@ Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i > MaxN) return Standard_False;
|
||||
if (i > MaxN)
|
||||
{
|
||||
Delta = h;
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
BiNormal.Normalize();
|
||||
k = i;
|
||||
|
||||
@@ -657,11 +672,14 @@ Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
|
||||
const Standard_Integer Index,
|
||||
gp_Vec& Tangent,
|
||||
gp_Vec& Normal,
|
||||
gp_Vec& BiNormal)
|
||||
gp_Vec& BiNormal,
|
||||
Standard_Real& Delta)
|
||||
{
|
||||
Standard_Integer n, k, TFlag, BNFlag;
|
||||
if(!DoSingular(Param, Index, Tangent, BiNormal,
|
||||
n, k, TFlag, BNFlag)) return Standard_False;
|
||||
n, k, TFlag, BNFlag, Delta))
|
||||
return Standard_False;
|
||||
|
||||
Tangent *= TFlag;
|
||||
BiNormal *= BNFlag;
|
||||
Normal = BiNormal;
|
||||
@@ -674,10 +692,12 @@ Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
|
||||
const Standard_Integer Index,
|
||||
gp_Vec& Tangent,gp_Vec& DTangent,
|
||||
gp_Vec& Normal,gp_Vec& DNormal,
|
||||
gp_Vec& BiNormal,gp_Vec& DBiNormal)
|
||||
gp_Vec& BiNormal,gp_Vec& DBiNormal,
|
||||
Standard_Real& Delta)
|
||||
{
|
||||
Standard_Integer n, k, TFlag, BNFlag;
|
||||
if(!DoSingular(Param, Index, Tangent, BiNormal, n, k, TFlag, BNFlag)) return Standard_False;
|
||||
if(!DoSingular(Param, Index, Tangent, BiNormal, n, k, TFlag, BNFlag, Delta))
|
||||
return Standard_False;
|
||||
|
||||
gp_Vec F, DF, Dtmp;
|
||||
F = myTrimmed->DN(Param, n);
|
||||
@@ -715,10 +735,11 @@ Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
|
||||
gp_Vec& D2Normal,
|
||||
gp_Vec& BiNormal,
|
||||
gp_Vec& DBiNormal,
|
||||
gp_Vec& D2BiNormal)
|
||||
gp_Vec& D2BiNormal,
|
||||
Standard_Real& Delta)
|
||||
{
|
||||
Standard_Integer n, k, TFlag, BNFlag;
|
||||
if(!DoSingular(Param, Index, Tangent, BiNormal, n, k, TFlag, BNFlag))
|
||||
if(!DoSingular(Param, Index, Tangent, BiNormal, n, k, TFlag, BNFlag, Delta))
|
||||
return Standard_False;
|
||||
|
||||
gp_Vec F, DF, D2F, Dtmp1, Dtmp2;
|
||||
|
@@ -78,7 +78,12 @@ is
|
||||
-- beetween tangents on the section law and
|
||||
-- tangent of iso-v on approximed surface
|
||||
|
||||
|
||||
SetForceApproxC1(me : in out;
|
||||
ForceApproxC1 : Boolean from Standard);
|
||||
---Purpose: Set the flag that indicates attempt to approximate
|
||||
-- a C1-continuous surface if a swept surface proved
|
||||
-- to be C0.
|
||||
|
||||
ExchangeUV(me)
|
||||
---Purpose: returns true if sections are U-Iso
|
||||
-- This can be produce in some cases when <WithKpart> is True.
|
||||
@@ -184,8 +189,9 @@ fields
|
||||
First, Last : Real;
|
||||
SFirst, SLast: Real;
|
||||
Tol3d, BoundTol, Tol2d, TolAngular : Real;
|
||||
SError : Real;
|
||||
|
||||
SError : Real;
|
||||
myForceApproxC1 : Boolean;
|
||||
|
||||
myLoc : LocationLaw from GeomFill;
|
||||
mySec : SectionLaw from GeomFill;
|
||||
mySurface : Surface from Geom;
|
||||
|
@@ -68,6 +68,7 @@
|
||||
#include <Approx_SweepApproximation.hxx>
|
||||
#include <AdvApprox_PrefAndRec.hxx>
|
||||
#include <AdvApprox_ApproxAFunction.hxx>
|
||||
#include <GeomConvert_ApproxSurface.hxx>
|
||||
|
||||
#include <Precision.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
@@ -121,6 +122,7 @@ GeomFill_Sweep::GeomFill_Sweep(const Handle(GeomFill_LocationLaw)& Location,
|
||||
myLoc = Location;
|
||||
myKPart = WithKpart;
|
||||
SetTolerance(1.e-4);
|
||||
myForceApproxC1 = Standard_False;
|
||||
|
||||
myLoc->GetDomain(First, Last);
|
||||
SFirst = SLast = 30.081996;
|
||||
@@ -157,6 +159,18 @@ GeomFill_Sweep::GeomFill_Sweep(const Handle(GeomFill_LocationLaw)& Location,
|
||||
TolAngular = ToleranceAngular;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//Function : SetForceApproxC1
|
||||
//Purpose : Set the flag that indicates attempt to approximate
|
||||
// a C1-continuous surface if a swept surface proved
|
||||
// to be C0.
|
||||
//=======================================================================
|
||||
void GeomFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
|
||||
{
|
||||
myForceApproxC1 = ForceApproxC1;
|
||||
}
|
||||
|
||||
|
||||
//===============================================================
|
||||
// Function : ExchangeUV
|
||||
// Purpose :
|
||||
@@ -298,56 +312,101 @@ GeomFill_Sweep::GeomFill_Sweep(const Handle(GeomFill_LocationLaw)& Location,
|
||||
Approx.UDegree(), Approx.VDegree(),
|
||||
mySec->IsUPeriodic());
|
||||
SError = Approx. MaxErrorOnSurf();
|
||||
|
||||
if (myForceApproxC1 && !mySurface->IsCNv(1))
|
||||
{
|
||||
Standard_Real theTol = 1.e-4;
|
||||
GeomAbs_Shape theUCont = GeomAbs_C1, theVCont = GeomAbs_C1;
|
||||
Standard_Integer degU = 14, degV = 14;
|
||||
Standard_Integer nmax = 16;
|
||||
Standard_Integer thePrec = 1;
|
||||
|
||||
GeomConvert_ApproxSurface ConvertApprox(mySurface,theTol,theUCont,theVCont,
|
||||
degU,degV,nmax,thePrec);
|
||||
if (ConvertApprox.HasResult())
|
||||
{
|
||||
mySurface = ConvertApprox.Surface();
|
||||
myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2);
|
||||
CError = new (TColStd_HArray2OfReal) (1,2, 1,2);
|
||||
|
||||
const Handle(Geom_BSplineSurface)& BSplSurf =
|
||||
Handle(Geom_BSplineSurface)::DownCast(mySurface);
|
||||
|
||||
gp_Dir2d D(0., 1.);
|
||||
gp_Pnt2d P(BSplSurf->UKnot(1), 0);
|
||||
Handle(Geom2d_Line) LC1 = new (Geom2d_Line) (P, D);
|
||||
Handle(Geom2d_TrimmedCurve) TC1 =
|
||||
new (Geom2d_TrimmedCurve) (LC1, 0, BSplSurf->VKnot(BSplSurf->NbVKnots()));
|
||||
|
||||
myCurve2d->SetValue(1, TC1);
|
||||
CError->SetValue(1, 1, 0.);
|
||||
CError->SetValue(2, 1, 0.);
|
||||
|
||||
P.SetCoord(BSplSurf->UKnot(BSplSurf->NbUKnots()), 0);
|
||||
Handle(Geom2d_Line) LC2 = new (Geom2d_Line) (P, D);
|
||||
Handle(Geom2d_TrimmedCurve) TC2 =
|
||||
new (Geom2d_TrimmedCurve) (LC2, 0, BSplSurf->VKnot(BSplSurf->NbVKnots()));
|
||||
|
||||
myCurve2d->SetValue(myCurve2d->Length(), TC2);
|
||||
CError->SetValue(1, myCurve2d->Length(), 0.);
|
||||
CError->SetValue(2, myCurve2d->Length(), 0.);
|
||||
|
||||
SError = theTol;
|
||||
}
|
||||
} //if (!mySurface->IsCNv(1))
|
||||
|
||||
// Les Courbes 2d
|
||||
myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2+myLoc->TraceNumber());
|
||||
CError = new (TColStd_HArray2OfReal) (1,2, 1, 2+myLoc->TraceNumber());
|
||||
Standard_Integer kk,ii, ifin = 1, ideb;
|
||||
|
||||
if (myLoc->HasFirstRestriction()) {
|
||||
ideb = 1;
|
||||
}
|
||||
else {
|
||||
ideb = 2;
|
||||
}
|
||||
ifin += myLoc->TraceNumber();
|
||||
if (myLoc->HasLastRestriction()) ifin++;
|
||||
|
||||
for (ii=ideb, kk=1; ii<=ifin; ii++, kk++) {
|
||||
Handle(Geom2d_BSplineCurve) C
|
||||
= new (Geom2d_BSplineCurve) (Approx.Curve2dPoles(kk),
|
||||
Approx.Curves2dKnots(),
|
||||
Approx.Curves2dMults(),
|
||||
Approx.Curves2dDegree());
|
||||
myCurve2d->SetValue(ii, C);
|
||||
CError->SetValue(1, ii, Approx.Max2dError(kk));
|
||||
CError->SetValue(2, ii, Approx.Max2dError(kk));
|
||||
}
|
||||
|
||||
// Si les courbes de restriction, ne sont pas calcules, on prend
|
||||
// les iso Bords.
|
||||
if (! myLoc->HasFirstRestriction()) {
|
||||
gp_Dir2d D(0., 1.);
|
||||
gp_Pnt2d P(UKnots(UKnots.Lower()), 0);
|
||||
Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
|
||||
Handle(Geom2d_TrimmedCurve) TC = new (Geom2d_TrimmedCurve)
|
||||
(LC, First, Last);
|
||||
|
||||
myCurve2d->SetValue(1, TC);
|
||||
CError->SetValue(1, 1, 0.);
|
||||
CError->SetValue(2, 1, 0.);
|
||||
}
|
||||
|
||||
if (! myLoc->HasLastRestriction()) {
|
||||
gp_Dir2d D(0., 1.);
|
||||
gp_Pnt2d P(UKnots(UKnots.Upper()), 0);
|
||||
Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
|
||||
Handle(Geom2d_TrimmedCurve) TC =
|
||||
new (Geom2d_TrimmedCurve) (LC, First, Last);
|
||||
myCurve2d->SetValue(myCurve2d->Length(), TC);
|
||||
CError->SetValue(1, myCurve2d->Length(), 0.);
|
||||
CError->SetValue(2, myCurve2d->Length(), 0.);
|
||||
}
|
||||
if (myCurve2d.IsNull())
|
||||
{
|
||||
myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2+myLoc->TraceNumber());
|
||||
CError = new (TColStd_HArray2OfReal) (1,2, 1, 2+myLoc->TraceNumber());
|
||||
Standard_Integer kk,ii, ifin = 1, ideb;
|
||||
|
||||
if (myLoc->HasFirstRestriction()) {
|
||||
ideb = 1;
|
||||
}
|
||||
else {
|
||||
ideb = 2;
|
||||
}
|
||||
ifin += myLoc->TraceNumber();
|
||||
if (myLoc->HasLastRestriction()) ifin++;
|
||||
|
||||
for (ii=ideb, kk=1; ii<=ifin; ii++, kk++) {
|
||||
Handle(Geom2d_BSplineCurve) C
|
||||
= new (Geom2d_BSplineCurve) (Approx.Curve2dPoles(kk),
|
||||
Approx.Curves2dKnots(),
|
||||
Approx.Curves2dMults(),
|
||||
Approx.Curves2dDegree());
|
||||
myCurve2d->SetValue(ii, C);
|
||||
CError->SetValue(1, ii, Approx.Max2dError(kk));
|
||||
CError->SetValue(2, ii, Approx.Max2dError(kk));
|
||||
}
|
||||
|
||||
// Si les courbes de restriction, ne sont pas calcules, on prend
|
||||
// les iso Bords.
|
||||
if (! myLoc->HasFirstRestriction()) {
|
||||
gp_Dir2d D(0., 1.);
|
||||
gp_Pnt2d P(UKnots(UKnots.Lower()), 0);
|
||||
Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
|
||||
Handle(Geom2d_TrimmedCurve) TC = new (Geom2d_TrimmedCurve)
|
||||
(LC, First, Last);
|
||||
|
||||
myCurve2d->SetValue(1, TC);
|
||||
CError->SetValue(1, 1, 0.);
|
||||
CError->SetValue(2, 1, 0.);
|
||||
}
|
||||
|
||||
if (! myLoc->HasLastRestriction()) {
|
||||
gp_Dir2d D(0., 1.);
|
||||
gp_Pnt2d P(UKnots(UKnots.Upper()), 0);
|
||||
Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
|
||||
Handle(Geom2d_TrimmedCurve) TC =
|
||||
new (Geom2d_TrimmedCurve) (LC, First, Last);
|
||||
myCurve2d->SetValue(myCurve2d->Length(), TC);
|
||||
CError->SetValue(1, myCurve2d->Length(), 0.);
|
||||
CError->SetValue(2, myCurve2d->Length(), 0.);
|
||||
}
|
||||
} //if (myCurve2d.IsNull())
|
||||
}
|
||||
return Ok;
|
||||
}
|
||||
|
Reference in New Issue
Block a user