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:
@@ -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.
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
Reference in New Issue
Block a user