1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0030391: Improvement of the method BRepOffset_Tool::EnLargeFace

Add options to set the length of enlargement for each of 4 directions.
Add restriction of enlargement in the case of singularity on the surface.
This commit is contained in:
jgv
2018-09-03 12:14:47 +03:00
committed by msv
parent e2240d3a56
commit 09a61e33d8
2 changed files with 213 additions and 172 deletions

View File

@@ -2814,34 +2814,40 @@ static void MakeFace(const Handle(Geom_Surface)& S,
//purpose : //purpose :
//======================================================================= //=======================================================================
static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S, static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
Standard_Real& U1, Standard_Real& U1,
Standard_Real& U2, Standard_Real& U2,
Standard_Real& V1, Standard_Real& V1,
Standard_Real& V2, Standard_Real& V2,
Standard_Boolean& IsV1degen, Standard_Boolean& IsV1degen,
Standard_Boolean& IsV2degen, Standard_Boolean& IsV2degen,
const Standard_Real uf1, const Standard_Real uf1,
const Standard_Real uf2, const Standard_Real uf2,
const Standard_Real vf1, const Standard_Real vf1,
const Standard_Real vf2, const Standard_Real vf2,
const Standard_Boolean GlobalEnlargeU, const Standard_Real coeff,
const Standard_Boolean GlobalEnlargeVfirst, const Standard_Boolean theGlobalEnlargeU,
const Standard_Boolean GlobalEnlargeVlast) const Standard_Boolean theGlobalEnlargeVfirst,
const Standard_Boolean theGlobalEnlargeVlast,
const Standard_Real theLenBeforeUfirst,
const Standard_Real theLenAfterUlast,
const Standard_Real theLenBeforeVfirst,
const Standard_Real theLenAfterVlast)
{ {
const Standard_Real coeff = 1.;
const Standard_Real TolApex = 1.e-5; const Standard_Real TolApex = 1.e-5;
Standard_Boolean SurfaceChange = Standard_False; Standard_Boolean SurfaceChange = Standard_False;
if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
Handle(Geom_Surface) BS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface(); Handle(Geom_Surface) BS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen, EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen,
uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast); uf1,uf2,vf1,vf2,coeff,
if (!GlobalEnlargeVfirst) theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
if (!theGlobalEnlargeVfirst)
V1 = vf1; V1 = vf1;
if (!GlobalEnlargeVlast) if (!theGlobalEnlargeVlast)
V2 = vf2; V2 = vf2;
if (!GlobalEnlargeVfirst || !GlobalEnlargeVlast) if (!theGlobalEnlargeVfirst || !theGlobalEnlargeVlast)
//Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->SetTrim( U1, U2, V1, V2 ); //Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->SetTrim( U1, U2, V1, V2 );
S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 ); S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 );
else else
@@ -2851,155 +2857,178 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) { else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) {
Handle(Geom_Surface) Surf = Handle(Geom_OffsetSurface)::DownCast (S)->BasisSurface(); Handle(Geom_Surface) Surf = Handle(Geom_OffsetSurface)::DownCast (S)->BasisSurface();
SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen, SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen,
uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast); uf1,uf2,vf1,vf2,coeff,
theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf); Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
} }
else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) || else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution)) S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution))
{
Standard_Real du_first = 0., du_last = 0.,
dv_first = 0., dv_last = 0.;
Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
Standard_Real u1, u2, v1, v2;
Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
S->Bounds( u1, u2, v1, v2 );
if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
{ {
Standard_Real du=0., dv=0.; du_first = du_last = uf2-uf1;
Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2; u1 = uf1 - du_first;
Standard_Real u1, u2, v1, v2; u2 = uf2 + du_last;
Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True; enlargeU = Standard_False;
Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
S->Bounds( u1, u2, v1, v2 );
if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
{
du = uf2-uf1;
u1 = uf1-du;
u2 = uf2+du;
enlargeU = Standard_False;
}
else if (S->IsUClosed())
enlargeU = Standard_False;
else
{
viso = S->VIso( vf1 );
GeomAdaptor_Curve gac( viso );
du = GCPnts_AbscissaPoint::Length( gac ) * coeff;
uiso1 = S->UIso( uf1 );
uiso2 = S->UIso( uf2 );
if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
enlargeUfirst = Standard_False;
if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
enlargeUlast = Standard_False;
}
if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
{
dv = vf2-vf1;
v1 = vf1-dv;
v2 = vf2+dv;
enlargeV = Standard_False;
}
else if (S->IsVClosed())
enlargeV = Standard_False;
else
{
uiso = S->UIso( uf1 );
GeomAdaptor_Curve gac( uiso );
dv = GCPnts_AbscissaPoint::Length( gac ) * coeff;
viso1 = S->VIso( vf1 );
viso2 = S->VIso( vf2 );
if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
{
enlargeVfirst = Standard_False;
IsV1degen = Standard_True;
}
if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
{
enlargeVlast = Standard_False;
IsV2degen = Standard_True;
}
}
Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
if (enlargeU)
{
if (enlargeUfirst)
GeomLib::ExtendSurfByLength (aSurf, du, 1, Standard_True, Standard_False);
if (enlargeUlast)
GeomLib::ExtendSurfByLength (aSurf, du, 1, Standard_True, Standard_True);
}
if (enlargeV)
{
if (enlargeVfirst)
GeomLib::ExtendSurfByLength (aSurf, dv, 1, Standard_False, Standard_False);
if (enlargeVlast)
GeomLib::ExtendSurfByLength (aSurf, dv, 1, Standard_False, Standard_True);
}
S = aSurf;
S->Bounds( U1, U2, V1, V2 );
SurfaceChange = Standard_True;
} }
else if (S->IsUClosed())
enlargeU = Standard_False;
else
{
viso = S->VIso( vf1 );
GeomAdaptor_Curve gac( viso );
Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
du_last = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
uiso1 = S->UIso( uf1 );
uiso2 = S->UIso( uf2 );
if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
enlargeUfirst = Standard_False;
if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
enlargeUlast = Standard_False;
}
if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
{
dv_first = dv_last = vf2-vf1;
v1 = vf1 - dv_first;
v2 = vf2 + dv_last;
enlargeV = Standard_False;
}
else if (S->IsVClosed())
enlargeV = Standard_False;
else
{
uiso = S->UIso( uf1 );
GeomAdaptor_Curve gac( uiso );
Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
dv_last = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
viso1 = S->VIso( vf1 );
viso2 = S->VIso( vf2 );
if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
{
enlargeVfirst = Standard_False;
IsV1degen = Standard_True;
}
if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
{
enlargeVlast = Standard_False;
IsV2degen = Standard_True;
}
}
Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
if (enlargeU)
{
if (enlargeUfirst && du_first != 0.)
GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
if (enlargeUlast && du_last != 0.)
GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
}
if (enlargeV)
{
if (enlargeVfirst && dv_first != 0.)
GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
if (enlargeVlast && dv_last != 0.)
GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
}
S = aSurf;
S->Bounds( U1, U2, V1, V2 );
SurfaceChange = Standard_True;
}
else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) || else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface)) S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
{
Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
if (S->IsUClosed())
enlargeU = Standard_False;
if (S->IsVClosed())
enlargeV = Standard_False;
Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
Standard_Real u1, u2, v1, v2;
S->Bounds( u1, u2, v1, v2 );
Standard_Real du_first = 0., du_last = 0.,
dv_first = 0., dv_last = 0.;
Handle( Geom_Curve ) uiso1, uiso2, viso1, viso2;
Standard_Real gabarit_uiso1, gabarit_uiso2, gabarit_viso1, gabarit_viso2;
uiso1 = S->UIso( u1 );
uiso2 = S->UIso( u2 );
viso1 = S->VIso( v1 );
viso2 = S->VIso( v2 );
gabarit_uiso1 = BRepOffset_Tool::Gabarit( uiso1 );
gabarit_uiso2 = BRepOffset_Tool::Gabarit( uiso2 );
gabarit_viso1 = BRepOffset_Tool::Gabarit( viso1 );
gabarit_viso2 = BRepOffset_Tool::Gabarit( viso2 );
if (gabarit_viso1 <= TolApex ||
gabarit_viso2 <= TolApex)
enlargeU = Standard_False;
if (gabarit_uiso1 <= TolApex ||
gabarit_uiso2 <= TolApex)
enlargeV = Standard_False;
GeomAdaptor_Curve gac;
if (enlargeU)
{ {
Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True; gac.Load( viso1 );
Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU; Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast; du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
if (S->IsUClosed()) du_last = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
enlargeU = Standard_False; if (gabarit_uiso1 <= TolApex)
if (S->IsVClosed()) enlargeUfirst = Standard_False;
enlargeV = Standard_False; if (gabarit_uiso2 <= TolApex)
enlargeUlast = Standard_False;
Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
Standard_Real u1, u2, v1, v2;
S->Bounds( u1, u2, v1, v2 );
Standard_Real du=0., dv=0.;
Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
GeomAdaptor_Curve gac;
if (enlargeU)
{
viso = S->VIso( v1 );
gac.Load( viso );
du = GCPnts_AbscissaPoint::Length( gac ) * coeff;
uiso1 = S->UIso( u1 );
uiso2 = S->UIso( u2 );
if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
enlargeUfirst = Standard_False;
if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
enlargeUlast = Standard_False;
}
if (enlargeV)
{
uiso = S->UIso( u1 );
gac.Load( uiso );
dv = GCPnts_AbscissaPoint::Length( gac ) * coeff;
viso1 = S->VIso( v1 );
viso2 = S->VIso( v2 );
if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
{
enlargeVfirst = Standard_False;
IsV1degen = Standard_True;
}
if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
{
enlargeVlast = Standard_False;
IsV2degen = Standard_True;
}
}
Handle(Geom_BoundedSurface) aSurf = Handle(Geom_BoundedSurface)::DownCast (S);
if (enlargeU)
{
if (enlargeUfirst && uf1-u1 < duf)
GeomLib::ExtendSurfByLength (aSurf, du, 1, Standard_True, Standard_False);
if (enlargeUlast && u2-uf2 < duf)
GeomLib::ExtendSurfByLength (aSurf, du, 1, Standard_True, Standard_True);
}
if (enlargeV)
{
if (enlargeVfirst && vf1-v1 < dvf)
GeomLib::ExtendSurfByLength (aSurf, dv, 1, Standard_False, Standard_False);
if (enlargeVlast && v2-vf2 < dvf)
GeomLib::ExtendSurfByLength (aSurf, dv, 1, Standard_False, Standard_True);
}
S = aSurf;
S->Bounds( U1, U2, V1, V2 );
SurfaceChange = Standard_True;
} }
if (enlargeV)
{
gac.Load( uiso1 );
Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
dv_last = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
if (gabarit_viso1 <= TolApex)
{
enlargeVfirst = Standard_False;
IsV1degen = Standard_True;
}
if (gabarit_viso2 <= TolApex)
{
enlargeVlast = Standard_False;
IsV2degen = Standard_True;
}
}
Handle(Geom_BoundedSurface) aSurf = Handle(Geom_BoundedSurface)::DownCast (S);
if (enlargeU)
{
if (enlargeUfirst && uf1-u1 < duf && du_first != 0.)
GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
if (enlargeUlast && u2-uf2 < duf && du_last != 0.)
GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
}
if (enlargeV)
{
if (enlargeVfirst && vf1-v1 < dvf && dv_first != 0.)
GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
if (enlargeVlast && v2-vf2 < dvf && dv_last != 0.)
GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
}
S = aSurf;
S->Bounds( U1, U2, V1, V2 );
SurfaceChange = Standard_True;
}
// else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) || // else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
// S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface)) { // S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface)) {
// S->Bounds(U1,U2,V1,V2); // S->Bounds(U1,U2,V1,V2);
@@ -3244,10 +3273,14 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
TopoDS_Face& BF, TopoDS_Face& BF,
const Standard_Boolean CanExtentSurface, const Standard_Boolean CanExtentSurface,
const Standard_Boolean UpdatePCurve, const Standard_Boolean UpdatePCurve,
const Standard_Boolean enlargeU, const Standard_Boolean theEnlargeU,
const Standard_Boolean enlargeVfirst, const Standard_Boolean theEnlargeVfirst,
const Standard_Boolean enlargeVlast, const Standard_Boolean theEnlargeVlast,
const Standard_Boolean UseInfini) const Standard_Integer theExtensionMode,
const Standard_Real theLenBeforeUfirst,
const Standard_Real theLenAfterUlast,
const Standard_Real theLenBeforeVfirst,
const Standard_Real theLenAfterVlast)
{ {
//Detect closedness in U and V //Detect closedness in U and V
Standard_Boolean uclosed = Standard_False, vclosed = Standard_False; Standard_Boolean uclosed = Standard_False, vclosed = Standard_False;
@@ -3283,10 +3316,12 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
} }
S->Bounds (US1,US2,VS1,VS2); S->Bounds (US1,US2,VS1,VS2);
if (UseInfini) Standard_Real coeff;
if (theExtensionMode == 1)
{ {
UU1 = VV1 = - infini; UU1 = VV1 = - infini;
UU2 = VV2 = infini; UU2 = VV2 = infini;
coeff = 0.25;
} }
else else
{ {
@@ -3296,11 +3331,13 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
UU2 = UF2 + 10*FaceDU; UU2 = UF2 + 10*FaceDU;
VV1 = VF1 - 10*FaceDV; VV1 = VF1 - 10*FaceDV;
VV2 = VF2 + 10*FaceDV; VV2 = VF2 + 10*FaceDV;
coeff = 1.;
} }
if (CanExtentSurface) { if (CanExtentSurface) {
SurfaceChange = EnlargeGeometry( S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2, SurfaceChange = EnlargeGeometry(S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2, coeff,
enlargeU, enlargeVfirst, enlargeVlast ); theEnlargeU, theEnlargeVfirst, theEnlargeVlast,
theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
} }
else { else {
UU1 = Max(US1,UU1); UU2 = Min(UU2,US2); UU1 = Max(US1,UU1); UU2 = Min(UU2,US2);
@@ -3349,13 +3386,13 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
} }
} }
if (!enlargeU) if (!theEnlargeU)
{ {
UU1 = UF1; UU2 = UF2; UU1 = UF1; UU2 = UF2;
} }
if (!enlargeVfirst) if (!theEnlargeVfirst)
VV1 = VF1; VV1 = VF1;
if (!enlargeVlast) if (!theEnlargeVlast)
VV2 = VF2; VV2 = VF2;
MakeFace(S,UU1,UU2,VV1,VV2,uclosed,vclosed,isVV1degen,isVV2degen,BF); MakeFace(S,UU1,UU2,VV1,VV2,uclosed,vclosed,isVV1degen,isVV2degen,BF);

View File

@@ -112,10 +112,14 @@ public:
TopoDS_Face& NF, TopoDS_Face& NF,
const Standard_Boolean ChangeGeom, const Standard_Boolean ChangeGeom,
const Standard_Boolean UpDatePCurve = Standard_False, const Standard_Boolean UpDatePCurve = Standard_False,
const Standard_Boolean enlargeU = Standard_True, const Standard_Boolean theEnlargeU = Standard_True,
const Standard_Boolean enlargeVfirst = Standard_True, const Standard_Boolean theEnlargeVfirst = Standard_True,
const Standard_Boolean enlargeVlast = Standard_True, const Standard_Boolean theEnlargeVlast = Standard_True,
const Standard_Boolean UseInfini = Standard_True); const Standard_Integer theExtensionMode = 1,
const Standard_Real theLenBeforeUfirst = -1.,
const Standard_Real theLenAfterUlast = -1.,
const Standard_Real theLenBeforeVfirst = -1.,
const Standard_Real theLenAfterVlast = -1.);
Standard_EXPORT static void ExtentFace (const TopoDS_Face& F, TopTools_DataMapOfShapeShape& ConstShapes, TopTools_DataMapOfShapeShape& ToBuild, const TopAbs_State Side, const Standard_Real TolConf, TopoDS_Face& NF); Standard_EXPORT static void ExtentFace (const TopoDS_Face& F, TopTools_DataMapOfShapeShape& ConstShapes, TopTools_DataMapOfShapeShape& ToBuild, const TopAbs_State Side, const Standard_Real TolConf, TopoDS_Face& NF);