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

0025124: [Feature request] Removal of continuity checks for offset geometries

Sometimes curve or surface, which is defined as C0, has continuity G1 or above. Offset can be built from these shapes.
Therefore, this extended checking was added into SetBasisCurve and SetBasisSurface methods.

Main changes in function BRepOffset_Tool::ExtentFace(...):
*  "return" is added if intersection (in 2D-space) between two edges in a face cannot be found.

Basis curve/surface continuity value found (if G1-checking is OK) is set up as BasisContinuity (see myBasisCurveContinuity and myBasisSurfContinuity members which is returned by GetBasisCurveContinuity and GetBasisSurfContinuity() methods). This fact is used in Geom2dAdaptor and in GeomAdaptor classes.

Possibility is entered, which allows for basis elements of offset curve/surface to avoid of C0-checking.

Test cases were changed according to their new behavior.

Test-cases for issue #25124
This commit is contained in:
nbv
2014-12-10 16:18:05 +03:00
committed by bugmaster
parent 68cdb44b0a
commit 3d58dc498b
33 changed files with 1959 additions and 1336 deletions

View File

@@ -563,6 +563,14 @@ is
raises RangeError;
---Purpose : Raised if N < 0.
IsG1 (me; theTf, theTl, theAngTol : Real) returns Boolean;
---Purpose :
-- Check if curve has at least G1 continuity in interval [theTf, theTl]
-- Returns true if IsCN(1)
-- or
-- angle betweem "left" and "right" first derivatives at
-- knots with C0 continuity is less then theAngTol
-- only knots in interval [theTf, theTl] is checked
IsClosed (me) returns Boolean;
---Purpose :

View File

@@ -62,6 +62,84 @@ Standard_Boolean Geom_BSplineCurve::IsCN ( const Standard_Integer N) const
return Standard_False;
}
}
//=======================================================================
//function : IsG1
//purpose :
//=======================================================================
Standard_Boolean Geom_BSplineCurve::IsG1 ( const Standard_Real theTf,
const Standard_Real theTl,
const Standard_Real theAngTol) const
{
if(IsCN(1))
{
return Standard_True;
}
Standard_Integer start = FirstUKnotIndex()+1,
finish = LastUKnotIndex()-1;
Standard_Integer aDeg = Degree();
for(Standard_Integer aNKnot = start; aNKnot <= finish; aNKnot++)
{
const Standard_Real aTpar = Knot(aNKnot);
if(aTpar < theTf)
continue;
if(aTpar > theTl)
break;
Standard_Integer mult = Multiplicity(aNKnot);
if (mult < aDeg)
continue;
gp_Pnt aP1, aP2;
gp_Vec aV1, aV2;
LocalD1(aTpar, aNKnot-1, aNKnot, aP1, aV1);
LocalD1(aTpar, aNKnot, aNKnot+1, aP2, aV2);
if((aV1.SquareMagnitude() <= gp::Resolution()) ||
aV2.SquareMagnitude() <= gp::Resolution())
{
return Standard_False;
}
if(Abs(aV1.Angle(aV2)) > theAngTol)
return Standard_False;
}
if(!IsPeriodic())
return Standard_True;
const Standard_Real aFirstParam = FirstParameter(),
aLastParam = LastParameter();
if( ((aFirstParam - theTf)*(theTl - aFirstParam) < 0.0) &&
((aLastParam - theTf)*(theTl - aLastParam) < 0.0))
{
//Range [theTf, theTl] does not intersect curve bounadries
return Standard_True;
}
//Curve is closed or periodic and range [theTf, theTl]
//intersect curve boundary. Therefore, it is necessary to
//check if curve is smooth in its first and last point.
gp_Pnt aP;
gp_Vec aV1, aV2;
D1(Knot(FirstUKnotIndex()), aP, aV1);
D1(Knot(LastUKnotIndex()), aP, aV2);
if((aV1.SquareMagnitude() <= gp::Resolution()) ||
aV2.SquareMagnitude() <= gp::Resolution())
{
return Standard_False;
}
if(Abs(aV1.Angle(aV2)) > theAngTol)
return Standard_False;
return Standard_True;
}
//=======================================================================
//function : IsClosed

View File

@@ -84,7 +84,10 @@ is
Create (C : Curve from Geom; Offset : Real; V : Dir)
Create (C : Curve from Geom;
Offset : Real;
V : Dir;
isNotCheckC0 : Boolean = Standard_False)
returns OffsetCurve
---Purpose :
-- C is the basis curve, Offset is the distance between <me> and
@@ -94,6 +97,8 @@ is
-- at this point, the corresponding point on the offset curve is
-- in the direction of the vector-product N = V ^ T where
-- N is a unitary vector.
-- If isNotCheckC0 = TRUE checking if basis curve has C0-continuity
-- is not made.
-- Warnings :
-- In this package the entities are not shared. The OffsetCurve is
-- built with a copy of the curve C. So when C is modified the
@@ -122,9 +127,14 @@ is
-- the point of parameter U on this offset curve.
SetBasisCurve (me : mutable; C : Curve from Geom)
SetBasisCurve ( me : mutable;
C : Curve from Geom;
isNotCheckC0 : Boolean = Standard_False)
raises ConstructionError;
---Purpose : Changes this offset curve by assigning C as the basis curve from which it is built.
---Purpose : Changes this offset curve by assigning C
-- as the basis curve from which it is built.
-- If isNotCheckC0 = TRUE checking if basis curve
-- has C0-continuity is not made.
-- Exceptions
-- Standard_ConstructionError if the curve C is not at least "C1" continuous.
@@ -348,10 +358,15 @@ is
Copy (me) returns like me;
---Purpose: Creates a new object which is a copy of this offset curve.
GetBasisCurveContinuity(me)
returns Shape from GeomAbs;
---Purpose: Returns continuity of the basis curve.
fields
basisCurve : Curve from Geom;
direction : Dir;
offsetValue : Real;
myBasisCurveContinuity : Shape from GeomAbs;
end;

View File

@@ -59,6 +59,7 @@ typedef gp_XYZ XYZ;
//derivee non nulle
static const int maxDerivOrder = 3;
static const Standard_Real MinStep = 1e-7;
static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
@@ -79,34 +80,17 @@ Handle(Geom_Geometry) Geom_OffsetCurve::Copy () const {
//=======================================================================
//function : Geom_OffsetCurve
//purpose :
//purpose : Basis curve cannot be an Offset curve or trimmed from
// offset curve.
//=======================================================================
Geom_OffsetCurve::Geom_OffsetCurve (const Handle(Curve)& C,
const Standard_Real Offset,
const Dir& V )
: direction(V), offsetValue(Offset)
Geom_OffsetCurve::Geom_OffsetCurve (const Handle(Geom_Curve)& theCurve,
const Standard_Real theOffset,
const gp_Dir& theDir,
const Standard_Boolean isTheNotCheckC0)
: direction(theDir), offsetValue(theOffset)
{
if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) {
Handle(OffsetCurve) OC = Handle(OffsetCurve)::DownCast(C);
SetBasisCurve (OC->BasisCurve());
Standard_Real PrevOff = OC->Offset();
gp_Vec V1(OC->Direction());
gp_Vec V2(direction);
gp_Vec Vdir(PrevOff*V1 + offsetValue*V2);
if (Offset >= 0.) {
offsetValue = Vdir.Magnitude();
direction.SetXYZ(Vdir.XYZ());
} else {
offsetValue = -Vdir.Magnitude();
direction.SetXYZ((-Vdir).XYZ());
}
}
else {
SetBasisCurve(C);
}
SetBasisCurve (theCurve, isTheNotCheckC0);
}
@@ -182,36 +166,78 @@ Standard_Real Geom_OffsetCurve::Period () const
//purpose :
//=======================================================================
void Geom_OffsetCurve::SetBasisCurve (const Handle(Curve)& C)
void Geom_OffsetCurve::SetBasisCurve (const Handle(Curve)& C,
const Standard_Boolean isNotCheckC0)
{
Handle(Curve) aBasisCurve = Handle(Curve)::DownCast(C->Copy());
const Standard_Real aUf = C->FirstParameter(),
aUl = C->LastParameter();
Handle(Curve) aCheckingCurve = Handle(Curve)::DownCast(C->Copy());
Standard_Boolean isTrimmed = Standard_False;
while(aCheckingCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ||
aCheckingCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
{
if (aCheckingCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
{
Handle(Geom_TrimmedCurve) aTrimC =
Handle(Geom_TrimmedCurve)::DownCast(aCheckingCurve);
aCheckingCurve = aTrimC->BasisCurve();
isTrimmed = Standard_True;
}
if (aCheckingCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
{
Handle(Geom_OffsetCurve) aOC =
Handle(Geom_OffsetCurve)::DownCast(aCheckingCurve);
aCheckingCurve = aOC->BasisCurve();
Standard_Real PrevOff = aOC->Offset();
gp_Vec V1(aOC->Direction());
gp_Vec V2(direction);
gp_Vec Vdir(PrevOff*V1 + offsetValue*V2);
if (offsetValue >= 0.)
{
offsetValue = Vdir.Magnitude();
direction.SetXYZ(Vdir.XYZ());
}
else
{
offsetValue = -Vdir.Magnitude();
direction.SetXYZ((-Vdir).XYZ());
}
}
}
myBasisCurveContinuity = aCheckingCurve->Continuity();
Standard_Boolean isC0 = !isNotCheckC0 &&
(myBasisCurveContinuity == GeomAbs_C0);
// Basis curve must be at least C1
if (aBasisCurve->Continuity() == GeomAbs_C0)
if (isC0 && aCheckingCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
{
// For B-splines it is sometimes possible to increase continuity by removing
// unnecessarily duplicated knots
if (aBasisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
Handle(Geom_BSplineCurve) aBC = Handle(Geom_BSplineCurve)::DownCast(aCheckingCurve);
if(aBC->IsG1(aUf, aUl, MyAngularToleranceForG1))
{
Handle(Geom_BSplineCurve) aBCurve = Handle(Geom_BSplineCurve)::DownCast(aBasisCurve);
Standard_Integer degree = aBCurve->Degree();
Standard_Real Toler = Precision::Confusion();
Standard_Integer start = aBCurve->IsPeriodic() ? 1 : aBCurve->FirstUKnotIndex(),
finish = aBCurve->IsPeriodic() ? aBCurve->NbKnots() : aBCurve->LastUKnotIndex();
for (Standard_Integer i = start; i <= finish; i++)
{
Standard_Integer mult = aBCurve->Multiplicity(i);
if ( mult == degree )
aBCurve->RemoveKnot(i,degree - 1, Toler);
}
//Checking if basis curve has more smooth (C1, G2 and above) is not done.
//It can be done in case of need.
myBasisCurveContinuity = GeomAbs_G1;
isC0 = Standard_False;
}
// Raise exception if still C0
if (aBasisCurve->Continuity() == GeomAbs_C0)
if (isC0)
Standard_ConstructionError::Raise("Offset on C0 curve");
}
basisCurve = aBasisCurve;
//
if(isTrimmed)
{
basisCurve = new Geom_TrimmedCurve(aCheckingCurve, aUf, aUl);
}
else
{
basisCurve = aCheckingCurve;
}
}
@@ -235,7 +261,7 @@ Handle(Curve) Geom_OffsetCurve::BasisCurve () const
GeomAbs_Shape Geom_OffsetCurve::Continuity () const {
GeomAbs_Shape OffsetShape=GeomAbs_C0;
switch (basisCurve->Continuity()) {
switch (myBasisCurveContinuity) {
case GeomAbs_C0 : OffsetShape = GeomAbs_C0; break;
case GeomAbs_C1 : OffsetShape = GeomAbs_C0; break;
case GeomAbs_C2 : OffsetShape = GeomAbs_C1; break;
@@ -825,13 +851,13 @@ Standard_Real Geom_OffsetCurve::Offset () const { return offsetValue; }
void Geom_OffsetCurve::Value (const Standard_Real theU, Pnt& theP,
Pnt& thePbasis, Vec& theV1basis) const
{
if (basisCurve->Continuity() == GeomAbs_C0)
{
if (myBasisCurveContinuity == GeomAbs_C0)
Geom_UndefinedValue::Raise("Exception: Basis curve is C0 continuity!");
basisCurve->D1(theU, thePbasis, theV1basis);
D0(theU,theP);
}
}
//=======================================================================
@@ -894,3 +920,12 @@ const
{
return basisCurve->ParametricTransformation(T);
}
//=======================================================================
//function : GetBasisCurveContinuity
//purpose :
//=======================================================================
GeomAbs_Shape Geom_OffsetCurve::GetBasisCurveContinuity() const
{
return myBasisCurveContinuity;
}

View File

@@ -68,7 +68,10 @@ is
Create (S : Surface from Geom; Offset : Real) returns OffsetSurface
Create (S : Surface from Geom;
Offset : Real;
isNotCheckC0 : Boolean = Standard_False)
returns OffsetSurface
---Purpose : Constructs a surface offset from the basis surface
-- S, where Offset is the distance between the offset
-- surface and the basis surface at any point.
@@ -81,6 +84,8 @@ is
-- which the offset value is measured is indicated by
-- this normal vector if Offset is positive, or is the
-- inverse sense if Offset is negative.
-- If isNotCheckC0 = TRUE checking if basis surface has C0-continuity
-- is not made.
-- Warnings :
-- - The offset surface is built with a copy of the
-- surface S. Therefore, when S is modified the
@@ -95,12 +100,16 @@ is
SetBasisSurface (me : mutable; S : Surface from Geom)
SetBasisSurface ( me : mutable;
S : Surface from Geom;
isNotCheckC0 : Boolean = Standard_False)
raises ConstructionError;
---Purpose : Raised if S is not at least C1.
-- Warnings :
-- No check is done to verify that a unique normal direction is
-- defined at any point of the basis surface S.
-- If isNotCheckC0 = TRUE checking if basis surface has C0-continuity
-- is not made.
-- Exceptions
-- Standard_ConstructionError if the surface S is not
-- at least "C1" continuous.
@@ -484,11 +493,15 @@ is
-- these vectors have opposite direction.
returns Boolean from Standard;
GetBasisSurfContinuity(me)
returns Shape from GeomAbs;
---Purpose: Returns continuity of the basis surface.
fields
basisSurf : Surface from Geom;
equivSurf : Surface from Geom;
offsetValue : Real;
myOscSurf : OsculatingSurface from Geom;
myBasisSurfContinuity : Shape from GeomAbs;
end;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff