Loading files
// Copyright (c) 2025 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 <GeomBndLib_Curve.hxx>
#include <BndLib_Add3dCurve.hxx>
#include <Bnd_Box.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Ellipse.hxx>
#include <Geom_Hyperbola.hxx>
#include <Geom_Line.hxx>
#include <Geom_Parabola.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomBndLib_SamplingHelpers.pxx>
#include <NCollection_Array1.hxx>
#include <Precision.hxx>
#include <gp_Circ.hxx>
#include <gp_Elips.hxx>
#include <gp_Hypr.hxx>
#include <gp_Parab.hxx>
#include <gp_Pnt.hxx>
#include <gtest/gtest.h>
namespace
{
//! Helper: compare two Bnd_Box results within tolerance.
void CompareBoxes(const Bnd_Box& theNew, const Bnd_Box& theOld, const double theTol)
{
const auto [aXminN, aXmaxN, aYminN, aYmaxN, aZminN, aZmaxN] = theNew.Get();
const auto [aXminO, aXmaxO, aYminO, aYmaxO, aZminO, aZmaxO] = theOld.Get();
EXPECT_NEAR(aXminN, aXminO, theTol);
EXPECT_NEAR(aXmaxN, aXmaxO, theTol);
EXPECT_NEAR(aYminN, aYminO, theTol);
EXPECT_NEAR(aYmaxN, aYmaxO, theTol);
EXPECT_NEAR(aZminN, aZminO, theTol);
EXPECT_NEAR(aZmaxN, aZmaxO, theTol);
}
//! Helper: verify that the new box conservatively encloses the old box.
void ExpectConservativeEnvelope(const Bnd_Box& theNew, const Bnd_Box& theOld, const double theTol)
{
const auto [aXminN, aXmaxN, aYminN, aYmaxN, aZminN, aZmaxN] = theNew.Get();
const auto [aXminO, aXmaxO, aYminO, aYmaxO, aZminO, aZmaxO] = theOld.Get();
EXPECT_LE(aXminN, aXminO + theTol);
EXPECT_GE(aXmaxN, aXmaxO - theTol);
EXPECT_LE(aYminN, aYminO + theTol);
EXPECT_GE(aYmaxN, aYmaxO - theTol);
EXPECT_LE(aZminN, aZminO + theTol);
EXPECT_GE(aZmaxN, aZmaxO - theTol);
}
} // namespace
// =========================================================================
// Line
// =========================================================================
TEST(GeomBndLib_CurveTest, Line_FiniteSegment)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 1.0, 0.0));
GeomBndLib_Curve aCurve(aLine);
EXPECT_EQ(aCurve.GetType(), GeomAbs_Line);
Bnd_Box aBox;
aCurve.Add(0.0, 10.0, 0.0, aBox);
const auto [aXmin, aXmax, aYmin, aYmax, aZmin, aZmax] = aBox.Get();
// Line from (0,0,0) in direction (1,1,0) normalized, parameter 10
// Endpoint: (10/sqrt(2), 10/sqrt(2), 0)
const double aLen = 10.0 / std::sqrt(2.0);
EXPECT_NEAR(aXmin, 0.0, Precision::Confusion());
EXPECT_NEAR(aYmin, 0.0, Precision::Confusion());
EXPECT_NEAR(aZmin, 0.0, Precision::Confusion());
EXPECT_NEAR(aXmax, aLen, Precision::Confusion());
EXPECT_NEAR(aYmax, aLen, Precision::Confusion());
EXPECT_NEAR(aZmax, 0.0, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, Line_CompareWithBndLib)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(1.0, 2.0, 3.0), gp_Dir(0.0, 0.0, 1.0));
GeomAdaptor_Curve anAdaptor(aLine);
Bnd_Box aNewBox;
GeomBndLib_Curve(aLine).Add(0.0, 5.0, Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, 0.0, 5.0, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
// =========================================================================
// Circle
// =========================================================================
TEST(GeomBndLib_CurveTest, Circle_Full)
{
const double aRadius = 5.0;
occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp::XOY(), aRadius);
GeomBndLib_Curve aCurve(aCircle);
EXPECT_EQ(aCurve.GetType(), GeomAbs_Circle);
Bnd_Box aBox;
aCurve.Add(0.0, aBox);
const auto [aXmin, aXmax, aYmin, aYmax, aZmin, aZmax] = aBox.Get();
EXPECT_NEAR(aXmin, -aRadius, Precision::Confusion());
EXPECT_NEAR(aYmin, -aRadius, Precision::Confusion());
EXPECT_NEAR(aXmax, aRadius, Precision::Confusion());
EXPECT_NEAR(aYmax, aRadius, Precision::Confusion());
EXPECT_NEAR(aZmin, 0.0, Precision::Confusion());
EXPECT_NEAR(aZmax, 0.0, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, Circle_Arc)
{
const double aRadius = 10.0;
occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp::XOY(), aRadius);
GeomBndLib_Curve aCurve(aCircle);
Bnd_Box aBox;
// Pass 0 tolerance for precise reference comparison
aCurve.Add(0.0, M_PI / 2.0, 0.0, aBox);
const auto [aXmin, aXmax, aYmin, aYmax, aZmin, aZmax] = aBox.Get();
EXPECT_NEAR(aXmin, 0.0, Precision::Confusion());
EXPECT_NEAR(aYmin, 0.0, Precision::Confusion());
EXPECT_NEAR(aXmax, aRadius, Precision::Confusion());
EXPECT_NEAR(aYmax, aRadius, Precision::Confusion());
EXPECT_NEAR(aZmin, 0.0, Precision::Confusion());
EXPECT_NEAR(aZmax, 0.0, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, Circle_CompareWithBndLib)
{
occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp::XOY(), 7.5);
GeomAdaptor_Curve anAdaptor(aCircle);
Bnd_Box aNewBox;
GeomBndLib_Curve(aCircle).Add(Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, Circle_Arc_CompareWithBndLib)
{
occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp::XOY(), 7.5);
GeomAdaptor_Curve anAdaptor(aCircle);
Bnd_Box aNewBox;
GeomBndLib_Curve(aCircle).Add(0.5, 2.5, Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, 0.5, 2.5, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
// =========================================================================
// Ellipse
// =========================================================================
TEST(GeomBndLib_CurveTest, Ellipse_Full)
{
const double aMajR = 10.0;
const double aMinR = 5.0;
occ::handle<Geom_Ellipse> anEllipse = new Geom_Ellipse(gp::XOY(), aMajR, aMinR);
GeomBndLib_Curve aCurve(anEllipse);
EXPECT_EQ(aCurve.GetType(), GeomAbs_Ellipse);
Bnd_Box aBox;
aCurve.Add(0.0, aBox);
const auto [aXmin, aXmax, aYmin, aYmax, aZmin, aZmax] = aBox.Get();
EXPECT_NEAR(aXmin, -aMajR, Precision::Confusion());
EXPECT_NEAR(aXmax, aMajR, Precision::Confusion());
EXPECT_NEAR(aYmin, -aMinR, Precision::Confusion());
EXPECT_NEAR(aYmax, aMinR, Precision::Confusion());
EXPECT_NEAR(aZmin, 0.0, Precision::Confusion());
EXPECT_NEAR(aZmax, 0.0, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, Ellipse_CompareWithBndLib)
{
occ::handle<Geom_Ellipse> anEllipse = new Geom_Ellipse(gp::XOY(), 8.0, 3.0);
GeomAdaptor_Curve anAdaptor(anEllipse);
Bnd_Box aNewBox;
GeomBndLib_Curve(anEllipse).Add(Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, Ellipse_Arc_CompareWithBndLib)
{
occ::handle<Geom_Ellipse> anEllipse = new Geom_Ellipse(gp::XOY(), 8.0, 3.0);
GeomAdaptor_Curve anAdaptor(anEllipse);
Bnd_Box aNewBox;
GeomBndLib_Curve(anEllipse).Add(0.3, 2.0, Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, 0.3, 2.0, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
// =========================================================================
// Hyperbola
// =========================================================================
TEST(GeomBndLib_CurveTest, Hyperbola_FiniteArc)
{
const double aMajR = 5.0;
const double aMinR = 3.0;
occ::handle<Geom_Hyperbola> aHyp = new Geom_Hyperbola(gp::XOY(), aMajR, aMinR);
GeomBndLib_Curve aCurve(aHyp);
EXPECT_EQ(aCurve.GetType(), GeomAbs_Hyperbola);
Bnd_Box aBox;
const double aU = 1.0;
aCurve.Add(-aU, aU, 0.0, aBox);
const auto [aXmin, aXmax, aYmin, aYmax, aZmin, aZmax] = aBox.Get();
// Hyperbola: x = aMajR * cosh(t), y = aMinR * sinh(t)
const double aXEnd = aMajR * std::cosh(aU);
const double aYEnd = aMinR * std::sinh(aU);
// Box should contain the vertex (aMajR, 0) and endpoints
EXPECT_LE(aXmin, aMajR + Precision::Confusion());
EXPECT_GE(aXmax, aXEnd - Precision::Confusion());
EXPECT_LE(aYmin, -aYEnd + Precision::Confusion());
EXPECT_GE(aYmax, aYEnd - Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, Hyperbola_CompareWithBndLib)
{
occ::handle<Geom_Hyperbola> aHyp = new Geom_Hyperbola(gp::XOY(), 5.0, 3.0);
GeomAdaptor_Curve anAdaptor(aHyp);
Bnd_Box aNewBox;
GeomBndLib_Curve(aHyp).Add(-1.0, 1.0, Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, -1.0, 1.0, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
// =========================================================================
// Parabola
// =========================================================================
TEST(GeomBndLib_CurveTest, Parabola_FiniteArc)
{
const double aFocal = 2.0;
occ::handle<Geom_Parabola> aParab = new Geom_Parabola(gp::XOY(), aFocal);
GeomBndLib_Curve aCurve(aParab);
EXPECT_EQ(aCurve.GetType(), GeomAbs_Parabola);
Bnd_Box aBox;
const double aU = 5.0;
aCurve.Add(-aU, aU, 0.0, aBox);
const auto [aXmin, aXmax, aYmin, aYmax, aZmin, aZmax] = aBox.Get();
// Parabola: x = t^2/(4*focal), y = t
const double aXEnd = aU * aU / (4.0 * aFocal);
EXPECT_LE(aXmin, Precision::Confusion());
EXPECT_GE(aXmax, aXEnd - Precision::Confusion());
EXPECT_LE(aYmin, -aU + Precision::Confusion());
EXPECT_GE(aYmax, aU - Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, Parabola_CompareWithBndLib)
{
occ::handle<Geom_Parabola> aParab = new Geom_Parabola(gp::XOY(), 2.0);
GeomAdaptor_Curve anAdaptor(aParab);
Bnd_Box aNewBox;
GeomBndLib_Curve(aParab).Add(-5.0, 5.0, Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, -5.0, 5.0, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
// =========================================================================
// BezierCurve
// =========================================================================
TEST(GeomBndLib_CurveTest, BezierCurve_Simple)
{
NCollection_Array1<gp_Pnt> aPoles(1, 3);
aPoles.SetValue(1, gp_Pnt(0.0, 0.0, 0.0));
aPoles.SetValue(2, gp_Pnt(5.0, 10.0, 0.0));
aPoles.SetValue(3, gp_Pnt(10.0, 0.0, 0.0));
occ::handle<Geom_BezierCurve> aBez = new Geom_BezierCurve(aPoles);
GeomBndLib_Curve aCurve(aBez);
EXPECT_EQ(aCurve.GetType(), GeomAbs_BezierCurve);
Bnd_Box aBox;
aCurve.Add(Precision::Confusion(), aBox);
const auto [aXmin, aXmax, aYmin, aYmax, aZmin, aZmax] = aBox.Get();
// Bezier convex hull: x in [0,10], y in [0, <=10], z = 0
EXPECT_LE(aXmin, Precision::Confusion());
EXPECT_GE(aXmax, 10.0 - Precision::Confusion());
EXPECT_LE(aYmin, Precision::Confusion());
EXPECT_GE(aYmax, 0.0);
EXPECT_NEAR(aZmin, 0.0, Precision::Confusion());
EXPECT_NEAR(aZmax, 0.0, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, BezierCurve_CompareWithBndLib)
{
NCollection_Array1<gp_Pnt> aPoles(1, 4);
aPoles.SetValue(1, gp_Pnt(0.0, 0.0, 0.0));
aPoles.SetValue(2, gp_Pnt(3.0, 8.0, 1.0));
aPoles.SetValue(3, gp_Pnt(7.0, 2.0, -1.0));
aPoles.SetValue(4, gp_Pnt(10.0, 5.0, 0.0));
occ::handle<Geom_BezierCurve> aBez = new Geom_BezierCurve(aPoles);
GeomAdaptor_Curve anAdaptor(aBez);
Bnd_Box aNewBox;
GeomBndLib_Curve(aBez).Add(Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
// =========================================================================
// BSplineCurve
// =========================================================================
TEST(GeomBndLib_CurveTest, BSplineCurve_Simple)
{
NCollection_Array1<gp_Pnt> aPoles(1, 4);
aPoles.SetValue(1, gp_Pnt(0.0, 0.0, 0.0));
aPoles.SetValue(2, gp_Pnt(2.0, 5.0, 0.0));
aPoles.SetValue(3, gp_Pnt(8.0, 5.0, 0.0));
aPoles.SetValue(4, gp_Pnt(10.0, 0.0, 0.0));
NCollection_Array1<double> aKnots(1, 3);
aKnots.SetValue(1, 0.0);
aKnots.SetValue(2, 0.5);
aKnots.SetValue(3, 1.0);
NCollection_Array1<int> aMults(1, 3);
aMults.SetValue(1, 3);
aMults.SetValue(2, 1);
aMults.SetValue(3, 3);
occ::handle<Geom_BSplineCurve> aBSpl = new Geom_BSplineCurve(aPoles, aKnots, aMults, 2);
GeomBndLib_Curve aCurve(aBSpl);
EXPECT_EQ(aCurve.GetType(), GeomAbs_BSplineCurve);
Bnd_Box aBox;
aCurve.Add(Precision::Confusion(), aBox);
const auto [aXmin, aXmax, aYmin, aYmax, aZmin, aZmax] = aBox.Get();
EXPECT_LE(aXmin, Precision::Confusion());
EXPECT_GE(aXmax, 10.0 - Precision::Confusion());
EXPECT_LE(aYmin, Precision::Confusion());
EXPECT_GE(aYmax, 0.0);
EXPECT_NEAR(aZmin, 0.0, Precision::Confusion());
EXPECT_NEAR(aZmax, 0.0, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, BSplineCurve_CompareWithBndLib)
{
NCollection_Array1<gp_Pnt> aPoles(1, 4);
aPoles.SetValue(1, gp_Pnt(0.0, 0.0, 0.0));
aPoles.SetValue(2, gp_Pnt(2.0, 5.0, 1.0));
aPoles.SetValue(3, gp_Pnt(8.0, 5.0, -1.0));
aPoles.SetValue(4, gp_Pnt(10.0, 0.0, 0.0));
NCollection_Array1<double> aKnots(1, 3);
aKnots.SetValue(1, 0.0);
aKnots.SetValue(2, 0.5);
aKnots.SetValue(3, 1.0);
NCollection_Array1<int> aMults(1, 3);
aMults.SetValue(1, 3);
aMults.SetValue(2, 1);
aMults.SetValue(3, 3);
occ::handle<Geom_BSplineCurve> aBSpl = new Geom_BSplineCurve(aPoles, aKnots, aMults, 2);
GeomAdaptor_Curve anAdaptor(aBSpl);
Bnd_Box aNewBox;
GeomBndLib_Curve(aBSpl).Add(Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, BSplineCurve_TrimmedRange_CompareWithBndLib)
{
NCollection_Array1<gp_Pnt> aPoles(1, 7);
aPoles.SetValue(1, gp_Pnt(0.0, 0.0, 0.0));
aPoles.SetValue(2, gp_Pnt(10.0, 20.0, 0.0));
aPoles.SetValue(3, gp_Pnt(20.0, -10.0, 5.0));
aPoles.SetValue(4, gp_Pnt(30.0, 40.0, 0.0));
aPoles.SetValue(5, gp_Pnt(40.0, 5.0, -5.0));
aPoles.SetValue(6, gp_Pnt(50.0, 15.0, 0.0));
aPoles.SetValue(7, gp_Pnt(60.0, 0.0, 0.0));
NCollection_Array1<double> aKnots(1, 5);
aKnots.SetValue(1, 0.0);
aKnots.SetValue(2, 1.0);
aKnots.SetValue(3, 2.0);
aKnots.SetValue(4, 3.0);
aKnots.SetValue(5, 4.0);
NCollection_Array1<int> aMults(1, 5);
aMults.SetValue(1, 4);
aMults.SetValue(2, 1);
aMults.SetValue(3, 1);
aMults.SetValue(4, 1);
aMults.SetValue(5, 4);
occ::handle<Geom_BSplineCurve> aBSpl = new Geom_BSplineCurve(aPoles, aKnots, aMults, 3);
GeomAdaptor_Curve anAdaptor(aBSpl);
constexpr double aU1 = 1.82;
constexpr double aU2 = 2.04;
Bnd_Box aNewBox;
GeomBndLib_Curve(aBSpl).Add(aU1, aU2, Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, aU1, aU2, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
// =========================================================================
// Adaptor constructor
// =========================================================================
TEST(GeomBndLib_CurveTest, AdaptorConstructor_Circle)
{
const double aRadius = 5.0;
occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp::XOY(), aRadius);
// Construct from handle
GeomBndLib_Curve aCurveH(aCircle);
Bnd_Box aBoxH;
aCurveH.Add(Precision::Confusion(), aBoxH);
// Construct from adaptor
GeomAdaptor_Curve anAdaptor(aCircle);
GeomBndLib_Curve aCurveA(anAdaptor);
EXPECT_EQ(aCurveA.GetType(), GeomAbs_Circle);
Bnd_Box aBoxA;
aCurveA.Add(Precision::Confusion(), aBoxA);
CompareBoxes(aBoxH, aBoxA, Precision::Confusion());
}
// =========================================================================
// AddOptimal
// =========================================================================
TEST(GeomBndLib_CurveTest, AddOptimal_Circle)
{
const double aRadius = 5.0;
occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp::XOY(), aRadius);
GeomBndLib_Curve aCurve(aCircle);
Bnd_Box aBox;
aCurve.Add(Precision::Confusion(), aBox);
Bnd_Box aBoxOpt;
aCurve.AddOptimal(Precision::Confusion(), aBoxOpt);
const auto [aXmin, aXmax, aYmin, aYmax, aZmin, aZmax] = aBox.Get();
const auto [aXminO, aXmaxO, aYminO, aYmaxO, aZminO, aZmaxO] = aBoxOpt.Get();
// AddOptimal should produce a box no larger than Add
EXPECT_GE(aXminO, aXmin - Precision::Confusion());
EXPECT_GE(aYminO, aYmin - Precision::Confusion());
EXPECT_GE(aZminO, aZmin - Precision::Confusion());
EXPECT_LE(aXmaxO, aXmax + Precision::Confusion());
EXPECT_LE(aYmaxO, aYmax + Precision::Confusion());
EXPECT_LE(aZmaxO, aZmax + Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, AddOptimal_CompareWithBndLib)
{
occ::handle<Geom_Ellipse> anEllipse = new Geom_Ellipse(gp::XOY(), 8.0, 3.0);
GeomAdaptor_Curve anAdaptor(anEllipse);
Bnd_Box aNewBox;
GeomBndLib_Curve(anEllipse).AddOptimal(Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::AddOptimal(anAdaptor, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, AdaptorConstructor_TrimmedRangeUsedForFullAdd)
{
occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp::XOY(), 10.0);
GeomAdaptor_Curve anAdaptor(aCircle, 0.0, M_PI / 2.0);
Bnd_Box aNewBox;
GeomBndLib_Curve(anAdaptor).Add(Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, TrimmedCurveHandle_Fallback_CompareWithBndLib)
{
occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp::XOY(), 10.0);
occ::handle<Geom_TrimmedCurve> aTrim = new Geom_TrimmedCurve(aCircle, 0.0, M_PI / 2.0);
GeomAdaptor_Curve anAdaptor(aTrim);
Bnd_Box aNewBox;
GeomBndLib_Curve(aTrim).Add(Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, Precision::Confusion(), anOldBox);
EXPECT_FALSE(aNewBox.IsVoid());
ExpectConservativeEnvelope(aNewBox, anOldBox, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, TrimmedCurveHandle_UsesBasisSpecialization)
{
occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp::XOY(), 10.0);
occ::handle<Geom_TrimmedCurve> aTrim = new Geom_TrimmedCurve(aCircle, 0.0, M_PI / 2.0);
GeomBndLib_Curve aCurve(aTrim);
EXPECT_EQ(aCurve.GetType(), GeomAbs_Circle);
GeomAdaptor_Curve anAdaptor(aTrim);
Bnd_Box aNewBox;
aCurve.Add(Precision::Confusion(), aNewBox);
Bnd_Box anOldBox;
BndLib_Add3dCurve::Add(anAdaptor, Precision::Confusion(), anOldBox);
CompareBoxes(aNewBox, anOldBox, Precision::Confusion());
}
TEST(GeomBndLib_CurveTest, SamplingHelpers3d_MatchesLegacyPolicy)
{
occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp::XOY(), 10.0);
GeomAdaptor_Curve aCircleGA(aCircle);
EXPECT_EQ(GeomBndLib_SamplingHelpers::ComputeNbSamples(aCircleGA, 0.0, 1.0), 33);
constexpr int aDegree = 3;
constexpr int aNbKnots = 40;
constexpr int aNbPoles = 42;
NCollection_Array1<gp_Pnt> aPoles(1, aNbPoles);
for (int i = 1; i <= aNbPoles; ++i)
{
const double t = static_cast<double>(i - 1) / static_cast<double>(aNbPoles - 1);
aPoles.SetValue(i, gp_Pnt(10.0 * t, t, 0.0));
}
NCollection_Array1<double> aKnots(1, aNbKnots);
for (int i = 1; i <= aNbKnots; ++i)
{
aKnots.SetValue(i, static_cast<double>(i - 1));
}
NCollection_Array1<int> aMults(1, aNbKnots);
aMults.SetValue(1, aDegree + 1);
for (int i = 2; i < aNbKnots; ++i)
{
aMults.SetValue(i, 1);
}
aMults.SetValue(aNbKnots, aDegree + 1);
occ::handle<Geom_BSplineCurve> aBSpl = new Geom_BSplineCurve(aPoles, aKnots, aMults, aDegree);
GeomAdaptor_Curve aBSplGA(aBSpl);
EXPECT_EQ(GeomBndLib_SamplingHelpers::ComputeNbSamples(aBSplGA,
aBSpl->FirstParameter(),
aBSpl->LastParameter()),
312);
}
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.