Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1998-11-12
// Created by: data exchange team
// Copyright (c) 1998-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 <ShapeUpgrade.hxx>
#include <BSplCLib.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <gp_Pnt.hxx>
#include <NCollection_Array1.hxx>
#include <Standard_Integer.hxx>
/*
// Debug state= True / False.
static bool Dbg=false;
void ShapeUpgrade::SetDebug(const bool State)
{
Dbg=State;
}
bool ShapeUpgrade::Debug()
{
return Dbg;
}
*/
//=================================================================================================
bool ShapeUpgrade::C0BSplineToSequenceOfC1BSplineCurve(
const occ::handle<Geom_BSplineCurve>& BS,
occ::handle<NCollection_HSequence<occ::handle<Geom_BoundedCurve>>>& seqBS)
{
if (BS.IsNull() || (BS->IsCN(1)))
{
return false;
}
seqBS = new NCollection_HSequence<occ::handle<Geom_BoundedCurve>>;
BS->SetNotPeriodic(); // to have equation NbPoles = NbKnots with Multiplicities - degree - 1
int deg = BS->Degree();
const NCollection_Array1<gp_Pnt>& Poles = BS->Poles();
const NCollection_Array1<double>& Weights = BS->WeightsArray();
const NCollection_Array1<double>& Knots = BS->Knots();
const NCollection_Array1<int>& Mults = BS->Multiplicities();
const NCollection_Array1<double>& KnotSequence = BS->KnotSequence();
int StartKnotIndex, EndKnotIndex, j;
StartKnotIndex = BS->FirstUKnotIndex();
for (EndKnotIndex = StartKnotIndex + 1; EndKnotIndex <= BS->LastUKnotIndex(); EndKnotIndex++)
{
if ((Mults(EndKnotIndex) < deg) && (EndKnotIndex < BS->LastUKnotIndex()))
{
continue;
}
int StartFlatIndex = BSplCLib::FlatIndex(deg, StartKnotIndex, Mults, false);
// StartFlatIndex += Mults (StartKnotIndex) - 1;
int EndFlatIndex = BSplCLib::FlatIndex(deg, EndKnotIndex, Mults, false);
EndFlatIndex -= Mults(EndKnotIndex) - 1;
NCollection_Array1<double> TempKnots(1, Knots.Length());
NCollection_Array1<int> TempMults(1, Knots.Length());
TempMults.Init(1);
int TempKnotIndex = 1;
TempKnots(TempKnotIndex) = KnotSequence(StartFlatIndex - deg);
for (j = StartFlatIndex - deg + 1; j <= EndFlatIndex + deg; j++)
{
if (std::abs(KnotSequence(j) - KnotSequence(j - 1)) <= gp::Resolution())
{
TempMults(TempKnotIndex)++;
}
else
{
TempKnots(++TempKnotIndex) = KnotSequence(j);
}
}
int TempStartIndex = 1, TempEndIndex = TempKnotIndex;
if (TempMults(TempStartIndex) == 1)
{
TempMults(++TempStartIndex)++;
}
if (TempMults(TempEndIndex) == 1)
{
TempMults(--TempEndIndex)++;
}
int NewNbKnots = TempEndIndex - TempStartIndex + 1;
NCollection_Array1<int> newMults(1, NewNbKnots);
NCollection_Array1<double> newKnots(1, NewNbKnots);
for (j = 1; j <= NewNbKnots; j++)
{
newMults(j) = TempMults(j + TempStartIndex - 1);
newKnots(j) = TempKnots(j + TempStartIndex - 1);
}
int NewNbPoles = BSplCLib::NbPoles(deg, false, newMults);
NCollection_Array1<gp_Pnt> newPoles(1, NewNbPoles);
NCollection_Array1<double> newWeights(1, NewNbPoles);
// clang-format off
int PoleIndex = StartFlatIndex - deg;//Index of starting pole when splitting B-Spline is an index of starting knot
// clang-format on
for (j = 1; j <= NewNbPoles; j++)
{
newWeights(j) = Weights(j + PoleIndex - 1);
newPoles(j) = Poles(j + PoleIndex - 1);
}
occ::handle<Geom_BSplineCurve> newC =
new Geom_BSplineCurve(newPoles, newWeights, newKnots, newMults, deg);
seqBS->Append(newC);
StartKnotIndex = EndKnotIndex;
}
return true;
}
//=================================================================================================
static occ::handle<Geom_BSplineCurve> BSplineCurve2dTo3d(const occ::handle<Geom2d_BSplineCurve>& BS)
{
int deg = BS->Degree();
int NbPoles = BS->NbPoles();
const NCollection_Array1<gp_Pnt2d>& Poles2d = BS->Poles();
const NCollection_Array1<double>& Weights = BS->WeightsArray();
const NCollection_Array1<double>& Knots = BS->Knots();
const NCollection_Array1<int>& Mults = BS->Multiplicities();
NCollection_Array1<gp_Pnt> Poles3d(1, NbPoles);
for (int i = 1; i <= NbPoles; i++)
{
Poles3d(i) = gp_Pnt(Poles2d(i).X(), Poles2d(i).Y(), 0);
}
occ::handle<Geom_BSplineCurve> BS3d =
new Geom_BSplineCurve(Poles3d, Weights, Knots, Mults, deg, BS->IsPeriodic());
return BS3d;
}
static occ::handle<Geom2d_BSplineCurve> BSplineCurve3dTo2d(const occ::handle<Geom_BSplineCurve>& BS)
{
int deg = BS->Degree();
int NbPoles = BS->NbPoles();
const NCollection_Array1<gp_Pnt>& Poles3d = BS->Poles();
const NCollection_Array1<double>& Weights = BS->WeightsArray();
const NCollection_Array1<double>& Knots = BS->Knots();
const NCollection_Array1<int>& Mults = BS->Multiplicities();
NCollection_Array1<gp_Pnt2d> Poles2d(1, NbPoles);
for (int i = 1; i <= NbPoles; i++)
{
Poles2d(i) = gp_Pnt2d(Poles3d(i).X(), Poles3d(i).Y());
}
occ::handle<Geom2d_BSplineCurve> BS2d =
new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults, deg, BS->IsPeriodic());
return BS2d;
}
bool ShapeUpgrade::C0BSplineToSequenceOfC1BSplineCurve(
const occ::handle<Geom2d_BSplineCurve>& BS,
occ::handle<NCollection_HSequence<occ::handle<Geom2d_BoundedCurve>>>& seqBS)
{
if (BS.IsNull() || (BS->IsCN(1)))
{
return false;
}
occ::handle<Geom_BSplineCurve> BS3d = BSplineCurve2dTo3d(BS);
occ::handle<NCollection_HSequence<occ::handle<Geom_BoundedCurve>>> seqBS3d;
bool result = C0BSplineToSequenceOfC1BSplineCurve(BS3d, seqBS3d);
if (result)
{
seqBS = new NCollection_HSequence<occ::handle<Geom2d_BoundedCurve>>;
for (int i = 1; i <= seqBS3d->Length(); i++)
{
seqBS->Append(BSplineCurve3dTo2d(occ::down_cast<Geom_BSplineCurve>(seqBS3d->Value(i))));
}
}
return result;
}