mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-16 10:08:36 +03:00
CR23683: Geom_BSplineSurface incorrectly determines continuity for periodic cases
Add a checking into files Geom_OffsetSurface.cxx, Geom_OffsetCurve.cxx, Geom2d_OffsetCurve.cxx , which try to make continuity of bspline surfaces and curves more than C0 to build offset. Delete duplicate code and checkings Prevent change of offset curve / surface when exception is raised due to attempt to set new C0 basis curve / surface Added new QA command OCC23683. Added test case bugs/moddata_3/bug23683
This commit is contained in:
parent
973f1c39ac
commit
06be28a4f1
@ -104,7 +104,7 @@ package BSplCLib
|
|||||||
-- . Curves and Surfaces for Computer Aided Geometric Design,
|
-- . Curves and Surfaces for Computer Aided Geometric Design,
|
||||||
-- a practical guide Gerald Farin
|
-- a practical guide Gerald Farin
|
||||||
|
|
||||||
uses TColStd, gp, TColgp, math
|
uses TColStd, gp, TColgp, math, GeomAbs
|
||||||
|
|
||||||
|
|
||||||
is
|
is
|
||||||
@ -353,6 +353,15 @@ is
|
|||||||
-- Analyses the distribution of multiplicities between
|
-- Analyses the distribution of multiplicities between
|
||||||
-- the knot FromK1 and the Knot ToK2.
|
-- the knot FromK1 and the Knot ToK2.
|
||||||
|
|
||||||
|
KnotAnalysis (Degree : Integer;
|
||||||
|
Periodic : Boolean;
|
||||||
|
CKnots : Array1OfReal from TColStd;
|
||||||
|
CMults : Array1OfInteger from TColStd;
|
||||||
|
KnotForm : out BSplKnotDistribution from GeomAbs;
|
||||||
|
MaxKnotMult: out Integer);
|
||||||
|
---Purpose: Analyzes the array of knots.
|
||||||
|
-- Returns the form and the maximum knot multiplicity.
|
||||||
|
|
||||||
Reparametrize (U1, U2 : Real;
|
Reparametrize (U1, U2 : Real;
|
||||||
Knots : in out Array1OfReal from TColStd);
|
Knots : in out Array1OfReal from TColStd);
|
||||||
---Purpose:
|
---Purpose:
|
||||||
|
@ -649,6 +649,62 @@ BSplCLib_MultDistribution BSplCLib::MultForm
|
|||||||
return MForm;
|
return MForm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : KnotAnalysis
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
void BSplCLib::KnotAnalysis (const Standard_Integer Degree,
|
||||||
|
const Standard_Boolean Periodic,
|
||||||
|
const TColStd_Array1OfReal& CKnots,
|
||||||
|
const TColStd_Array1OfInteger& CMults,
|
||||||
|
GeomAbs_BSplKnotDistribution& KnotForm,
|
||||||
|
Standard_Integer& MaxKnotMult)
|
||||||
|
{
|
||||||
|
KnotForm = GeomAbs_NonUniform;
|
||||||
|
|
||||||
|
BSplCLib_KnotDistribution KSet =
|
||||||
|
BSplCLib::KnotForm (CKnots, 1, CKnots.Length());
|
||||||
|
|
||||||
|
|
||||||
|
if (KSet == BSplCLib_Uniform) {
|
||||||
|
BSplCLib_MultDistribution MSet =
|
||||||
|
BSplCLib::MultForm (CMults, 1, CMults.Length());
|
||||||
|
switch (MSet) {
|
||||||
|
case BSplCLib_NonConstant :
|
||||||
|
break;
|
||||||
|
case BSplCLib_Constant :
|
||||||
|
if (CKnots.Length() == 2) {
|
||||||
|
KnotForm = GeomAbs_PiecewiseBezier;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (CMults (1) == 1) KnotForm = GeomAbs_Uniform;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BSplCLib_QuasiConstant :
|
||||||
|
if (CMults (1) == Degree + 1) {
|
||||||
|
Standard_Real M = CMults (2);
|
||||||
|
if (M == Degree ) KnotForm = GeomAbs_PiecewiseBezier;
|
||||||
|
else if (M == 1) KnotForm = GeomAbs_QuasiUniform;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Standard_Integer FirstKM =
|
||||||
|
Periodic ? CKnots.Lower() : BSplCLib::FirstUKnotIndex (Degree,CMults);
|
||||||
|
Standard_Integer LastKM =
|
||||||
|
Periodic ? CKnots.Upper() : BSplCLib::LastUKnotIndex (Degree,CMults);
|
||||||
|
MaxKnotMult = 0;
|
||||||
|
if (LastKM - FirstKM != 1) {
|
||||||
|
Standard_Integer Multi;
|
||||||
|
for (Standard_Integer i = FirstKM + 1; i < LastKM; i++) {
|
||||||
|
Multi = CMults (i);
|
||||||
|
MaxKnotMult = Max (MaxKnotMult, Multi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : Reparametrize
|
//function : Reparametrize
|
||||||
//purpose :
|
//purpose :
|
||||||
|
@ -74,63 +74,6 @@ static void CheckCurveData
|
|||||||
Standard_ConstructionError::Raise();
|
Standard_ConstructionError::Raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : KnotAnalysis
|
|
||||||
//purpose : Internal use only
|
|
||||||
//=======================================================================
|
|
||||||
|
|
||||||
static void KnotAnalysis
|
|
||||||
(const Standard_Integer Degree,
|
|
||||||
const Standard_Boolean Periodic,
|
|
||||||
const TColStd_Array1OfReal& CKnots,
|
|
||||||
const TColStd_Array1OfInteger& CMults,
|
|
||||||
GeomAbs_BSplKnotDistribution& KnotForm,
|
|
||||||
Standard_Integer& MaxKnotMult)
|
|
||||||
{
|
|
||||||
KnotForm = GeomAbs_NonUniform;
|
|
||||||
|
|
||||||
BSplCLib_KnotDistribution KSet =
|
|
||||||
BSplCLib::KnotForm (CKnots, 1, CKnots.Length());
|
|
||||||
|
|
||||||
|
|
||||||
if (KSet == BSplCLib_Uniform) {
|
|
||||||
BSplCLib_MultDistribution MSet =
|
|
||||||
BSplCLib::MultForm (CMults, 1, CMults.Length());
|
|
||||||
switch (MSet) {
|
|
||||||
case BSplCLib_NonConstant :
|
|
||||||
break;
|
|
||||||
case BSplCLib_Constant :
|
|
||||||
if (CKnots.Length() == 2) {
|
|
||||||
KnotForm = GeomAbs_PiecewiseBezier;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (CMults (1) == 1) KnotForm = GeomAbs_Uniform;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BSplCLib_QuasiConstant :
|
|
||||||
if (CMults (1) == Degree + 1) {
|
|
||||||
Standard_Real M = CMults (2);
|
|
||||||
if (M == Degree ) KnotForm = GeomAbs_PiecewiseBezier;
|
|
||||||
else if (M == 1) KnotForm = GeomAbs_QuasiUniform;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Integer FirstKM =
|
|
||||||
Periodic ? CKnots.Lower() : BSplCLib::FirstUKnotIndex (Degree,CMults);
|
|
||||||
Standard_Integer LastKM =
|
|
||||||
Periodic ? CKnots.Upper() : BSplCLib::LastUKnotIndex (Degree,CMults);
|
|
||||||
MaxKnotMult = 0;
|
|
||||||
if (LastKM - FirstKM != 1) {
|
|
||||||
Standard_Integer Multi;
|
|
||||||
for (Standard_Integer i = FirstKM + 1; i < LastKM; i++) {
|
|
||||||
Multi = CMults (i);
|
|
||||||
MaxKnotMult = Max (MaxKnotMult, Multi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : Rational
|
//function : Rational
|
||||||
//purpose : check rationality of an array of weights
|
//purpose : check rationality of an array of weights
|
||||||
@ -1181,7 +1124,7 @@ void Geom_BSplineCurve::UpdateKnots()
|
|||||||
rational = !weights.IsNull();
|
rational = !weights.IsNull();
|
||||||
|
|
||||||
Standard_Integer MaxKnotMult = 0;
|
Standard_Integer MaxKnotMult = 0;
|
||||||
KnotAnalysis (deg,
|
BSplCLib::KnotAnalysis (deg,
|
||||||
periodic,
|
periodic,
|
||||||
knots->Array1(),
|
knots->Array1(),
|
||||||
mults->Array1(),
|
mults->Array1(),
|
||||||
|
@ -87,60 +87,6 @@ static void CheckSurfaceData
|
|||||||
Standard_ConstructionError::Raise("Geom_BSplineSurface");
|
Standard_ConstructionError::Raise("Geom_BSplineSurface");
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : KnotAnalysis
|
|
||||||
//purpose : Internal use only.
|
|
||||||
//=======================================================================
|
|
||||||
|
|
||||||
static void KnotAnalysis
|
|
||||||
(const Standard_Integer Degree,
|
|
||||||
const TColStd_Array1OfReal& CKnots,
|
|
||||||
const TColStd_Array1OfInteger& CMults,
|
|
||||||
GeomAbs_BSplKnotDistribution& KnotForm,
|
|
||||||
Standard_Integer& MaxKnotMult)
|
|
||||||
{
|
|
||||||
KnotForm = GeomAbs_NonUniform;
|
|
||||||
|
|
||||||
BSplCLib_KnotDistribution KSet =
|
|
||||||
BSplCLib::KnotForm (CKnots, 1, CKnots.Length());
|
|
||||||
|
|
||||||
|
|
||||||
if (KSet == BSplCLib_Uniform) {
|
|
||||||
BSplCLib_MultDistribution MSet =
|
|
||||||
BSplCLib::MultForm (CMults, 1, CMults.Length());
|
|
||||||
switch (MSet) {
|
|
||||||
case BSplCLib_NonConstant :
|
|
||||||
break;
|
|
||||||
case BSplCLib_Constant :
|
|
||||||
if (CKnots.Length() == 2) {
|
|
||||||
KnotForm = GeomAbs_PiecewiseBezier;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (CMults (1) == 1) KnotForm = GeomAbs_Uniform;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BSplCLib_QuasiConstant :
|
|
||||||
if (CMults (1) == Degree + 1) {
|
|
||||||
Standard_Real M = CMults (2);
|
|
||||||
if (M == Degree ) KnotForm = GeomAbs_PiecewiseBezier;
|
|
||||||
else if (M == 1) KnotForm = GeomAbs_QuasiUniform;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Integer FirstKM = BSplCLib::FirstUKnotIndex (Degree, CMults);
|
|
||||||
Standard_Integer LastKM = BSplCLib::LastUKnotIndex (Degree, CMults);
|
|
||||||
MaxKnotMult = 0;
|
|
||||||
if (LastKM - FirstKM != 1) {
|
|
||||||
Standard_Integer Multi;
|
|
||||||
for (Standard_Integer i = FirstKM + 1; i < LastKM; i++) {
|
|
||||||
Multi = CMults (i);
|
|
||||||
MaxKnotMult = Max (MaxKnotMult, Multi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : Rational
|
//function : Rational
|
||||||
//purpose : Internal use only.
|
//purpose : Internal use only.
|
||||||
@ -1297,7 +1243,7 @@ void Geom_BSplineSurface::UpdateUKnots()
|
|||||||
{
|
{
|
||||||
|
|
||||||
Standard_Integer MaxKnotMult = 0;
|
Standard_Integer MaxKnotMult = 0;
|
||||||
KnotAnalysis (udeg,
|
BSplCLib::KnotAnalysis (udeg, uperiodic,
|
||||||
uknots->Array1(),
|
uknots->Array1(),
|
||||||
umults->Array1(),
|
umults->Array1(),
|
||||||
uknotSet, MaxKnotMult);
|
uknotSet, MaxKnotMult);
|
||||||
@ -1337,7 +1283,7 @@ void Geom_BSplineSurface::UpdateUKnots()
|
|||||||
void Geom_BSplineSurface::UpdateVKnots()
|
void Geom_BSplineSurface::UpdateVKnots()
|
||||||
{
|
{
|
||||||
Standard_Integer MaxKnotMult = 0;
|
Standard_Integer MaxKnotMult = 0;
|
||||||
KnotAnalysis (vdeg,
|
BSplCLib::KnotAnalysis (vdeg, vperiodic,
|
||||||
vknots->Array1(),
|
vknots->Array1(),
|
||||||
vmults->Array1(),
|
vmults->Array1(),
|
||||||
vknotSet, MaxKnotMult);
|
vknotSet, MaxKnotMult);
|
||||||
|
@ -89,14 +89,12 @@ Handle(Geom_Geometry) Geom_OffsetCurve::Copy () const {
|
|||||||
Geom_OffsetCurve::Geom_OffsetCurve (const Handle(Curve)& C,
|
Geom_OffsetCurve::Geom_OffsetCurve (const Handle(Curve)& C,
|
||||||
const Standard_Real Offset,
|
const Standard_Real Offset,
|
||||||
const Dir& V )
|
const Dir& V )
|
||||||
: direction(V), offsetValue(Offset) {
|
: direction(V), offsetValue(Offset)
|
||||||
|
{
|
||||||
if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) {
|
if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) {
|
||||||
Handle(OffsetCurve) OC = Handle(OffsetCurve)::DownCast(C);
|
Handle(OffsetCurve) OC = Handle(OffsetCurve)::DownCast(C);
|
||||||
if ((OC->BasisCurve())->Continuity() == GeomAbs_C0)
|
SetBasisCurve (OC->BasisCurve());
|
||||||
Standard_ConstructionError::Raise();
|
|
||||||
|
|
||||||
basisCurve = Handle(Curve)::DownCast((OC->BasisCurve())->Copy());
|
|
||||||
Standard_Real PrevOff = OC->Offset();
|
Standard_Real PrevOff = OC->Offset();
|
||||||
gp_Vec V1(OC->Direction());
|
gp_Vec V1(OC->Direction());
|
||||||
gp_Vec V2(direction);
|
gp_Vec V2(direction);
|
||||||
@ -109,9 +107,9 @@ Geom_OffsetCurve::Geom_OffsetCurve (const Handle(Curve)& C,
|
|||||||
offsetValue = -Vdir.Magnitude();
|
offsetValue = -Vdir.Magnitude();
|
||||||
direction.SetXYZ((-Vdir).XYZ());
|
direction.SetXYZ((-Vdir).XYZ());
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (C->Continuity() == GeomAbs_C0) Standard_ConstructionError::Raise();
|
else {
|
||||||
basisCurve = Handle(Curve)::DownCast(C->Copy()); // DownCast: 10-03-93
|
SetBasisCurve(C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,10 +186,36 @@ Standard_Real Geom_OffsetCurve::Period () const
|
|||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
void Geom_OffsetCurve::SetBasisCurve (const Handle(Curve)& C) {
|
void Geom_OffsetCurve::SetBasisCurve (const Handle(Curve)& C)
|
||||||
|
{
|
||||||
|
Handle(Curve) aBasisCurve = Handle(Curve)::DownCast(C->Copy());
|
||||||
|
|
||||||
if (C->Continuity() == GeomAbs_C0) Standard_ConstructionError::Raise();
|
// Basis curve must be at least C1
|
||||||
basisCurve = Handle(Curve)::DownCast(C->Copy()); // DownCast: 10-03-93
|
if (aBasisCurve->Continuity() == GeomAbs_C0)
|
||||||
|
{
|
||||||
|
// 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) 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Raise exception if still C0
|
||||||
|
if (aBasisCurve->Continuity() == GeomAbs_C0)
|
||||||
|
Standard_ConstructionError::Raise("Offset on C0 curve");
|
||||||
|
}
|
||||||
|
|
||||||
|
basisCurve = aBasisCurve;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,19 +229,16 @@ Geom_OffsetSurface::Geom_OffsetSurface ( const Handle(Surface)& S,
|
|||||||
const Standard_Real Offset )
|
const Standard_Real Offset )
|
||||||
: offsetValue (Offset)
|
: offsetValue (Offset)
|
||||||
{
|
{
|
||||||
|
|
||||||
Handle(Geom_OffsetSurface) Off_S;
|
Handle(Geom_OffsetSurface) Off_S;
|
||||||
Off_S = Handle(Geom_OffsetSurface)::DownCast(S);
|
Off_S = Handle(Geom_OffsetSurface)::DownCast(S);
|
||||||
if (!Off_S.IsNull()) {
|
if (!Off_S.IsNull()) {
|
||||||
offsetValue += Off_S->Offset();
|
offsetValue += Off_S->Offset();
|
||||||
basisSurf = Handle(Surface)::DownCast(Off_S->BasisSurface()->Copy());
|
SetBasisSurface (Off_S->BasisSurface());
|
||||||
}
|
|
||||||
else {
|
|
||||||
basisSurf = Handle(Surface)::DownCast(S->Copy());
|
|
||||||
if (S->Continuity() == GeomAbs_C0)
|
|
||||||
Standard_ConstructionError::Raise("Offset with no C1 Surface");
|
|
||||||
}
|
}
|
||||||
equivSurf = Surface();
|
else {
|
||||||
|
SetBasisSurface(S);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Tolerance en dur pour l'instant ,mais on devrait la proposer dans le constructeur
|
// Tolerance en dur pour l'instant ,mais on devrait la proposer dans le constructeur
|
||||||
// et la mettre en champ, on pourrait utiliser par exemple pour l'extraction d'iso
|
// et la mettre en champ, on pourrait utiliser par exemple pour l'extraction d'iso
|
||||||
@ -258,11 +255,45 @@ Geom_OffsetSurface::Geom_OffsetSurface ( const Handle(Surface)& S,
|
|||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
void Geom_OffsetSurface::SetBasisSurface (const Handle(Surface)& S) {
|
void Geom_OffsetSurface::SetBasisSurface (const Handle(Surface)& S)
|
||||||
|
{
|
||||||
|
Handle(Surface) aBasisSurf = Handle(Surface)::DownCast(S->Copy());
|
||||||
|
|
||||||
basisSurf = Handle(Surface)::DownCast(S->Copy());
|
// Basis surface must be at least C1
|
||||||
|
if (aBasisSurf->Continuity() == GeomAbs_C0)
|
||||||
|
{
|
||||||
|
// For B-splines it is sometimes possible to increase continuity by removing
|
||||||
|
// unnecessarily duplicated knots
|
||||||
|
if (aBasisSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface)))
|
||||||
|
{
|
||||||
|
Handle(Geom_BSplineSurface) aBSurf = Handle(Geom_BSplineSurface)::DownCast(aBasisSurf);
|
||||||
|
Standard_Integer uDegree = aBSurf->UDegree(), vDegree = aBSurf->VDegree();
|
||||||
|
Standard_Real Toler = Precision::Confusion();
|
||||||
|
Standard_Integer start = aBSurf->IsUPeriodic() ? 1 : aBSurf->FirstUKnotIndex(),
|
||||||
|
finish = aBSurf->IsUPeriodic() ? aBSurf->NbUKnots() : aBSurf->LastUKnotIndex();
|
||||||
|
for (Standard_Integer i = start; i <= finish; i++)
|
||||||
|
{
|
||||||
|
Standard_Integer mult = aBSurf->UMultiplicity(i);
|
||||||
|
if ( mult == uDegree )
|
||||||
|
aBSurf->RemoveUKnot(i,uDegree - 1, Toler);
|
||||||
|
}
|
||||||
|
start = aBSurf->IsVPeriodic() ? 1 : aBSurf->FirstVKnotIndex();
|
||||||
|
finish = aBSurf->IsVPeriodic() ? aBSurf->NbVKnots() : aBSurf->LastVKnotIndex();
|
||||||
|
for (Standard_Integer i = start; i <= finish; i++)
|
||||||
|
{
|
||||||
|
Standard_Integer mult = aBSurf->VMultiplicity(i);
|
||||||
|
if ( mult == vDegree )
|
||||||
|
aBSurf->RemoveVKnot(i,vDegree - 1, Toler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Raise exception if still C0
|
||||||
|
if (aBasisSurf->Continuity() == GeomAbs_C0)
|
||||||
|
Standard_ConstructionError::Raise("Offset with no C1 Surface");
|
||||||
|
}
|
||||||
|
|
||||||
|
basisSurf = aBasisSurf;
|
||||||
equivSurf = Surface();
|
equivSurf = Surface();
|
||||||
if (S->Continuity() == GeomAbs_C0) Standard_ConstructionError::Raise();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,63 +71,6 @@ static void CheckCurveData
|
|||||||
Standard_ConstructionError::Raise("BSpline curve : # Poles and degree mismatch");
|
Standard_ConstructionError::Raise("BSpline curve : # Poles and degree mismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : KnotAnalysis
|
|
||||||
//purpose : Internal use only
|
|
||||||
//=======================================================================
|
|
||||||
|
|
||||||
static void KnotAnalysis
|
|
||||||
(const Standard_Integer Degree,
|
|
||||||
const Standard_Boolean Periodic,
|
|
||||||
const TColStd_Array1OfReal& CKnots,
|
|
||||||
const TColStd_Array1OfInteger& CMults,
|
|
||||||
GeomAbs_BSplKnotDistribution& KnotForm,
|
|
||||||
Standard_Integer& MaxKnotMult)
|
|
||||||
{
|
|
||||||
KnotForm = GeomAbs_NonUniform;
|
|
||||||
|
|
||||||
BSplCLib_KnotDistribution KSet =
|
|
||||||
BSplCLib::KnotForm (CKnots, 1, CKnots.Length());
|
|
||||||
|
|
||||||
|
|
||||||
if (KSet == BSplCLib_Uniform) {
|
|
||||||
BSplCLib_MultDistribution MSet =
|
|
||||||
BSplCLib::MultForm (CMults, 1, CMults.Length());
|
|
||||||
switch (MSet) {
|
|
||||||
case BSplCLib_NonConstant :
|
|
||||||
break;
|
|
||||||
case BSplCLib_Constant :
|
|
||||||
if (CKnots.Length() == 2) {
|
|
||||||
KnotForm = GeomAbs_PiecewiseBezier;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (CMults (1) == 1) KnotForm = GeomAbs_Uniform;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BSplCLib_QuasiConstant :
|
|
||||||
if (CMults (1) == Degree + 1) {
|
|
||||||
Standard_Real M = CMults (2);
|
|
||||||
if (M == Degree ) KnotForm = GeomAbs_PiecewiseBezier;
|
|
||||||
else if (M == 1) KnotForm = GeomAbs_QuasiUniform;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Integer FirstKM =
|
|
||||||
Periodic ? CKnots.Lower() : BSplCLib::FirstUKnotIndex (Degree,CMults);
|
|
||||||
Standard_Integer LastKM =
|
|
||||||
Periodic ? CKnots.Upper() : BSplCLib::LastUKnotIndex (Degree,CMults);
|
|
||||||
MaxKnotMult = 0;
|
|
||||||
if (LastKM - FirstKM != 1) {
|
|
||||||
Standard_Integer Multi;
|
|
||||||
for (Standard_Integer i = FirstKM + 1; i < LastKM; i++) {
|
|
||||||
Multi = CMults (i);
|
|
||||||
MaxKnotMult = Max (MaxKnotMult, Multi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : Rational
|
//function : Rational
|
||||||
//purpose : check rationality of an array of weights
|
//purpose : check rationality of an array of weights
|
||||||
@ -1298,7 +1241,7 @@ void Geom2d_BSplineCurve::UpdateKnots()
|
|||||||
rational = !weights.IsNull();
|
rational = !weights.IsNull();
|
||||||
|
|
||||||
Standard_Integer MaxKnotMult = 0;
|
Standard_Integer MaxKnotMult = 0;
|
||||||
KnotAnalysis (deg,
|
BSplCLib::KnotAnalysis (deg,
|
||||||
periodic,
|
periodic,
|
||||||
knots->Array1(),
|
knots->Array1(),
|
||||||
mults->Array1(),
|
mults->Array1(),
|
||||||
|
@ -84,16 +84,11 @@ Geom2d_OffsetCurve::Geom2d_OffsetCurve (const Handle(Curve)& C,
|
|||||||
{
|
{
|
||||||
if (C->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)) {
|
if (C->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)) {
|
||||||
Handle(OffsetCurve) OC = Handle(OffsetCurve)::DownCast(C);
|
Handle(OffsetCurve) OC = Handle(OffsetCurve)::DownCast(C);
|
||||||
if ((OC->BasisCurve())->Continuity() == GeomAbs_C0)
|
SetBasisCurve (OC->BasisCurve());
|
||||||
Standard_ConstructionError::Raise();
|
|
||||||
|
|
||||||
basisCurve = Handle(Curve)::DownCast((OC->BasisCurve())->Copy());
|
|
||||||
offsetValue += OC->Offset();
|
offsetValue += OC->Offset();
|
||||||
} else {
|
}
|
||||||
if (C->Continuity() == GeomAbs_C0)
|
else {
|
||||||
Standard_ConstructionError::Raise();
|
SetBasisCurve(C);
|
||||||
|
|
||||||
basisCurve = Handle(Curve)::DownCast(C->Copy());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,8 +120,34 @@ Standard_Real Geom2d_OffsetCurve::ReversedParameter( const Standard_Real U) cons
|
|||||||
|
|
||||||
void Geom2d_OffsetCurve::SetBasisCurve (const Handle(Curve)& C)
|
void Geom2d_OffsetCurve::SetBasisCurve (const Handle(Curve)& C)
|
||||||
{
|
{
|
||||||
if (C->Continuity() == GeomAbs_C0) Standard_ConstructionError::Raise();
|
Handle(Geom2d_Curve) aBasisCurve = Handle(Geom2d_Curve)::DownCast(C->Copy());
|
||||||
basisCurve = Handle(Geom2d_Curve)::DownCast(C->Copy());
|
|
||||||
|
// Basis curve must be at least C1
|
||||||
|
if (aBasisCurve->Continuity() == GeomAbs_C0)
|
||||||
|
{
|
||||||
|
// For B-splines it is sometimes possible to increase continuity by removing
|
||||||
|
// unnecessarily duplicated knots
|
||||||
|
if (aBasisCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)))
|
||||||
|
{
|
||||||
|
Handle(Geom2d_BSplineCurve) aBCurve = Handle(Geom2d_BSplineCurve)::DownCast(aBasisCurve);
|
||||||
|
Standard_Integer degree = aBCurve->Degree();
|
||||||
|
Standard_Real Toler = 1e-7;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Raise exception if still C0
|
||||||
|
if (aBasisCurve->Continuity() == GeomAbs_C0)
|
||||||
|
Standard_ConstructionError::Raise("Offset on C0 curve");
|
||||||
|
}
|
||||||
|
|
||||||
|
basisCurve = aBasisCurve;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@ -387,6 +387,26 @@ static Standard_Integer OCC23774(Draw_Interpretor& di, Standard_Integer n, const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Standard_Integer OCC23683 (Draw_Interpretor& di, Standard_Integer argc,const char ** argv)
|
||||||
|
{
|
||||||
|
if (argc < 2) {
|
||||||
|
di<<"Usage: " << argv[0] << " invalid number of arguments"<<"\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Standard_Integer ucontinuity = 1;
|
||||||
|
Standard_Integer vcontinuity = 1;
|
||||||
|
Standard_Boolean iscnu = false;
|
||||||
|
Standard_Boolean iscnv = false;
|
||||||
|
|
||||||
|
Handle(Geom_Surface) aSurf = DrawTrSurf::GetSurface(argv[1]);
|
||||||
|
|
||||||
|
QCOMPARE (aSurf->IsCNu (ucontinuity), iscnu);
|
||||||
|
QCOMPARE (aSurf->IsCNv (vcontinuity), iscnv);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void QABugs::Commands_19(Draw_Interpretor& theCommands) {
|
void QABugs::Commands_19(Draw_Interpretor& theCommands) {
|
||||||
const char *group = "QABugs";
|
const char *group = "QABugs";
|
||||||
|
|
||||||
@ -399,6 +419,7 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
|
|||||||
theCommands.Add ("OCC22611", "OCC22611 string nb", __FILE__, OCC22611, group);
|
theCommands.Add ("OCC22611", "OCC22611 string nb", __FILE__, OCC22611, group);
|
||||||
theCommands.Add ("OCC22595", "OCC22595", __FILE__, OCC22595, group);
|
theCommands.Add ("OCC22595", "OCC22595", __FILE__, OCC22595, group);
|
||||||
theCommands.Add ("OCC23774", "OCC23774 shape1 shape2", __FILE__, OCC23774, group);
|
theCommands.Add ("OCC23774", "OCC23774 shape1 shape2", __FILE__, OCC23774, group);
|
||||||
|
theCommands.Add ("OCC23683", "OCC23683 shape", __FILE__, OCC23683, group);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
20
tests/bugs/moddata_3/bug23683
Normal file
20
tests/bugs/moddata_3/bug23683
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
puts "================"
|
||||||
|
puts "OCC23683"
|
||||||
|
puts "================"
|
||||||
|
puts ""
|
||||||
|
|
||||||
|
pload QAcommands
|
||||||
|
|
||||||
|
restore [locate_data_file bug23683_a_31_draw] result
|
||||||
|
set info [OCC23683 result]
|
||||||
|
|
||||||
|
if { [regexp "iscnu: OK" $info] != 1 } {
|
||||||
|
puts "Error : ucontinuity is incorrect"
|
||||||
|
}
|
||||||
|
|
||||||
|
if { [regexp "iscnv: OK" $info] != 1 } {
|
||||||
|
puts "Error : vcontinuity is incorrect"
|
||||||
|
}
|
||||||
|
|
||||||
|
set 2dviewer 0
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user