1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +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:
jgv 2013-03-22 17:10:51 +04:00
parent 26347898a8
commit a31abc03d7
26 changed files with 1226 additions and 105 deletions

View File

@ -525,7 +525,7 @@ static Standard_Boolean GoodOrientation(const Bnd_Box& B,
BRepFill_Sweep Sweep(mySec, myLoc, Standard_True);
Sweep.SetTolerance(myTol);
Sweep.SetAngularControl(angmin, angmax);
Sweep.Build(myStyle, GeomFill_Location, myCont);
Sweep.Build(myStyle, myCont);
if (Sweep.IsDone()) {
myShape = Sweep.Shape();
myShell = TopoDS::Shell(myShape);

View File

@ -41,8 +41,8 @@ uses
Edge from TopoDS,
Vertex from TopoDS,
Pnt from gp,
Trsf from gp
Trsf from gp,
Trihedron from GeomFill
raises
DomainError from Standard,
@ -57,6 +57,21 @@ is
GeneratePartCase : Boolean from Standard = Standard_False)
returns Pipe from BRepFill;
SetMode(me : in out;
aMode : Trihedron from GeomFill);
---Purpose: Set the mode of sweeping
-- It can be:
-- - Frenet
-- - Corrected Frenet
-- - Discrete Trihedron
-- By default the mode is Corrected Frenet
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.
Perform (me : in out; Spine : Wire from TopoDS;
Profile : Shape from TopoDS;
GeneratePartCase : Boolean from Standard = Standard_False)
@ -175,4 +190,7 @@ fields
myDegmax : Integer from Standard;
mySegmax : Integer from Standard;
myMode : Trihedron from GeomFill;
myForceApproxC1 : Boolean from Standard;
end Pipe;

View File

@ -30,6 +30,8 @@
#include <BRepTools_Substitution.hxx>
#include <GeomFill_CorrectedFrenet.hxx>
#include <GeomFill_Frenet.hxx>
#include <GeomFill_DiscreteTrihedron.hxx>
#include <GeomFill_CurveAndTrihedron.hxx>
#include <BRepFill_SectionPlacement.hxx>
@ -70,6 +72,8 @@ BRepFill_Pipe::BRepFill_Pipe()
{
myDegmax = 10;
mySegmax = 100;
myMode = GeomFill_IsCorrectedFrenet;
myForceApproxC1 = Standard_False;
}
@ -84,9 +88,39 @@ BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire& Spine,
{
myDegmax = 10;
mySegmax = 100;
myMode = GeomFill_IsCorrectedFrenet;
myForceApproxC1 = Standard_False;
Perform(Spine, Profile, KPart);
}
//=======================================================================
//function : SetMode
//purpose : Set the mode of sweeping
// It can be:
// - Frenet
// - Corrected Frenet
// - Discrete Trihedron
//=======================================================================
void BRepFill_Pipe::SetMode(const GeomFill_Trihedron aMode)
{
if (aMode == GeomFill_IsFrenet ||
aMode == GeomFill_IsCorrectedFrenet ||
aMode == GeomFill_IsDiscreteTrihedron)
myMode = aMode;
}
//=======================================================================
//function : SetForceApproxC1
//purpose : Set the flag that indicates attempt to approximate
// a C1-continuous surface if a swept surface proved
// to be C0.
//=======================================================================
void BRepFill_Pipe::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
{
myForceApproxC1 = ForceApproxC1;
}
//=======================================================================
@ -111,9 +145,19 @@ void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine,
BRepTools_WireExplorer wexp;
TopoDS_Shape TheProf;
Handle(GeomFill_CorrectedFrenet) TLaw =
new (GeomFill_CorrectedFrenet) ();
Handle(GeomFill_TrihedronLaw) TLaw;
switch (myMode)
{
case GeomFill_IsFrenet:
TLaw = new GeomFill_Frenet();
break;
case GeomFill_IsCorrectedFrenet:
TLaw = new GeomFill_CorrectedFrenet();
break;
case GeomFill_IsDiscreteTrihedron:
TLaw = new GeomFill_DiscreteTrihedron();
break;
}
Handle(GeomFill_CurveAndTrihedron) Loc =
new (GeomFill_CurveAndTrihedron) (TLaw);
myLoc = new (BRepFill_Edge3DLaw) (mySpine, Loc);
@ -366,7 +410,8 @@ TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const
// Sweeping
BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
MkSw.SetForceApproxC1(myForceApproxC1);
MkSw.Build( BRepFill_Modified, GeomAbs_C2, GeomFill_Location, myDegmax, mySegmax );
TopoDS_Shape aLocalShape = MkSw.Shape();
return TopoDS::Wire(aLocalShape);
// return TopoDS::Wire(MkSw.Shape());
@ -491,7 +536,8 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
Handle(BRepFill_ShapeLaw) Section =
new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS));
BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
MkSw.SetForceApproxC1(myForceApproxC1);
MkSw.Build( BRepFill_Modified, GeomAbs_C2, GeomFill_Location, myDegmax, mySegmax );
result = MkSw.Shape();
}
@ -501,7 +547,8 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
MkSw.SetBounds(TopoDS::Wire(TheFirst),
TopoDS::Wire(TheLast));
MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
MkSw.SetForceApproxC1(myForceApproxC1);
MkSw.Build( BRepFill_Modified, GeomAbs_C2, GeomFill_Location, myDegmax, mySegmax );
result = MkSw.Shape();
// Labeling of elements

View File

@ -66,6 +66,12 @@ is
---Level: Public
---See Also:GeomFill_IsCorrectedFrenet
SetDiscrete(me : mutable);
---Purpose: Set a Discrete trihedron
-- to perform the sweeping
---Level: Public
---See Also:GeomFill_IsDiscreteTrihedron
Set(me : mutable; Axe : Ax2 from gp);
---Purpose: Set an fixed trihedron to perform the sweeping
-- all sections will be parallel.
@ -106,6 +112,13 @@ is
---Level: Public
SetForceApproxC1(me : mutable;
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.
-- =================================
-- Methodes to define section(s)
-- =================================
@ -271,8 +284,9 @@ fields
myTol3d : Real;
myBoundTol : Real;
myTolAngular : Real;
myTolAngular : Real;
angmin, angmax : Real;
myForceApproxC1 : Boolean;
myLaw : Function from Law;
myLocation : LocationLaw from BRepFill;

View File

@ -52,6 +52,7 @@
#include <GeomFill_TrihedronLaw.hxx>
#include <GeomFill_CorrectedFrenet.hxx>
#include <GeomFill_Frenet.hxx>
#include <GeomFill_DiscreteTrihedron.hxx>
#include <GeomFill_Fixed.hxx>
#include <GeomFill_ConstantBiNormal.hxx>
#include <GeomFill_SectionLaw.hxx>
@ -211,6 +212,7 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
: mySpine(Spine),
myTrihedron(GeomFill_IsCorrectedFrenet),
myTransition(BRepFill_Modified),
myForceApproxC1(Standard_False),
myStatus(GeomFill_PipeOk)
{
myLocation.Nullify();
@ -247,6 +249,23 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
mySection.Nullify(); //It is required to relocalize sections.
}
//=======================================================================
//function : SetDiscrete
//purpose : Define a law of Discrete Trihedron
//=======================================================================
void BRepFill_PipeShell::SetDiscrete()
{
Handle(GeomFill_TrihedronLaw) TLaw;
myTrihedron = GeomFill_IsDiscreteTrihedron;
TLaw = new (GeomFill_DiscreteTrihedron) ();
Handle(GeomFill_CurveAndTrihedron) Loc =
new (GeomFill_CurveAndTrihedron) (TLaw);
myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
mySection.Nullify(); //It is required to relocalize sections.
}
//=======================================================================
//function : Set
//purpose : Define a law Constant
@ -384,6 +403,17 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
mySection.Nullify(); //It is required to relocalize the sections.
}
//=======================================================================
//function : SetForceApproxC1
//purpose : Set the flag that indicates attempt to approximate
// a C1-continuous surface if a swept surface proved
// to be C0.
//=======================================================================
void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
{
myForceApproxC1 = ForceApproxC1;
}
//=======================================================================
//function : Add
//purpose : Add a Section
@ -629,9 +659,13 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
BRepFill_Sweep MkSw(mySection, myLocation, Standard_True);
MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular);
MkSw.SetAngularControl(angmin, angmax);
MkSw.SetForceApproxC1(myForceApproxC1);
MkSw.SetBounds(TopoDS::Wire(myFirst),
TopoDS::Wire(myLast));
MkSw.Build(myTransition);
GeomAbs_Shape theContinuity = GeomAbs_C2;
if (myTrihedron == GeomFill_IsDiscreteTrihedron)
theContinuity = GeomAbs_C0;
MkSw.Build(myTransition, theContinuity);
myStatus = myLocation->GetStatus();
Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk));

View File

@ -80,10 +80,17 @@ is
-- Transition "Round" replace the Transition "Right"
is static;
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.
Build(me : in out;
Transition : TransitionStyle = BRepFill_Modified;
Approx : ApproxStyle = GeomFill_Location;
Continuity : Shape from GeomAbs = GeomAbs_C2;
Approx : ApproxStyle = GeomFill_Location;
Degmax : Integer = 11;
Segmax : Integer = 30);
@ -170,6 +177,7 @@ fields
myContinuity : Shape from GeomAbs;
myDegmax : Integer;
mySegmax : Integer;
myForceApproxC1 : Boolean;
myShape : Shape from TopoDS;
myLoc : LocationLaw from BRepFill;
mySec : SectionLaw from BRepFill;

View File

@ -1685,6 +1685,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
myContinuity = GeomAbs_C2;
myDegmax = 11;
mySegmax = 30;
myForceApproxC1 = Standard_False;
}
//=======================================================================
@ -1752,6 +1753,17 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
myAngMax = Min (MaxAngle, 6.28);
}
//=======================================================================
//function : SetForceApproxC1
//purpose : Set the flag that indicates attempt to approximate
// a C1-continuous surface if a swept surface proved
// to be C0.
//=======================================================================
void BRepFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
{
myForceApproxC1 = ForceApproxC1;
}
///=======================================================================
//function : CorrectApproxParameters
//purpose :
@ -1820,6 +1832,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
// Curve by iso value
GeomFill_Sweep Sweep(myLoc->Law(ipath), KPart);
Sweep.SetTolerance(myTol3d, myBoundTol, myTol2d, myTolAngular);
Sweep.SetForceApproxC1(myForceApproxC1);
Sweep.Build(mySec->Law(isec), myApproxStyle, myContinuity, myDegmax, mySegmax);
if (!Sweep.IsDone())
return Standard_False;
@ -1985,6 +1998,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
GeomFill_Sweep Sweep(myLoc->Law(IPath), KPart);
Sweep.SetTolerance(myTol3d, myBoundTol, myTol2d, myTolAngular);
Sweep.SetForceApproxC1(myForceApproxC1);
// Case of evolutionary section, definition of parametric correspondence
if (!constSection) {
@ -2491,13 +2505,13 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
//purpose : Construt the result of sweeping
//======================================================================
void BRepFill_Sweep::Build(const BRepFill_TransitionStyle Transition,
const GeomFill_ApproxStyle Approx,
const GeomAbs_Shape Continuity,
const GeomFill_ApproxStyle Approx,
const Standard_Integer Degmax,
const Standard_Integer Segmax)
{
myApproxStyle = Approx;
myContinuity = Continuity;
myApproxStyle = Approx;
myDegmax = Degmax;
mySegmax = Segmax;

View File

@ -28,7 +28,8 @@ uses
StdFail,
gp,
GeomAbs,
Geom,
Geom,
GeomFill,
Approx,
TopoDS,
TopTools,

View File

@ -35,6 +35,7 @@ class MakePipe from BRepOffsetAPI inherits MakeSweep from BRepPrimAPI
-- with G1 continuous spines only.
uses
Pipe from BRepFill,
Trihedron from GeomFill,
Wire from TopoDS,
Shape from TopoDS,
Edge from TopoDS,
@ -58,6 +59,21 @@ is
-- composite solid.
returns MakePipe from BRepOffsetAPI;
SetMode(me : in out;
aMode : Trihedron from GeomFill);
---Purpose: Set the mode of sweeping
-- It can be:
-- - Frenet
-- - Corrected Frenet
-- - Discrete Trihedron
-- By default the mode is Corrected Frenet
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.
Pipe(me) returns Pipe from BRepFill
---C++: return const &

View File

@ -40,6 +40,32 @@ BRepOffsetAPI_MakePipe::BRepOffsetAPI_MakePipe(const TopoDS_Wire& Spine ,
Build();
}
//=======================================================================
//function : SetMode
//purpose : Set the mode of sweeping
// It can be:
// - Frenet
// - Corrected Frenet
// - Discrete Trihedron
//=======================================================================
void BRepOffsetAPI_MakePipe::SetMode(const GeomFill_Trihedron aMode)
{
myPipe.SetMode(aMode);
}
//=======================================================================
//function : SetForceApproxC1
//purpose : Set the flag that indicates attempt to approximate
// a C1-continuous surface if a swept surface proved
// to be C0.
//=======================================================================
void BRepOffsetAPI_MakePipe::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
{
myPipe.SetForceApproxC1(ForceApproxC1);
}
//=======================================================================
//function : Pipe
//purpose :

View File

@ -73,6 +73,10 @@ is
-- to perform the sweeping
-- If IsFrenet is false, a corrected Frenet trihedron is used.
SetDiscreteMode(me : in out);
---Purpose: Sets a Discrete trihedron
-- to perform the sweeping
SetMode(me : in out; Axe : Ax2 from gp);
---Purpose: Sets a fixed trihedron to perform the sweeping
-- all sections will be parallel.
@ -110,6 +114,7 @@ is
---Level: Public
-- =================================
-- Methodes to define section(s)
-- =================================
@ -212,6 +217,12 @@ is
-- - boundary tolerance BoundTol
-- - angular tolerance TolAngular.
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.
SetTransitionMode(me : in out;
Mode :TransitionMode from BRepBuilderAPI = BRepBuilderAPI_Transformed)
---Purpose: Sets the transition mode to manage discontinuities on

View File

@ -49,6 +49,15 @@ BRepOffsetAPI_MakePipeShell::BRepOffsetAPI_MakePipeShell(const TopoDS_Wire& Spin
myPipe->Set(IsFrenet);
}
//=======================================================================
//function : SetDiscreteMode
//purpose :
//=======================================================================
void BRepOffsetAPI_MakePipeShell::SetDiscreteMode()
{
myPipe->SetDiscrete();
}
//=======================================================================
//function : SetMode
//purpose :
@ -185,8 +194,9 @@ void BRepOffsetAPI_MakePipeShell::Delete( const TopoDS_Shape& Profile)
}
return Status;
}
//=======================================================================
//function : SetTransitionMode
//function : SetTolerance
//purpose :
//=======================================================================
void BRepOffsetAPI_MakePipeShell::SetTolerance(const Standard_Real Tol3d,
@ -196,6 +206,17 @@ void BRepOffsetAPI_MakePipeShell::Delete( const TopoDS_Shape& Profile)
myPipe->SetTolerance(Tol3d, BoundTol, TolAngular);
}
//=======================================================================
//function : SetForceApproxC1
//purpose : Set the flag that indicates attempt to approximate
// a C1-continuous surface if a swept surface proved
// to be C0.
//=======================================================================
void BRepOffsetAPI_MakePipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
{
myPipe->SetForceApproxC1(ForceApproxC1);
}
//=======================================================================
//function : SetTransitionMode
//purpose :

View File

@ -431,6 +431,7 @@ static Standard_Integer setsweep(Draw_Interpretor& di,
di << " -FR : Tangent and Normal are given by Frenet trihedron" <<"\n";
di << " -CF : Tangente is given by Frenet," << "\n";
di << " the Normal is computed to minimize the torsion " << "\n";
di << " -DT : discrete trihedron" << "\n";
di << " -DX Surf : Tangent and Normal are given by Darboux trihedron," <<"\n";
di << " Surf have to be a shell or a face" <<"\n";
di << " -CN dx dy dz : BiNormal is given by dx dy dz" << "\n";
@ -450,6 +451,9 @@ static Standard_Integer setsweep(Draw_Interpretor& di,
else if (!strcmp(a[1],"-CF")) {
Sweep->SetMode(Standard_False);
}
else if (!strcmp(a[1],"-DT")) {
Sweep->SetDiscreteMode();
}
else if (!strcmp(a[1],"-DX")) {
if (n!=3) {
//cout << "bad arguments !" << endl;

View File

@ -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;

View File

@ -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;

View File

@ -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 :

View 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;

View 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;
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

33
tests/bugs/modalg_5/bug23824_1 Executable file
View File

@ -0,0 +1,33 @@
puts "============"
puts "OCC23824"
puts "============"
puts ""
#######################################################################
# Bad results of sweep operation when a path curve has unpredictable torsion along its way.
#######################################################################
set BugNumber OCC23824
restore [locate_data_file bug23824_AXE.brep] spine
restore [locate_data_file bug23824_profil.brep] profile
wire spine spine
mksweep spine
setsweep -DT
addsweep profile
buildsweep result
set square 516.633
set nb_v_good 8
set nb_e_good 10
set nb_w_good 3
set nb_f_good 3
set nb_sh_good 1
set nb_sol_good 0
set nb_compsol_good 0
set nb_compound_good 0
set nb_shape_good 25
set 2dviewer 1

34
tests/bugs/modalg_5/bug23824_2 Executable file
View File

@ -0,0 +1,34 @@
puts "============"
puts "OCC23824"
puts "============"
puts ""
#######################################################################
# Bad results of sweep operation when a path curve has unpredictable torsion along its way.
#######################################################################
set BugNumber OCC23824
restore [locate_data_file bug23824_Case1_Path.brep] spine
restore [locate_data_file bug23824_Case1_Profile.brep] profile
wire spine spine
wire profile profile
mksweep spine
setsweep -DT
addsweep profile
buildsweep result
set square 8997.97
set nb_v_good 2
set nb_e_good 3
set nb_w_good 1
set nb_f_good 1
set nb_sh_good 1
set nb_sol_good 0
set nb_compsol_good 0
set nb_compound_good 0
set nb_shape_good 8
set 2dviewer 1

35
tests/bugs/modalg_5/bug23824_3 Executable file
View File

@ -0,0 +1,35 @@
puts "============"
puts "OCC23824"
puts "============"
puts ""
#######################################################################
# Bad results of sweep operation when a path curve has unpredictable torsion along its way.
#######################################################################
set BugNumber OCC23824
restore [locate_data_file bug23824_Case2_Path.brep] spine
restore [locate_data_file bug23824_Case2_Profile.brep] profile
wire spine spine
wire profile profile
mksweep spine
setsweep -DT
addsweep profile
buildsweep result
set square 848.989
set nb_v_good 2
set nb_e_good 3
set nb_w_good 1
set nb_f_good 1
set nb_sh_good 1
set nb_sol_good 0
set nb_compsol_good 0
set nb_compound_good 0
set nb_shape_good 8
set 2dviewer 1

35
tests/bugs/modalg_5/bug23824_4 Executable file
View File

@ -0,0 +1,35 @@
puts "============"
puts "OCC23824"
puts "============"
puts ""
#######################################################################
# Bad results of sweep operation when a path curve has unpredictable torsion along its way.
#######################################################################
set BugNumber OCC23824
restore [locate_data_file bug23824_Case3_Path.brep] spine
restore [locate_data_file bug23824_Case3_Profile.brep] profile
wire profile profile
explode spine
wire spine spine_1
mksweep spine
setsweep -DT
addsweep profile
buildsweep result
set square 38260.5
set nb_v_good 2
set nb_e_good 3
set nb_w_good 1
set nb_f_good 1
set nb_sh_good 1
set nb_sol_good 0
set nb_compsol_good 0
set nb_compound_good 0
set nb_shape_good 8
set 2dviewer 1