Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1997-05-28
// Created by: Xavier BENVENISTE
// Copyright (c) 1997-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 <Geom2d_BSplineCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <GeomLib_Check2dBSplineCurve.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
//=================================================================================================
GeomLib_Check2dBSplineCurve::GeomLib_Check2dBSplineCurve(
const occ::handle<Geom2d_BSplineCurve>& Curve,
const double Tolerance,
const double AngularTolerance)
: myCurve(Curve),
myDone(false),
myFixFirstTangent(false),
myFixLastTangent(false),
myAngularTolerance(std::abs(AngularTolerance)),
myTolerance(std::abs(Tolerance)),
myIndSecondPole(-1),
myIndPrelastPole(-1)
{
int ii, num_poles;
double tangent_magnitude, value, vector_magnitude;
num_poles = myCurve->NbPoles();
if ((!myCurve->IsPeriodic()) && num_poles >= 4)
{
gp_Vec2d tangent, tangent_normalized, a_vector, avector_normalized;
const double CrossProdTol = myAngularTolerance;
// Near first
tangent = gp_Vec2d(myCurve->Pole(1), myCurve->Pole(2));
tangent_magnitude = tangent.Magnitude();
if (tangent_magnitude > myTolerance)
{
tangent_normalized = tangent / tangent_magnitude;
}
for (ii = 3; ii <= num_poles; ii++)
{
a_vector = gp_Vec2d(myCurve->Pole(1), myCurve->Pole(ii));
vector_magnitude = a_vector.Magnitude();
if (tangent_magnitude > myTolerance && vector_magnitude > myTolerance)
{
avector_normalized = a_vector / vector_magnitude;
double CrossProd = tangent_normalized ^ avector_normalized;
if (std::abs(CrossProd) > CrossProdTol)
{
break;
}
value = tangent.Dot(a_vector);
if (value < 0.0e0)
{
myFixFirstTangent = true;
myIndSecondPole = ii;
break;
}
}
}
// Near last
tangent = gp_Vec2d(myCurve->Pole(num_poles), myCurve->Pole(num_poles - 1));
tangent_magnitude = tangent.Magnitude();
if (tangent_magnitude > myTolerance)
{
tangent_normalized = tangent / tangent_magnitude;
}
for (ii = num_poles - 2; ii >= 1; ii--)
{
a_vector = gp_Vec2d(myCurve->Pole(num_poles), myCurve->Pole(ii));
vector_magnitude = a_vector.Magnitude();
if (tangent_magnitude > myTolerance && vector_magnitude > myTolerance)
{
avector_normalized = a_vector / vector_magnitude;
double CrossProd = tangent_normalized ^ avector_normalized;
if (std::abs(CrossProd) > CrossProdTol)
{
break;
}
value = tangent.Dot(a_vector);
if (value < 0.0e0)
{
myFixLastTangent = true;
myIndPrelastPole = ii;
break;
}
}
}
} // if (( ! myCurve->IsPeriodic() )&& num_poles >= 4)
else
{
myDone = true;
}
}
//=================================================================================================
void GeomLib_Check2dBSplineCurve::NeedTangentFix(bool& FirstFlag, bool& LastFlag) const
{
FirstFlag = myFixFirstTangent;
LastFlag = myFixLastTangent;
}
//=================================================================================================
occ::handle<Geom2d_BSplineCurve> GeomLib_Check2dBSplineCurve::FixedTangent(const bool FirstFlag,
const bool LastFlag)
{
occ::handle<Geom2d_BSplineCurve> new_curve;
if ((myFixFirstTangent && FirstFlag) || (myFixLastTangent && LastFlag))
{
new_curve = occ::down_cast<Geom2d_BSplineCurve>(myCurve->Copy());
FixTangentOnCurve(new_curve, FirstFlag, LastFlag);
}
return new_curve;
}
//=================================================================================================
void GeomLib_Check2dBSplineCurve::FixTangent(const bool FirstFlag, const bool LastFlag)
{
FixTangentOnCurve(myCurve, FirstFlag, LastFlag);
}
//=================================================================================================
void GeomLib_Check2dBSplineCurve::FixTangentOnCurve(occ::handle<Geom2d_BSplineCurve>& theCurve,
const bool FirstFlag,
const bool LastFlag)
{
if (myFixFirstTangent && FirstFlag)
{
gp_XY XY1 = theCurve->Pole(1).XY();
gp_XY XY2 = theCurve->Pole(myIndSecondPole).XY();
double NbSamples = myIndSecondPole - 1;
for (int i = 2; i < myIndSecondPole; i++)
{
double ii = i - 1;
gp_Pnt2d aNewPole((1. - ii / NbSamples) * XY1 + ii / NbSamples * XY2);
theCurve->SetPole(i, aNewPole);
}
}
if (myFixLastTangent && LastFlag)
{
int num_poles = theCurve->NbPoles();
gp_XY XY1 = theCurve->Pole(num_poles).XY();
gp_XY XY2 = theCurve->Pole(myIndPrelastPole).XY();
double NbSamples = num_poles - myIndPrelastPole;
for (int i = num_poles - 1; i > myIndPrelastPole; i--)
{
double ii = num_poles - i;
gp_Pnt2d aNewPole((1. - ii / NbSamples) * XY1 + ii / NbSamples * XY2);
theCurve->SetPole(i, aNewPole);
}
}
myDone = true;
}