mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-05-19 01:39:00 +08:00
Update empty method guards to new style with regex (see PR). Used clang-format 18.1.8. New actions to validate code formatting is added. Update .clang-format with disabling of include sorting. It is temporary changes, then include will be sorted. Apply formatting for /src and /tools folder. The files with .hxx,.cxx,.lxx,.h,.pxx,.hpp,*.cpp extensions.
833 lines
26 KiB
C++
833 lines
26 KiB
C++
// Created on: 1994-08-18
|
|
// Created by: Laurent PAINNOT
|
|
// Copyright (c) 1994-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.
|
|
|
|
// 8-Aug-95 : xab : interpolation uses BSplCLib::Interpolate
|
|
|
|
#include <BSplCLib.hxx>
|
|
#include <Geom2d_BSplineCurve.hxx>
|
|
#include <Geom2dAPI_Interpolate.hxx>
|
|
#include <gp_Vec2d.hxx>
|
|
#include <PLib.hxx>
|
|
#include <Standard_ConstructionError.hxx>
|
|
#include <StdFail_NotDone.hxx>
|
|
#include <TColgp_Array1OfPnt2d.hxx>
|
|
#include <TColStd_Array1OfBoolean.hxx>
|
|
#include <TColStd_Array1OfInteger.hxx>
|
|
#include <TColStd_HArray1OfBoolean.hxx>
|
|
#include <TColStd_HArray1OfReal.hxx>
|
|
|
|
//=================================================================================================
|
|
|
|
static Standard_Boolean CheckPoints(const TColgp_Array1OfPnt2d& PointArray,
|
|
const Standard_Real Tolerance)
|
|
{
|
|
Standard_Integer ii;
|
|
Standard_Real tolerance_squared = Tolerance * Tolerance, distance_squared;
|
|
Standard_Boolean result = Standard_True;
|
|
for (ii = PointArray.Lower(); result && ii < PointArray.Upper(); ii++)
|
|
{
|
|
distance_squared = PointArray.Value(ii).SquareDistance(PointArray.Value(ii + 1));
|
|
result = (distance_squared >= tolerance_squared);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
static Standard_Boolean CheckTangents(const TColgp_Array1OfVec2d& Tangents,
|
|
const TColStd_Array1OfBoolean& TangentFlags,
|
|
const Standard_Real Tolerance)
|
|
{
|
|
Standard_Integer ii, index;
|
|
Standard_Real tolerance_squared = Tolerance * Tolerance, distance_squared;
|
|
Standard_Boolean result = Standard_True;
|
|
index = TangentFlags.Lower();
|
|
for (ii = Tangents.Lower(); result && ii <= Tangents.Upper(); ii++)
|
|
{
|
|
if (TangentFlags.Value(index))
|
|
{
|
|
distance_squared = Tangents.Value(ii).SquareMagnitude();
|
|
result = (distance_squared >= tolerance_squared);
|
|
}
|
|
index += 1;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
static Standard_Boolean CheckParameters(const TColStd_Array1OfReal& Parameters)
|
|
{
|
|
Standard_Integer ii;
|
|
Standard_Real distance;
|
|
Standard_Boolean result = Standard_True;
|
|
for (ii = Parameters.Lower(); result && ii < Parameters.Upper(); ii++)
|
|
{
|
|
distance = Parameters.Value(ii + 1) - Parameters.Value(ii);
|
|
result = (distance >= RealSmall());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
static void BuildParameters(const Standard_Boolean PeriodicFlag,
|
|
const TColgp_Array1OfPnt2d& PointsArray,
|
|
Handle(TColStd_HArray1OfReal)& ParametersPtr)
|
|
{
|
|
Standard_Integer ii, index;
|
|
Standard_Real distance;
|
|
Standard_Integer num_parameters = PointsArray.Length();
|
|
if (PeriodicFlag)
|
|
{
|
|
num_parameters += 1;
|
|
}
|
|
ParametersPtr = new TColStd_HArray1OfReal(1, num_parameters);
|
|
ParametersPtr->SetValue(1, 0.0e0);
|
|
index = 2;
|
|
for (ii = PointsArray.Lower(); ii < PointsArray.Upper(); ii++)
|
|
{
|
|
distance = PointsArray.Value(ii).Distance(PointsArray.Value(ii + 1));
|
|
ParametersPtr->SetValue(index, ParametersPtr->Value(ii) + distance);
|
|
index += 1;
|
|
}
|
|
if (PeriodicFlag)
|
|
{
|
|
distance =
|
|
PointsArray.Value(PointsArray.Upper()).Distance(PointsArray.Value(PointsArray.Lower()));
|
|
ParametersPtr->SetValue(index, ParametersPtr->Value(ii) + distance);
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
static void BuildPeriodicTangent(const TColgp_Array1OfPnt2d& PointsArray,
|
|
TColgp_Array1OfVec2d& TangentsArray,
|
|
TColStd_Array1OfBoolean& TangentFlags,
|
|
const TColStd_Array1OfReal& ParametersArray)
|
|
{
|
|
Standard_Integer ii, degree;
|
|
Standard_Real * point_array, *parameter_array, eval_result[2][2];
|
|
|
|
gp_Vec2d a_vector;
|
|
|
|
if (PointsArray.Length() < 3)
|
|
{
|
|
throw Standard_ConstructionError();
|
|
}
|
|
|
|
if (!TangentFlags.Value(1))
|
|
{
|
|
degree = 3;
|
|
if (PointsArray.Length() == 3)
|
|
{
|
|
degree = 2;
|
|
}
|
|
point_array = (Standard_Real*)&PointsArray.Value(PointsArray.Lower());
|
|
parameter_array = (Standard_Real*)&ParametersArray.Value(1);
|
|
TangentFlags.SetValue(1, Standard_True);
|
|
PLib::EvalLagrange(ParametersArray.Value(1),
|
|
1,
|
|
degree,
|
|
2,
|
|
point_array[0],
|
|
parameter_array[0],
|
|
eval_result[0][0]);
|
|
for (ii = 1; ii <= 2; ii++)
|
|
{
|
|
a_vector.SetCoord(ii, eval_result[1][ii - 1]);
|
|
}
|
|
TangentsArray.SetValue(1, a_vector);
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
static void BuildTangents(const TColgp_Array1OfPnt2d& PointsArray,
|
|
TColgp_Array1OfVec2d& TangentsArray,
|
|
TColStd_Array1OfBoolean& TangentFlags,
|
|
const TColStd_Array1OfReal& ParametersArray)
|
|
{
|
|
Standard_Integer ii, degree;
|
|
Standard_Real * point_array, *parameter_array,
|
|
|
|
eval_result[2][2];
|
|
gp_Vec2d a_vector;
|
|
|
|
degree = 3;
|
|
|
|
if (PointsArray.Length() < 3)
|
|
{
|
|
throw Standard_ConstructionError();
|
|
}
|
|
if (PointsArray.Length() == 3)
|
|
{
|
|
degree = 2;
|
|
}
|
|
if (!TangentFlags.Value(1))
|
|
{
|
|
point_array = (Standard_Real*)&PointsArray.Value(PointsArray.Lower());
|
|
parameter_array = (Standard_Real*)&ParametersArray.Value(1);
|
|
TangentFlags.SetValue(1, Standard_True);
|
|
PLib::EvalLagrange(ParametersArray.Value(1),
|
|
1,
|
|
degree,
|
|
2,
|
|
point_array[0],
|
|
parameter_array[0],
|
|
eval_result[0][0]);
|
|
for (ii = 1; ii <= 2; ii++)
|
|
{
|
|
a_vector.SetCoord(ii, eval_result[1][ii - 1]);
|
|
}
|
|
TangentsArray.SetValue(1, a_vector);
|
|
}
|
|
if (!TangentFlags.Value(TangentFlags.Upper()))
|
|
{
|
|
point_array = (Standard_Real*)&PointsArray.Value(PointsArray.Upper() - degree);
|
|
TangentFlags.SetValue(TangentFlags.Upper(), Standard_True);
|
|
parameter_array = (Standard_Real*)&ParametersArray.Value(ParametersArray.Upper() - degree);
|
|
PLib::EvalLagrange(ParametersArray.Value(ParametersArray.Upper()),
|
|
1,
|
|
degree,
|
|
2,
|
|
point_array[0],
|
|
parameter_array[0],
|
|
eval_result[0][0]);
|
|
for (ii = 1; ii <= 2; ii++)
|
|
{
|
|
a_vector.SetCoord(ii, eval_result[1][ii - 1]);
|
|
}
|
|
TangentsArray.SetValue(TangentsArray.Upper(), a_vector);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : BuildTangents
|
|
// purpose : scale the given tangent so that they have the length of
|
|
// the size of the derivative of the lagrange interpolation
|
|
//
|
|
//=======================================================================
|
|
static void ScaleTangents(const TColgp_Array1OfPnt2d& PointsArray,
|
|
TColgp_Array1OfVec2d& TangentsArray,
|
|
const TColStd_Array1OfBoolean& TangentFlags,
|
|
const TColStd_Array1OfReal& ParametersArray)
|
|
{
|
|
Standard_Integer ii, jj, degree = 0, index, num_points;
|
|
|
|
Standard_Real *point_array, *parameter_array, value[2], ratio, eval_result[2][2];
|
|
|
|
gp_Vec2d a_vector;
|
|
|
|
num_points = PointsArray.Length();
|
|
if (num_points == 2)
|
|
{
|
|
degree = 1;
|
|
}
|
|
else if (num_points >= 3)
|
|
{
|
|
degree = 2;
|
|
}
|
|
|
|
index = PointsArray.Lower();
|
|
for (ii = TangentFlags.Lower(); ii <= TangentFlags.Upper(); ii++)
|
|
{
|
|
if (TangentFlags.Value(ii))
|
|
{
|
|
point_array = (Standard_Real*)&PointsArray.Value(index);
|
|
parameter_array = (Standard_Real*)&ParametersArray.Value(index);
|
|
PLib::EvalLagrange(ParametersArray.Value(ii),
|
|
1,
|
|
degree,
|
|
2,
|
|
point_array[0],
|
|
parameter_array[0],
|
|
eval_result[0][0]);
|
|
value[0] = value[1] = 0.0e0;
|
|
for (jj = 1; jj <= 2; jj++)
|
|
{
|
|
value[0] += Abs(TangentsArray.Value(ii).Coord(jj));
|
|
value[1] += Abs(eval_result[1][jj - 1]);
|
|
}
|
|
ratio = value[1] / value[0];
|
|
for (jj = 1; jj <= 2; jj++)
|
|
{
|
|
a_vector.SetCoord(jj, ratio * TangentsArray.Value(ii).Coord(jj));
|
|
}
|
|
TangentsArray.SetValue(ii, a_vector);
|
|
if (ii != TangentFlags.Lower())
|
|
{
|
|
index += 1;
|
|
}
|
|
if (index > PointsArray.Upper() - degree)
|
|
{
|
|
index = PointsArray.Upper() - degree;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Geom2dAPI_Interpolate::Geom2dAPI_Interpolate(const Handle(TColgp_HArray1OfPnt2d)& PointsPtr,
|
|
const Standard_Boolean PeriodicFlag,
|
|
const Standard_Real Tolerance)
|
|
: myTolerance(Tolerance),
|
|
myPoints(PointsPtr),
|
|
myIsDone(Standard_False),
|
|
myPeriodic(PeriodicFlag),
|
|
myTangentRequest(Standard_False)
|
|
|
|
{
|
|
Standard_Integer ii;
|
|
Standard_Boolean result = CheckPoints(PointsPtr->Array1(), Tolerance);
|
|
myTangents = new TColgp_HArray1OfVec2d(myPoints->Lower(), myPoints->Upper());
|
|
myTangentFlags = new TColStd_HArray1OfBoolean(myPoints->Lower(), myPoints->Upper());
|
|
|
|
if (!result)
|
|
{
|
|
throw Standard_ConstructionError();
|
|
}
|
|
BuildParameters(PeriodicFlag, PointsPtr->Array1(), myParameters);
|
|
|
|
for (ii = myPoints->Lower(); ii <= myPoints->Upper(); ii++)
|
|
{
|
|
myTangentFlags->SetValue(ii, Standard_False);
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Geom2dAPI_Interpolate::Geom2dAPI_Interpolate(const Handle(TColgp_HArray1OfPnt2d)& PointsPtr,
|
|
const Handle(TColStd_HArray1OfReal)& ParametersPtr,
|
|
const Standard_Boolean PeriodicFlag,
|
|
const Standard_Real Tolerance)
|
|
: myTolerance(Tolerance),
|
|
myPoints(PointsPtr),
|
|
myIsDone(Standard_False),
|
|
myParameters(ParametersPtr),
|
|
myPeriodic(PeriodicFlag),
|
|
myTangentRequest(Standard_False)
|
|
{
|
|
Standard_Integer ii;
|
|
|
|
Standard_Boolean result = CheckPoints(PointsPtr->Array1(), Tolerance);
|
|
|
|
if (PeriodicFlag)
|
|
{
|
|
if ((PointsPtr->Length()) + 1 != ParametersPtr->Length())
|
|
{
|
|
throw Standard_ConstructionError();
|
|
}
|
|
}
|
|
myTangents = new TColgp_HArray1OfVec2d(myPoints->Lower(), myPoints->Upper());
|
|
myTangentFlags = new TColStd_HArray1OfBoolean(myPoints->Lower(), myPoints->Upper());
|
|
|
|
if (!result)
|
|
{
|
|
throw Standard_ConstructionError();
|
|
}
|
|
|
|
result = CheckParameters(ParametersPtr->Array1());
|
|
if (!result)
|
|
{
|
|
throw Standard_ConstructionError();
|
|
}
|
|
|
|
for (ii = myPoints->Lower(); ii <= myPoints->Upper(); ii++)
|
|
{
|
|
myTangentFlags->SetValue(ii, Standard_False);
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void Geom2dAPI_Interpolate::Load(const TColgp_Array1OfVec2d& Tangents,
|
|
const Handle(TColStd_HArray1OfBoolean)& TangentFlagsPtr,
|
|
const Standard_Boolean Scale)
|
|
|
|
{
|
|
Standard_Boolean result;
|
|
Standard_Integer ii;
|
|
myTangentRequest = Standard_True;
|
|
myTangentFlags = TangentFlagsPtr;
|
|
if (Tangents.Length() != myPoints->Length() || TangentFlagsPtr->Length() != myPoints->Length())
|
|
{
|
|
throw Standard_ConstructionError();
|
|
}
|
|
result = CheckTangents(Tangents, TangentFlagsPtr->Array1(), myTolerance);
|
|
if (result)
|
|
{
|
|
myTangents = new TColgp_HArray1OfVec2d(Tangents.Lower(), Tangents.Upper());
|
|
for (ii = Tangents.Lower(); ii <= Tangents.Upper(); ii++)
|
|
{
|
|
myTangents->SetValue(ii, Tangents.Value(ii));
|
|
}
|
|
if (Scale)
|
|
{
|
|
ScaleTangents(myPoints->Array1(),
|
|
myTangents->ChangeArray1(),
|
|
TangentFlagsPtr->Array1(),
|
|
myParameters->Array1());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw Standard_ConstructionError();
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void Geom2dAPI_Interpolate::Load(const gp_Vec2d& InitialTangent,
|
|
const gp_Vec2d& FinalTangent,
|
|
const Standard_Boolean Scale)
|
|
{
|
|
Standard_Boolean result;
|
|
myTangentRequest = Standard_True;
|
|
myTangentFlags->SetValue(1, Standard_True);
|
|
myTangentFlags->SetValue(myPoints->Length(), Standard_True);
|
|
myTangents->SetValue(1, InitialTangent);
|
|
myTangents->SetValue(myPoints->Length(), FinalTangent);
|
|
result = CheckTangents(myTangents->Array1(), myTangentFlags->Array1(), myTolerance);
|
|
if (!result)
|
|
{
|
|
throw Standard_ConstructionError();
|
|
}
|
|
if (Scale)
|
|
{
|
|
ScaleTangents(myPoints->Array1(),
|
|
myTangents->ChangeArray1(),
|
|
myTangentFlags->Array1(),
|
|
myParameters->Array1());
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void Geom2dAPI_Interpolate::Perform()
|
|
{
|
|
if (myPeriodic)
|
|
{
|
|
PerformPeriodic();
|
|
}
|
|
else
|
|
{
|
|
PerformNonPeriodic();
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void Geom2dAPI_Interpolate::PerformPeriodic()
|
|
{
|
|
Standard_Integer degree, ii, jj, index, index1,
|
|
// index2,
|
|
mult_index, half_order, inversion_problem, num_points, num_distinct_knots, num_poles;
|
|
|
|
Standard_Real period;
|
|
|
|
gp_Pnt2d a_point;
|
|
|
|
num_points = myPoints->Length();
|
|
period = myParameters->Value(myParameters->Upper()) - myParameters->Value(myParameters->Lower());
|
|
num_poles = num_points + 1;
|
|
if (num_points == 2 && !myTangentRequest)
|
|
{
|
|
//
|
|
// build a periodic curve of degree 1
|
|
//
|
|
|
|
degree = 1;
|
|
TColStd_Array1OfInteger deg1_mults(1, num_poles);
|
|
for (ii = 1; ii <= num_poles; ii++)
|
|
{
|
|
deg1_mults.SetValue(ii, 1);
|
|
}
|
|
|
|
myCurve = new Geom2d_BSplineCurve(myPoints->Array1(),
|
|
myParameters->Array1(),
|
|
deg1_mults,
|
|
degree,
|
|
myPeriodic);
|
|
myIsDone = Standard_True;
|
|
}
|
|
else
|
|
{
|
|
num_distinct_knots = num_points + 1;
|
|
half_order = 2;
|
|
degree = 3;
|
|
num_poles += 2;
|
|
if (myTangentRequest)
|
|
for (ii = myTangentFlags->Lower() + 1; ii <= myTangentFlags->Upper(); ii++)
|
|
{
|
|
if (myTangentFlags->Value(ii))
|
|
{
|
|
num_poles += 1;
|
|
}
|
|
}
|
|
|
|
TColStd_Array1OfReal parameters(1, num_poles);
|
|
TColStd_Array1OfReal flatknots(1, num_poles + degree + 1);
|
|
TColStd_Array1OfInteger mults(1, num_distinct_knots);
|
|
TColStd_Array1OfInteger contact_order_array(1, num_poles);
|
|
TColgp_Array1OfPnt2d poles(1, num_poles);
|
|
|
|
for (ii = 1; ii <= half_order; ii++)
|
|
{
|
|
flatknots.SetValue(ii, myParameters->Value(myParameters->Upper() - 1) - period);
|
|
flatknots.SetValue(ii + half_order, myParameters->Value(myParameters->Lower()));
|
|
flatknots.SetValue(num_poles + ii, myParameters->Value(myParameters->Upper()));
|
|
flatknots.SetValue(num_poles + half_order + ii, myParameters->Value(half_order) + period);
|
|
}
|
|
for (ii = 1; ii <= num_poles; ii++)
|
|
{
|
|
contact_order_array.SetValue(ii, 0);
|
|
}
|
|
for (ii = 2; ii < num_distinct_knots; ii++)
|
|
{
|
|
mults.SetValue(ii, 1);
|
|
}
|
|
mults.SetValue(1, half_order);
|
|
mults.SetValue(num_distinct_knots, half_order);
|
|
if (num_points >= 3)
|
|
{
|
|
|
|
//
|
|
// only enter here if there are more than 3 points otherwise
|
|
// it means we have already the tangent
|
|
//
|
|
BuildPeriodicTangent(myPoints->Array1(),
|
|
myTangents->ChangeArray1(),
|
|
myTangentFlags->ChangeArray1(),
|
|
myParameters->Array1());
|
|
}
|
|
contact_order_array.SetValue(2, 1);
|
|
parameters.SetValue(1, myParameters->Value(1));
|
|
parameters.SetValue(2, myParameters->Value(1));
|
|
poles.SetValue(1, myPoints->Value(1));
|
|
for (jj = 1; jj <= 2; jj++)
|
|
{
|
|
a_point.SetCoord(jj, myTangents->Value(1).Coord(jj));
|
|
}
|
|
poles.SetValue(2, a_point);
|
|
|
|
mult_index = 2;
|
|
index = 3;
|
|
index1 = degree + 2;
|
|
if (myTangentRequest)
|
|
{
|
|
for (ii = myTangentFlags->Lower() + 1; ii <= myTangentFlags->Upper(); ii++)
|
|
{
|
|
parameters.SetValue(index, myParameters->Value(ii));
|
|
flatknots.SetValue(index1, myParameters->Value(ii));
|
|
poles.SetValue(index, myPoints->Value(ii));
|
|
index += 1;
|
|
index1 += 1;
|
|
if (myTangentFlags->Value(ii))
|
|
{
|
|
mults.SetValue(mult_index, mults.Value(mult_index) + 1);
|
|
contact_order_array(index) = 1;
|
|
|
|
parameters.SetValue(index, myParameters->Value(ii));
|
|
flatknots.SetValue(index1, myParameters->Value(ii));
|
|
for (jj = 1; jj <= 2; jj++)
|
|
{
|
|
a_point.SetCoord(jj, myTangents->Value(ii).Coord(jj));
|
|
}
|
|
poles.SetValue(index, a_point);
|
|
index += 1;
|
|
index1 += 1;
|
|
}
|
|
mult_index += 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
index = degree + 1;
|
|
index1 = 2;
|
|
for (ii = myParameters->Lower(); ii <= myParameters->Upper(); ii++)
|
|
{
|
|
parameters.SetValue(index1, myParameters->Value(ii));
|
|
flatknots.SetValue(index, myParameters->Value(ii));
|
|
index += 1;
|
|
index1 += 1;
|
|
}
|
|
index = 3;
|
|
for (ii = myPoints->Lower() + 1; ii <= myPoints->Upper(); ii++)
|
|
{
|
|
//
|
|
// copy all the given points since the last one will be initialized
|
|
// below by the first point in the array myPoints
|
|
//
|
|
poles.SetValue(index, myPoints->Value(ii));
|
|
index += 1;
|
|
}
|
|
}
|
|
contact_order_array.SetValue(num_poles - 1, 1);
|
|
parameters.SetValue(num_poles - 1, myParameters->Value(myParameters->Upper()));
|
|
//
|
|
// for the periodic curve ONLY the tangent of the first point
|
|
// will be used since the curve should close itself at the first
|
|
// point See BuildPeriodicTangent
|
|
//
|
|
for (jj = 1; jj <= 2; jj++)
|
|
{
|
|
a_point.SetCoord(jj, myTangents->Value(1).Coord(jj));
|
|
}
|
|
poles.SetValue(num_poles - 1, a_point);
|
|
|
|
parameters.SetValue(num_poles, myParameters->Value(myParameters->Upper()));
|
|
|
|
poles.SetValue(num_poles, myPoints->Value(1));
|
|
|
|
BSplCLib::Interpolate(degree,
|
|
flatknots,
|
|
parameters,
|
|
contact_order_array,
|
|
poles,
|
|
inversion_problem);
|
|
if (!inversion_problem)
|
|
{
|
|
TColgp_Array1OfPnt2d newpoles(poles.Value(1), 1, num_poles - 2);
|
|
myCurve =
|
|
new Geom2d_BSplineCurve(newpoles, myParameters->Array1(), mults, degree, myPeriodic);
|
|
myIsDone = Standard_True;
|
|
}
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void Geom2dAPI_Interpolate::PerformNonPeriodic()
|
|
{
|
|
Standard_Integer degree, ii, jj, index, index1, index2, index3, mult_index, inversion_problem,
|
|
num_points, num_distinct_knots, num_poles;
|
|
|
|
gp_Pnt2d a_point;
|
|
|
|
num_points = num_distinct_knots = num_poles = myPoints->Length();
|
|
if (num_poles == 2 && !myTangentRequest)
|
|
{
|
|
degree = 1;
|
|
}
|
|
else if (num_poles == 3 && !myTangentRequest)
|
|
{
|
|
degree = 2;
|
|
num_distinct_knots = 2;
|
|
}
|
|
else
|
|
{
|
|
degree = 3;
|
|
num_poles += 2;
|
|
if (myTangentRequest)
|
|
for (ii = myTangentFlags->Lower() + 1; ii < myTangentFlags->Upper(); ii++)
|
|
{
|
|
if (myTangentFlags->Value(ii))
|
|
{
|
|
num_poles += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
TColStd_Array1OfReal parameters(1, num_poles);
|
|
TColStd_Array1OfReal flatknots(1, num_poles + degree + 1);
|
|
TColStd_Array1OfInteger mults(1, num_distinct_knots);
|
|
TColStd_Array1OfReal knots(1, num_distinct_knots);
|
|
TColStd_Array1OfInteger contact_order_array(1, num_poles);
|
|
TColgp_Array1OfPnt2d poles(1, num_poles);
|
|
|
|
for (ii = 1; ii <= degree + 1; ii++)
|
|
{
|
|
flatknots.SetValue(ii, myParameters->Value(1));
|
|
flatknots.SetValue(ii + num_poles, myParameters->Value(num_points));
|
|
}
|
|
for (ii = 1; ii <= num_poles; ii++)
|
|
{
|
|
contact_order_array.SetValue(ii, 0);
|
|
}
|
|
for (ii = 2; ii < num_distinct_knots; ii++)
|
|
{
|
|
mults.SetValue(ii, 1);
|
|
}
|
|
mults.SetValue(1, degree + 1);
|
|
mults.SetValue(num_distinct_knots, degree + 1);
|
|
|
|
switch (degree)
|
|
{
|
|
case 1:
|
|
for (ii = 1; ii <= num_poles; ii++)
|
|
{
|
|
poles.SetValue(ii, myPoints->Value(ii));
|
|
}
|
|
myCurve = new Geom2d_BSplineCurve(poles, myParameters->Array1(), mults, degree);
|
|
myIsDone = Standard_True;
|
|
break;
|
|
case 2:
|
|
knots.SetValue(1, myParameters->Value(1));
|
|
knots.SetValue(2, myParameters->Value(3));
|
|
for (ii = 1; ii <= num_poles; ii++)
|
|
{
|
|
poles.SetValue(ii, myPoints->Value(ii));
|
|
}
|
|
BSplCLib::Interpolate(degree,
|
|
flatknots,
|
|
myParameters->Array1(),
|
|
contact_order_array,
|
|
poles,
|
|
inversion_problem);
|
|
if (!inversion_problem)
|
|
{
|
|
myCurve = new Geom2d_BSplineCurve(poles, knots, mults, degree);
|
|
myIsDone = Standard_True;
|
|
}
|
|
break;
|
|
case 3:
|
|
//
|
|
// check if the boundary conditions are set
|
|
//
|
|
if (num_points >= 3)
|
|
{
|
|
//
|
|
// cannot build the tangents with degree 3 with only 2 points
|
|
// if those where not given in advance
|
|
//
|
|
BuildTangents(myPoints->Array1(),
|
|
myTangents->ChangeArray1(),
|
|
myTangentFlags->ChangeArray1(),
|
|
myParameters->Array1());
|
|
}
|
|
contact_order_array.SetValue(2, 1);
|
|
parameters.SetValue(1, myParameters->Value(1));
|
|
parameters.SetValue(2, myParameters->Value(1));
|
|
poles.SetValue(1, myPoints->Value(1));
|
|
for (jj = 1; jj <= 2; jj++)
|
|
{
|
|
a_point.SetCoord(jj, myTangents->Value(1).Coord(jj));
|
|
}
|
|
poles.SetValue(2, a_point);
|
|
mult_index = 2;
|
|
index = 3;
|
|
index1 = 2;
|
|
index2 = myPoints->Lower() + 1;
|
|
index3 = degree + 2;
|
|
if (myTangentRequest)
|
|
{
|
|
for (ii = myParameters->Lower() + 1; ii < myParameters->Upper(); ii++)
|
|
{
|
|
parameters.SetValue(index, myParameters->Value(ii));
|
|
poles.SetValue(index, myPoints->Value(index2));
|
|
flatknots.SetValue(index3, myParameters->Value(ii));
|
|
index += 1;
|
|
index3 += 1;
|
|
if (myTangentFlags->Value(index1))
|
|
{
|
|
//
|
|
// set the multiplicities, the order of the contact, the
|
|
// the flatknots,
|
|
//
|
|
mults.SetValue(mult_index, mults.Value(mult_index) + 1);
|
|
contact_order_array(index) = 1;
|
|
flatknots.SetValue(index3, myParameters->Value(ii));
|
|
parameters.SetValue(index, myParameters->Value(ii));
|
|
for (jj = 1; jj <= 2; jj++)
|
|
{
|
|
a_point.SetCoord(jj, myTangents->Value(ii).Coord(jj));
|
|
}
|
|
poles.SetValue(index, a_point);
|
|
index += 1;
|
|
index3 += 1;
|
|
}
|
|
mult_index += 1;
|
|
index1 += 1;
|
|
index2 += 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
index1 = 2;
|
|
for (ii = myParameters->Lower(); ii <= myParameters->Upper(); ii++)
|
|
{
|
|
parameters.SetValue(index1, myParameters->Value(ii));
|
|
index1 += 1;
|
|
}
|
|
index = 3;
|
|
for (ii = myPoints->Lower() + 1; ii <= myPoints->Upper() - 1; ii++)
|
|
{
|
|
poles.SetValue(index, myPoints->Value(ii));
|
|
index += 1;
|
|
}
|
|
|
|
index = degree + 1;
|
|
for (ii = myParameters->Lower(); ii <= myParameters->Upper(); ii++)
|
|
{
|
|
flatknots.SetValue(index, myParameters->Value(ii));
|
|
index += 1;
|
|
}
|
|
}
|
|
for (jj = 1; jj <= 2; jj++)
|
|
{
|
|
a_point.SetCoord(jj, myTangents->Value(num_points).Coord(jj));
|
|
}
|
|
poles.SetValue(num_poles - 1, a_point);
|
|
|
|
contact_order_array.SetValue(num_poles - 1, 1);
|
|
parameters.SetValue(num_poles, myParameters->Value(myParameters->Upper()));
|
|
parameters.SetValue(num_poles - 1, myParameters->Value(myParameters->Upper()));
|
|
|
|
poles.SetValue(num_poles, myPoints->Value(num_points));
|
|
|
|
BSplCLib::Interpolate(degree,
|
|
flatknots,
|
|
parameters,
|
|
contact_order_array,
|
|
poles,
|
|
inversion_problem);
|
|
if (!inversion_problem)
|
|
{
|
|
myCurve = new Geom2d_BSplineCurve(poles, myParameters->Array1(), mults, degree);
|
|
myIsDone = Standard_True;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : Handle(Geom2d_BSplineCurve)&
|
|
// purpose :
|
|
//=======================================================================
|
|
|
|
const Handle(Geom2d_BSplineCurve)& Geom2dAPI_Interpolate::Curve() const
|
|
{
|
|
if (!myIsDone)
|
|
throw StdFail_NotDone(" ");
|
|
return myCurve;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Geom2dAPI_Interpolate::operator Handle(Geom2d_BSplineCurve)() const
|
|
{
|
|
return myCurve;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
Standard_Boolean Geom2dAPI_Interpolate::IsDone() const
|
|
{
|
|
return myIsDone;
|
|
}
|