1
0
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:
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;