diff --git a/src/StepToGeom/FILES b/src/StepToGeom/FILES index 7a57bb0eb4..8ca04539e2 100755 --- a/src/StepToGeom/FILES +++ b/src/StepToGeom/FILES @@ -1,3 +1,2 @@ StepToGeom.cxx StepToGeom.hxx -StepToGeom_MakeBSplineCurve.pxx diff --git a/src/StepToGeom/StepToGeom.cxx b/src/StepToGeom/StepToGeom.cxx index 7b9c377779..b65e1b0d91 100644 --- a/src/StepToGeom/StepToGeom.cxx +++ b/src/StepToGeom/StepToGeom.cxx @@ -622,29 +622,179 @@ Handle(Geom_BoundedSurface) StepToGeom::MakeBoundedSurface (const Handle(StepGeo return 0; } +//============================================================================= +// Template function for use in MakeBSplineCurve / MakeBSplineCurve2d +//============================================================================= + +template +< + class TPntArray, + class TCartesianPoint, + class TGpPnt, + class TBSplineCurve +> +Handle(TBSplineCurve) MakeBSplineCurveCommon +( + const Handle(StepGeom_BSplineCurve)& theStepGeom_BSplineCurve, + TGpPnt(TCartesianPoint::* thePntGetterFunction)() const, + Handle(TCartesianPoint) (*thePointMakerFunction)(const Handle(StepGeom_CartesianPoint)&) +) +{ + Handle(StepGeom_BSplineCurveWithKnots) aBSplineCurveWithKnots; + Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) aBSplineCurveWithKnotsAndRationalBSplineCurve; + + if (theStepGeom_BSplineCurve->IsKind(STANDARD_TYPE(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve))) + { + aBSplineCurveWithKnotsAndRationalBSplineCurve = + Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve)::DownCast(theStepGeom_BSplineCurve); + aBSplineCurveWithKnots = aBSplineCurveWithKnotsAndRationalBSplineCurve->BSplineCurveWithKnots(); + } + else + aBSplineCurveWithKnots = Handle(StepGeom_BSplineCurveWithKnots)::DownCast(theStepGeom_BSplineCurve); + + const Standard_Integer aDegree = aBSplineCurveWithKnots->Degree(); + const Standard_Integer NbPoles = aBSplineCurveWithKnots->NbControlPointsList(); + const Standard_Integer NbKnots = aBSplineCurveWithKnots->NbKnotMultiplicities(); + + const Handle(TColStd_HArray1OfInteger)& aKnotMultiplicities = aBSplineCurveWithKnots->KnotMultiplicities(); + const Handle(TColStd_HArray1OfReal)& aKnots = aBSplineCurveWithKnots->Knots(); + + // Count number of unique knots + Standard_Integer NbUniqueKnots = 0; + Standard_Real lastKnot = RealFirst(); + for (Standard_Integer i = 1; i <= NbKnots; ++i) + { + if (aKnots->Value(i) - lastKnot > Epsilon(Abs(lastKnot))) + { + NbUniqueKnots++; + lastKnot = aKnots->Value(i); + } + } + if (NbUniqueKnots <= 1) + { + return 0; + } + TColStd_Array1OfReal aUniqueKnots(1, NbUniqueKnots); + TColStd_Array1OfInteger aUniqueKnotMultiplicities(1, NbUniqueKnots); + lastKnot = aKnots->Value(1); + aUniqueKnots.SetValue(1, aKnots->Value(1)); + aUniqueKnotMultiplicities.SetValue(1, aKnotMultiplicities->Value(1)); + Standard_Integer aKnotPosition = 1; + for (Standard_Integer i = 2; i <= NbKnots; i++) + { + if (aKnots->Value(i) - lastKnot > Epsilon(Abs(lastKnot))) + { + aKnotPosition++; + aUniqueKnots.SetValue(aKnotPosition, aKnots->Value(i)); + aUniqueKnotMultiplicities.SetValue(aKnotPosition, aKnotMultiplicities->Value(i)); + lastKnot = aKnots->Value(i); + } + else + { + // Knot not unique, increase multiplicity + Standard_Integer aCurrentMultiplicity = aUniqueKnotMultiplicities.Value(aKnotPosition); + aUniqueKnotMultiplicities.SetValue(aKnotPosition, aCurrentMultiplicity + aKnotMultiplicities->Value(i)); + } + } + + Standard_Integer aFirstMuultypisityDifference = 0; + Standard_Integer aLastMuultypisityDifference = 0; + for (Standard_Integer i = 1; i <= NbUniqueKnots; ++i) + { + Standard_Integer aCurrentVal = aUniqueKnotMultiplicities.Value(i); + if (aCurrentVal > aDegree + 1) + { + if (i == 1) + aFirstMuultypisityDifference = aCurrentVal - aDegree - 1; + if (i == NbUniqueKnots) + aLastMuultypisityDifference = aCurrentVal - aDegree - 1; +#ifdef OCCT_DEBUG + std::cout << "\nWrong multiplicity " << aCurrentVal << " on " << i + << " knot!" << "\nChanged to " << aDegree + 1 << std::endl; +#endif + aCurrentVal = aDegree + 1; + } + aUniqueKnotMultiplicities.SetValue(i, aCurrentVal); + } + + const Handle(StepGeom_HArray1OfCartesianPoint)& aControlPointsList = aBSplineCurveWithKnots->ControlPointsList(); + Standard_Integer aSummaryMuultypisityDifference = aFirstMuultypisityDifference + aLastMuultypisityDifference; + Standard_Integer NbUniquePoles = NbPoles - aSummaryMuultypisityDifference; + if (NbUniquePoles <= 0) + { + return 0; + } + TPntArray Poles(1, NbPoles - aSummaryMuultypisityDifference); + + for (Standard_Integer i = 1 + aFirstMuultypisityDifference; i <= NbPoles - aLastMuultypisityDifference; ++i) + { + Handle(TCartesianPoint) aPoint = (*thePointMakerFunction)(aControlPointsList->Value(i)); + if (!aPoint.IsNull()) + { + TCartesianPoint* pPoint = aPoint.get(); + TGpPnt aGpPnt = (pPoint->*thePntGetterFunction)(); + Poles.SetValue(i - aFirstMuultypisityDifference, aGpPnt); + } + else + { + return 0; + } + } + + // --- Does the Curve descriptor LOOKS like a periodic descriptor ? --- + Standard_Integer aSummaryMuultypisity = 0; + for (Standard_Integer i = 1; i <= NbUniqueKnots; i++) + { + aSummaryMuultypisity += aUniqueKnotMultiplicities.Value(i); + } + + Standard_Boolean shouldBePeriodic; + if (aSummaryMuultypisity == (NbPoles + aDegree + 1)) + { + shouldBePeriodic = Standard_False; + } + else if ((aUniqueKnotMultiplicities.Value(1) == aUniqueKnotMultiplicities.Value(NbUniqueKnots)) && + ((aSummaryMuultypisity - aUniqueKnotMultiplicities.Value(1)) == NbPoles)) + { + shouldBePeriodic = Standard_True; + } + else + { + // --- What is that ??? --- + shouldBePeriodic = Standard_False; + } + + Handle(TBSplineCurve) aBSplineCurve; + if (theStepGeom_BSplineCurve->IsKind(STANDARD_TYPE(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve))) + { + const Handle(TColStd_HArray1OfReal)& aWeights = aBSplineCurveWithKnotsAndRationalBSplineCurve->WeightsData(); + TColStd_Array1OfReal aUniqueWeights(1, NbPoles - aSummaryMuultypisityDifference); + for (Standard_Integer i = 1 + aFirstMuultypisityDifference; i <= NbPoles - aLastMuultypisityDifference; ++i) + aUniqueWeights.SetValue(i - aFirstMuultypisityDifference, aWeights->Value(i)); + aBSplineCurve = new TBSplineCurve(Poles, aUniqueWeights, aUniqueKnots, aUniqueKnotMultiplicities, aDegree, shouldBePeriodic); + } + else + { + aBSplineCurve = new TBSplineCurve(Poles, aUniqueKnots, aUniqueKnotMultiplicities, aDegree, shouldBePeriodic); + } + + // abv 04.07.00 CAX-IF TRJ4: trj4_k1_top-md-203.stp #716 (face #581): + // force periodicity on closed curves + if (theStepGeom_BSplineCurve->ClosedCurve() && aBSplineCurve->Degree() > 1 && aBSplineCurve->IsClosed()) + { + aBSplineCurve->SetPeriodic(); + } + return aBSplineCurve; +} + //============================================================================= // Creation d' une BSplineCurve de Geom a partir d' une BSplineCurve de Step //============================================================================= -Handle(Geom_BSplineCurve) StepToGeom::MakeBSplineCurve (const Handle(StepGeom_BSplineCurve)& SC) +Handle(Geom_BSplineCurve) StepToGeom::MakeBSplineCurve (const Handle(StepGeom_BSplineCurve)& theStepGeom_BSplineCurve) { -#define Array1OfPnt_gen TColgp_Array1OfPnt -#define Pnt_gen gp_Pnt -#define Pnt_fonc Pnt -#define CartesianPoint_gen Handle(Geom_CartesianPoint) -#define MakeCartesianPoint_gen MakeCartesianPoint -#define BSplineCurve_gen Geom_BSplineCurve -#define BSplineCurve_retour Handle(Geom_BSplineCurve) -#define MakeBSplineCurve_gen MakeBSplineCurve -#include "StepToGeom_MakeBSplineCurve.pxx" -#undef Array1OfPnt_gen -#undef Pnt_gen -#undef Pnt_fonc -#undef CartesianPoint_gen -#undef MakeCartesianPoint_gen -#undef BSplineCurve_gen -#undef MakeBSplineCurve_gen -#undef BSplineCurve_retour + return MakeBSplineCurveCommon + (theStepGeom_BSplineCurve, &Geom_CartesianPoint::Pnt, &MakeCartesianPoint); } //============================================================================= @@ -652,25 +802,10 @@ Handle(Geom_BSplineCurve) StepToGeom::MakeBSplineCurve (const Handle(StepGeom_BS // BSplineCurveWithKnotsAndRationalBSplineCurve de Step //============================================================================= -Handle(Geom2d_BSplineCurve) StepToGeom::MakeBSplineCurve2d (const Handle(StepGeom_BSplineCurve)& SC) +Handle(Geom2d_BSplineCurve) StepToGeom::MakeBSplineCurve2d (const Handle(StepGeom_BSplineCurve)& theStepGeom_BSplineCurve) { -#define Array1OfPnt_gen TColgp_Array1OfPnt2d -#define Pnt_gen gp_Pnt2d -#define CartesianPoint_gen Handle(Geom2d_CartesianPoint) -#define MakeCartesianPoint_gen MakeCartesianPoint2d -#define Pnt_fonc Pnt2d -#define BSplineCurve_gen Geom2d_BSplineCurve -#define BSplineCurve_retour Handle(Geom2d_BSplineCurve) -#define MakeBSplineCurve_gen MakeBSplineCurve2d -#include "StepToGeom_MakeBSplineCurve.pxx" -#undef Array1OfPnt_gen -#undef Pnt_gen -#undef CartesianPoint_gen -#undef MakeCartesianPoint_gen -#undef Pnt_fonc -#undef BSplineCurve_gen -#undef MakeBSplineCurve_gen -#undef BSplineCurve_retour + return MakeBSplineCurveCommon + (theStepGeom_BSplineCurve, &Geom2d_CartesianPoint::Pnt2d, &MakeCartesianPoint2d); } //============================================================================= diff --git a/src/StepToGeom/StepToGeom_MakeBSplineCurve.pxx b/src/StepToGeom/StepToGeom_MakeBSplineCurve.pxx deleted file mode 100644 index 4ea9525c1d..0000000000 --- a/src/StepToGeom/StepToGeom_MakeBSplineCurve.pxx +++ /dev/null @@ -1,142 +0,0 @@ -// Created on: 1993-07-02 -// Created by: Martine LANGLOIS -// Copyright (c) 1993-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - - Handle(StepGeom_BSplineCurveWithKnots) BSCW; - Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) BSCWR; - - if (SC->IsKind(STANDARD_TYPE(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve))) { - BSCWR = Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve)::DownCast(SC); - BSCW = BSCWR->BSplineCurveWithKnots(); - } - else - BSCW = Handle(StepGeom_BSplineCurveWithKnots)::DownCast(SC); - - const Standard_Integer Deg = BSCW->Degree(); - const Standard_Integer NbPoles = BSCW->NbControlPointsList(); - const Standard_Integer NbKnots = BSCW->NbKnotMultiplicities(); - - //aKnotMultiplicities = new TColStd_HArray1OfInteger(1,NbKnots); - const Handle(TColStd_HArray1OfInteger)& aKnotMultiplicities = BSCW->KnotMultiplicities(); - //aKnots = new TColStd_HArray1OfReal(1,NbKnots); - const Handle(TColStd_HArray1OfReal)& aKnots = BSCW->Knots(); - - // Count number of unique knots - Standard_Integer i; - Standard_Integer NbUniqueKnots = 0; - Standard_Real lastKnot = RealFirst(); - for (i=1; i<=NbKnots; ++i) { - if (aKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) { - NbUniqueKnots++; - lastKnot = aKnots->Value(i); - } - } - if(NbUniqueKnots <= 1) - { - return 0; - } - TColStd_Array1OfReal Kn(1,NbUniqueKnots); - TColStd_Array1OfInteger Mult(1,NbUniqueKnots); - lastKnot = aKnots->Value(1); - Kn.SetValue(1, aKnots->Value(1)); - Mult.SetValue(1, aKnotMultiplicities->Value(1)); - Standard_Integer pos = 1; - for (i=2; i<=NbKnots; i++) { - if (aKnots->Value(i) - lastKnot > Epsilon (Abs(lastKnot))) { - pos++; - Kn.SetValue(pos, aKnots->Value(i)); - Mult.SetValue(pos, aKnotMultiplicities->Value(i)); - lastKnot = aKnots->Value(i); - } - else { - // Knot not unique, increase multiplicity - Standard_Integer curMult = Mult.Value(pos); - Mult.SetValue(pos, curMult + aKnotMultiplicities->Value(i)); - } - } - - Standard_Integer aFMulDiff = 0,aLMulDiff = 0; - for (i=1; i<=NbUniqueKnots; ++i) { - Standard_Integer aCurrentVal = Mult.Value(i); - if (aCurrentVal > Deg + 1) - { - if (i == 1) aFMulDiff = aCurrentVal - Deg - 1; - if (i == NbUniqueKnots) aLMulDiff = aCurrentVal - Deg - 1; -#ifdef OCCT_DEBUG - std::cout << "\nWrong multiplicity " << aCurrentVal << " on " << i - << " knot!" << "\nChanged to " << Deg + 1 << std::endl; -#endif - aCurrentVal = Deg + 1; - } - Mult.SetValue(i,aCurrentVal); - } - - //aControlPointsList = new StepGeom_HArray1OfCartesianPoint(1,NbPoles); - const Handle(StepGeom_HArray1OfCartesianPoint)& aControlPointsList = BSCW->ControlPointsList(); - Standard_Integer aSumMulDiff = aFMulDiff + aLMulDiff; - Standard_Integer nbP = NbPoles - aSumMulDiff; - if( nbP <= 0) - { - return 0; - } - Array1OfPnt_gen Poles(1,NbPoles - aSumMulDiff); - - for (i = 1 + aFMulDiff; i<= NbPoles - aLMulDiff; ++i) - { - CartesianPoint_gen P = MakeCartesianPoint_gen (aControlPointsList->Value(i)); - if (! P.IsNull()) - Poles.SetValue(i - aFMulDiff,P->Pnt_fonc()); - else - return 0; - } - - // --- Does the Curve descriptor LOOKS like a periodic descriptor ? --- - - Standard_Integer SumMult = 0; - for (i=1; i<=NbUniqueKnots; i++) { - SumMult += Mult.Value(i); - } - - Standard_Boolean shouldBePeriodic; - if (SumMult == (NbPoles + Deg + 1)) { - shouldBePeriodic = Standard_False; - } - else if ((Mult.Value(1) == - Mult.Value(NbUniqueKnots)) && - ((SumMult - Mult.Value(1)) == NbPoles)) { - shouldBePeriodic = Standard_True; - } - else { // --- What is that ??? --- - shouldBePeriodic = Standard_False; - //cout << "Strange BSpline Curve Descriptor" << endl; - } - - BSplineCurve_retour CC; - if (SC->IsKind(STANDARD_TYPE(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve))) { - const Handle(TColStd_HArray1OfReal)& aWeight = BSCWR->WeightsData(); - TColStd_Array1OfReal W(1, NbPoles - aSumMulDiff); - for (i= 1 + aFMulDiff; i<= NbPoles - aLMulDiff; i++) - W.SetValue(i - aFMulDiff,aWeight->Value(i)); - CC = new BSplineCurve_gen(Poles, W, Kn, Mult, Deg, shouldBePeriodic); - } - else - CC = new BSplineCurve_gen(Poles, Kn, Mult, Deg, shouldBePeriodic); - - // abv 04.07.00 CAX-IF TRJ4: trj4_k1_top-md-203.stp #716 (face #581): - // force periodicity on closed curves - if ( SC->ClosedCurve() && CC->Degree() >1 && CC->IsClosed() ) { - CC->SetPeriodic(); - } - return CC;