1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0024305: New option in BRepOffsetAPI_MakePipeShell algorithm: the swept shell with varying width of section bounded by auxiliary spine

Test case for issue CR24305
This commit is contained in:
jgv
2013-11-14 12:37:05 +04:00
committed by bugmaster
parent 4058ef10a9
commit f9032cf2ee
12 changed files with 241 additions and 44 deletions

View File

@@ -72,6 +72,9 @@ is
enumeration TransitionStyle
is Modified, Right, Round end;
enumeration TypeOfContact
is NoContact, Contact, ContactOnBorder end;
-- private class FilledPair;
---Purpose: A pair of bound shapes with the result.

View File

@@ -41,8 +41,8 @@ uses
Section from BRepFill,
Sweep from BRepFill,
DataMapOfShapeListOfShape from TopTools,
SequenceOfSection from BRepFill
SequenceOfSection from BRepFill,
TypeOfContact from BRepFill
raises
DomainError from Standard,
@@ -96,7 +96,7 @@ is
Set(me : mutable;
AuxiliarySpine : Wire from TopoDS;
CurvilinearEquivalence : Boolean = Standard_True;
KeepContact : Boolean = Standard_False );
KeepContact : TypeOfContact from BRepFill = BRepFill_NoContact );
---Purpose: Set an auxiliary spine to define the Normal
-- For each Point of the Spine P, an Point Q is evalued
@@ -269,7 +269,7 @@ is
param : out Real from Standard) is private;
ResetLoc(me : mutable) is private;
BuildHistory(me: mutable; theSweep: Sweep from BRepFill)
is private;
@@ -289,6 +289,7 @@ fields
myForceApproxC1 : Boolean;
myLaw : Function from Law;
myIsAutomaticLaw : Boolean from Standard;
myLocation : LocationLaw from BRepFill;
mySection : SectionLaw from BRepFill;
myFaces : HArray2OfShape from TopTools;

View File

@@ -75,6 +75,14 @@
#include <BRepBuilderAPI_Copy.hxx>
#include <GProp_GProps.hxx>
#include <BRepGProp.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <IntCurveSurface_HInter.hxx>
#include <IntCurveSurface_IntersectionPoint.hxx>
#include <TColgp_HArray1OfPnt2d.hxx>
#include <Law_Interpol.hxx>
#ifdef DRAW
#include <Draw.hxx>
#include <DrawTrSurf.hxx>
@@ -211,7 +219,8 @@ static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
: mySpine(Spine),
myForceApproxC1(Standard_False),
myTrihedron(GeomFill_IsCorrectedFrenet),
myIsAutomaticLaw(Standard_False),
myTrihedron(GeomFill_IsCorrectedFrenet),
myTransition(BRepFill_Modified),
myStatus(GeomFill_PipeOk)
{
@@ -325,7 +334,7 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
//=======================================================================
void BRepFill_PipeShell::Set(const TopoDS_Wire& AuxiliarySpine,
const Standard_Boolean CurvilinearEquivalence,
const Standard_Boolean KeepContact)
const BRepFill_TypeOfContact KeepContact)
{
// Reorganization of the guide (pb of orientation and origin)
TopoDS_Wire TheGuide;
@@ -333,6 +342,9 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
Standard_Boolean SpClose = mySpine.Closed(),
GuideClose = AuxiliarySpine.Closed();
if (KeepContact == BRepFill_ContactOnBorder)
myIsAutomaticLaw = Standard_True;
if (!SpClose && !GuideClose) {
// Case open reorientation of the guide
TopoDS_Wire sp = mySpine;
@@ -377,7 +389,8 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
Guide->ChangeCurve().SetPeriodic(Standard_True);
if (CurvilinearEquivalence) { // trihedron by curvilinear reduced abscissa
if (KeepContact)
if (KeepContact == BRepFill_Contact ||
KeepContact == BRepFill_ContactOnBorder)
myTrihedron = GeomFill_IsGuideACWithContact; // with rotation
else
myTrihedron = GeomFill_IsGuideAC; // without rotation
@@ -389,7 +402,8 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
myLocation = new (BRepFill_ACRLaw) (mySpine, Loc);
}
else {// trihedron by plane
if (KeepContact)
if (KeepContact == BRepFill_Contact ||
KeepContact == BRepFill_ContactOnBorder)
myTrihedron = GeomFill_IsGuidePlanWithContact; // with rotation
else
myTrihedron = GeomFill_IsGuidePlan; // without rotation
@@ -438,10 +452,74 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
const Standard_Boolean WithCorrection)
{
Delete(Profile); // No duplication
BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
mySeq.Append(S);
mySection.Nullify();
ResetLoc();
if (myIsAutomaticLaw)
{
mySeq.Clear();
BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
S.Set(Standard_True);
mySeq.Append(S);
mySection.Nullify();
ResetLoc();
Handle(GeomFill_LocationGuide) Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(1));
Handle(TColgp_HArray1OfPnt2d) ParAndRad;
Loc->ComputeAutomaticLaw(ParAndRad);
//Compuite initial width of section (this will be 1.)
GProp_GProps GlobalProps;
BRepGProp::LinearProperties(Profile, GlobalProps);
gp_Pnt BaryCenter = GlobalProps.CentreOfMass();
TopoDS_Face ProfileFace = BRepLib_MakeFace(TopoDS::Wire(Profile), Standard_True); //only plane
Handle(Geom_Surface) thePlane = BRep_Tool::Surface(ProfileFace);
Handle(GeomAdaptor_HSurface) GAHplane = new GeomAdaptor_HSurface(thePlane);
IntCurveSurface_HInter Intersector;
Handle(Adaptor3d_HCurve) aHCurve [2];
aHCurve[0] = Loc->GetCurve();
aHCurve[1] = Loc->Guide();
gp_Pnt PointsOnSpines [2];
Standard_Integer i, j;
for (i = 0; i < 2; i++)
{
Intersector.Perform(aHCurve[i], GAHplane);
Standard_Real MinDist = RealLast();
for (j = 1; j <= Intersector.NbPoints(); j++)
{
gp_Pnt aPint = Intersector.Point(j).Pnt();
Standard_Real aDist = BaryCenter.Distance(aPint);
if (aDist < MinDist)
{
MinDist = aDist;
PointsOnSpines[i] = aPint;
}
}
}
//Correct <ParAndRad> according to <InitialWidth>
Standard_Real InitialWidth = PointsOnSpines[0].Distance(PointsOnSpines[1]);
Standard_Integer NbParRad = ParAndRad->Upper();
for (i = 1; i <= NbParRad; i++)
{
gp_Pnt2d aParRad = ParAndRad->Value(i);
aParRad.SetY( aParRad.Y() / InitialWidth );
ParAndRad->SetValue(i, aParRad);
}
myLaw = new Law_Interpol();
Standard_Boolean IsPeriodic =
(Abs(ParAndRad->Value(1).Y() - ParAndRad->Value(NbParRad).Y()) < Precision::Confusion());
(Handle(Law_Interpol)::DownCast(myLaw))->Set(ParAndRad->Array1(), IsPeriodic);
}
else
{
BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
mySeq.Append(S);
mySection.Nullify();
ResetLoc();
}
}
//=======================================================================