Loading files
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1995-01-17
// Created by: Remi LEQUETTE
// Copyright (c) 1995-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.
#include <AppDef_BSplineCompute.hxx>
#include <AppDef_Variational.hxx>
#include <AppParCurves_ConstraintCouple.hxx>
#include <NCollection_Array1.hxx>
#include <NCollection_HArray1.hxx>
#include <BSplCLib.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BSplineSurface.hxx>
#include <GeomAPI_PointsToBSpline.hxx>
#include <GeomAPI_PointsToBSplineSurface.hxx>
#include <GeomFill_AppSurf.hxx>
#include <GeomFill_Line.hxx>
#include <GeomFill_SectionGenerator.hxx>
#include <gp.hxx>
#include <gp_Pnt.hxx>
#include <math_Vector.hxx>
#include <StdFail_NotDone.hxx>
#include <AppDef_BSpParLeastSquareOfMyBSplGradientOfBSplineCompute.hxx>
namespace
{
bool hasMeaningfulSpan(const double theSpan)
{
const double aResolution = gp::Resolution();
return theSpan * theSpan > aResolution * aResolution;
}
} // namespace
static void BuildParameters(const AppDef_MultiLine& theLine,
const Approx_ParametrizationType theParT,
NCollection_Array1<double>& thePars)
{
int i, j, nbP3d = theLine.NbPoints();
double dist;
int firstP = 1, lastP = theLine.NbMultiPoints();
const int aNbp = lastP - firstP + 1;
if (aNbp == 2)
{
thePars(firstP) = 0.0;
thePars(lastP) = 1.0;
}
else if (theParT == Approx_ChordLength || theParT == Approx_Centripetal)
{
thePars(firstP) = 0.0;
dist = 0.0;
for (i = firstP + 1; i <= lastP; i++)
{
AppDef_MultiPointConstraint aMPC = theLine.Value(i - 1);
AppDef_MultiPointConstraint aMPC1 = theLine.Value(i);
dist = 0.0;
for (j = 1; j <= nbP3d; j++)
{
const gp_Pnt &aP1 = aMPC.Point(j), &aP2 = aMPC1.Point(j);
dist += aP2.SquareDistance(aP1);
}
dist = std::sqrt(dist);
if (theParT == Approx_ChordLength)
{
thePars(i) = thePars(i - 1) + dist;
}
else
{ // Par == Approx_Centripetal
thePars(i) = thePars(i - 1) + std::sqrt(dist);
}
}
if (hasMeaningfulSpan(thePars(lastP)))
{
for (i = firstP; i <= lastP; i++)
{
thePars(i) /= thePars(lastP);
}
}
else
{
for (i = firstP; i <= lastP; i++)
{
thePars(i) = (double(i) - firstP) / (double(lastP - firstP));
}
}
}
else
{
for (i = firstP; i <= lastP; i++)
{
thePars(i) = (double(i) - firstP) / (double(lastP - double(firstP)));
}
}
}
static void BuildPeriodicTangent(const AppDef_MultiLine& theLine,
const NCollection_Array1<double>& thePars,
math_Vector& theTang)
{
int firstpt = 1, lastpt = theLine.NbMultiPoints();
int nbpoints = lastpt - firstpt + 1;
//
if (nbpoints <= 2)
{
return;
}
//
int i, nnpol, nnp = std::min(nbpoints, 9);
nnpol = nnp;
int lastp = std::min(lastpt, firstpt + nnp - 1);
double U;
AppParCurves_Constraint Cons = AppParCurves_TangencyPoint;
if (nnp <= 4)
{
Cons = AppParCurves_PassPoint;
}
int nbP = 3 * theLine.NbPoints();
math_Vector V1(1, nbP), V2(1, nbP);
math_Vector P1(firstpt, lastp);
//
for (i = firstpt; i <= lastp; i++)
{
P1(i) = thePars(i);
}
AppDef_BSpParLeastSquareOfMyBSplGradientOfBSplineCompute SQ1(theLine,
firstpt,
lastp,
Cons,
Cons,
nnpol);
SQ1.Perform(P1);
const AppParCurves_MultiCurve& C1 = SQ1.BezierValue();
U = 0.0;
int j, nbP3d = theLine.NbPoints();
gp_Pnt aP;
gp_Vec aV;
j = 1;
for (i = 1; i <= nbP3d; i++)
{
C1.D1(i, U, aP, aV);
V1(j) = aV.X();
V1(j + 1) = aV.Y();
V1(j + 2) = aV.Z();
j += 3;
}
int firstp = std::max(firstpt, lastpt - nnp + 1);
if (firstp == firstpt && lastp == lastpt)
{
U = 1.0;
j = 1;
for (i = 1; i <= nbP3d; i++)
{
C1.D1(i, U, aP, aV);
V2(j) = aV.X();
V2(j + 1) = aV.Y();
V2(j + 2) = aV.Z();
j += 3;
}
}
else
{
AppDef_BSpParLeastSquareOfMyBSplGradientOfBSplineCompute SQ2(theLine,
firstp,
lastpt,
Cons,
Cons,
nnpol);
math_Vector P2(firstp, lastpt);
for (i = firstp; i <= lastpt; i++)
{
P2(i) = thePars(i);
}
SQ2.Perform(P2);
const AppParCurves_MultiCurve& C2 = SQ2.BezierValue();
U = 1.0;
j = 1;
for (i = 1; i <= nbP3d; i++)
{
C2.D1(i, U, aP, aV);
V2(j) = aV.X();
V2(j + 1) = aV.Y();
V2(j + 2) = aV.Z();
j += 3;
}
}
theTang = 0.5 * (V1 + V2);
}
//=================================================================================================
GeomAPI_PointsToBSplineSurface::GeomAPI_PointsToBSplineSurface()
: myIsDone(false)
{
}
//=================================================================================================
GeomAPI_PointsToBSplineSurface::GeomAPI_PointsToBSplineSurface(
const NCollection_Array2<gp_Pnt>& Points,
const int DegMin,
const int DegMax,
const GeomAbs_Shape Continuity,
const double Tol3D)
: myIsDone(false)
{
Init(Points, DegMin, DegMax, Continuity, Tol3D);
}
//=================================================================================================
GeomAPI_PointsToBSplineSurface::GeomAPI_PointsToBSplineSurface(
const NCollection_Array2<gp_Pnt>& Points,
const Approx_ParametrizationType ParType,
const int DegMin,
const int DegMax,
const GeomAbs_Shape Continuity,
const double Tol3D)
: myIsDone(false)
{
Init(Points, ParType, DegMin, DegMax, Continuity, Tol3D);
}
//=================================================================================================
GeomAPI_PointsToBSplineSurface::GeomAPI_PointsToBSplineSurface(
const NCollection_Array2<gp_Pnt>& Points,
const double Weight1,
const double Weight2,
const double Weight3,
const int DegMax,
const GeomAbs_Shape Continuity,
const double Tol3D)
: myIsDone(false)
{
Init(Points, Weight1, Weight2, Weight3, DegMax, Continuity, Tol3D);
}
//=================================================================================================
GeomAPI_PointsToBSplineSurface::GeomAPI_PointsToBSplineSurface(
const NCollection_Array2<double>& ZPoints,
const double X0,
const double dX,
const double Y0,
const double dY,
const int DegMin,
const int DegMax,
const GeomAbs_Shape Continuity,
const double Tol3D)
: myIsDone(false)
{
Init(ZPoints, X0, dX, Y0, dY, DegMin, DegMax, Continuity, Tol3D);
}
//=================================================================================================
void GeomAPI_PointsToBSplineSurface::Interpolate(const NCollection_Array2<gp_Pnt>& Points,
const bool thePeriodic)
{
Interpolate(Points, Approx_ChordLength, thePeriodic);
}
//=================================================================================================
void GeomAPI_PointsToBSplineSurface::Interpolate(const NCollection_Array2<gp_Pnt>& Points,
const Approx_ParametrizationType ParType,
const bool thePeriodic)
{
int DegMin, DegMax;
DegMin = DegMax = 3;
GeomAbs_Shape CC = GeomAbs_C2;
double Tol3d = -1.0;
Init(Points, ParType, DegMin, DegMax, CC, Tol3d, thePeriodic);
}
//=================================================================================================
void GeomAPI_PointsToBSplineSurface::Init(const NCollection_Array2<gp_Pnt>& Points,
const int DegMin,
const int DegMax,
const GeomAbs_Shape Continuity,
const double Tol3D)
{
Init(Points, Approx_ChordLength, DegMin, DegMax, Continuity, Tol3D);
}
//=================================================================================================
void GeomAPI_PointsToBSplineSurface::Init(const NCollection_Array2<gp_Pnt>& Points,
const Approx_ParametrizationType ParType,
const int DegMin,
const int DegMax,
const GeomAbs_Shape Continuity,
const double Tol3D,
const bool thePeriodic)
{
myIsDone = false;
int Imin = Points.LowerRow();
int Imax = Points.UpperRow();
int Jmin = Points.LowerCol();
int Jmax = Points.UpperCol();
double Tol2D = Tol3D;
// first approximate the U isos:
int add = 1;
if (thePeriodic)
{
add = 2;
}
AppDef_MultiLine Line(Jmax - Jmin + 1);
int i, j;
for (j = Jmin; j <= Jmax; j++)
{
AppDef_MultiPointConstraint MP(Imax - Imin + add, 0);
for (i = Imin; i <= Imax; i++)
{
MP.SetPoint(i, Points(i, j));
}
if (thePeriodic)
{
MP.SetPoint(Imax + 1, Points(1, j));
}
Line.SetValue(j, MP);
}
int nbit = 2;
bool UseSquares = false;
if (Tol3D <= 1.e-3)
{
UseSquares = true;
}
AppDef_BSplineCompute TheComputer(DegMin, DegMax, Tol3D, Tol2D, nbit, true, ParType, UseSquares);
switch (Continuity)
{
case GeomAbs_C0:
TheComputer.SetContinuity(0);
break;
case GeomAbs_G1:
case GeomAbs_C1:
TheComputer.SetContinuity(1);
break;
case GeomAbs_G2:
case GeomAbs_C2:
TheComputer.SetContinuity(2);
break;
default:
TheComputer.SetContinuity(3);
}
if (Tol3D <= 0.0)
{
TheComputer.Interpol(Line);
}
else
{
TheComputer.Perform(Line);
}
const AppParCurves_MultiBSpCurve& TheCurve = TheComputer.Value();
int VDegree = TheCurve.Degree();
NCollection_Array1<gp_Pnt> Poles(1, TheCurve.NbPoles());
const NCollection_Array1<double>& VKnots = TheCurve.Knots();
const NCollection_Array1<int>& VMults = TheCurve.Multiplicities();
int nbisosu = Imax - Imin + add;
AppDef_MultiLine Line2(nbisosu);
for (i = 1; i <= nbisosu; i++)
{
TheCurve.Curve(i, Poles);
AppDef_MultiPointConstraint MP(Poles.Upper(), 0);
for (j = 1; j <= Poles.Upper(); j++)
{
MP.SetPoint(j, Poles(j));
}
Line2.SetValue(i, MP);
}
// approximate the resulting poles:
AppDef_BSplineCompute TheComputer2(DegMin, DegMax, Tol3D, Tol2D, nbit, true, ParType, UseSquares);
if (Tol3D <= 0.0)
{
if (thePeriodic)
{
TheComputer2.SetPeriodic(thePeriodic);
}
TheComputer2.Interpol(Line2);
}
else
{
if (thePeriodic && Line2.NbMultiPoints() > 2)
{
TheComputer2.SetPeriodic(thePeriodic);
//
NCollection_Array1<double> aPars(1, Line2.NbMultiPoints());
BuildParameters(Line2, ParType, aPars);
math_Vector aTang(1, 3 * Poles.Upper());
BuildPeriodicTangent(Line2, aPars, aTang);
int ind = 1;
TheCurve.Curve(ind, Poles);
AppDef_MultiPointConstraint MP1(Poles.Upper(), 0);
for (j = 1; j <= Poles.Upper(); j++)
{
MP1.SetPoint(j, Poles(j));
int k = 3 * (j - 1);
gp_Vec aT(aTang(k + 1), aTang(k + 2), aTang(k + 3));
MP1.SetTang(j, aT);
}
Line2.SetValue(ind, MP1);
//
ind = Line2.NbMultiPoints();
TheCurve.Curve(ind, Poles);
AppDef_MultiPointConstraint MP2(Poles.Upper(), 0);
for (j = 1; j <= Poles.Upper(); j++)
{
MP2.SetPoint(j, Poles(j));
int k = 3 * (j - 1);
gp_Vec aT(aTang(k + 1), aTang(k + 2), aTang(k + 3));
MP2.SetTang(j, aT);
}
Line2.SetValue(ind, MP2);
}
TheComputer2.Perform(Line2);
}
const AppParCurves_MultiBSpCurve& TheCurve2 = TheComputer2.Value();
int UDegree = TheCurve2.Degree();
NCollection_Array1<gp_Pnt> Poles2(1, TheCurve2.NbPoles());
const NCollection_Array1<double>& UKnots = TheCurve2.Knots();
const NCollection_Array1<int>& UMults = TheCurve2.Multiplicities();
// computing the surface
NCollection_Array2<gp_Pnt> ThePoles(1, Poles2.Upper(), 1, Poles.Upper());
for (j = 1; j <= Poles.Upper(); j++)
{
TheCurve2.Curve(j, Poles2);
for (i = 1; i <= Poles2.Upper(); i++)
{
ThePoles(i, j) = Poles2(i);
}
}
mySurface = new Geom_BSplineSurface(ThePoles, UKnots, VKnots, UMults, VMults, UDegree, VDegree);
if (thePeriodic && Line2.NbMultiPoints() > 2)
{
mySurface->SetUPeriodic();
}
myIsDone = true;
}
//=================================================================================================
void GeomAPI_PointsToBSplineSurface::Init(const NCollection_Array2<gp_Pnt>& Points,
const double Weight1,
const double Weight2,
const double Weight3,
const int DegMax,
const GeomAbs_Shape Continuity,
const double Tol3D)
{
myIsDone = false;
int Imin = Points.LowerRow();
int Imax = Points.UpperRow();
int Jmin = Points.LowerCol();
int Jmax = Points.UpperCol();
int nbit = 2;
if (Tol3D <= 1.e-3)
{
nbit = 0;
}
// first approximate the U isos:
int NbPointJ = Jmax - Jmin + 1;
int NbPointI = Imax - Imin + 1;
int i, j;
AppDef_MultiLine Line(NbPointJ);
for (j = Jmin; j <= Jmax; j++)
{
AppDef_MultiPointConstraint MP(NbPointI, 0);
for (i = Imin; i <= Imax; i++)
{
MP.SetPoint(i, Points(i, j));
}
Line.SetValue(j, MP);
}
occ::handle<NCollection_HArray1<AppParCurves_ConstraintCouple>> TABofCC =
new NCollection_HArray1<AppParCurves_ConstraintCouple>(1, NbPointJ);
AppParCurves_Constraint Constraint = AppParCurves_NoConstraint;
for (i = 1; i <= NbPointJ; ++i)
{
AppParCurves_ConstraintCouple ACC(i, Constraint);
TABofCC->SetValue(i, ACC);
}
AppDef_Variational Variation(Line, 1, NbPointJ, TABofCC);
//===================================
int theMaxSegments = 1000;
bool theWithMinMax = false;
//===================================
Variation.SetMaxDegree(DegMax);
Variation.SetContinuity(Continuity);
Variation.SetMaxSegment(theMaxSegments);
Variation.SetTolerance(Tol3D);
Variation.SetWithMinMax(theWithMinMax);
Variation.SetNbIterations(nbit);
Variation.SetCriteriumWeight(Weight1, Weight2, Weight3);
if (!Variation.IsCreated())
{
return;
}
if (Variation.IsOverConstrained())
{
return;
}
try
{
Variation.Approximate();
}
catch (Standard_Failure const&)
{
return;
}
if (!Variation.IsDone())
{
return;
}
const AppParCurves_MultiBSpCurve& TheCurve = Variation.Value();
int VDegree = TheCurve.Degree();
NCollection_Array1<gp_Pnt> Poles(1, TheCurve.NbPoles());
const NCollection_Array1<double>& VKnots = TheCurve.Knots();
const NCollection_Array1<int>& VMults = TheCurve.Multiplicities();
AppDef_MultiLine Line2(NbPointI);
for (i = 1; i <= NbPointI; i++)
{
TheCurve.Curve(i, Poles);
AppDef_MultiPointConstraint MP(Poles.Upper(), 0);
for (j = 1; j <= Poles.Upper(); j++)
{
MP.SetPoint(j, Poles(j));
}
Line2.SetValue(i, MP);
}
occ::handle<NCollection_HArray1<AppParCurves_ConstraintCouple>> TABofCC2 =
new NCollection_HArray1<AppParCurves_ConstraintCouple>(1, NbPointI);
for (i = 1; i <= NbPointI; ++i)
{
AppParCurves_ConstraintCouple ACC(i, Constraint);
TABofCC2->SetValue(i, ACC);
}
AppDef_Variational Variation2(Line2, 1, NbPointI, TABofCC2);
Variation2.SetMaxDegree(DegMax);
Variation2.SetContinuity(Continuity);
Variation2.SetMaxSegment(theMaxSegments);
Variation2.SetTolerance(Tol3D);
Variation2.SetWithMinMax(theWithMinMax);
Variation2.SetNbIterations(nbit);
Variation2.SetCriteriumWeight(Weight1, Weight2, Weight3);
if (!Variation2.IsCreated())
{
return;
}
if (Variation2.IsOverConstrained())
{
return;
}
try
{
Variation2.Approximate();
}
catch (Standard_Failure const&)
{
return;
}
if (!Variation2.IsDone())
{
return;
}
const AppParCurves_MultiBSpCurve& TheCurve2 = Variation2.Value();
int UDegree = TheCurve2.Degree();
NCollection_Array1<gp_Pnt> Poles2(1, TheCurve2.NbPoles());
const NCollection_Array1<double>& UKnots = TheCurve2.Knots();
const NCollection_Array1<int>& UMults = TheCurve2.Multiplicities();
// computing the surface
NCollection_Array2<gp_Pnt> ThePoles(1, Poles2.Upper(), 1, Poles.Upper());
for (j = 1; j <= Poles.Upper(); j++)
{
TheCurve2.Curve(j, Poles2);
for (i = 1; i <= Poles2.Upper(); i++)
{
ThePoles(i, j) = Poles2(i);
}
}
mySurface = new Geom_BSplineSurface(ThePoles, UKnots, VKnots, UMults, VMults, UDegree, VDegree);
myIsDone = true;
}
//=================================================================================================
void GeomAPI_PointsToBSplineSurface::Interpolate(const NCollection_Array2<double>& ZPoints,
const double X0,
const double dX,
const double Y0,
const double dY)
{
int DegMin, DegMax;
DegMin = DegMax = 3;
double Tol3D = -1.0;
GeomAbs_Shape CC = GeomAbs_C2;
Init(ZPoints, X0, dX, Y0, dY, DegMin, DegMax, CC, Tol3D);
}
//=================================================================================================
void GeomAPI_PointsToBSplineSurface::Init(const NCollection_Array2<double>& ZPoints,
const double X0,
const double dX,
const double Y0,
const double dY,
const int DegMin,
const int DegMax,
const GeomAbs_Shape Continuity,
const double Tol3D)
{
myIsDone = false;
int Imin = ZPoints.LowerRow();
int Imax = ZPoints.UpperRow();
int Jmin = ZPoints.LowerCol();
int Jmax = ZPoints.UpperCol();
double length;
double Tol2D = Tol3D;
// first approximate the U isos:
AppDef_MultiLine Line(Jmax - Jmin + 1);
math_Vector Param(Jmin, Jmax);
int i, j;
const int aVSpan = Jmax - Jmin;
// double X, Y;
length = dY * (Jmax - Jmin);
for (j = Jmin; j <= Jmax; j++)
{
AppDef_MultiPointConstraint MP(0, Imax - Imin + 1);
for (i = Imin; i <= Imax; i++)
{
MP.SetPoint2d(i, gp_Pnt2d(0.0, ZPoints(i, j)));
}
Param(j) = (aVSpan > 0) ? double(j - Jmin) / double(aVSpan) : 0.0;
Line.SetValue(j, MP);
}
AppDef_BSplineCompute TheComputer(Param, DegMin, DegMax, Tol3D, Tol2D, 0, true, true);
switch (Continuity)
{
case GeomAbs_C0:
TheComputer.SetContinuity(0);
break;
case GeomAbs_G1:
case GeomAbs_C1:
TheComputer.SetContinuity(1);
break;
case GeomAbs_G2:
case GeomAbs_C2:
TheComputer.SetContinuity(2);
break;
default:
TheComputer.SetContinuity(3);
}
if (Tol3D <= 0.0)
{
TheComputer.Interpol(Line);
}
else
{
TheComputer.Perform(Line);
}
const AppParCurves_MultiBSpCurve& TheCurve = TheComputer.Value();
int VDegree = TheCurve.Degree();
NCollection_Array1<gp_Pnt2d> Poles(1, TheCurve.NbPoles());
int nk = TheCurve.Knots().Length();
NCollection_Array1<double> VKnots(1, nk);
NCollection_Array1<int> VMults(1, nk);
// compute Y values for the poles
NCollection_Array1<double> YPoles(1, Poles.Upper());
// start with a line
NCollection_Array1<double> TempPoles(1, 2);
NCollection_Array1<double> TempKnots(1, 2);
NCollection_Array1<int> TempMults(1, 2);
TempMults.Init(2);
TempPoles(1) = Y0;
TempPoles(2) = Y0 + length;
TempKnots(1) = 0.;
TempKnots(2) = 1.;
// increase the Degree
NCollection_Array1<double> NewTempPoles(1, VDegree + 1);
NCollection_Array1<double> NewTempKnots(1, 2);
NCollection_Array1<int> NewTempMults(1, 2);
BSplCLib::IncreaseDegree(1,
VDegree,
false,
1,
TempPoles,
TempKnots,
TempMults,
NewTempPoles,
NewTempKnots,
NewTempMults);
// insert the Knots
BSplCLib::InsertKnots(VDegree,
false,
1,
NewTempPoles,
NewTempKnots,
NewTempMults,
TheCurve.Knots(),
&TheCurve.Multiplicities(),
YPoles,
VKnots,
VMults,
Epsilon(1));
// scale the knots
for (i = 1; i <= nk; i++)
{
VKnots(i) = Y0 + length * VKnots(i);
}
int nbisosu = Imax - Imin + 1;
AppDef_MultiLine Line2(nbisosu);
math_Vector Param2(1, nbisosu);
const int aUSpan = nbisosu - 1;
length = dX * (Imax - Imin);
for (i = 1; i <= nbisosu; i++)
{
TheCurve.Curve(i, Poles);
AppDef_MultiPointConstraint MP(0, Poles.Upper());
for (j = 1; j <= Poles.Upper(); j++)
{
MP.SetPoint2d(j, gp_Pnt2d(0.0, Poles(j).Y()));
}
Param2(i) = (aUSpan > 0) ? double(i - 1) / double(aUSpan) : 0.0;
Line2.SetValue(i, MP);
}
// approximate the resulting poles:
AppDef_BSplineCompute TheComputer2(Param2, DegMin, DegMax, Tol3D, Tol2D, 0, true, true);
if (Tol3D <= 0.0)
{
TheComputer2.Interpol(Line2);
}
else
{
TheComputer2.Perform(Line2);
}
const AppParCurves_MultiBSpCurve& TheCurve2 = TheComputer2.Value();
int UDegree = TheCurve2.Degree();
NCollection_Array1<gp_Pnt2d> Poles2(1, TheCurve2.NbPoles());
int nk2 = TheCurve2.Knots().Length();
NCollection_Array1<double> UKnots(1, nk2);
NCollection_Array1<int> UMults(1, nk2);
// compute X values for the poles
NCollection_Array1<double> XPoles(1, Poles2.Upper());
// start with a line
TempPoles(1) = X0;
TempPoles(2) = X0 + length;
TempKnots(1) = 0.;
TempKnots(2) = 1.;
TempMults(1) = TempMults(2) = 2;
// increase the Degree
NCollection_Array1<double> NewTempPoles2(1, UDegree + 1);
BSplCLib::IncreaseDegree(1,
UDegree,
false,
1,
TempPoles,
TempKnots,
TempMults,
NewTempPoles2,
NewTempKnots,
NewTempMults);
// insert the Knots
BSplCLib::InsertKnots(UDegree,
false,
1,
NewTempPoles2,
NewTempKnots,
NewTempMults,
TheCurve2.Knots(),
&TheCurve2.Multiplicities(),
XPoles,
UKnots,
UMults,
Epsilon(1));
// scale the knots
for (i = 1; i <= nk2; i++)
{
UKnots(i) = X0 + length * UKnots(i);
}
// creating the surface
NCollection_Array2<gp_Pnt> ThePoles(1, Poles2.Upper(), 1, Poles.Upper());
for (j = 1; j <= Poles.Upper(); j++)
{
TheCurve2.Curve(j, Poles2);
for (i = 1; i <= Poles2.Upper(); i++)
{
ThePoles(i, j).SetCoord(XPoles(i), YPoles(j), Poles2(i).Y());
}
}
mySurface = new Geom_BSplineSurface(ThePoles, UKnots, VKnots, UMults, VMults, UDegree, VDegree);
myIsDone = true;
}
//=======================================================================
// function : occ::handle<Geom_BSplineSurface>&
// purpose :
//=======================================================================
const occ::handle<Geom_BSplineSurface>& GeomAPI_PointsToBSplineSurface::Surface() const
{
StdFail_NotDone_Raise_if(!myIsDone, "GeomAPI_PointsToBSplineSurface: Surface not done");
return mySurface;
}
//=================================================================================================
GeomAPI_PointsToBSplineSurface::operator occ::handle<Geom_BSplineSurface>() const
{
return Surface();
}
//=================================================================================================
bool GeomAPI_PointsToBSplineSurface::IsDone() const
{
return myIsDone;
}