1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +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); BRepFill_Sweep Sweep(mySec, myLoc, Standard_True);
Sweep.SetTolerance(myTol); Sweep.SetTolerance(myTol);
Sweep.SetAngularControl(angmin, angmax); Sweep.SetAngularControl(angmin, angmax);
Sweep.Build(myStyle, GeomFill_Location, myCont); Sweep.Build(myStyle, myCont);
if (Sweep.IsDone()) { if (Sweep.IsDone()) {
myShape = Sweep.Shape(); myShape = Sweep.Shape();
myShell = TopoDS::Shell(myShape); myShell = TopoDS::Shell(myShape);

View File

@ -41,8 +41,8 @@ uses
Edge from TopoDS, Edge from TopoDS,
Vertex from TopoDS, Vertex from TopoDS,
Pnt from gp, Pnt from gp,
Trsf from gp Trsf from gp,
Trihedron from GeomFill
raises raises
DomainError from Standard, DomainError from Standard,
@ -57,6 +57,21 @@ is
GeneratePartCase : Boolean from Standard = Standard_False) GeneratePartCase : Boolean from Standard = Standard_False)
returns Pipe from BRepFill; 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; Perform (me : in out; Spine : Wire from TopoDS;
Profile : Shape from TopoDS; Profile : Shape from TopoDS;
GeneratePartCase : Boolean from Standard = Standard_False) GeneratePartCase : Boolean from Standard = Standard_False)
@ -175,4 +190,7 @@ fields
myDegmax : Integer from Standard; myDegmax : Integer from Standard;
mySegmax : Integer from Standard; mySegmax : Integer from Standard;
myMode : Trihedron from GeomFill;
myForceApproxC1 : Boolean from Standard;
end Pipe; end Pipe;

View File

@ -30,6 +30,8 @@
#include <BRepTools_Substitution.hxx> #include <BRepTools_Substitution.hxx>
#include <GeomFill_CorrectedFrenet.hxx> #include <GeomFill_CorrectedFrenet.hxx>
#include <GeomFill_Frenet.hxx>
#include <GeomFill_DiscreteTrihedron.hxx>
#include <GeomFill_CurveAndTrihedron.hxx> #include <GeomFill_CurveAndTrihedron.hxx>
#include <BRepFill_SectionPlacement.hxx> #include <BRepFill_SectionPlacement.hxx>
@ -70,6 +72,8 @@ BRepFill_Pipe::BRepFill_Pipe()
{ {
myDegmax = 10; myDegmax = 10;
mySegmax = 100; mySegmax = 100;
myMode = GeomFill_IsCorrectedFrenet;
myForceApproxC1 = Standard_False;
} }
@ -84,9 +88,39 @@ BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire& Spine,
{ {
myDegmax = 10; myDegmax = 10;
mySegmax = 100; mySegmax = 100;
myMode = GeomFill_IsCorrectedFrenet;
myForceApproxC1 = Standard_False;
Perform(Spine, Profile, KPart); 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; BRepTools_WireExplorer wexp;
TopoDS_Shape TheProf; TopoDS_Shape TheProf;
Handle(GeomFill_TrihedronLaw) TLaw;
Handle(GeomFill_CorrectedFrenet) TLaw = switch (myMode)
new (GeomFill_CorrectedFrenet) (); {
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 = Handle(GeomFill_CurveAndTrihedron) Loc =
new (GeomFill_CurveAndTrihedron) (TLaw); new (GeomFill_CurveAndTrihedron) (TLaw);
myLoc = new (BRepFill_Edge3DLaw) (mySpine, Loc); myLoc = new (BRepFill_Edge3DLaw) (mySpine, Loc);
@ -366,7 +410,8 @@ TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const
// Sweeping // Sweeping
BRepFill_Sweep MkSw(Section, myLoc, Standard_True); 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(); TopoDS_Shape aLocalShape = MkSw.Shape();
return TopoDS::Wire(aLocalShape); return TopoDS::Wire(aLocalShape);
// return TopoDS::Wire(MkSw.Shape()); // return TopoDS::Wire(MkSw.Shape());
@ -491,7 +536,8 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
Handle(BRepFill_ShapeLaw) Section = Handle(BRepFill_ShapeLaw) Section =
new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS)); new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS));
BRepFill_Sweep MkSw(Section, myLoc, Standard_True); 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(); result = MkSw.Shape();
} }
@ -501,7 +547,8 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
BRepFill_Sweep MkSw(Section, myLoc, Standard_True); BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
MkSw.SetBounds(TopoDS::Wire(TheFirst), MkSw.SetBounds(TopoDS::Wire(TheFirst),
TopoDS::Wire(TheLast)); 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(); result = MkSw.Shape();
// Labeling of elements // Labeling of elements

View File

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

View File

@ -52,6 +52,7 @@
#include <GeomFill_TrihedronLaw.hxx> #include <GeomFill_TrihedronLaw.hxx>
#include <GeomFill_CorrectedFrenet.hxx> #include <GeomFill_CorrectedFrenet.hxx>
#include <GeomFill_Frenet.hxx> #include <GeomFill_Frenet.hxx>
#include <GeomFill_DiscreteTrihedron.hxx>
#include <GeomFill_Fixed.hxx> #include <GeomFill_Fixed.hxx>
#include <GeomFill_ConstantBiNormal.hxx> #include <GeomFill_ConstantBiNormal.hxx>
#include <GeomFill_SectionLaw.hxx> #include <GeomFill_SectionLaw.hxx>
@ -211,6 +212,7 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
: mySpine(Spine), : mySpine(Spine),
myTrihedron(GeomFill_IsCorrectedFrenet), myTrihedron(GeomFill_IsCorrectedFrenet),
myTransition(BRepFill_Modified), myTransition(BRepFill_Modified),
myForceApproxC1(Standard_False),
myStatus(GeomFill_PipeOk) myStatus(GeomFill_PipeOk)
{ {
myLocation.Nullify(); myLocation.Nullify();
@ -247,6 +249,23 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
mySection.Nullify(); //It is required to relocalize sections. 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 //function : Set
//purpose : Define a law Constant //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. 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 //function : Add
//purpose : Add a Section //purpose : Add a Section
@ -629,9 +659,13 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
BRepFill_Sweep MkSw(mySection, myLocation, Standard_True); BRepFill_Sweep MkSw(mySection, myLocation, Standard_True);
MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular); MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular);
MkSw.SetAngularControl(angmin, angmax); MkSw.SetAngularControl(angmin, angmax);
MkSw.SetForceApproxC1(myForceApproxC1);
MkSw.SetBounds(TopoDS::Wire(myFirst), MkSw.SetBounds(TopoDS::Wire(myFirst),
TopoDS::Wire(myLast)); 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(); myStatus = myLocation->GetStatus();
Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk)); Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk));

View File

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

View File

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

View File

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

View File

@ -35,6 +35,7 @@ class MakePipe from BRepOffsetAPI inherits MakeSweep from BRepPrimAPI
-- with G1 continuous spines only. -- with G1 continuous spines only.
uses uses
Pipe from BRepFill, Pipe from BRepFill,
Trihedron from GeomFill,
Wire from TopoDS, Wire from TopoDS,
Shape from TopoDS, Shape from TopoDS,
Edge from TopoDS, Edge from TopoDS,
@ -58,6 +59,21 @@ is
-- composite solid. -- composite solid.
returns MakePipe from BRepOffsetAPI; 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 Pipe(me) returns Pipe from BRepFill
---C++: return const & ---C++: return const &

View File

@ -40,6 +40,32 @@ BRepOffsetAPI_MakePipe::BRepOffsetAPI_MakePipe(const TopoDS_Wire& Spine ,
Build(); 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 //function : Pipe
//purpose : //purpose :

View File

@ -73,6 +73,10 @@ is
-- to perform the sweeping -- to perform the sweeping
-- If IsFrenet is false, a corrected Frenet trihedron is used. -- 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); SetMode(me : in out; Axe : Ax2 from gp);
---Purpose: Sets a fixed trihedron to perform the sweeping ---Purpose: Sets a fixed trihedron to perform the sweeping
-- all sections will be parallel. -- all sections will be parallel.
@ -110,6 +114,7 @@ is
---Level: Public ---Level: Public
-- ================================= -- =================================
-- Methodes to define section(s) -- Methodes to define section(s)
-- ================================= -- =================================
@ -212,6 +217,12 @@ is
-- - boundary tolerance BoundTol -- - boundary tolerance BoundTol
-- - angular tolerance TolAngular. -- - 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; SetTransitionMode(me : in out;
Mode :TransitionMode from BRepBuilderAPI = BRepBuilderAPI_Transformed) Mode :TransitionMode from BRepBuilderAPI = BRepBuilderAPI_Transformed)
---Purpose: Sets the transition mode to manage discontinuities on ---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); myPipe->Set(IsFrenet);
} }
//=======================================================================
//function : SetDiscreteMode
//purpose :
//=======================================================================
void BRepOffsetAPI_MakePipeShell::SetDiscreteMode()
{
myPipe->SetDiscrete();
}
//======================================================================= //=======================================================================
//function : SetMode //function : SetMode
//purpose : //purpose :
@ -185,8 +194,9 @@ void BRepOffsetAPI_MakePipeShell::Delete( const TopoDS_Shape& Profile)
} }
return Status; return Status;
} }
//======================================================================= //=======================================================================
//function : SetTransitionMode //function : SetTolerance
//purpose : //purpose :
//======================================================================= //=======================================================================
void BRepOffsetAPI_MakePipeShell::SetTolerance(const Standard_Real Tol3d, 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); 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 //function : SetTransitionMode
//purpose : //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 << " -FR : Tangent and Normal are given by Frenet trihedron" <<"\n";
di << " -CF : Tangente is given by Frenet," << "\n"; di << " -CF : Tangente is given by Frenet," << "\n";
di << " the Normal is computed to minimize the torsion " << "\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 << " -DX Surf : Tangent and Normal are given by Darboux trihedron," <<"\n";
di << " Surf have to be a shell or a face" <<"\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"; 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")) { else if (!strcmp(a[1],"-CF")) {
Sweep->SetMode(Standard_False); Sweep->SetMode(Standard_False);
} }
else if (!strcmp(a[1],"-DT")) {
Sweep->SetDiscreteMode();
}
else if (!strcmp(a[1],"-DX")) { else if (!strcmp(a[1],"-DX")) {
if (n!=3) { if (n!=3) {
//cout << "bad arguments !" << endl; //cout << "bad arguments !" << endl;

View File

@ -67,7 +67,7 @@ is
enumeration Trihedron enumeration Trihedron
is IsCorrectedFrenet, IsFixed, IsFrenet, IsConstantNormal, IsDarboux, is IsCorrectedFrenet, IsFixed, IsFrenet, IsConstantNormal, IsDarboux,
IsGuideAC, IsGuidePlan, IsGuideAC, IsGuidePlan,
IsGuideACWithContact, IsGuidePlanWithContact end; IsGuideACWithContact, IsGuidePlanWithContact, IsDiscreteTrihedron end;
class Filling; class Filling;
---Purpose: Root class for Filling; ---Purpose: Root class for Filling;
@ -195,6 +195,13 @@ is
class SequenceOfTrsf class SequenceOfTrsf
instantiates Sequence from TCollection (Trsf from gp); 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 -- private classes
-- --
@ -226,6 +233,7 @@ is
class Fixed; class Fixed;
class Frenet; class Frenet;
class CorrectedFrenet; class CorrectedFrenet;
class DiscreteTrihedron;
class ConstantBiNormal; class ConstantBiNormal;
class Darboux; class Darboux;
class DraftTrihedron; class DraftTrihedron;

View File

@ -37,7 +37,8 @@ uses
HArray1OfReal from TColStd, HArray1OfReal from TColStd,
SequenceOfReal from TColStd, SequenceOfReal from TColStd,
HArray1OfVec from TColgp, HArray1OfVec from TColgp,
SequenceOfVec from TColgp SequenceOfVec from TColgp,
Trihedron from GeomFill
raises raises
OutOfRange, ConstructionError OutOfRange, ConstructionError
@ -45,11 +46,14 @@ is
Create returns CorrectedFrenet from GeomFill; Create returns CorrectedFrenet from GeomFill;
Create (ForEvaluation: Boolean)
returns CorrectedFrenet from GeomFill;
Copy(me) Copy(me)
returns TrihedronLaw from GeomFill returns TrihedronLaw from GeomFill
is redefined; is redefined;
Init(me: mutable) Init(me: mutable)
is static private; is static private;
InitInterval(me; First, Last, Step: Real; InitInterval(me; First, Last, Step: Real;
@ -59,7 +63,7 @@ is
SeqPoles: out SequenceOfReal from TColStd; SeqPoles: out SequenceOfReal from TColStd;
SeqAngle: out SequenceOfReal from TColStd; SeqAngle: out SequenceOfReal from TColStd;
SeqTangent: out SequenceOfVec from TColgp; SeqTangent: out SequenceOfVec from TColgp;
SeqNormal: out SequenceOfVec from TColgp) SeqNormal: out SequenceOfVec from TColgp)
returns Boolean returns Boolean
--- Purpose: Computes BSpline representation of Normal evolution at one --- Purpose: Computes BSpline representation of Normal evolution at one
--- interval of continuity of Frenet. Returns True if FuncInt = 0 --- interval of continuity of Frenet. Returns True if FuncInt = 0
@ -142,6 +146,20 @@ is
OutOfRange from Standard OutOfRange from Standard
is redefined; 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 =============== -- =================== To help computation of Tolerance ===============
GetAverageLaw(me : mutable; GetAverageLaw(me : mutable;
@ -165,11 +183,13 @@ is
is redefined; is redefined;
fields fields
frenet : Frenet from GeomFill; frenet : Frenet from GeomFill;
EvolAroundT : Function from Law; EvolAroundT : Function from Law;
TLaw : Function from Law; TLaw : Function from Law;
AT, AN : Vec from gp; AT, AN : Vec from gp;
isFrenet : Boolean; isFrenet : Boolean;
myForEvaluation : Boolean;
---OCC78 ---OCC78
HArrPoles : HArray1OfReal from TColStd; HArrPoles : HArray1OfReal from TColStd;
HArrAngle : HArray1OfReal from TColStd; HArrAngle : HArray1OfReal from TColStd;

View File

@ -44,6 +44,7 @@
#include <Geom_BSplineCurve.hxx> #include <Geom_BSplineCurve.hxx>
#include <TColgp_HArray1OfPnt.hxx> #include <TColgp_HArray1OfPnt.hxx>
#ifdef DEB #ifdef DEB
static Standard_Boolean Affich=0; static Standard_Boolean Affich=0;
#endif #endif
@ -90,6 +91,30 @@ static void draw(const Handle(Law_Function)& law)
} }
#endif #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 // Function : smoothlaw
// Purpose : to smooth a law : Reduce the number of knots // 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 : // Purpose :
//=============================================================== //===============================================================
GeomFill_CorrectedFrenet::GeomFill_CorrectedFrenet() GeomFill_CorrectedFrenet::GeomFill_CorrectedFrenet()
: isFrenet(Standard_False) : isFrenet(Standard_False)
{ {
frenet = new GeomFill_Frenet(); 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 Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
@ -314,6 +351,7 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
{ {
// No probleme isFrenet // No probleme isFrenet
isFrenet = Standard_True; isFrenet = Standard_True;
break;
} }
default : default :
{ {
@ -382,8 +420,12 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
for(i = 1; i <= NbI; i++) { for(i = 1; i <= NbI; i++) {
NbStep = Max(Standard_Integer((T(i+1) - T(i))/AvStep), 3); NbStep = Max(Standard_Integer((T(i+1) - T(i))/AvStep), 3);
Step = (T(i+1) - T(i))/NbStep; 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(!InitInterval(T(i), T(i+1), Step, StartAng, Tangent, Normal, AT, AN, Func,
if(isFrenet) isFrenet = Standard_False; SeqPoles, SeqAngle, SeqTangent, SeqNormal))
{
if(isFrenet)
isFrenet = Standard_False;
}
Handle(Law_Composite)::DownCast(EvolAroundT)->ChangeLaws().Append(Func); Handle(Law_Composite)::DownCast(EvolAroundT)->ChangeLaws().Append(Func);
} }
if(myTrimmed->IsPeriodic()) if(myTrimmed->IsPeriodic())
@ -402,7 +444,7 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
HArrTangent->ChangeValue(i) = SeqTangent(i); HArrTangent->ChangeValue(i) = SeqTangent(i);
HArrNormal->ChangeValue(i) = SeqNormal(i); HArrNormal->ChangeValue(i) = SeqNormal(i);
}; };
#if DRAW #if DRAW
if (Affich) { if (Affich) {
draw(EvolAroundT); draw(EvolAroundT);
@ -431,6 +473,7 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
TColStd_SequenceOfReal EvolAT; TColStd_SequenceOfReal EvolAT;
Standard_Real Param = First, LengthMin, L, norm; Standard_Real Param = First, LengthMin, L, norm;
Standard_Boolean isZero = Standard_True, isConst = Standard_True; Standard_Boolean isZero = Standard_True, isConst = Standard_True;
const Standard_Real minnorm = 1.e-16;
Standard_Integer i; Standard_Integer i;
gp_Pnt PonC; gp_Pnt PonC;
gp_Vec D1; gp_Vec D1;
@ -446,7 +489,9 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
Standard_Real angleAT, currParam, currStep = Step; Standard_Real angleAT, currParam, currStep = Step;
Handle( Geom_Plane ) aPlane; Handle( Geom_Plane ) aPlane;
Standard_Boolean isPlanar = FindPlane( myCurve, aPlane ); Standard_Boolean isPlanar = Standard_False;
if (!myForEvaluation)
isPlanar = FindPlane( myCurve, aPlane );
i = 1; i = 1;
currParam = Param; currParam = Param;
@ -493,13 +538,21 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
//Evaluate the Next step //Evaluate the Next step
CS.D1(Param, PonC, D1); CS.D1(Param, PonC, D1);
L = Max(PonC.XYZ().Modulus()/2, LengthMin);
L = PonC.XYZ().Modulus()/2;
norm = D1.Magnitude(); norm = D1.Magnitude();
if (norm < Precision::Confusion()) { if (norm <= gp::Resolution())
norm = Precision::Confusion(); {
//norm = 2.*gp::Resolution();
norm = minnorm;
} }
currStep = L / norm; 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 else
currStep /= 2; // Step too long ! currStep /= 2; // Step too long !
@ -887,6 +940,59 @@ Standard_Real GeomFill_CorrectedFrenet::GetAngleAT(const Standard_Real Param) co
Precision::PConfusion()/2); 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 // Function : GetAverageLaw
// Purpose : // 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; DoSingular(me: mutable; U: Real; Index: Integer;
Tangent, BiNormal: out Vec from gp; Tangent, BiNormal: out Vec from gp;
n, k, TFlag, BNFlag: out Integer) n, k, TFlag, BNFlag: out Integer;
Delta: out Real)
returns Boolean returns Boolean
is private; is private;
@ -149,7 +150,8 @@ is
Param: Real; Index: Integer; Param: Real; Index: Integer;
Tangent : out Vec from gp; Tangent : out Vec from gp;
Normal : 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> ---Purpose: computes Triedrhon on curve at parameter <Param>
returns Boolean returns Boolean
is private; is private;
@ -161,7 +163,8 @@ is
Normal : out Vec from gp; Normal : out Vec from gp;
DNormal : out Vec from gp; DNormal : out Vec from gp;
BiNormal : 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 ---Purpose: computes Triedrhon and derivative Trihedron on curve
-- at parameter <Param> -- at parameter <Param>
-- Warning : It used only for C1 or C2 aproximation -- Warning : It used only for C1 or C2 aproximation
@ -178,7 +181,8 @@ is
D2Normal : out Vec from gp; D2Normal : out Vec from gp;
BiNormal : out Vec from gp; BiNormal : out Vec from gp;
DBiNormal : 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 ---Purpose: computes Trihedron on curve
-- first and seconde derivatives. -- first and seconde derivatives.
-- Warning : It used only for C2 aproximation -- Warning : It used only for C2 aproximation

View File

@ -326,11 +326,13 @@ Handle(GeomFill_TrihedronLaw) GeomFill_Frenet::Copy() const
{ {
Standard_Real norm; Standard_Real norm;
Standard_Integer Index; Standard_Integer Index;
Standard_Real Delta = 0.;
if(IsSingular(Param, Index)) if(IsSingular(Param, Index))
if (SingularD0(Param, Index, Tangent, Normal, BiNormal)) if (SingularD0(Param, Index, Tangent, Normal, BiNormal, Delta))
return Standard_True; return Standard_True;
myTrimmed->D2(Param, P, Tangent, BiNormal); Standard_Real theParam = Param + Delta;
myTrimmed->D2(theParam, P, Tangent, BiNormal);
Tangent.Normalize(); Tangent.Normalize();
BiNormal = Tangent.Crossed(BiNormal); BiNormal = Tangent.Crossed(BiNormal);
norm = BiNormal.Magnitude(); norm = BiNormal.Magnitude();
@ -360,13 +362,15 @@ Handle(GeomFill_TrihedronLaw) GeomFill_Frenet::Copy() const
gp_Vec& DBiNormal) gp_Vec& DBiNormal)
{ {
Standard_Integer Index; Standard_Integer Index;
Standard_Real Delta = 0.;
if(IsSingular(Param, Index)) 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; return Standard_True;
// Standard_Real Norma; // Standard_Real Norma;
Standard_Real theParam = Param + Delta;
gp_Vec DC1, DC2, DC3; gp_Vec DC1, DC2, DC3;
myTrimmed->D3(Param, P, DC1, DC2, DC3); myTrimmed->D3(theParam, P, DC1, DC2, DC3);
Tangent = DC1.Normalized(); Tangent = DC1.Normalized();
//if (DC2.Magnitude() <= NullTol || Tangent.Crossed(DC2).Magnitude() <= NullTol) { //if (DC2.Magnitude() <= NullTol || Tangent.Crossed(DC2).Magnitude() <= NullTol) {
@ -412,16 +416,19 @@ Handle(GeomFill_TrihedronLaw) GeomFill_Frenet::Copy() const
gp_Vec& D2BiNormal) gp_Vec& D2BiNormal)
{ {
Standard_Integer Index; Standard_Integer Index;
Standard_Real Delta = 0.;
if(IsSingular(Param, Index)) if(IsSingular(Param, Index))
if(SingularD2(Param, Index, Tangent, DTangent, D2Tangent, if(SingularD2(Param, Index, Tangent, DTangent, D2Tangent,
Normal, DNormal, D2Normal, Normal, DNormal, D2Normal,
BiNormal, DBiNormal, D2BiNormal)) BiNormal, DBiNormal, D2BiNormal,
Delta))
return Standard_True; return Standard_True;
// Standard_Real Norma; // Standard_Real Norma;
Standard_Real theParam = Param + Delta;
gp_Vec DC1, DC2, DC3, DC4; gp_Vec DC1, DC2, DC3, DC4;
myTrimmed->D3(Param, P, DC1, DC2, DC3); myTrimmed->D3(theParam, P, DC1, DC2, DC3);
DC4 = myTrimmed->DN(Param, 4); DC4 = myTrimmed->DN(theParam, 4);
Tangent = DC1.Normalized(); Tangent = DC1.Normalized();
@ -604,9 +611,11 @@ Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
Standard_Integer& n, Standard_Integer& n,
Standard_Integer& k, Standard_Integer& k,
Standard_Integer& TFlag, Standard_Integer& TFlag,
Standard_Integer& BNFlag) Standard_Integer& BNFlag,
Standard_Real& Delta)
{ {
Standard_Integer i, MaxN = 20; Standard_Integer i, MaxN = 20;
Delta = 0.;
Standard_Real h; Standard_Real h;
h = 2*mySnglLen->Value(Index); h = 2*mySnglLen->Value(Index);
@ -615,7 +624,8 @@ Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
TFlag = 1; TFlag = 1;
BNFlag = 1; BNFlag = 1;
GetInterval(A, B); GetInterval(A, B);
if (U >= (A + B)/2) h = -h; if (U >= (A + B)/2)
h = -h;
for(i = 1; i <= MaxN; i++) { for(i = 1; i <= MaxN; i++) {
Tangent = myTrimmed->DN(U, i); Tangent = myTrimmed->DN(U, i);
if(Tangent.Magnitude() > Precision::Confusion()) break; if(Tangent.Magnitude() > Precision::Confusion()) break;
@ -641,7 +651,12 @@ Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
break; break;
} }
} }
if (i > MaxN) return Standard_False; if (i > MaxN)
{
Delta = h;
return Standard_False;
}
BiNormal.Normalize(); BiNormal.Normalize();
k = i; k = i;
@ -657,11 +672,14 @@ Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
const Standard_Integer Index, const Standard_Integer Index,
gp_Vec& Tangent, gp_Vec& Tangent,
gp_Vec& Normal, gp_Vec& Normal,
gp_Vec& BiNormal) gp_Vec& BiNormal,
Standard_Real& Delta)
{ {
Standard_Integer n, k, TFlag, BNFlag; Standard_Integer n, k, TFlag, BNFlag;
if(!DoSingular(Param, Index, Tangent, BiNormal, if(!DoSingular(Param, Index, Tangent, BiNormal,
n, k, TFlag, BNFlag)) return Standard_False; n, k, TFlag, BNFlag, Delta))
return Standard_False;
Tangent *= TFlag; Tangent *= TFlag;
BiNormal *= BNFlag; BiNormal *= BNFlag;
Normal = BiNormal; Normal = BiNormal;
@ -674,10 +692,12 @@ Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
const Standard_Integer Index, const Standard_Integer Index,
gp_Vec& Tangent,gp_Vec& DTangent, gp_Vec& Tangent,gp_Vec& DTangent,
gp_Vec& Normal,gp_Vec& DNormal, 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; 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; gp_Vec F, DF, Dtmp;
F = myTrimmed->DN(Param, n); F = myTrimmed->DN(Param, n);
@ -715,10 +735,11 @@ Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
gp_Vec& D2Normal, gp_Vec& D2Normal,
gp_Vec& BiNormal, gp_Vec& BiNormal,
gp_Vec& DBiNormal, gp_Vec& DBiNormal,
gp_Vec& D2BiNormal) gp_Vec& D2BiNormal,
Standard_Real& Delta)
{ {
Standard_Integer n, k, TFlag, BNFlag; 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; return Standard_False;
gp_Vec F, DF, D2F, Dtmp1, Dtmp2; gp_Vec F, DF, D2F, Dtmp1, Dtmp2;

View File

@ -78,7 +78,12 @@ is
-- beetween tangents on the section law and -- beetween tangents on the section law and
-- tangent of iso-v on approximed surface -- 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) ExchangeUV(me)
---Purpose: returns true if sections are U-Iso ---Purpose: returns true if sections are U-Iso
-- This can be produce in some cases when <WithKpart> is True. -- This can be produce in some cases when <WithKpart> is True.
@ -184,8 +189,9 @@ fields
First, Last : Real; First, Last : Real;
SFirst, SLast: Real; SFirst, SLast: Real;
Tol3d, BoundTol, Tol2d, TolAngular : Real; Tol3d, BoundTol, Tol2d, TolAngular : Real;
SError : Real; SError : Real;
myForceApproxC1 : Boolean;
myLoc : LocationLaw from GeomFill; myLoc : LocationLaw from GeomFill;
mySec : SectionLaw from GeomFill; mySec : SectionLaw from GeomFill;
mySurface : Surface from Geom; mySurface : Surface from Geom;

View File

@ -68,6 +68,7 @@
#include <Approx_SweepApproximation.hxx> #include <Approx_SweepApproximation.hxx>
#include <AdvApprox_PrefAndRec.hxx> #include <AdvApprox_PrefAndRec.hxx>
#include <AdvApprox_ApproxAFunction.hxx> #include <AdvApprox_ApproxAFunction.hxx>
#include <GeomConvert_ApproxSurface.hxx>
#include <Precision.hxx> #include <Precision.hxx>
#include <ElCLib.hxx> #include <ElCLib.hxx>
@ -121,6 +122,7 @@ GeomFill_Sweep::GeomFill_Sweep(const Handle(GeomFill_LocationLaw)& Location,
myLoc = Location; myLoc = Location;
myKPart = WithKpart; myKPart = WithKpart;
SetTolerance(1.e-4); SetTolerance(1.e-4);
myForceApproxC1 = Standard_False;
myLoc->GetDomain(First, Last); myLoc->GetDomain(First, Last);
SFirst = SLast = 30.081996; SFirst = SLast = 30.081996;
@ -157,6 +159,18 @@ GeomFill_Sweep::GeomFill_Sweep(const Handle(GeomFill_LocationLaw)& Location,
TolAngular = ToleranceAngular; 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 // Function : ExchangeUV
// Purpose : // Purpose :
@ -298,56 +312,101 @@ GeomFill_Sweep::GeomFill_Sweep(const Handle(GeomFill_LocationLaw)& Location,
Approx.UDegree(), Approx.VDegree(), Approx.UDegree(), Approx.VDegree(),
mySec->IsUPeriodic()); mySec->IsUPeriodic());
SError = Approx. MaxErrorOnSurf(); 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 // Les Courbes 2d
myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2+myLoc->TraceNumber()); if (myCurve2d.IsNull())
CError = new (TColStd_HArray2OfReal) (1,2, 1, 2+myLoc->TraceNumber()); {
Standard_Integer kk,ii, ifin = 1, ideb; myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2+myLoc->TraceNumber());
CError = new (TColStd_HArray2OfReal) (1,2, 1, 2+myLoc->TraceNumber());
if (myLoc->HasFirstRestriction()) { Standard_Integer kk,ii, ifin = 1, ideb;
ideb = 1;
} if (myLoc->HasFirstRestriction()) {
else { ideb = 1;
ideb = 2; }
} else {
ifin += myLoc->TraceNumber(); ideb = 2;
if (myLoc->HasLastRestriction()) ifin++; }
ifin += myLoc->TraceNumber();
for (ii=ideb, kk=1; ii<=ifin; ii++, kk++) { if (myLoc->HasLastRestriction()) ifin++;
Handle(Geom2d_BSplineCurve) C
= new (Geom2d_BSplineCurve) (Approx.Curve2dPoles(kk), for (ii=ideb, kk=1; ii<=ifin; ii++, kk++) {
Approx.Curves2dKnots(), Handle(Geom2d_BSplineCurve) C
Approx.Curves2dMults(), = new (Geom2d_BSplineCurve) (Approx.Curve2dPoles(kk),
Approx.Curves2dDegree()); Approx.Curves2dKnots(),
myCurve2d->SetValue(ii, C); Approx.Curves2dMults(),
CError->SetValue(1, ii, Approx.Max2dError(kk)); Approx.Curves2dDegree());
CError->SetValue(2, ii, Approx.Max2dError(kk)); 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()) { // Si les courbes de restriction, ne sont pas calcules, on prend
gp_Dir2d D(0., 1.); // les iso Bords.
gp_Pnt2d P(UKnots(UKnots.Lower()), 0); if (! myLoc->HasFirstRestriction()) {
Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D); gp_Dir2d D(0., 1.);
Handle(Geom2d_TrimmedCurve) TC = new (Geom2d_TrimmedCurve) gp_Pnt2d P(UKnots(UKnots.Lower()), 0);
(LC, First, Last); Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
Handle(Geom2d_TrimmedCurve) TC = new (Geom2d_TrimmedCurve)
myCurve2d->SetValue(1, TC); (LC, First, Last);
CError->SetValue(1, 1, 0.);
CError->SetValue(2, 1, 0.); 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); if (! myLoc->HasLastRestriction()) {
Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D); gp_Dir2d D(0., 1.);
Handle(Geom2d_TrimmedCurve) TC = gp_Pnt2d P(UKnots(UKnots.Upper()), 0);
new (Geom2d_TrimmedCurve) (LC, First, Last); Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
myCurve2d->SetValue(myCurve2d->Length(), TC); Handle(Geom2d_TrimmedCurve) TC =
CError->SetValue(1, myCurve2d->Length(), 0.); new (Geom2d_TrimmedCurve) (LC, First, Last);
CError->SetValue(2, myCurve2d->Length(), 0.); myCurve2d->SetValue(myCurve2d->Length(), TC);
} CError->SetValue(1, myCurve2d->Length(), 0.);
CError->SetValue(2, myCurve2d->Length(), 0.);
}
} //if (myCurve2d.IsNull())
} }
return Ok; 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