mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +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:
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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));
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user