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

Check of extension validity

This commit is contained in:
nbv
2018-01-24 11:15:36 +03:00
parent 3828af0c3b
commit 0273a8a01e
12 changed files with 256 additions and 62 deletions

View File

@@ -39,6 +39,7 @@
#include <BRepTools.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_BezierSurface.hxx>
#include <GeomLib.hxx>
#include <Bnd_Box2d.hxx>
#include <BndLib_Add2dCurve.hxx>
#include <BRepTopAdaptor_FClass2d.hxx>
@@ -47,6 +48,8 @@
#include <Geom_Plane.hxx>
#include <Extrema_ExtSS.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomAdaptor_HSurface.hxx>
//
static Standard_Boolean CanUseEdges(const Adaptor3d_Surface& BS);
//
@@ -587,33 +590,33 @@ void FindExactUVBounds(const TopoDS_Face FF,
Handle(Geom_Surface) aS = BRep_Tool::Surface(FF, aLoc);
Standard_Real aUmin, aUmax, aVmin, aVmax;
aS->Bounds(aUmin, aUmax, aVmin, aVmax);
if(!aS->IsUPeriodic111())
if (!GeomLib::AllowExtendUParameter(aBAS.Surface(), umin, umax))
{
umin = Max(aUmin, umin);
umax = Min(aUmax, umax);
}
else
{
if(umax - umin > aS->UPeriod())
const Standard_Real aDelta = (umax - umin - aBAS.UPeriod()) / 2.0;
if (aBAS.IsUPeriodic222() && (aDelta > 0.0))
{
Standard_Real delta = umax - umin - aS->UPeriod();
umin += delta/2.;
umax -= delta/2;
umin += aDelta;
umax -= aDelta;
}
}
//
if(!aS->IsVPeriodic111())
if (!GeomLib::AllowExtendVParameter(aBAS.Surface(), vmin, vmax))
{
vmin = Max(aVmin, vmin);
vmax = Min(aVmax, vmax);
}
else
{
if(vmax - vmin > aS->VPeriod())
const Standard_Real aDelta = (vmax - vmin - aS->VPeriod()) / 2.0;
if (aBAS.IsVPeriodic222() && (aDelta > 0.0))
{
Standard_Real delta = vmax - vmin - aS->VPeriod();
vmin += delta/2.;
vmax -= delta/2;
vmin += aDelta;
vmax -= aDelta;
}
}
}

View File

@@ -1283,17 +1283,21 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge,
Geom2dAdaptor_Curve& GAC2d = HC2d->ChangeCurve2d();
GeomAdaptor_Surface& GAS = HS->ChangeSurface();
if (!C3d->IsPeriodic111())
if (C3d->IsPeriodic111())
{
Standard_Real Udeb = C3d->FirstParameter();
Standard_Real Ufin = C3d->LastParameter();
// modified by NIZHNY-OCC486 Tue Aug 27 17:17:14 2002 :
//if (Udeb > f3d) f3d = Udeb;
//if (l3d > Ufin) l3d = Ufin;
if (Udeb > f3d) f3d = Udeb;
if (l3d > Ufin) l3d = Ufin;
// modified by NIZHNY-OCC486 Tue Aug 27 17:17:55 2002 .
// Range of the curve cannot be greater than period.
// If it is greater then it must be reduced.
const Standard_Real aDelta = Max(l3d - f3d - C3d->Period(), 0.0)/2.0;
f3d += aDelta;
l3d -= aDelta;
}
if (!GeomLib::AllowExtend(*C3d, f3d, l3d))
{
if (C3d->FirstParameter() > f3d) f3d = C3d->FirstParameter();
if (l3d > C3d->LastParameter()) l3d = C3d->LastParameter();
}
if(!L3d.IsIdentity()){
C3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(L3d.Transformation()));
}

View File

@@ -63,6 +63,7 @@
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <GeomLib.hxx>
#include <GeomLib_CheckCurveOnSurface.hxx>
#include <errno.h>
@@ -1020,12 +1021,32 @@ Standard_Real BRepTools::EvalAndUpdateTol(const TopoDS_Edge& theE,
//Set first, last to avoid ErrosStatus = 2 because of
//too strong checking of limits in class CheckCurveOnSurface
//
if(!C3d->IsPeriodic111())
if (C3d->IsPeriodic111())
{
// Range of the curve cannot be greater than period.
// If it is greater then it must be reduced.
const Standard_Real aDelta = Max(last - first - C3d->Period(), 0.0)/2.0;
first += aDelta;
last -= aDelta;
}
if (C2d->IsPeriodic111())
{
// Range of the curve cannot be greater than period.
// If it is greater then it must be reduced.
const Standard_Real aDelta = Max(last - first - C2d->Period(), 0.0)/2.0;
first += aDelta;
last -= aDelta;
}
if (!GeomLib::AllowExtend(*C3d, first, last))
{
first = Max(first, C3d->FirstParameter());
last = Min(last, C3d->LastParameter());
}
if(!C2d->IsPeriodic111())
if (!GeomLib::AllowExtend(*C2d, first, last))
{
first = Max(first, C2d->FirstParameter());
last = Min(last, C2d->LastParameter());

View File

@@ -50,6 +50,7 @@
#include <GeomAdaptor_HSurface.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomConvert.hxx>
#include <GeomLib.hxx>
#include <gp_GTrsf2d.hxx>
#include <gp_Pnt.hxx>
#include <gp_TrsfForm.hxx>
@@ -386,11 +387,13 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
C2d = TC->BasisCurve();
}
Standard_Real fc = C2d->FirstParameter(), lc = C2d->LastParameter();
const Standard_Real fc = C2d->FirstParameter(),
lc = C2d->LastParameter();
if(!C2d->IsPeriodic111()) {
if(fc - f2d > Precision::PConfusion()) f2d = fc;
if(l2d - lc > Precision::PConfusion()) l2d = lc;
if (!GeomLib::AllowExtend(*C2d, f2d, l2d))
{
if (fc - f2d > Precision::PConfusion()) f2d = fc;
if (l2d - lc > Precision::PConfusion()) l2d = lc;
}
C2d = new Geom2d_TrimmedCurve(C2d, f2d, l2d);

View File

@@ -175,21 +175,22 @@ Standard_Boolean BRepTools_TrsfModification::NewCurve2d
NewC = TC->BasisCurve();
}
Standard_Real fc = NewC->FirstParameter(), lc = NewC->LastParameter();
const Standard_Real fc = NewC->FirstParameter(), lc = NewC->LastParameter();
if (!GeomLib::AllowExtend(*NewC, f, l))
{
if (fc - f > Precision::PConfusion()) f = fc;
if (l - lc > Precision::PConfusion()) l = lc;
}
if(!NewC->IsPeriodic111()) {
if(fc - f > Precision::PConfusion()) f = fc;
if(l - lc > Precision::PConfusion()) l = lc;
if(Abs(l - f) < Precision::PConfusion())
if (!NewC->IsPeriodic111() && (Abs(l - f) < Precision::PConfusion()))
{
if (Abs(f - fc) < Precision::PConfusion())
{
if(Abs(f - fc) < Precision::PConfusion())
{
l = lc;
}
else
{
f = fc;
}
l = lc;
}
else
{
f = fc;
}
}

View File

@@ -617,8 +617,16 @@ void ChFi3d_BoundSrf(GeomAdaptor_Surface& S,
Standard_Real vv1 = vmin - Stepv;
Standard_Real vv2 = vmax + Stepv;
if(checknaturalbounds) {
if(!S.IsUPeriodic222()) {uu1 = Max(uu1,u1); uu2 = Min(uu2,u2);}
if(!S.IsVPeriodic222()) {vv1 = Max(vv1,v1); vv2 = Min(vv2,v2);}
if (!GeomLib::AllowExtendUParameter(S, uu1, uu2))
{
uu1 = Max(uu1,u1);
uu2 = Min(uu2,u2);
}
if (!GeomLib::AllowExtendVParameter(S, vv1, vv2))
{
vv1 = Max(vv1, v1);
vv2 = Min(vv2, v2);
}
}
S.Load(surface,uu1,uu2,vv1,vv2);
}

View File

@@ -37,6 +37,7 @@
#include <Geom2dConvert_ApproxCurve.hxx>
#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
#include <GeomAbs_Shape.hxx>
#include <GeomLib.hxx>
#include <gp.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
@@ -207,13 +208,17 @@ const Convert_ParameterisationType Parameterisation)
// Si la courbe n'est pas vraiment restreinte, on ne risque pas
// le Raise dans le BS->Segment.
if (!Curv->IsPeriodic111()) {
// Attention while processing case like:
// 1. Curv is a circle with range [0, 2PI], U1 = 3PI/2, U2=5PI/2.
// 2. Curv is a circle with range [0, 2PI], U1 = 7PI/2, U2=4PI.
if (!GeomLib::AllowExtend(*Curv, U1, U2))
{
if (U1 < Curv->FirstParameter())
U1 = Curv->FirstParameter();
U1 = Curv->FirstParameter();
if (U2 > Curv->LastParameter())
U2 = Curv->LastParameter();
}
U2 = Curv->LastParameter();
}
if (Curv->IsKind(STANDARD_TYPE(Geom2d_Line))) {
gp_Pnt2d Pdeb = Ctrim->StartPoint();
gp_Pnt2d Pfin = Ctrim->EndPoint();

View File

@@ -41,6 +41,7 @@
#include <GeomConvert.hxx>
#include <GeomConvert_ApproxCurve.hxx>
#include <GeomConvert_CompCurveToBSplineCurve.hxx>
#include <GeomLib.hxx>
#include <GeomLProp.hxx>
#include <gp.hxx>
#include <gp_Ax3.hxx>
@@ -194,11 +195,15 @@ Handle(Geom_BSplineCurve) GeomConvert::CurveToBSplineCurve
// Si la courbe n'est pas vraiment restreinte, on ne risque pas
// le Raise dans le BS->Segment.
if (!Curv->IsPeriodic111()) {
// Attention while processing case like:
// 1. Curv is a circle with range [0, 2PI], U1 = 3PI/2, U2=5PI/2.
// 2. Curv is a circle with range [0, 2PI], U1 = 7PI/2, U2=4PI.
if (!GeomLib::AllowExtend(*Curv, U1, U2))
{
if (U1 < Curv->FirstParameter())
U1 = Curv->FirstParameter();
U1 = Curv->FirstParameter();
if (U2 > Curv->LastParameter())
U2 = Curv->LastParameter();
U2 = Curv->LastParameter();
}
if (Curv->IsKind(STANDARD_TYPE(Geom_Line))) {

View File

@@ -53,6 +53,7 @@
#include <CSLib.hxx>
#include <CSLib_NormalStatus.hxx>
#include <ElCLib.hxx>
#include <Extrema_ECC.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_Circle.hxx>
@@ -79,11 +80,13 @@
#include <Geom_Hyperbola.hxx>
#include <Geom_Line.hxx>
#include <Geom_OffsetCurve.hxx>
#include <Geom_OffsetSurface.hxx>
#include <Geom_Parabola.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomConvert.hxx>
@@ -2744,12 +2747,99 @@ Standard_Boolean GeomLib::IsBzVClosed (const Handle(Geom_BezierSurface)& S,
return CompareWeightPoles(aPF, 0, aPL, 0, Tol2);
}
//=======================================================================
//function : AllowExtendUParameter
//purpose :
//=======================================================================
Standard_Boolean GeomLib::AllowExtendUParameter(const GeomAdaptor_Surface& theS,
const Standard_Real theNewUFirst,
const Standard_Real theNewULast)
{
const Handle(Geom_Surface) &aSurf = theS.Surface();
const Handle(Geom_Curve) aC = aSurf->VIso(theS.FirstVParameter());
return (AllowExtend(*aC, theNewUFirst, theNewULast));
}
//=======================================================================
//function : AllowExtendVParameter
//purpose :
//=======================================================================
Standard_Boolean GeomLib::AllowExtendVParameter(const GeomAdaptor_Surface& theS,
const Standard_Real theNewVFirst,
const Standard_Real theNewVLast)
{
const GeomAbs_SurfaceType aSType = theS.GetType();
const Handle(Geom_Surface) &aSurf = theS.Surface();
if (aSType == GeomAbs_OffsetSurface)
{
const Handle(Geom_OffsetSurface) aOS = Handle(Geom_OffsetSurface)::DownCast(aSurf);
return AllowExtendVParameter(GeomAdaptor_Surface(aOS->BasisSurface()),
theNewVFirst, theNewVLast);
}
const Handle(Geom_Curve) aC = aSurf->UIso(theS.FirstUParameter());
if (!AllowExtend(*aC, theNewVFirst, theNewVLast))
return Standard_False;
switch (aSType)
{
case GeomAbs_OtherSurface:
return Standard_True;
case GeomAbs_Sphere:
{
if ((theNewVFirst < -M_PI_2) || (theNewVLast > M_PI_2))
{
// After extending, the surface isoline will go
// through the sphere pole
return Standard_False;
}
break;
}
case GeomAbs_SurfaceOfRevolution:
{
const Handle(Adaptor3d_HCurve) aCurv = theS.BasisCurve();
const Handle(Geom_Line) aL = new Geom_Line(theS.AxeOfRevolution());
const GeomAdaptor_Curve aLin(aL);
Extrema_ECC anExtr(aCurv->Curve(), aLin);
anExtr.Perform();
if (anExtr.IsDone() && anExtr.NbExt() > 0)
{
const Standard_Real aParF = theNewVFirst - Precision::PConfusion(),
aParL = theNewVLast + Precision::PConfusion();
Extrema_POnCurv aP1, aP2;
for (Standard_Integer i = 1; i <= anExtr.NbExt(); i++)
{
if (anExtr.SquareDistance(i) > Precision::SquareConfusion())
continue;
anExtr.Points(i, aP1, aP2);
if ((aParF < aP1.Parameter()) && (aP1.Parameter() < aParL))
{
// After extending, the surface isoline will go
// through the pole (singular point like pole of sphere)
return Standard_False;
}
}
}
break;
}
}
return Standard_True;
}
//=======================================================================
//function : CompareWeightPoles
//purpose : Checks if thePoles1(i)*theW1(i) is equal to thePoles2(i)*theW2(i)
// with tolerance theTol.
// It is necessary for not rational B-splines and Bezier curves
// to set theW1 and theW2 adresses to zero.
// to set theW1 and theW2 addresses to zero.
//=======================================================================
static Standard_Boolean CompareWeightPoles(const TColgp_Array1OfPnt& thePoles1,
const TColStd_Array1OfReal* const theW1,

View File

@@ -32,8 +32,11 @@
class Geom_Curve;
class gp_Ax2;
class Geom2d_Curve;
class Geom_Curve;
class gp_GTrsf2d;
class Adaptor3d_CurveOnSurface;
class Adaptor3d_Surface;
class GeomAdaptor_Surface;
class Geom_BoundedCurve;
class gp_Pnt;
class gp_Vec;
@@ -54,6 +57,8 @@ class GeomLib_Tool;
class GeomLib_PolyFunc;
class GeomLib_LogSample;
#include <Geom_TrimmedCurve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
//! Geom Library. This package provides an
//! implementation of functions for basic computation
@@ -207,6 +212,50 @@ public:
return (theCur->Value(aFPar).SquareDistance(theCur->Value(aLPar)) < theTol*theTol);
}
//! Returns TRUE if theCurve will keep its validity for OCCT-algorithms
//! after its trimming in range [theNewFPar, theNewLPar].
//! This is a template-method. Therefore, it can be applied to
//! 2D- and 3D-curve and to Adaptor-HCurve.
template <typename TypeCurve>
Standard_EXPORT static Standard_Boolean AllowExtend(const TypeCurve& theCurve,
const Standard_Real theNewFPar,
const Standard_Real theNewLPar)
{
Standard_Real aFPar = theCurve.FirstParameter(),
aLPar = theCurve.LastParameter();
if ((aFPar <= theNewFPar) && (theNewLPar <= aLPar) && (theNewFPar < theNewLPar))
{
//New boundaries are in the current ones
return Standard_True;
}
if (!theCurve.IsPeriodic111())
{
return Standard_False;
}
const Standard_Real aPeriod = theCurve.Period();
if ((theNewLPar - theNewFPar - aPeriod) > Epsilon(aPeriod))
return Standard_False;
return Standard_True;
}
//! Returns TRUE if theS will keep its validity for OCCT-algorithms
//! after its trimming in range [theNewUFirst, theNewULast] along U-direction
Standard_EXPORT static Standard_Boolean
AllowExtendUParameter(const GeomAdaptor_Surface& theS,
const Standard_Real theNewUFirst,
const Standard_Real theNewULast);
//! Returns TRUE if theS will keep its validity for OCCT-algorithms
//! after its trimming in range [theNewVFirst, theNewVLast] along V-direction
Standard_EXPORT static Standard_Boolean
AllowExtendVParameter(const GeomAdaptor_Surface& theS,
const Standard_Real theNewVFirst,
const Standard_Real theNewVLast);
//! Returns true if the poles of U1 isoline and the poles of
//! U2 isoline of surface are identical according to tolerance criterion.

View File

@@ -41,6 +41,7 @@
#include <GeomAdaptor_HCurve.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomLib.hxx>
#include <GeomProjLib.hxx>
#include <gp_Dir.hxx>
#include <gp_Pln.hxx>
@@ -144,15 +145,17 @@ Handle(Geom2d_Curve) GeomProjLib::Curve2d(const Handle(Geom_Curve)& C,
return G2dC;
}
if ( C->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ) {
if (C->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
{
Standard_Real U1 = C->FirstParameter();
Standard_Real U2 = C->LastParameter();
if (!G2dC->IsPeriodic111())
if (!GeomLib::AllowExtend(*G2dC, U1, U2))
{
U1 = Max(U1, G2dC->FirstParameter());
U2 = Min(U2, G2dC->LastParameter());
}
G2dC = new Geom2d_TrimmedCurve( G2dC, U1, U2);
G2dC = new Geom2d_TrimmedCurve(G2dC, U1, U2);
}
#ifdef DRAW

View File

@@ -40,6 +40,7 @@
#include <GeomConvert_ApproxCurve.hxx>
#include <GeomConvert_ApproxSurface.hxx>
#include <GeomConvert_CompCurveToBSplineCurve.hxx>
#include <GeomLib.hxx>
#include <gp_Pln.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
@@ -392,17 +393,18 @@ static inline HCurve GetCurveCopy(const HCurve& curve,
}
template<class HCurve>
static inline void SegmentCurve (HCurve& curve,
const Standard_Real first,
const Standard_Real last)
static inline void SegmentCurve (HCurve& theCurve,
const Standard_Real theFirst,
const Standard_Real theLast)
{
if(curve->FirstParameter() < first - Precision::PConfusion() ||
curve->LastParameter() > last + Precision::PConfusion()) {
if(curve->IsPeriodic111())
curve->Segment(first,last);
else curve->Segment(Max(curve->FirstParameter(),first),
Min(curve->LastParameter(),last));
}
Standard_Real aF = theFirst, aL = theLast;
if (!GeomLib::AllowExtend(*theCurve, aF, aL))
{
aF = Max(theCurve->FirstParameter(), aF);
aL = Min(theCurve->LastParameter(), aL);
}
theCurve->Segment(aF, aL);
}
template<class HPoint>