added: utility function to lower/raise order of a Bspline basis
and tests
This commit is contained in:
parent
a9096e5333
commit
5bfae73494
|
@ -309,6 +309,30 @@ Go::SplineVolume* SplineUtils::project (const Go::SplineVolume* volume,
|
|||
}
|
||||
|
||||
|
||||
Go::BsplineBasis SplineUtils::adjustBasis (const Go::BsplineBasis& basis,
|
||||
SplineUtils::AdjustOp adjust)
|
||||
{
|
||||
if (adjust == AdjustOp::Original)
|
||||
return basis;
|
||||
|
||||
std::vector<double> knots;
|
||||
basis.knotsSimple(knots);
|
||||
std::vector<int> mult;
|
||||
basis.knotMultiplicities(mult);
|
||||
std::vector<int> cont(knots.size());
|
||||
cont.front() = cont.back() = -1;
|
||||
int order = basis.order();
|
||||
int start_cont = adjust == AdjustOp::Lower ? order-2 : order;
|
||||
int mult_adjust = adjust == AdjustOp::Lower ? 0 : 1;
|
||||
int new_order = adjust == AdjustOp::Lower ? order - 1 : order + 1;
|
||||
for (size_t i = 1; i < knots.size()-1; ++i)
|
||||
cont[i] = start_cont - (mult[i] == 1 ? 1 : mult[i] + mult_adjust);
|
||||
|
||||
std::vector<double> newknot = SplineUtils::buildKnotVector(new_order-1, knots, cont);
|
||||
return Go::BsplineBasis(new_order, newknot.begin(), newknot.end());
|
||||
}
|
||||
|
||||
|
||||
std::vector<double> SplineUtils::buildKnotVector(int p,
|
||||
const std::vector<double>& knots,
|
||||
const std::vector<int>& cont)
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace Go {
|
|||
struct BasisDerivsSf3;
|
||||
struct BasisDerivs;
|
||||
struct BasisDerivs2;
|
||||
class BsplineBasis;
|
||||
class SplineCurve;
|
||||
class SplineSurface;
|
||||
class SplineVolume;
|
||||
|
@ -82,6 +83,17 @@ namespace SplineUtils //! Various utility functions on spline objects.
|
|||
const FunctionBase& f,
|
||||
int nComp = 1, Real time = Real(0));
|
||||
|
||||
//! \brief Enumeration of basis adjustment operations.
|
||||
enum class AdjustOp {
|
||||
Lower, //!< Lower order by one
|
||||
Original, //!< Keep original
|
||||
Raise, //!< Raise order by one
|
||||
};
|
||||
|
||||
//! \brief Returns a basis adjusted according to the given operation.
|
||||
Go::BsplineBasis adjustBasis(const Go::BsplineBasis& basis,
|
||||
AdjustOp adjust);
|
||||
|
||||
//! \brief Builds a knot vector from a given polynomial order, knots and continuities.
|
||||
std::vector<double> buildKnotVector(int p, const std::vector<double>& simple_knots,
|
||||
const std::vector<int>& continuities);
|
||||
|
|
|
@ -12,10 +12,11 @@
|
|||
|
||||
#include "SplineUtils.h"
|
||||
#include "GoTools/utils/Point.h"
|
||||
#include "GoTools/geometry/SplineSurface.h"
|
||||
#include <GoTools/geometry/BsplineBasis.h>
|
||||
#include "GoTools/geometry/Line.h"
|
||||
#include "GoTools/geometry/Disc.h"
|
||||
#include "GoTools/geometry/Plane.h"
|
||||
#include "GoTools/geometry/SplineSurface.h"
|
||||
#include "GoTools/trivariate/SphereVolume.h"
|
||||
#include "GoTools/trivariate/SplineVolume.h"
|
||||
#include "ExprFunctions.h"
|
||||
|
@ -450,3 +451,75 @@ TEST(TestSplineUtils, BuildKnotVector)
|
|||
for (size_t i = 0; i < ref.size(); ++i)
|
||||
EXPECT_FLOAT_EQ(ref[i], res[i]);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct AdjustBasisTest {
|
||||
int order_in;
|
||||
std::vector<double> knots_in;
|
||||
SplineUtils::AdjustOp op;
|
||||
std::vector<double> knots_out;
|
||||
};
|
||||
|
||||
using Op = SplineUtils::AdjustOp;
|
||||
|
||||
const std::vector<AdjustBasisTest> tests = {
|
||||
// p1 -> p1
|
||||
{2, {0.0, 0.0, 1.0, 1.0}, Op::Original,
|
||||
{0.0, 0.0, 1.0, 1.0}},
|
||||
|
||||
// p1 -> p2
|
||||
{2, {0.0, 0.0, 1.0, 1.0}, Op::Raise,
|
||||
{0.0, 0.0, 0.0, 1.0, 1.0, 1.0}},
|
||||
// p1 -> p2, extra knot
|
||||
{2, {0.0, 0.0, 0.5, 1.0, 1.0}, Op::Raise,
|
||||
{0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0}},
|
||||
// p2 -> p3, extra knot
|
||||
{3, {0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0}, Op::Raise,
|
||||
{0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0, 1.0}},
|
||||
// p2 -> p3, reduced cont
|
||||
{3, {0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, 1.0}, Op::Raise,
|
||||
{0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0}},
|
||||
//p3 -> p4
|
||||
{4, {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}, Op::Raise,
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0}},
|
||||
//p3 -> p4, reduced cont
|
||||
{4, {0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0}, Op::Raise,
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0}},
|
||||
|
||||
//p2 -> p1
|
||||
{3, {0.0, 0.0, 0.0, 1.0, 1.0, 1.0}, Op::Lower,
|
||||
{0.0, 0.0, 1.0, 1.0}},
|
||||
//p2 -> p1, extra knot
|
||||
{3, {0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0}, Op::Lower,
|
||||
{0.0, 0.0, 0.5, 1.0, 1.0}},
|
||||
//p3 -> p2, reduced cont
|
||||
{4, {0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0}, Op::Lower,
|
||||
{0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, 1.0}},
|
||||
//p4 -> p3
|
||||
{5, {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0}, Op::Lower,
|
||||
{0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}},
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class TestSplineUtils : public testing::Test,
|
||||
public testing::WithParamInterface<AdjustBasisTest>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
TEST_P(TestSplineUtils, AdjustBasis)
|
||||
{
|
||||
Go::BsplineBasis basis_in(GetParam().order_in,
|
||||
GetParam().knots_in.begin(),
|
||||
GetParam().knots_in.end());
|
||||
|
||||
const Go::BsplineBasis res = SplineUtils::adjustBasis(basis_in,GetParam().op);
|
||||
const std::vector<double> out{res.begin(), res.end()};
|
||||
EXPECT_EQ(out, GetParam().knots_out);
|
||||
}
|
||||
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(TestSplineUtils, TestSplineUtils, testing::ValuesIn(tests));
|
||||
|
|
Loading…
Reference in New Issue
Block a user