Testing - Add unit tests for geometric classes and conversions (#1099)

- Introduced new tests for TopExp class to validate shape mapping and vertex retrieval.
- Added tests for Geom_Circle, Geom_Line, and Geom_Plane classes to ensure correct geometric behavior and transformations.
- Implemented tests for GCPnts_AbscissaPoint to verify length calculations and parameter retrieval for lines and circles.
- Created conversion tests in GeomConvert to check the accuracy of converting geometric entities to B-spline representations.
- Updated CMake files to include new test files for the added tests.
This commit is contained in:
Pasukhin Dmitry
2026-02-20 20:25:09 +00:00
committed by GitHub
parent e72d772e70
commit e384f0bb93
44 changed files with 4243 additions and 26 deletions
@@ -42,8 +42,18 @@ set(OCCT_TKMath_GTests_FILES
CSLib_Test.cxx
ElCLib_Test.cxx
gp_Ax3_Test.cxx
gp_Circ_Test.cxx
gp_Dir_Test.cxx
gp_Dir2d_Test.cxx
gp_Lin_Test.cxx
gp_Mat_Test.cxx
gp_Pln_Test.cxx
gp_Pnt_Test.cxx
gp_Pnt2d_Test.cxx
gp_Trsf_Test.cxx
gp_Vec_Test.cxx
gp_Vec2d_Test.cxx
gp_XYZ_Test.cxx
math_BFGS_Test.cxx
math_BissecNewton_Test.cxx
math_BracketMinimum_Test.cxx
@@ -0,0 +1,96 @@
// 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 <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
#include <gp_Circ.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(gp_CircTest, Constructor)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Circ aCirc(anAxis, 5.0);
EXPECT_NEAR(aCirc.Radius(), 5.0, Precision::Confusion());
}
TEST(gp_CircTest, Area)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Circ aCirc(anAxis, 1.0);
EXPECT_NEAR(aCirc.Area(), M_PI, Precision::Confusion());
}
TEST(gp_CircTest, Length)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Circ aCirc(anAxis, 1.0);
EXPECT_NEAR(aCirc.Length(), 2.0 * M_PI, Precision::Confusion());
}
TEST(gp_CircTest, Center)
{
gp_Pnt aCenter(1.0, 2.0, 3.0);
gp_Ax2 anAxis(aCenter, gp_Dir(0.0, 0.0, 1.0));
gp_Circ aCirc(anAxis, 5.0);
EXPECT_TRUE(aCirc.Location().IsEqual(aCenter, Precision::Confusion()));
}
TEST(gp_CircTest, Translate)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Circ aCirc(anAxis, 5.0);
gp_Vec aVec(10.0, 20.0, 30.0);
gp_Circ aTranslated = aCirc.Translated(aVec);
EXPECT_NEAR(aTranslated.Location().X(), 10.0, Precision::Confusion());
EXPECT_NEAR(aTranslated.Location().Y(), 20.0, Precision::Confusion());
EXPECT_NEAR(aTranslated.Location().Z(), 30.0, Precision::Confusion());
EXPECT_NEAR(aTranslated.Radius(), 5.0, Precision::Confusion());
}
TEST(gp_CircTest, Rotate)
{
gp_Ax2 anAxis(gp_Pnt(1.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Circ aCirc(anAxis, 2.0);
gp_Ax1 aRotAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Circ aRotated = aCirc.Rotated(aRotAxis, M_PI_2);
EXPECT_NEAR(aRotated.Location().X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aRotated.Location().Y(), 1.0, Precision::Confusion());
EXPECT_NEAR(aRotated.Radius(), 2.0, Precision::Confusion());
}
TEST(gp_CircTest, Mirror)
{
gp_Ax2 anAxis(gp_Pnt(1.0, 2.0, 3.0), gp_Dir(0.0, 0.0, 1.0));
gp_Circ aCirc(anAxis, 5.0);
gp_Pnt aMirrorPnt(0.0, 0.0, 0.0);
gp_Circ aMirrored = aCirc.Mirrored(aMirrorPnt);
EXPECT_NEAR(aMirrored.Location().X(), -1.0, Precision::Confusion());
EXPECT_NEAR(aMirrored.Location().Y(), -2.0, Precision::Confusion());
EXPECT_NEAR(aMirrored.Location().Z(), -3.0, Precision::Confusion());
}
TEST(gp_CircTest, Transform)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Circ aCirc(anAxis, 3.0);
gp_Trsf aTrsf;
aTrsf.SetScale(gp_Pnt(0.0, 0.0, 0.0), 2.0);
gp_Circ aTransformed = aCirc.Transformed(aTrsf);
EXPECT_NEAR(aTransformed.Radius(), 6.0, Precision::Confusion());
}
@@ -0,0 +1,138 @@
// 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 <gp_Ax2d.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Trsf2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_XY.hxx>
#include <Precision.hxx>
#include <Standard_ConstructionError.hxx>
#include <gtest/gtest.h>
TEST(gp_Dir2dTest, CoordinateConstructor)
{
gp_Dir2d aDir(1.0, 0.0);
EXPECT_NEAR(aDir.X(), 1.0, Precision::Confusion());
EXPECT_NEAR(aDir.Y(), 0.0, Precision::Confusion());
}
TEST(gp_Dir2dTest, XYConstructor)
{
gp_XY aXY(0.0, 3.0);
gp_Dir2d aDir(aXY);
EXPECT_NEAR(aDir.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aDir.Y(), 1.0, Precision::Confusion());
}
TEST(gp_Dir2dTest, Vec2dConstructor)
{
gp_Vec2d aVec(3.0, 0.0);
gp_Dir2d aDir(aVec);
EXPECT_NEAR(aDir.X(), 1.0, Precision::Confusion());
EXPECT_NEAR(aDir.Y(), 0.0, Precision::Confusion());
}
TEST(gp_Dir2dTest, Angle)
{
gp_Dir2d aD1(1.0, 0.0);
gp_Dir2d aD2(0.0, 1.0);
EXPECT_NEAR(aD1.Angle(aD2), M_PI_2, Precision::Angular());
}
TEST(gp_Dir2dTest, IsEqual)
{
gp_Dir2d aD1(1.0, 0.0);
gp_Dir2d aD2(1.0, 0.0);
EXPECT_TRUE(aD1.IsEqual(aD2, Precision::Angular()));
}
TEST(gp_Dir2dTest, IsNormal)
{
gp_Dir2d aD1(1.0, 0.0);
gp_Dir2d aD2(0.0, 1.0);
EXPECT_TRUE(aD1.IsNormal(aD2, Precision::Angular()));
}
TEST(gp_Dir2dTest, IsOpposite)
{
gp_Dir2d aD1(1.0, 0.0);
gp_Dir2d aD2(-1.0, 0.0);
EXPECT_TRUE(aD1.IsOpposite(aD2, Precision::Angular()));
}
TEST(gp_Dir2dTest, IsParallel)
{
gp_Dir2d aD1(1.0, 0.0);
gp_Dir2d aD2(-1.0, 0.0);
EXPECT_TRUE(aD1.IsParallel(aD2, Precision::Angular()));
}
TEST(gp_Dir2dTest, Dot)
{
gp_Dir2d aD1(1.0, 0.0);
gp_Dir2d aD2(0.0, 1.0);
EXPECT_NEAR(aD1.Dot(aD2), 0.0, Precision::Confusion());
gp_Dir2d aD3(1.0, 0.0);
EXPECT_NEAR(aD1.Dot(aD3), 1.0, Precision::Confusion());
}
TEST(gp_Dir2dTest, Crossed)
{
gp_Dir2d aD1(1.0, 0.0);
gp_Dir2d aD2(0.0, 1.0);
// D1.X*D2.Y - D1.Y*D2.X = 1*1 - 0*0 = 1
EXPECT_NEAR(aD1.Crossed(aD2), 1.0, Precision::Confusion());
}
TEST(gp_Dir2dTest, Rotate)
{
gp_Dir2d aDir(1.0, 0.0);
gp_Dir2d aRotated = aDir.Rotated(M_PI_2);
EXPECT_NEAR(aRotated.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aRotated.Y(), 1.0, Precision::Confusion());
}
TEST(gp_Dir2dTest, Mirror)
{
gp_Dir2d aDir(1.0, 0.0);
// Mirror through the Y axis
gp_Ax2d anAxis(gp_Pnt2d(0.0, 0.0), gp_Dir2d(0.0, 1.0));
gp_Dir2d aMirrored = aDir.Mirrored(anAxis);
// Mirroring (1,0) through axis with direction (0,1):
// d_mirror = 2*(d.axis_dir)*axis_dir - d = 2*0*(0,1) - (1,0) = (-1,0)
EXPECT_NEAR(aMirrored.X(), -1.0, Precision::Confusion());
EXPECT_NEAR(aMirrored.Y(), 0.0, Precision::Confusion());
}
TEST(gp_Dir2dTest, Transform)
{
gp_Dir2d aDir(1.0, 0.0);
gp_Trsf2d aTrsf;
aTrsf.SetRotation(gp_Pnt2d(0.0, 0.0), M_PI);
gp_Dir2d aTransformed = aDir.Transformed(aTrsf);
EXPECT_NEAR(aTransformed.X(), -1.0, Precision::Confusion());
EXPECT_NEAR(aTransformed.Y(), 0.0, Precision::Confusion());
}
TEST(gp_Dir2dTest, ZeroMagnitudeThrows)
{
#ifndef No_Exception
EXPECT_THROW(gp_Dir2d aDir(0.0, 0.0), Standard_ConstructionError);
#else
GTEST_SKIP() << "No_Exception is defined; exception behavior is disabled in this build.";
#endif
}
@@ -0,0 +1,182 @@
// 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 <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <gp_XYZ.hxx>
#include <Precision.hxx>
#include <Standard_ConstructionError.hxx>
#include <gtest/gtest.h>
TEST(gp_DirTest, CoordinateConstructor)
{
gp_Dir aDir(0.0, 0.0, 1.0);
EXPECT_NEAR(aDir.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aDir.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aDir.Z(), 1.0, Precision::Confusion());
}
TEST(gp_DirTest, XYZConstructor)
{
gp_XYZ aXYZ(0.0, 3.0, 4.0);
gp_Dir aDir(aXYZ);
EXPECT_NEAR(aDir.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aDir.Y(), 0.6, Precision::Confusion());
EXPECT_NEAR(aDir.Z(), 0.8, Precision::Confusion());
}
TEST(gp_DirTest, VecConstructor)
{
gp_Vec aVec(3.0, 0.0, 0.0);
gp_Dir aDir(aVec);
EXPECT_NEAR(aDir.X(), 1.0, Precision::Confusion());
EXPECT_NEAR(aDir.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aDir.Z(), 0.0, Precision::Confusion());
}
TEST(gp_DirTest, PredefinedDirections)
{
EXPECT_TRUE(gp_Dir(1.0, 0.0, 0.0).IsEqual(gp_Dir(gp_Dir::D::X), Precision::Angular()));
EXPECT_TRUE(gp_Dir(0.0, 1.0, 0.0).IsEqual(gp_Dir(gp_Dir::D::Y), Precision::Angular()));
EXPECT_TRUE(gp_Dir(0.0, 0.0, 1.0).IsEqual(gp_Dir(gp_Dir::D::Z), Precision::Angular()));
}
TEST(gp_DirTest, Angle)
{
gp_Dir aD1(1.0, 0.0, 0.0);
gp_Dir aD2(0.0, 1.0, 0.0);
EXPECT_NEAR(aD1.Angle(aD2), M_PI_2, Precision::Angular());
}
TEST(gp_DirTest, AngleWithRef)
{
gp_Dir aD1(1.0, 0.0, 0.0);
gp_Dir aD2(0.0, 1.0, 0.0);
gp_Dir aRef(0.0, 0.0, 1.0);
double anAngle = aD1.AngleWithRef(aD2, aRef);
EXPECT_NEAR(anAngle, M_PI_2, Precision::Angular());
// Reverse reference direction should negate the angle
double anAngleReversed = aD1.AngleWithRef(aD2, gp_Dir(0.0, 0.0, -1.0));
EXPECT_NEAR(anAngleReversed, -M_PI_2, Precision::Angular());
}
TEST(gp_DirTest, IsEqual)
{
gp_Dir aD1(1.0, 0.0, 0.0);
gp_Dir aD2(1.0, 0.0, 0.0);
EXPECT_TRUE(aD1.IsEqual(aD2, Precision::Angular()));
}
TEST(gp_DirTest, IsNormal)
{
gp_Dir aD1(1.0, 0.0, 0.0);
gp_Dir aD2(0.0, 1.0, 0.0);
EXPECT_TRUE(aD1.IsNormal(aD2, Precision::Angular()));
}
TEST(gp_DirTest, IsOpposite)
{
gp_Dir aD1(1.0, 0.0, 0.0);
gp_Dir aD2(-1.0, 0.0, 0.0);
EXPECT_TRUE(aD1.IsOpposite(aD2, Precision::Angular()));
}
TEST(gp_DirTest, IsParallel)
{
gp_Dir aD1(1.0, 0.0, 0.0);
gp_Dir aD2(-1.0, 0.0, 0.0);
EXPECT_TRUE(aD1.IsParallel(aD2, Precision::Angular()));
}
TEST(gp_DirTest, Cross)
{
gp_Dir aD1(1.0, 0.0, 0.0);
gp_Dir aD2(0.0, 1.0, 0.0);
gp_Dir aCross = aD1.Crossed(aD2);
EXPECT_NEAR(aCross.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aCross.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aCross.Z(), 1.0, Precision::Confusion());
}
TEST(gp_DirTest, CrossCross)
{
gp_Dir aA(1.0, 0.0, 0.0);
gp_Dir aB(1.0, 1.0, 0.0);
gp_Dir aC(0.0, 0.0, 1.0);
gp_Dir aCrossCross = aA.CrossCrossed(aB, aC);
// Result should be a valid normalized direction
double aMag = std::sqrt(aCrossCross.X() * aCrossCross.X() + aCrossCross.Y() * aCrossCross.Y()
+ aCrossCross.Z() * aCrossCross.Z());
EXPECT_NEAR(aMag, 1.0, Precision::Confusion());
}
TEST(gp_DirTest, Dot)
{
gp_Dir aD1(1.0, 0.0, 0.0);
gp_Dir aD2(0.0, 1.0, 0.0);
EXPECT_NEAR(aD1.Dot(aD2), 0.0, Precision::Confusion());
gp_Dir aD3(1.0, 0.0, 0.0);
EXPECT_NEAR(aD1.Dot(aD3), 1.0, Precision::Confusion());
}
TEST(gp_DirTest, Mirror_Point)
{
gp_Dir aDir(1.0, 0.0, 0.0);
gp_Ax1 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 1.0, 0.0));
gp_Dir aMirrored = aDir.Mirrored(anAxis);
// Mirror X direction through Y axis: result should be (-1,0,0)...
// Actually mirroring direction (1,0,0) through axis Y means reflecting about the Y axis line
// The component along Y stays, the perpendicular component reverses: result is (-1,0,0)
// But for axis mirror of a direction, it reflects in the axis:
// d_mirror = 2*(d.axis)*axis - d
// d.axis = (1,0,0).(0,1,0) = 0
// result = 2*0*(0,1,0) - (1,0,0) = (-1,0,0)
EXPECT_NEAR(aMirrored.X(), -1.0, Precision::Confusion());
EXPECT_NEAR(aMirrored.Y(), 0.0, Precision::Confusion());
}
TEST(gp_DirTest, Rotate)
{
gp_Dir aDir(1.0, 0.0, 0.0);
gp_Ax1 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Dir aRotated = aDir.Rotated(anAxis, M_PI_2);
EXPECT_NEAR(aRotated.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aRotated.Y(), 1.0, Precision::Confusion());
EXPECT_NEAR(aRotated.Z(), 0.0, Precision::Confusion());
}
TEST(gp_DirTest, Transform)
{
gp_Dir aDir(1.0, 0.0, 0.0);
gp_Trsf aTrsf;
aTrsf.SetRotation(gp_Ax1(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), M_PI);
gp_Dir aTransformed = aDir.Transformed(aTrsf);
EXPECT_NEAR(aTransformed.X(), -1.0, Precision::Confusion());
EXPECT_NEAR(aTransformed.Y(), 0.0, Precision::Confusion());
}
TEST(gp_DirTest, ZeroMagnitudeInput_ThrowsException)
{
#ifndef No_Exception
EXPECT_THROW(gp_Dir aDir(0.0, 0.0, 0.0), Standard_ConstructionError);
#else
GTEST_SKIP() << "No_Exception is defined; exception behavior is disabled in this build.";
#endif
}
@@ -0,0 +1,111 @@
// 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 <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
#include <gp_Dir.hxx>
#include <gp_Lin.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(gp_LinTest, ConstructorFromAx1)
{
gp_Ax1 anAx1(gp_Pnt(1.0, 2.0, 3.0), gp_Dir(1.0, 0.0, 0.0));
gp_Lin aLin(anAx1);
EXPECT_TRUE(aLin.Location().IsEqual(gp_Pnt(1.0, 2.0, 3.0), Precision::Confusion()));
EXPECT_TRUE(aLin.Direction().IsEqual(gp_Dir(1.0, 0.0, 0.0), Precision::Angular()));
}
TEST(gp_LinTest, ConstructorFromPointAndDir)
{
gp_Lin aLin(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
EXPECT_TRUE(aLin.Location().IsEqual(gp_Pnt(0.0, 0.0, 0.0), Precision::Confusion()));
EXPECT_TRUE(aLin.Direction().IsEqual(gp_Dir(0.0, 0.0, 1.0), Precision::Angular()));
}
TEST(gp_LinTest, DistanceToPoint)
{
gp_Lin aLin(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Pnt aPnt(5.0, 3.0, 4.0);
// Distance from point to X axis: sqrt(3^2 + 4^2) = 5
EXPECT_NEAR(aLin.Distance(aPnt), 5.0, Precision::Confusion());
}
TEST(gp_LinTest, DistanceToLine_Parallel)
{
gp_Lin aL1(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Lin aL2(gp_Pnt(0.0, 3.0, 4.0), gp_Dir(1.0, 0.0, 0.0));
EXPECT_NEAR(aL1.Distance(aL2), 5.0, Precision::Confusion());
}
TEST(gp_LinTest, DistanceToLine_Intersecting)
{
gp_Lin aL1(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Lin aL2(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 1.0, 0.0));
EXPECT_NEAR(aL1.Distance(aL2), 0.0, Precision::Confusion());
}
TEST(gp_LinTest, Contains)
{
gp_Lin aLin(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Pnt aOnLine(5.0, 0.0, 0.0);
gp_Pnt aOffLine(5.0, 1.0, 0.0);
EXPECT_TRUE(aLin.Contains(aOnLine, Precision::Confusion()));
EXPECT_FALSE(aLin.Contains(aOffLine, Precision::Confusion()));
}
TEST(gp_LinTest, Angle)
{
gp_Lin aL1(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Lin aL2(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 1.0, 0.0));
EXPECT_NEAR(aL1.Angle(aL2), M_PI_2, Precision::Angular());
}
TEST(gp_LinTest, Translate)
{
gp_Lin aLin(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Vec aVec(0.0, 5.0, 0.0);
gp_Lin aTranslated = aLin.Translated(aVec);
EXPECT_NEAR(aTranslated.Location().Y(), 5.0, Precision::Confusion());
}
TEST(gp_LinTest, Rotate)
{
gp_Lin aLin(gp_Pnt(1.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Ax1 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Lin aRotated = aLin.Rotated(anAxis, M_PI_2);
EXPECT_NEAR(aRotated.Location().X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aRotated.Location().Y(), 1.0, Precision::Confusion());
EXPECT_TRUE(aRotated.Direction().IsEqual(gp_Dir(0.0, 1.0, 0.0), Precision::Angular()));
}
TEST(gp_LinTest, Mirror)
{
gp_Lin aLin(gp_Pnt(1.0, 1.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Ax1 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Lin aMirrored = aLin.Mirrored(anAxis);
EXPECT_NEAR(aMirrored.Location().Y(), -1.0, Precision::Confusion());
}
TEST(gp_LinTest, Transform)
{
gp_Lin aLin(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Trsf aTrsf;
aTrsf.SetTranslation(gp_Vec(0.0, 0.0, 10.0));
gp_Lin aTransformed = aLin.Transformed(aTrsf);
EXPECT_NEAR(aTransformed.Location().Z(), 10.0, Precision::Confusion());
}
@@ -0,0 +1,124 @@
// 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 <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
#include <gp_Ax3.hxx>
#include <gp_Dir.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(gp_PlnTest, ConstructorFromAx3)
{
gp_Ax3 anAx3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Pln aPln(anAx3);
EXPECT_TRUE(aPln.Location().IsEqual(gp_Pnt(0.0, 0.0, 0.0), Precision::Confusion()));
EXPECT_TRUE(aPln.Axis().Direction().IsEqual(gp_Dir(0.0, 0.0, 1.0), Precision::Angular()));
}
TEST(gp_PlnTest, ConstructorFromPointAndDir)
{
gp_Pnt aLoc(1.0, 2.0, 3.0);
gp_Dir aNorm(0.0, 0.0, 1.0);
gp_Pln aPln(aLoc, aNorm);
EXPECT_TRUE(aPln.Location().IsEqual(aLoc, Precision::Confusion()));
EXPECT_TRUE(aPln.Axis().Direction().IsEqual(aNorm, Precision::Angular()));
}
TEST(gp_PlnTest, ConstructorFromCoefficients)
{
// Plane Z = 5 => 0*X + 0*Y + 1*Z - 5 = 0
gp_Pln aPln(0.0, 0.0, 1.0, -5.0);
double anA, aB, aC, aD;
aPln.Coefficients(anA, aB, aC, aD);
EXPECT_NEAR(anA, 0.0, Precision::Confusion());
EXPECT_NEAR(aB, 0.0, Precision::Confusion());
EXPECT_NEAR(aC, 1.0, Precision::Confusion());
EXPECT_NEAR(aD, -5.0, Precision::Confusion());
}
TEST(gp_PlnTest, DistanceToPoint)
{
gp_Pln aPln(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Pnt aPnt(3.0, 4.0, 5.0);
EXPECT_NEAR(aPln.Distance(aPnt), 5.0, Precision::Confusion());
}
TEST(gp_PlnTest, Contains)
{
gp_Pln aPln(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Pnt aOnPlane(3.0, 4.0, 0.0);
gp_Pnt aOffPlane(3.0, 4.0, 1.0);
EXPECT_TRUE(aPln.Contains(aOnPlane, Precision::Confusion()));
EXPECT_FALSE(aPln.Contains(aOffPlane, Precision::Confusion()));
}
TEST(gp_PlnTest, Coefficients)
{
gp_Pln aPln(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
double anA, aB, aC, aD;
aPln.Coefficients(anA, aB, aC, aD);
EXPECT_NEAR(anA, 0.0, Precision::Confusion());
EXPECT_NEAR(aB, 0.0, Precision::Confusion());
EXPECT_NEAR(aC, 1.0, Precision::Confusion());
EXPECT_NEAR(aD, 0.0, Precision::Confusion());
}
TEST(gp_PlnTest, Mirror)
{
gp_Pln aPln(gp_Pnt(0.0, 0.0, 5.0), gp_Dir(0.0, 0.0, 1.0));
gp_Ax2 aMirrorPlane(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Pln aMirrored = aPln.Mirrored(aMirrorPlane);
EXPECT_NEAR(aMirrored.Location().Z(), -5.0, Precision::Confusion());
}
TEST(gp_PlnTest, Rotate)
{
gp_Pln aPln(gp_Pnt(1.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Ax1 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Pln aRotated = aPln.Rotated(anAxis, M_PI_2);
EXPECT_NEAR(aRotated.Location().X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aRotated.Location().Y(), 1.0, Precision::Confusion());
}
TEST(gp_PlnTest, Scale)
{
gp_Pln aPln(gp_Pnt(1.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Pnt aCenter(0.0, 0.0, 0.0);
gp_Pln aScaled = aPln.Scaled(aCenter, 3.0);
EXPECT_NEAR(aScaled.Location().X(), 3.0, Precision::Confusion());
}
TEST(gp_PlnTest, Translate)
{
gp_Pln aPln(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Vec aVec(1.0, 2.0, 3.0);
gp_Pln aTranslated = aPln.Translated(aVec);
EXPECT_NEAR(aTranslated.Location().X(), 1.0, Precision::Confusion());
EXPECT_NEAR(aTranslated.Location().Y(), 2.0, Precision::Confusion());
EXPECT_NEAR(aTranslated.Location().Z(), 3.0, Precision::Confusion());
}
TEST(gp_PlnTest, Transform)
{
gp_Pln aPln(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Trsf aTrsf;
aTrsf.SetTranslation(gp_Vec(0.0, 0.0, 10.0));
gp_Pln aTransformed = aPln.Transformed(aTrsf);
EXPECT_NEAR(aTransformed.Location().Z(), 10.0, Precision::Confusion());
}
@@ -0,0 +1,137 @@
// 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 <gp_Ax2d.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Trsf2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_XY.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(gp_Pnt2dTest, DefaultConstructor)
{
gp_Pnt2d aPnt;
EXPECT_DOUBLE_EQ(aPnt.X(), 0.0);
EXPECT_DOUBLE_EQ(aPnt.Y(), 0.0);
}
TEST(gp_Pnt2dTest, CoordinateConstructor)
{
gp_Pnt2d aPnt(1.0, 2.0);
EXPECT_DOUBLE_EQ(aPnt.X(), 1.0);
EXPECT_DOUBLE_EQ(aPnt.Y(), 2.0);
}
TEST(gp_Pnt2dTest, XYConstructor)
{
gp_XY aXY(3.0, 4.0);
gp_Pnt2d aPnt(aXY);
EXPECT_DOUBLE_EQ(aPnt.X(), 3.0);
EXPECT_DOUBLE_EQ(aPnt.Y(), 4.0);
}
TEST(gp_Pnt2dTest, SetCoord)
{
gp_Pnt2d aPnt;
aPnt.SetX(10.0);
aPnt.SetY(20.0);
EXPECT_DOUBLE_EQ(aPnt.X(), 10.0);
EXPECT_DOUBLE_EQ(aPnt.Y(), 20.0);
aPnt.SetCoord(7.0, 8.0);
EXPECT_DOUBLE_EQ(aPnt.X(), 7.0);
EXPECT_DOUBLE_EQ(aPnt.Y(), 8.0);
}
TEST(gp_Pnt2dTest, Distance)
{
gp_Pnt2d aP1(0.0, 0.0);
gp_Pnt2d aP2(3.0, 4.0);
EXPECT_NEAR(aP1.Distance(aP2), 5.0, Precision::Confusion());
}
TEST(gp_Pnt2dTest, SquareDistance)
{
gp_Pnt2d aP1(1.0, 2.0);
gp_Pnt2d aP2(4.0, 6.0);
// (4-1)^2 + (6-2)^2 = 9 + 16 = 25
EXPECT_NEAR(aP1.SquareDistance(aP2), 25.0, Precision::Confusion());
}
TEST(gp_Pnt2dTest, IsEqual)
{
gp_Pnt2d aP1(1.0, 2.0);
gp_Pnt2d aP2(1.0, 2.0);
gp_Pnt2d aP3(1.0, 3.0);
EXPECT_TRUE(aP1.IsEqual(aP2, Precision::Confusion()));
EXPECT_FALSE(aP1.IsEqual(aP3, Precision::Confusion()));
}
TEST(gp_Pnt2dTest, Translate_ByVec2d)
{
gp_Pnt2d aPnt(1.0, 2.0);
gp_Vec2d aVec(10.0, 20.0);
gp_Pnt2d aResult = aPnt.Translated(aVec);
EXPECT_NEAR(aResult.X(), 11.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 22.0, Precision::Confusion());
}
TEST(gp_Pnt2dTest, Scale)
{
gp_Pnt2d aPnt(2.0, 4.0);
gp_Pnt2d aCenter(0.0, 0.0);
gp_Pnt2d aResult = aPnt.Scaled(aCenter, 2.0);
EXPECT_NEAR(aResult.X(), 4.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 8.0, Precision::Confusion());
}
TEST(gp_Pnt2dTest, Rotate)
{
gp_Pnt2d aPnt(1.0, 0.0);
gp_Pnt2d aCenter(0.0, 0.0);
gp_Pnt2d aResult = aPnt.Rotated(aCenter, M_PI_2);
EXPECT_NEAR(aResult.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 1.0, Precision::Confusion());
}
TEST(gp_Pnt2dTest, Mirror_Point)
{
gp_Pnt2d aPnt(1.0, 0.0);
gp_Pnt2d aCenter(0.0, 0.0);
gp_Pnt2d aResult = aPnt.Mirrored(aCenter);
EXPECT_NEAR(aResult.X(), -1.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 0.0, Precision::Confusion());
}
TEST(gp_Pnt2dTest, Mirror_Axis)
{
gp_Pnt2d aPnt(1.0, 1.0);
// Mirror through the X axis
gp_Ax2d anAxis(gp_Pnt2d(0.0, 0.0), gp_Dir2d(1.0, 0.0));
gp_Pnt2d aResult = aPnt.Mirrored(anAxis);
EXPECT_NEAR(aResult.X(), 1.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), -1.0, Precision::Confusion());
}
TEST(gp_Pnt2dTest, Transformed)
{
gp_Pnt2d aPnt(1.0, 0.0);
gp_Trsf2d aTrsf;
aTrsf.SetTranslation(gp_Vec2d(0.0, 5.0));
gp_Pnt2d aResult = aPnt.Transformed(aTrsf);
EXPECT_NEAR(aResult.X(), 1.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 5.0, Precision::Confusion());
}
@@ -0,0 +1,181 @@
// 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 <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(gp_PntTest, DefaultConstructor)
{
gp_Pnt aPnt;
EXPECT_DOUBLE_EQ(aPnt.X(), 0.0);
EXPECT_DOUBLE_EQ(aPnt.Y(), 0.0);
EXPECT_DOUBLE_EQ(aPnt.Z(), 0.0);
}
TEST(gp_PntTest, CoordinateConstructor)
{
gp_Pnt aPnt(1.0, 2.0, 3.0);
EXPECT_DOUBLE_EQ(aPnt.X(), 1.0);
EXPECT_DOUBLE_EQ(aPnt.Y(), 2.0);
EXPECT_DOUBLE_EQ(aPnt.Z(), 3.0);
}
TEST(gp_PntTest, XYZConstructor)
{
gp_XYZ aXYZ(4.0, 5.0, 6.0);
gp_Pnt aPnt(aXYZ);
EXPECT_DOUBLE_EQ(aPnt.X(), 4.0);
EXPECT_DOUBLE_EQ(aPnt.Y(), 5.0);
EXPECT_DOUBLE_EQ(aPnt.Z(), 6.0);
}
TEST(gp_PntTest, SetCoord)
{
gp_Pnt aPnt;
aPnt.SetX(10.0);
aPnt.SetY(20.0);
aPnt.SetZ(30.0);
EXPECT_DOUBLE_EQ(aPnt.X(), 10.0);
EXPECT_DOUBLE_EQ(aPnt.Y(), 20.0);
EXPECT_DOUBLE_EQ(aPnt.Z(), 30.0);
aPnt.SetCoord(7.0, 8.0, 9.0);
EXPECT_DOUBLE_EQ(aPnt.X(), 7.0);
EXPECT_DOUBLE_EQ(aPnt.Y(), 8.0);
EXPECT_DOUBLE_EQ(aPnt.Z(), 9.0);
}
TEST(gp_PntTest, Distance)
{
gp_Pnt aP1(0.0, 0.0, 0.0);
gp_Pnt aP2(3.0, 4.0, 0.0);
EXPECT_NEAR(aP1.Distance(aP2), 5.0, Precision::Confusion());
}
TEST(gp_PntTest, SquareDistance)
{
gp_Pnt aP1(1.0, 2.0, 3.0);
gp_Pnt aP2(4.0, 6.0, 3.0);
// (4-1)^2 + (6-2)^2 + (3-3)^2 = 9 + 16 + 0 = 25
EXPECT_NEAR(aP1.SquareDistance(aP2), 25.0, Precision::Confusion());
}
TEST(gp_PntTest, IsEqual)
{
gp_Pnt aP1(1.0, 2.0, 3.0);
gp_Pnt aP2(1.0, 2.0, 3.0);
gp_Pnt aP3(1.0, 2.0, 4.0);
EXPECT_TRUE(aP1.IsEqual(aP2, Precision::Confusion()));
EXPECT_FALSE(aP1.IsEqual(aP3, Precision::Confusion()));
}
TEST(gp_PntTest, BaryCenter)
{
gp_Pnt aP1(0.0, 0.0, 0.0);
gp_Pnt aP2(10.0, 0.0, 0.0);
// BaryCenter with equal weights: midpoint
aP1.BaryCenter(1.0, aP2, 1.0);
EXPECT_NEAR(aP1.X(), 5.0, Precision::Confusion());
EXPECT_NEAR(aP1.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aP1.Z(), 0.0, Precision::Confusion());
}
TEST(gp_PntTest, Translate_ByVec)
{
gp_Pnt aPnt(1.0, 2.0, 3.0);
gp_Vec aVec(10.0, 20.0, 30.0);
gp_Pnt aResult = aPnt.Translated(aVec);
EXPECT_NEAR(aResult.X(), 11.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 22.0, Precision::Confusion());
EXPECT_NEAR(aResult.Z(), 33.0, Precision::Confusion());
}
TEST(gp_PntTest, Translate_ByTwoPoints)
{
gp_Pnt aPnt(1.0, 2.0, 3.0);
gp_Pnt aFrom(0.0, 0.0, 0.0);
gp_Pnt aTo(5.0, 5.0, 5.0);
gp_Pnt aResult = aPnt.Translated(aFrom, aTo);
EXPECT_NEAR(aResult.X(), 6.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 7.0, Precision::Confusion());
EXPECT_NEAR(aResult.Z(), 8.0, Precision::Confusion());
}
TEST(gp_PntTest, Scale)
{
gp_Pnt aPnt(2.0, 4.0, 6.0);
gp_Pnt aCenter(0.0, 0.0, 0.0);
gp_Pnt aResult = aPnt.Scaled(aCenter, 2.0);
EXPECT_NEAR(aResult.X(), 4.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 8.0, Precision::Confusion());
EXPECT_NEAR(aResult.Z(), 12.0, Precision::Confusion());
}
TEST(gp_PntTest, Rotate)
{
gp_Pnt aPnt(1.0, 0.0, 0.0);
gp_Ax1 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Pnt aResult = aPnt.Rotated(anAxis, M_PI_2);
EXPECT_NEAR(aResult.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 1.0, Precision::Confusion());
EXPECT_NEAR(aResult.Z(), 0.0, Precision::Confusion());
}
TEST(gp_PntTest, Mirror_Point)
{
gp_Pnt aPnt(1.0, 0.0, 0.0);
gp_Pnt aCenter(0.0, 0.0, 0.0);
gp_Pnt aResult = aPnt.Mirrored(aCenter);
EXPECT_NEAR(aResult.X(), -1.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aResult.Z(), 0.0, Precision::Confusion());
}
TEST(gp_PntTest, Mirror_Axis)
{
gp_Pnt aPnt(1.0, 1.0, 0.0);
gp_Ax1 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Pnt aResult = aPnt.Mirrored(anAxis);
EXPECT_NEAR(aResult.X(), 1.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), -1.0, Precision::Confusion());
EXPECT_NEAR(aResult.Z(), 0.0, Precision::Confusion());
}
TEST(gp_PntTest, Mirror_Plane)
{
gp_Pnt aPnt(1.0, 2.0, 3.0);
// Mirror through XY plane (Z=0)
gp_Ax2 anAx2(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Pnt aResult = aPnt.Mirrored(anAx2);
EXPECT_NEAR(aResult.X(), 1.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 2.0, Precision::Confusion());
EXPECT_NEAR(aResult.Z(), -3.0, Precision::Confusion());
}
TEST(gp_PntTest, Transformed)
{
gp_Pnt aPnt(1.0, 0.0, 0.0);
gp_Trsf aTrsf;
aTrsf.SetTranslation(gp_Vec(0.0, 0.0, 5.0));
gp_Pnt aResult = aPnt.Transformed(aTrsf);
EXPECT_NEAR(aResult.X(), 1.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aResult.Z(), 5.0, Precision::Confusion());
}
@@ -0,0 +1,165 @@
// 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 <gp_Dir2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_XY.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(gp_Vec2dTest, DefaultConstructor)
{
gp_Vec2d aVec;
EXPECT_DOUBLE_EQ(aVec.X(), 0.0);
EXPECT_DOUBLE_EQ(aVec.Y(), 0.0);
}
TEST(gp_Vec2dTest, CoordinateConstructor)
{
gp_Vec2d aVec(1.0, 2.0);
EXPECT_DOUBLE_EQ(aVec.X(), 1.0);
EXPECT_DOUBLE_EQ(aVec.Y(), 2.0);
}
TEST(gp_Vec2dTest, TwoPointConstructor)
{
gp_Pnt2d aP1(1.0, 2.0);
gp_Pnt2d aP2(4.0, 6.0);
gp_Vec2d aVec(aP1, aP2);
EXPECT_DOUBLE_EQ(aVec.X(), 3.0);
EXPECT_DOUBLE_EQ(aVec.Y(), 4.0);
}
TEST(gp_Vec2dTest, Dir2dConstructor)
{
gp_Dir2d aDir(0.0, 1.0);
gp_Vec2d aVec(aDir);
EXPECT_NEAR(aVec.Magnitude(), 1.0, Precision::Confusion());
EXPECT_NEAR(aVec.Y(), 1.0, Precision::Confusion());
}
TEST(gp_Vec2dTest, AddSubtract)
{
gp_Vec2d aV1(1.0, 2.0);
gp_Vec2d aV2(4.0, 5.0);
gp_Vec2d aSum = aV1 + aV2;
EXPECT_DOUBLE_EQ(aSum.X(), 5.0);
EXPECT_DOUBLE_EQ(aSum.Y(), 7.0);
gp_Vec2d aDiff = aV2 - aV1;
EXPECT_DOUBLE_EQ(aDiff.X(), 3.0);
EXPECT_DOUBLE_EQ(aDiff.Y(), 3.0);
}
TEST(gp_Vec2dTest, MultiplyDivide)
{
gp_Vec2d aVec(2.0, 4.0);
gp_Vec2d aScaled = aVec * 3.0;
EXPECT_DOUBLE_EQ(aScaled.X(), 6.0);
EXPECT_DOUBLE_EQ(aScaled.Y(), 12.0);
gp_Vec2d aDivided = aVec / 2.0;
EXPECT_DOUBLE_EQ(aDivided.X(), 1.0);
EXPECT_DOUBLE_EQ(aDivided.Y(), 2.0);
}
TEST(gp_Vec2dTest, Dot)
{
gp_Vec2d aV1(1.0, 0.0);
gp_Vec2d aV2(0.0, 1.0);
EXPECT_DOUBLE_EQ(aV1.Dot(aV2), 0.0);
gp_Vec2d aV3(1.0, 2.0);
gp_Vec2d aV4(4.0, 5.0);
// 1*4 + 2*5 = 14
EXPECT_DOUBLE_EQ(aV3.Dot(aV4), 14.0);
}
TEST(gp_Vec2dTest, Crossed)
{
gp_Vec2d aV1(1.0, 0.0);
gp_Vec2d aV2(0.0, 1.0);
// V1.X*V2.Y - V1.Y*V2.X = 1*1 - 0*0 = 1
EXPECT_NEAR(aV1.Crossed(aV2), 1.0, Precision::Confusion());
gp_Vec2d aV3(3.0, 4.0);
gp_Vec2d aV4(2.0, 5.0);
// 3*5 - 4*2 = 15 - 8 = 7
EXPECT_NEAR(aV3.Crossed(aV4), 7.0, Precision::Confusion());
}
TEST(gp_Vec2dTest, Magnitude)
{
gp_Vec2d aVec(3.0, 4.0);
EXPECT_NEAR(aVec.Magnitude(), 5.0, Precision::Confusion());
EXPECT_NEAR(aVec.SquareMagnitude(), 25.0, Precision::Confusion());
}
TEST(gp_Vec2dTest, Normalize)
{
gp_Vec2d aVec(3.0, 4.0);
gp_Vec2d aNormalized = aVec.Normalized();
EXPECT_NEAR(aNormalized.Magnitude(), 1.0, Precision::Confusion());
EXPECT_NEAR(aNormalized.X(), 0.6, Precision::Confusion());
EXPECT_NEAR(aNormalized.Y(), 0.8, Precision::Confusion());
}
TEST(gp_Vec2dTest, Angle)
{
gp_Vec2d aV1(1.0, 0.0);
gp_Vec2d aV2(0.0, 1.0);
EXPECT_NEAR(aV1.Angle(aV2), M_PI_2, Precision::Angular());
}
TEST(gp_Vec2dTest, IsParallel)
{
gp_Vec2d aV1(1.0, 0.0);
gp_Vec2d aV2(5.0, 0.0);
EXPECT_TRUE(aV1.IsParallel(aV2, Precision::Angular()));
}
TEST(gp_Vec2dTest, IsNormal)
{
gp_Vec2d aV1(1.0, 0.0);
gp_Vec2d aV2(0.0, 1.0);
EXPECT_TRUE(aV1.IsNormal(aV2, Precision::Angular()));
}
TEST(gp_Vec2dTest, IsOpposite)
{
gp_Vec2d aV1(1.0, 0.0);
gp_Vec2d aV2(-3.0, 0.0);
EXPECT_TRUE(aV1.IsOpposite(aV2, Precision::Angular()));
}
TEST(gp_Vec2dTest, Reverse)
{
gp_Vec2d aVec(1.0, 2.0);
gp_Vec2d aReversed = aVec.Reversed();
EXPECT_DOUBLE_EQ(aReversed.X(), -1.0);
EXPECT_DOUBLE_EQ(aReversed.Y(), -2.0);
}
TEST(gp_Vec2dTest, SetLinearForm)
{
gp_Vec2d aV1(1.0, 0.0);
gp_Vec2d aV2(0.0, 1.0);
gp_Vec2d aResult;
aResult.SetLinearForm(2.0, aV1, 3.0, aV2);
EXPECT_NEAR(aResult.X(), 2.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 3.0, Precision::Confusion());
}
@@ -0,0 +1,187 @@
// 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 <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <gp_XYZ.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(gp_VecTest, DefaultConstructor)
{
gp_Vec aVec;
EXPECT_DOUBLE_EQ(aVec.X(), 0.0);
EXPECT_DOUBLE_EQ(aVec.Y(), 0.0);
EXPECT_DOUBLE_EQ(aVec.Z(), 0.0);
}
TEST(gp_VecTest, CoordinateConstructor)
{
gp_Vec aVec(1.0, 2.0, 3.0);
EXPECT_DOUBLE_EQ(aVec.X(), 1.0);
EXPECT_DOUBLE_EQ(aVec.Y(), 2.0);
EXPECT_DOUBLE_EQ(aVec.Z(), 3.0);
}
TEST(gp_VecTest, TwoPointConstructor)
{
gp_Pnt aP1(1.0, 2.0, 3.0);
gp_Pnt aP2(4.0, 6.0, 8.0);
gp_Vec aVec(aP1, aP2);
EXPECT_DOUBLE_EQ(aVec.X(), 3.0);
EXPECT_DOUBLE_EQ(aVec.Y(), 4.0);
EXPECT_DOUBLE_EQ(aVec.Z(), 5.0);
}
TEST(gp_VecTest, DirConstructor)
{
gp_Dir aDir(0.0, 0.0, 1.0);
gp_Vec aVec(aDir);
EXPECT_NEAR(aVec.Magnitude(), 1.0, Precision::Confusion());
EXPECT_NEAR(aVec.Z(), 1.0, Precision::Confusion());
}
TEST(gp_VecTest, AddSubtract)
{
gp_Vec aV1(1.0, 2.0, 3.0);
gp_Vec aV2(4.0, 5.0, 6.0);
gp_Vec aSum = aV1 + aV2;
EXPECT_DOUBLE_EQ(aSum.X(), 5.0);
EXPECT_DOUBLE_EQ(aSum.Y(), 7.0);
EXPECT_DOUBLE_EQ(aSum.Z(), 9.0);
gp_Vec aDiff = aV2 - aV1;
EXPECT_DOUBLE_EQ(aDiff.X(), 3.0);
EXPECT_DOUBLE_EQ(aDiff.Y(), 3.0);
EXPECT_DOUBLE_EQ(aDiff.Z(), 3.0);
}
TEST(gp_VecTest, MultiplyDivide)
{
gp_Vec aVec(2.0, 4.0, 6.0);
gp_Vec aScaled = aVec * 3.0;
EXPECT_DOUBLE_EQ(aScaled.X(), 6.0);
EXPECT_DOUBLE_EQ(aScaled.Y(), 12.0);
EXPECT_DOUBLE_EQ(aScaled.Z(), 18.0);
gp_Vec aDivided = aVec / 2.0;
EXPECT_DOUBLE_EQ(aDivided.X(), 1.0);
EXPECT_DOUBLE_EQ(aDivided.Y(), 2.0);
EXPECT_DOUBLE_EQ(aDivided.Z(), 3.0);
}
TEST(gp_VecTest, Dot)
{
gp_Vec aV1(1.0, 0.0, 0.0);
gp_Vec aV2(0.0, 1.0, 0.0);
EXPECT_DOUBLE_EQ(aV1.Dot(aV2), 0.0);
gp_Vec aV3(1.0, 2.0, 3.0);
gp_Vec aV4(4.0, 5.0, 6.0);
// 1*4 + 2*5 + 3*6 = 32
EXPECT_DOUBLE_EQ(aV3.Dot(aV4), 32.0);
}
TEST(gp_VecTest, Cross)
{
gp_Vec aVx(1.0, 0.0, 0.0);
gp_Vec aVy(0.0, 1.0, 0.0);
gp_Vec aCross = aVx.Crossed(aVy);
EXPECT_NEAR(aCross.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aCross.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aCross.Z(), 1.0, Precision::Confusion());
}
TEST(gp_VecTest, CrossMagnitude)
{
gp_Vec aV1(1.0, 0.0, 0.0);
gp_Vec aV2(0.0, 1.0, 0.0);
EXPECT_NEAR(aV1.CrossMagnitude(aV2), 1.0, Precision::Confusion());
}
TEST(gp_VecTest, DotCross_TripleScalarProduct)
{
gp_Vec aV1(1.0, 0.0, 0.0);
gp_Vec aV2(0.0, 1.0, 0.0);
gp_Vec aV3(0.0, 0.0, 1.0);
// Triple scalar product of orthogonal unit vectors = 1
EXPECT_NEAR(aV1.DotCross(aV2, aV3), 1.0, Precision::Confusion());
}
TEST(gp_VecTest, Magnitude)
{
gp_Vec aVec(3.0, 4.0, 0.0);
EXPECT_NEAR(aVec.Magnitude(), 5.0, Precision::Confusion());
EXPECT_NEAR(aVec.SquareMagnitude(), 25.0, Precision::Confusion());
}
TEST(gp_VecTest, Normalize)
{
gp_Vec aVec(3.0, 4.0, 0.0);
gp_Vec aNormalized = aVec.Normalized();
EXPECT_NEAR(aNormalized.Magnitude(), 1.0, Precision::Confusion());
EXPECT_NEAR(aNormalized.X(), 0.6, Precision::Confusion());
EXPECT_NEAR(aNormalized.Y(), 0.8, Precision::Confusion());
}
TEST(gp_VecTest, Angle)
{
gp_Vec aV1(1.0, 0.0, 0.0);
gp_Vec aV2(0.0, 1.0, 0.0);
EXPECT_NEAR(aV1.Angle(aV2), M_PI_2, Precision::Angular());
}
TEST(gp_VecTest, IsParallel)
{
gp_Vec aV1(1.0, 0.0, 0.0);
gp_Vec aV2(5.0, 0.0, 0.0);
EXPECT_TRUE(aV1.IsParallel(aV2, Precision::Angular()));
}
TEST(gp_VecTest, IsNormal)
{
gp_Vec aV1(1.0, 0.0, 0.0);
gp_Vec aV2(0.0, 1.0, 0.0);
EXPECT_TRUE(aV1.IsNormal(aV2, Precision::Angular()));
}
TEST(gp_VecTest, IsOpposite)
{
gp_Vec aV1(1.0, 0.0, 0.0);
gp_Vec aV2(-3.0, 0.0, 0.0);
EXPECT_TRUE(aV1.IsOpposite(aV2, Precision::Angular()));
}
TEST(gp_VecTest, Reverse)
{
gp_Vec aVec(1.0, 2.0, 3.0);
gp_Vec aReversed = aVec.Reversed();
EXPECT_DOUBLE_EQ(aReversed.X(), -1.0);
EXPECT_DOUBLE_EQ(aReversed.Y(), -2.0);
EXPECT_DOUBLE_EQ(aReversed.Z(), -3.0);
}
TEST(gp_VecTest, SetLinearForm)
{
gp_Vec aV1(1.0, 0.0, 0.0);
gp_Vec aV2(0.0, 1.0, 0.0);
gp_Vec aResult;
aResult.SetLinearForm(2.0, aV1, 3.0, aV2);
EXPECT_NEAR(aResult.X(), 2.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 3.0, Precision::Confusion());
EXPECT_NEAR(aResult.Z(), 0.0, Precision::Confusion());
}
@@ -0,0 +1,160 @@
// 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 <gp_XYZ.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(gp_XYZTest, DefaultConstructor)
{
gp_XYZ aXYZ;
EXPECT_DOUBLE_EQ(aXYZ.X(), 0.0);
EXPECT_DOUBLE_EQ(aXYZ.Y(), 0.0);
EXPECT_DOUBLE_EQ(aXYZ.Z(), 0.0);
}
TEST(gp_XYZTest, CoordinateConstructor)
{
gp_XYZ aXYZ(1.0, 2.0, 3.0);
EXPECT_DOUBLE_EQ(aXYZ.X(), 1.0);
EXPECT_DOUBLE_EQ(aXYZ.Y(), 2.0);
EXPECT_DOUBLE_EQ(aXYZ.Z(), 3.0);
}
TEST(gp_XYZTest, SetCoord)
{
gp_XYZ aXYZ;
aXYZ.SetCoord(7.0, 8.0, 9.0);
EXPECT_DOUBLE_EQ(aXYZ.X(), 7.0);
EXPECT_DOUBLE_EQ(aXYZ.Y(), 8.0);
EXPECT_DOUBLE_EQ(aXYZ.Z(), 9.0);
}
TEST(gp_XYZTest, Accessors)
{
gp_XYZ aXYZ(1.0, 2.0, 3.0);
EXPECT_DOUBLE_EQ(aXYZ.Coord(1), 1.0);
EXPECT_DOUBLE_EQ(aXYZ.Coord(2), 2.0);
EXPECT_DOUBLE_EQ(aXYZ.Coord(3), 3.0);
}
TEST(gp_XYZTest, Add)
{
gp_XYZ aA(1.0, 2.0, 3.0);
gp_XYZ aB(4.0, 5.0, 6.0);
gp_XYZ aSum = aA + aB;
EXPECT_DOUBLE_EQ(aSum.X(), 5.0);
EXPECT_DOUBLE_EQ(aSum.Y(), 7.0);
EXPECT_DOUBLE_EQ(aSum.Z(), 9.0);
}
TEST(gp_XYZTest, Subtract)
{
gp_XYZ aA(4.0, 5.0, 6.0);
gp_XYZ aB(1.0, 2.0, 3.0);
gp_XYZ aDiff = aA - aB;
EXPECT_DOUBLE_EQ(aDiff.X(), 3.0);
EXPECT_DOUBLE_EQ(aDiff.Y(), 3.0);
EXPECT_DOUBLE_EQ(aDiff.Z(), 3.0);
}
TEST(gp_XYZTest, Multiply)
{
gp_XYZ aXYZ(1.0, 2.0, 3.0);
gp_XYZ aScaled = aXYZ * 2.0;
EXPECT_DOUBLE_EQ(aScaled.X(), 2.0);
EXPECT_DOUBLE_EQ(aScaled.Y(), 4.0);
EXPECT_DOUBLE_EQ(aScaled.Z(), 6.0);
}
TEST(gp_XYZTest, Divide)
{
gp_XYZ aXYZ(4.0, 6.0, 8.0);
gp_XYZ aDivided = aXYZ / 2.0;
EXPECT_DOUBLE_EQ(aDivided.X(), 2.0);
EXPECT_DOUBLE_EQ(aDivided.Y(), 3.0);
EXPECT_DOUBLE_EQ(aDivided.Z(), 4.0);
}
TEST(gp_XYZTest, Cross)
{
gp_XYZ aA(1.0, 0.0, 0.0);
gp_XYZ aB(0.0, 1.0, 0.0);
gp_XYZ aCross = aA.Crossed(aB);
EXPECT_NEAR(aCross.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aCross.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aCross.Z(), 1.0, Precision::Confusion());
}
TEST(gp_XYZTest, Dot)
{
gp_XYZ aA(1.0, 2.0, 3.0);
gp_XYZ aB(4.0, 5.0, 6.0);
// 1*4 + 2*5 + 3*6 = 32
EXPECT_DOUBLE_EQ(aA.Dot(aB), 32.0);
}
TEST(gp_XYZTest, CrossMagnitude)
{
gp_XYZ aA(1.0, 0.0, 0.0);
gp_XYZ aB(0.0, 1.0, 0.0);
EXPECT_NEAR(aA.CrossMagnitude(aB), 1.0, Precision::Confusion());
}
TEST(gp_XYZTest, CrossSquareMagnitude)
{
gp_XYZ aA(1.0, 0.0, 0.0);
gp_XYZ aB(0.0, 1.0, 0.0);
EXPECT_NEAR(aA.CrossSquareMagnitude(aB), 1.0, Precision::Confusion());
}
TEST(gp_XYZTest, DotCross)
{
gp_XYZ aA(1.0, 0.0, 0.0);
gp_XYZ aB(0.0, 1.0, 0.0);
gp_XYZ aC(0.0, 0.0, 1.0);
EXPECT_NEAR(aA.DotCross(aB, aC), 1.0, Precision::Confusion());
}
TEST(gp_XYZTest, Modulus)
{
gp_XYZ aXYZ(3.0, 4.0, 0.0);
EXPECT_NEAR(aXYZ.Modulus(), 5.0, Precision::Confusion());
}
TEST(gp_XYZTest, SquareModulus)
{
gp_XYZ aXYZ(3.0, 4.0, 0.0);
EXPECT_NEAR(aXYZ.SquareModulus(), 25.0, Precision::Confusion());
}
TEST(gp_XYZTest, SetLinearForm)
{
gp_XYZ aA(1.0, 0.0, 0.0);
gp_XYZ aB(0.0, 1.0, 0.0);
gp_XYZ aResult;
aResult.SetLinearForm(2.0, aA, 3.0, aB);
EXPECT_NEAR(aResult.X(), 2.0, Precision::Confusion());
EXPECT_NEAR(aResult.Y(), 3.0, Precision::Confusion());
EXPECT_NEAR(aResult.Z(), 0.0, Precision::Confusion());
}
TEST(gp_XYZTest, IsEqual)
{
gp_XYZ aA(1.0, 2.0, 3.0);
gp_XYZ aB(1.0, 2.0, 3.0);
gp_XYZ aC(1.0, 2.0, 4.0);
EXPECT_TRUE(aA.IsEqual(aB, Precision::Confusion()));
EXPECT_FALSE(aA.IsEqual(aC, Precision::Confusion()));
}
@@ -0,0 +1,94 @@
// 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 <BRepCheck_Analyzer.hxx>
#include <BRepFilletAPI_MakeChamfer.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <NCollection_IndexedDataMap.hxx>
#include <NCollection_List.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_ShapeMapHasher.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(BRepFilletAPI_MakeChamferTest, SymmetricChamfer)
{
BRepPrimAPI_MakeBox aBoxMaker(20.0, 20.0, 20.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_EDGE);
ASSERT_TRUE(anExp.More());
const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
BRepFilletAPI_MakeChamfer aChamfer(aBox);
aChamfer.Add(2.0, anEdge);
const TopoDS_Shape& aResult = aChamfer.Shape();
ASSERT_TRUE(aChamfer.IsDone());
BRepCheck_Analyzer anAnalyzer(aResult);
EXPECT_TRUE(anAnalyzer.IsValid());
}
TEST(BRepFilletAPI_MakeChamferTest, AsymmetricChamfer)
{
BRepPrimAPI_MakeBox aBoxMaker(20.0, 20.0, 20.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
NCollection_IndexedDataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>
anEdgeFaceMap;
TopExp::MapShapesAndAncestors(aBox, TopAbs_EDGE, TopAbs_FACE, anEdgeFaceMap);
TopExp_Explorer anExp(aBox, TopAbs_EDGE);
ASSERT_TRUE(anExp.More());
const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
const TopoDS_Face& aFace = TopoDS::Face(anEdgeFaceMap.FindFromKey(anEdge).First());
BRepFilletAPI_MakeChamfer aChamfer(aBox);
aChamfer.Add(1.0, 3.0, anEdge, aFace);
const TopoDS_Shape& aResult = aChamfer.Shape();
ASSERT_TRUE(aChamfer.IsDone());
BRepCheck_Analyzer anAnalyzer(aResult);
EXPECT_TRUE(anAnalyzer.IsValid());
}
TEST(BRepFilletAPI_MakeChamferTest, ChamferMoreFaces)
{
BRepPrimAPI_MakeBox aBoxMaker(20.0, 20.0, 20.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_EDGE);
ASSERT_TRUE(anExp.More());
const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
BRepFilletAPI_MakeChamfer aChamfer(aBox);
aChamfer.Add(2.0, anEdge);
const TopoDS_Shape& aResult = aChamfer.Shape();
ASSERT_TRUE(aChamfer.IsDone());
int aFaceCount = 0;
for (TopExp_Explorer aFaceExp(aResult, TopAbs_FACE); aFaceExp.More(); aFaceExp.Next())
{
aFaceCount++;
}
EXPECT_GT(aFaceCount, 6);
}
@@ -0,0 +1,101 @@
// 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 <BRepCheck_Analyzer.hxx>
#include <BRepFilletAPI_MakeFillet.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(BRepFilletAPI_MakeFilletTest, FilletOneEdge)
{
BRepPrimAPI_MakeBox aBoxMaker(20.0, 20.0, 20.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_EDGE);
ASSERT_TRUE(anExp.More());
const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
BRepFilletAPI_MakeFillet aFillet(aBox);
aFillet.Add(2.0, anEdge);
const TopoDS_Shape& aResult = aFillet.Shape();
ASSERT_TRUE(aFillet.IsDone());
BRepCheck_Analyzer anAnalyzer(aResult);
EXPECT_TRUE(anAnalyzer.IsValid());
}
TEST(BRepFilletAPI_MakeFilletTest, FilletAllEdges)
{
BRepPrimAPI_MakeBox aBoxMaker(20.0, 20.0, 20.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
BRepFilletAPI_MakeFillet aFillet(aBox);
for (TopExp_Explorer anExp(aBox, TopAbs_EDGE); anExp.More(); anExp.Next())
{
aFillet.Add(1.0, TopoDS::Edge(anExp.Current()));
}
const TopoDS_Shape& aResult = aFillet.Shape();
ASSERT_TRUE(aFillet.IsDone());
BRepCheck_Analyzer anAnalyzer(aResult);
EXPECT_TRUE(anAnalyzer.IsValid());
}
TEST(BRepFilletAPI_MakeFilletTest, FilletMoreFaces)
{
BRepPrimAPI_MakeBox aBoxMaker(20.0, 20.0, 20.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
BRepFilletAPI_MakeFillet aFillet(aBox);
for (TopExp_Explorer anExp(aBox, TopAbs_EDGE); anExp.More(); anExp.Next())
{
aFillet.Add(1.0, TopoDS::Edge(anExp.Current()));
}
const TopoDS_Shape& aResult = aFillet.Shape();
ASSERT_TRUE(aFillet.IsDone());
int aFaceCount = 0;
for (TopExp_Explorer aFaceExp(aResult, TopAbs_FACE); aFaceExp.More(); aFaceExp.Next())
{
aFaceCount++;
}
EXPECT_GT(aFaceCount, 6);
}
TEST(BRepFilletAPI_MakeFilletTest, FilletVariableRadius)
{
BRepPrimAPI_MakeBox aBoxMaker(20.0, 20.0, 20.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_EDGE);
ASSERT_TRUE(anExp.More());
const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
BRepFilletAPI_MakeFillet aFillet(aBox);
aFillet.Add(1.0, 3.0, anEdge);
const TopoDS_Shape& aResult = aFillet.Shape();
ASSERT_TRUE(aFillet.IsDone());
BRepCheck_Analyzer anAnalyzer(aResult);
EXPECT_TRUE(anAnalyzer.IsValid());
}
@@ -2,4 +2,6 @@
set(OCCT_TKFillet_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
set(OCCT_TKFillet_GTests_FILES
BRepFilletAPI_MakeChamfer_Test.cxx
BRepFilletAPI_MakeFillet_Test.cxx
)
@@ -0,0 +1,117 @@
// 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 <BRepBuilderAPI_Sewing.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <Precision.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(BRepBuilderAPI_SewingTest, SewTwoFaces)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_FACE);
ASSERT_TRUE(anExp.More());
TopoDS_Face aFace1 = TopoDS::Face(anExp.Current());
anExp.Next();
ASSERT_TRUE(anExp.More());
TopoDS_Face aFace2 = TopoDS::Face(anExp.Current());
BRepBuilderAPI_Sewing aSewing;
aSewing.Add(aFace1);
aSewing.Add(aFace2);
aSewing.Perform();
const TopoDS_Shape& aResult = aSewing.SewedShape();
EXPECT_FALSE(aResult.IsNull());
}
TEST(BRepBuilderAPI_SewingTest, NbFreeEdges)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_FACE);
ASSERT_TRUE(anExp.More());
TopoDS_Face aFace1 = TopoDS::Face(anExp.Current());
anExp.Next();
ASSERT_TRUE(anExp.More());
TopoDS_Face aFace2 = TopoDS::Face(anExp.Current());
BRepBuilderAPI_Sewing aSewing;
aSewing.Add(aFace1);
aSewing.Add(aFace2);
aSewing.Perform();
// Two faces from a box share one edge; the remaining edges are free.
EXPECT_GT(aSewing.NbFreeEdges(), 0);
}
TEST(BRepBuilderAPI_SewingTest, NbDegeneratedShapes)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_FACE);
ASSERT_TRUE(anExp.More());
TopoDS_Face aFace1 = TopoDS::Face(anExp.Current());
anExp.Next();
ASSERT_TRUE(anExp.More());
TopoDS_Face aFace2 = TopoDS::Face(anExp.Current());
BRepBuilderAPI_Sewing aSewing;
aSewing.Add(aFace1);
aSewing.Add(aFace2);
aSewing.Perform();
// Planar faces should have no degenerated shapes.
EXPECT_EQ(aSewing.NbDegeneratedShapes(), 0);
}
TEST(BRepBuilderAPI_SewingTest, SetTolerance)
{
BRepBuilderAPI_Sewing aSewing;
const double aTol = 0.01;
aSewing.SetTolerance(aTol);
EXPECT_NEAR(aSewing.Tolerance(), aTol, Precision::Confusion());
}
TEST(BRepBuilderAPI_SewingTest, SewAllBoxFaces)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
BRepBuilderAPI_Sewing aSewing;
for (TopExp_Explorer anExp(aBox, TopAbs_FACE); anExp.More(); anExp.Next())
{
aSewing.Add(anExp.Current());
}
aSewing.Perform();
const TopoDS_Shape& aResult = aSewing.SewedShape();
EXPECT_FALSE(aResult.IsNull());
// All 6 faces of a box form a closed shell, so there should be no free edges.
EXPECT_EQ(aSewing.NbFreeEdges(), 0);
}
@@ -0,0 +1,149 @@
// 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 <BRepCheck_Analyzer.hxx>
#include <BRepGProp.hxx>
#include <BRepOffsetAPI_MakeThickSolid.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <GProp_GProps.hxx>
#include <NCollection_List.hxx>
#include <Precision.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <cmath>
#include <gtest/gtest.h>
TEST(BRepOffsetAPI_MakeThickSolidTest, HollowBox)
{
BRepPrimAPI_MakeBox aBoxMaker(20.0, 20.0, 20.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
// Get the first face to remove.
TopExp_Explorer anExp(aBox, TopAbs_FACE);
ASSERT_TRUE(anExp.More());
TopoDS_Face aFaceToRemove = TopoDS::Face(anExp.Current());
NCollection_List<TopoDS_Shape> aFacesToRemove;
aFacesToRemove.Append(aFaceToRemove);
BRepOffsetAPI_MakeThickSolid aMaker;
aMaker.MakeThickSolidByJoin(aBox, aFacesToRemove, -1.0, Precision::Confusion());
aMaker.Build();
ASSERT_TRUE(aMaker.IsDone());
const TopoDS_Shape& aResult = aMaker.Shape();
EXPECT_FALSE(aResult.IsNull());
BRepCheck_Analyzer aChecker(aResult);
EXPECT_TRUE(aChecker.IsValid());
}
TEST(BRepOffsetAPI_MakeThickSolidTest, HollowBoxVolume)
{
BRepPrimAPI_MakeBox aBoxMaker(20.0, 20.0, 20.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
GProp_GProps aOrigProps;
BRepGProp::VolumeProperties(aBox, aOrigProps);
const double anOrigVolume = aOrigProps.Mass();
TopExp_Explorer anExp(aBox, TopAbs_FACE);
ASSERT_TRUE(anExp.More());
TopoDS_Face aFaceToRemove = TopoDS::Face(anExp.Current());
NCollection_List<TopoDS_Shape> aFacesToRemove;
aFacesToRemove.Append(aFaceToRemove);
BRepOffsetAPI_MakeThickSolid aMaker;
aMaker.MakeThickSolidByJoin(aBox, aFacesToRemove, -1.0, Precision::Confusion());
aMaker.Build();
ASSERT_TRUE(aMaker.IsDone());
const TopoDS_Shape& aResult = aMaker.Shape();
ASSERT_FALSE(aResult.IsNull());
GProp_GProps aHollowProps;
BRepGProp::VolumeProperties(aResult, aHollowProps);
const double aHollowVolume = aHollowProps.Mass();
// Hollowed box must have less volume than the original solid.
EXPECT_LT(aHollowVolume, anOrigVolume);
}
TEST(BRepOffsetAPI_MakeThickSolidTest, MakeThickSolidBySimple)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
// Extract a single face (non-closed shell) for MakeThickSolidBySimple.
TopExp_Explorer anExp(aBox, TopAbs_FACE);
ASSERT_TRUE(anExp.More());
TopoDS_Face aFace = TopoDS::Face(anExp.Current());
BRepOffsetAPI_MakeThickSolid aMaker;
aMaker.MakeThickSolidBySimple(aFace, 2.0);
aMaker.Build();
ASSERT_TRUE(aMaker.IsDone());
const TopoDS_Shape& aResult = aMaker.Shape();
EXPECT_FALSE(aResult.IsNull());
BRepCheck_Analyzer aChecker(aResult);
EXPECT_TRUE(aChecker.IsValid());
}
TEST(BRepOffsetAPI_MakeThickSolidTest, ThickSolidLargerVolume)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
// Extract a single face for MakeThickSolidBySimple.
TopExp_Explorer anExp(aBox, TopAbs_FACE);
ASSERT_TRUE(anExp.More());
TopoDS_Face aFace = TopoDS::Face(anExp.Current());
// Compute the area of the original face to estimate expected volume.
GProp_GProps aFaceProps;
BRepGProp::SurfaceProperties(aFace, aFaceProps);
const double aFaceArea = aFaceProps.Mass();
const double anOffset = 2.0;
BRepOffsetAPI_MakeThickSolid aMaker;
aMaker.MakeThickSolidBySimple(aFace, anOffset);
aMaker.Build();
ASSERT_TRUE(aMaker.IsDone());
const TopoDS_Shape& aResult = aMaker.Shape();
ASSERT_FALSE(aResult.IsNull());
GProp_GProps aResultProps;
BRepGProp::VolumeProperties(aResult, aResultProps);
const double aResultVolume = std::abs(aResultProps.Mass());
// The thickened face should produce a solid with volume > 0.
// A planar face of area A thickened by offset d produces volume approximately A*d.
EXPECT_GT(aResultVolume, aFaceArea * anOffset * 0.5);
}
@@ -2,5 +2,7 @@
set(OCCT_TKOffset_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
set(OCCT_TKOffset_GTests_FILES
BRepBuilderAPI_Sewing_Test.cxx
BRepOffset_MakeOffset_Test.cxx
BRepOffsetAPI_MakeThickSolid_Test.cxx
)
@@ -0,0 +1,124 @@
// 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 <BRepCheck_Analyzer.hxx>
#include <BRepGProp.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <gp_Pnt.hxx>
#include <GProp_GProps.hxx>
#include <Precision.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(BRepPrimAPI_MakeBoxTest, UnitBox)
{
BRepPrimAPI_MakeBox aBox(1.0, 1.0, 1.0);
TopoDS_Shape aShape = aBox.Shape();
ASSERT_TRUE(aBox.IsDone()) << "Unit box creation failed";
ASSERT_FALSE(aShape.IsNull()) << "Resulting shape is null";
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Unit box shape is not valid";
}
TEST(BRepPrimAPI_MakeBoxTest, TopologyCounts)
{
BRepPrimAPI_MakeBox aBox(10.0, 20.0, 30.0);
TopoDS_Shape aShape = aBox.Shape();
ASSERT_TRUE(aBox.IsDone());
int aFaceCount = 0;
for (TopExp_Explorer anExp(aShape, TopAbs_FACE); anExp.More(); anExp.Next())
{
aFaceCount++;
}
EXPECT_EQ(aFaceCount, 6) << "Box should have 6 faces";
int anEdgeCount = 0;
for (TopExp_Explorer anExp(aShape, TopAbs_EDGE); anExp.More(); anExp.Next())
{
anEdgeCount++;
}
EXPECT_EQ(anEdgeCount, 24) << "Box should have 24 edge occurrences (12 edges x 2 faces each)";
int aVertexCount = 0;
for (TopExp_Explorer anExp(aShape, TopAbs_VERTEX); anExp.More(); anExp.Next())
{
aVertexCount++;
}
EXPECT_EQ(aVertexCount, 48) << "Box should have 48 vertex occurrences (8 vertices x 6 faces)";
}
TEST(BRepPrimAPI_MakeBoxTest, Volume)
{
const double aWidth = 3.0;
const double aHeight = 4.0;
const double aDepth = 5.0;
BRepPrimAPI_MakeBox aBox(aWidth, aHeight, aDepth);
TopoDS_Shape aShape = aBox.Shape();
ASSERT_TRUE(aBox.IsDone());
GProp_GProps aProps;
BRepGProp::VolumeProperties(aShape, aProps);
EXPECT_NEAR(aProps.Mass(), aWidth * aHeight * aDepth, Precision::Confusion());
}
TEST(BRepPrimAPI_MakeBoxTest, SurfaceArea)
{
const double aW = 3.0;
const double aH = 4.0;
const double aD = 5.0;
BRepPrimAPI_MakeBox aBox(aW, aH, aD);
TopoDS_Shape aShape = aBox.Shape();
ASSERT_TRUE(aBox.IsDone());
GProp_GProps aProps;
BRepGProp::SurfaceProperties(aShape, aProps);
double anExpectedArea = 2.0 * (aW * aH + aW * aD + aH * aD);
EXPECT_NEAR(aProps.Mass(), anExpectedArea, Precision::Confusion());
}
TEST(BRepPrimAPI_MakeBoxTest, TwoCornerPoints)
{
gp_Pnt aP1(1.0, 2.0, 3.0);
gp_Pnt aP2(4.0, 6.0, 8.0);
BRepPrimAPI_MakeBox aBox(aP1, aP2);
TopoDS_Shape aShape = aBox.Shape();
ASSERT_TRUE(aBox.IsDone()) << "Box from two corner points failed";
ASSERT_FALSE(aShape.IsNull());
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Box from two points is not valid";
// Volume = (4-1)*(6-2)*(8-3) = 3*4*5 = 60
GProp_GProps aProps;
BRepGProp::VolumeProperties(aShape, aProps);
EXPECT_NEAR(aProps.Mass(), 60.0, Precision::Confusion());
}
TEST(BRepPrimAPI_MakeBoxTest, ShapeValidity)
{
BRepPrimAPI_MakeBox aBox(100.0, 200.0, 300.0);
TopoDS_Shape aShape = aBox.Shape();
ASSERT_TRUE(aBox.IsDone());
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Large box shape is not valid";
}
@@ -0,0 +1,113 @@
// 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 <BRepCheck_Analyzer.hxx>
#include <BRepGProp.hxx>
#include <BRepPrimAPI_MakeCone.hxx>
#include <gp_Ax2.hxx>
#include <GProp_GProps.hxx>
#include <Precision.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(BRepPrimAPI_MakeConeTest, FullCone)
{
BRepPrimAPI_MakeCone aCone(gp_Ax2(), 5.0, 0.0, 10.0);
TopoDS_Shape aShape = aCone.Shape();
ASSERT_TRUE(aCone.IsDone()) << "Full cone creation failed";
ASSERT_FALSE(aShape.IsNull()) << "Resulting shape is null";
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Full cone shape is not valid";
}
TEST(BRepPrimAPI_MakeConeTest, TruncatedCone)
{
BRepPrimAPI_MakeCone aCone(gp_Ax2(), 5.0, 2.0, 10.0);
TopoDS_Shape aShape = aCone.Shape();
ASSERT_TRUE(aCone.IsDone()) << "Truncated cone creation failed";
ASSERT_FALSE(aShape.IsNull()) << "Resulting shape is null";
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Truncated cone shape is not valid";
}
TEST(BRepPrimAPI_MakeConeTest, FullConeFaceCount)
{
BRepPrimAPI_MakeCone aCone(gp_Ax2(), 5.0, 0.0, 10.0);
TopoDS_Shape aShape = aCone.Shape();
ASSERT_TRUE(aCone.IsDone());
int aFaceCount = 0;
for (TopExp_Explorer anExp(aShape, TopAbs_FACE); anExp.More(); anExp.Next())
{
aFaceCount++;
}
EXPECT_EQ(aFaceCount, 2) << "Full cone should have 2 faces (lateral + base)";
}
TEST(BRepPrimAPI_MakeConeTest, TruncatedConeFaceCount)
{
BRepPrimAPI_MakeCone aCone(gp_Ax2(), 5.0, 2.0, 10.0);
TopoDS_Shape aShape = aCone.Shape();
ASSERT_TRUE(aCone.IsDone());
int aFaceCount = 0;
for (TopExp_Explorer anExp(aShape, TopAbs_FACE); anExp.More(); anExp.Next())
{
aFaceCount++;
}
EXPECT_EQ(aFaceCount, 3) << "Truncated cone should have 3 faces (lateral + 2 bases)";
}
TEST(BRepPrimAPI_MakeConeTest, TruncatedConeVolume)
{
const double aR1 = 5.0;
const double aR2 = 2.0;
const double aH = 10.0;
BRepPrimAPI_MakeCone aCone(gp_Ax2(), aR1, aR2, aH);
TopoDS_Shape aShape = aCone.Shape();
ASSERT_TRUE(aCone.IsDone());
GProp_GProps aProps;
BRepGProp::VolumeProperties(aShape, aProps);
// V = PI * H / 3 * (R1^2 + R1*R2 + R2^2)
const double anExpectedVolume = M_PI * aH / 3.0 * (aR1 * aR1 + aR1 * aR2 + aR2 * aR2);
EXPECT_NEAR(aProps.Mass(), anExpectedVolume, Precision::Confusion());
}
TEST(BRepPrimAPI_MakeConeTest, PartialCone)
{
BRepPrimAPI_MakeCone aCone(gp_Ax2(), 5.0, 2.0, 10.0, M_PI);
TopoDS_Shape aShape = aCone.Shape();
ASSERT_TRUE(aCone.IsDone()) << "Partial cone creation failed";
ASSERT_FALSE(aShape.IsNull()) << "Resulting shape is null";
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Partial cone shape is not valid";
int aFaceCount = 0;
for (TopExp_Explorer anExp(aShape, TopAbs_FACE); anExp.More(); anExp.Next())
{
aFaceCount++;
}
EXPECT_GT(aFaceCount, 3) << "Partial cone should have more than 3 faces";
}
@@ -0,0 +1,99 @@
// 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 <BRepCheck_Analyzer.hxx>
#include <BRepGProp.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <gp_Pnt.hxx>
#include <GProp_GProps.hxx>
#include <Precision.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(BRepPrimAPI_MakeCylinderTest, FullCylinder)
{
const double aRadius = 5.0;
const double aHeight = 10.0;
BRepPrimAPI_MakeCylinder aCylinder(aRadius, aHeight);
TopoDS_Shape aShape = aCylinder.Shape();
ASSERT_TRUE(aCylinder.IsDone()) << "Full cylinder creation failed";
ASSERT_FALSE(aShape.IsNull()) << "Resulting shape is null";
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Full cylinder shape is not valid";
}
TEST(BRepPrimAPI_MakeCylinderTest, FaceCount)
{
BRepPrimAPI_MakeCylinder aCylinder(5.0, 10.0);
TopoDS_Shape aShape = aCylinder.Shape();
ASSERT_TRUE(aCylinder.IsDone());
int aFaceCount = 0;
for (TopExp_Explorer anExp(aShape, TopAbs_FACE); anExp.More(); anExp.Next())
{
aFaceCount++;
}
// Full cylinder: 1 lateral + 2 caps = 3
EXPECT_EQ(aFaceCount, 3) << "Full cylinder should have 3 faces (lateral + 2 caps)";
}
TEST(BRepPrimAPI_MakeCylinderTest, Volume)
{
const double aRadius = 5.0;
const double aHeight = 10.0;
BRepPrimAPI_MakeCylinder aCylinder(aRadius, aHeight);
TopoDS_Shape aShape = aCylinder.Shape();
ASSERT_TRUE(aCylinder.IsDone());
GProp_GProps aProps;
BRepGProp::VolumeProperties(aShape, aProps);
double anExpectedVolume = M_PI * aRadius * aRadius * aHeight;
EXPECT_NEAR(aProps.Mass(), anExpectedVolume, 0.01);
}
TEST(BRepPrimAPI_MakeCylinderTest, PartialCylinder_AngleLimited)
{
const double aRadius = 5.0;
const double aHeight = 10.0;
// Half cylinder: angle = PI
BRepPrimAPI_MakeCylinder aCylinder(aRadius, aHeight, M_PI);
TopoDS_Shape aShape = aCylinder.Shape();
ASSERT_TRUE(aCylinder.IsDone()) << "Partial cylinder creation failed";
ASSERT_FALSE(aShape.IsNull());
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Partial cylinder shape is not valid";
// Partial cylinder should have more faces: 1 lateral + 2 caps + 2 planar sides = 5
int aFaceCount = 0;
for (TopExp_Explorer anExp(aShape, TopAbs_FACE); anExp.More(); anExp.Next())
{
aFaceCount++;
}
EXPECT_EQ(aFaceCount, 5) << "Half cylinder should have 5 faces";
}
TEST(BRepPrimAPI_MakeCylinderTest, ShapeValidity)
{
BRepPrimAPI_MakeCylinder aCylinder(100.0, 200.0);
TopoDS_Shape aShape = aCylinder.Shape();
ASSERT_TRUE(aCylinder.IsDone());
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Large cylinder shape is not valid";
}
@@ -0,0 +1,102 @@
// 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 <BRepCheck_Analyzer.hxx>
#include <BRepGProp.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <gp_Pnt.hxx>
#include <GProp_GProps.hxx>
#include <Precision.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(BRepPrimAPI_MakeSphereTest, FullSphere)
{
const double aRadius = 5.0;
BRepPrimAPI_MakeSphere aSphere(aRadius);
TopoDS_Shape aShape = aSphere.Shape();
ASSERT_TRUE(aSphere.IsDone()) << "Full sphere creation failed";
ASSERT_FALSE(aShape.IsNull()) << "Resulting shape is null";
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Full sphere shape is not valid";
}
TEST(BRepPrimAPI_MakeSphereTest, FaceCount)
{
BRepPrimAPI_MakeSphere aSphere(5.0);
TopoDS_Shape aShape = aSphere.Shape();
ASSERT_TRUE(aSphere.IsDone());
int aFaceCount = 0;
for (TopExp_Explorer anExp(aShape, TopAbs_FACE); anExp.More(); anExp.Next())
{
aFaceCount++;
}
EXPECT_EQ(aFaceCount, 1) << "Full sphere should have 1 face";
}
TEST(BRepPrimAPI_MakeSphereTest, Volume)
{
const double aRadius = 5.0;
BRepPrimAPI_MakeSphere aSphere(aRadius);
TopoDS_Shape aShape = aSphere.Shape();
ASSERT_TRUE(aSphere.IsDone());
GProp_GProps aProps;
BRepGProp::VolumeProperties(aShape, aProps);
double anExpectedVolume = (4.0 / 3.0) * M_PI * aRadius * aRadius * aRadius;
EXPECT_NEAR(aProps.Mass(), anExpectedVolume, 0.01);
}
TEST(BRepPrimAPI_MakeSphereTest, PartialSphere_AngleLimited)
{
const double aRadius = 5.0;
// Half sphere: angle from 0 to PI
BRepPrimAPI_MakeSphere aSphere(aRadius, M_PI);
TopoDS_Shape aShape = aSphere.Shape();
ASSERT_TRUE(aSphere.IsDone()) << "Partial sphere creation failed";
ASSERT_FALSE(aShape.IsNull());
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Partial sphere shape is not valid";
// Partial sphere should have more faces than a full sphere
int aFaceCount = 0;
for (TopExp_Explorer anExp(aShape, TopAbs_FACE); anExp.More(); anExp.Next())
{
aFaceCount++;
}
EXPECT_GT(aFaceCount, 1) << "Partial sphere should have more than 1 face";
}
TEST(BRepPrimAPI_MakeSphereTest, CenterOfMass)
{
const double aRadius = 5.0;
BRepPrimAPI_MakeSphere aSphere(aRadius);
TopoDS_Shape aShape = aSphere.Shape();
ASSERT_TRUE(aSphere.IsDone());
GProp_GProps aProps;
BRepGProp::VolumeProperties(aShape, aProps);
gp_Pnt aCOM = aProps.CentreOfMass();
// Center of mass of full sphere should be at origin
EXPECT_NEAR(aCOM.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aCOM.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aCOM.Z(), 0.0, Precision::Confusion());
}
@@ -0,0 +1,94 @@
// 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 <BRepCheck_Analyzer.hxx>
#include <BRepGProp.hxx>
#include <BRepPrimAPI_MakeWedge.hxx>
#include <GProp_GProps.hxx>
#include <Precision.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(BRepPrimAPI_MakeWedgeTest, WedgeFromDimensions)
{
BRepPrimAPI_MakeWedge aWedge(10.0, 10.0, 10.0, 5.0);
TopoDS_Shape aShape = aWedge.Shape();
ASSERT_TRUE(aWedge.IsDone()) << "Wedge creation failed";
ASSERT_FALSE(aShape.IsNull()) << "Resulting shape is null";
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Wedge shape is not valid";
}
TEST(BRepPrimAPI_MakeWedgeTest, WedgeFaceCount_Ltx5)
{
BRepPrimAPI_MakeWedge aWedge(10.0, 10.0, 10.0, 5.0);
TopoDS_Shape aShape = aWedge.Shape();
ASSERT_TRUE(aWedge.IsDone());
int aFaceCount = 0;
for (TopExp_Explorer anExp(aShape, TopAbs_FACE); anExp.More(); anExp.Next())
{
aFaceCount++;
}
EXPECT_EQ(aFaceCount, 6) << "Wedge with ltx=5 should have 6 faces";
}
TEST(BRepPrimAPI_MakeWedgeTest, WedgeFaceCount_Ltx0)
{
BRepPrimAPI_MakeWedge aWedge(10.0, 10.0, 10.0, 0.0);
TopoDS_Shape aShape = aWedge.Shape();
ASSERT_TRUE(aWedge.IsDone());
int aFaceCount = 0;
for (TopExp_Explorer anExp(aShape, TopAbs_FACE); anExp.More(); anExp.Next())
{
aFaceCount++;
}
EXPECT_EQ(aFaceCount, 5) << "Wedge with ltx=0 should have 5 faces (top degenerates to a line)";
}
TEST(BRepPrimAPI_MakeWedgeTest, WedgeVolume)
{
const double aDx = 10.0;
const double aDy = 10.0;
const double aDz = 10.0;
const double aLtx = 5.0;
BRepPrimAPI_MakeWedge aWedge(aDx, aDy, aDz, aLtx);
TopoDS_Shape aShape = aWedge.Shape();
ASSERT_TRUE(aWedge.IsDone());
GProp_GProps aProps;
BRepGProp::VolumeProperties(aShape, aProps);
// Volume = dy * dz * (dx + ltx) / 2
const double anExpectedVolume = aDy * aDz * (aDx + aLtx) / 2.0;
EXPECT_NEAR(aProps.Mass(), anExpectedVolume, Precision::Confusion());
}
TEST(BRepPrimAPI_MakeWedgeTest, WedgeFullParams)
{
BRepPrimAPI_MakeWedge aWedge(20.0, 10.0, 20.0, 5.0, 5.0, 15.0, 15.0);
TopoDS_Shape aShape = aWedge.Shape();
ASSERT_TRUE(aWedge.IsDone()) << "Wedge with full parameters creation failed";
ASSERT_FALSE(aShape.IsNull()) << "Resulting shape is null";
BRepCheck_Analyzer anAnalyzer(aShape);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Wedge with full parameters shape is not valid";
}
@@ -2,6 +2,11 @@
set(OCCT_TKPrim_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
set(OCCT_TKPrim_GTests_FILES
BRepPrimAPI_MakeBox_Test.cxx
BRepPrimAPI_MakeCone_Test.cxx
BRepPrimAPI_MakeCylinder_Test.cxx
BRepPrimAPI_MakePrism_Test.cxx
BRepPrimAPI_MakeSphere_Test.cxx
BRepPrimAPI_MakeTorus_Test.cxx
BRepPrimAPI_MakeWedge_Test.cxx
)
@@ -3,6 +3,8 @@ set(OCCT_TKShHealing_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
set(OCCT_TKShHealing_GTests_FILES
ShapeAnalysis_CanonicalRecognition_Test.cxx
ShapeAnalysis_Edge_Test.cxx
ShapeConstruct_ProjectCurveOnSurface_Test.cxx
ShapeFix_Shape_Test.cxx
ShapeUpgrade_UnifySameDomain_Test.cxx
)
@@ -0,0 +1,91 @@
// 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 <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <Geom_Circle.hxx>
#include <gp_Ax2.hxx>
#include <gp_Pnt.hxx>
#include <ShapeAnalysis_Edge.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <gtest/gtest.h>
TEST(ShapeAnalysis_EdgeTest, HasCurve3d)
{
BRepBuilderAPI_MakeEdge aMakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(10.0, 0.0, 0.0));
ASSERT_TRUE(aMakeEdge.IsDone());
const TopoDS_Edge& anEdge = aMakeEdge.Edge();
ShapeAnalysis_Edge anAnalyzer;
EXPECT_TRUE(anAnalyzer.HasCurve3d(anEdge));
}
TEST(ShapeAnalysis_EdgeTest, FirstVertex_LastVertex)
{
BRepBuilderAPI_MakeEdge aMakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(10.0, 0.0, 0.0));
ASSERT_TRUE(aMakeEdge.IsDone());
const TopoDS_Edge& anEdge = aMakeEdge.Edge();
ShapeAnalysis_Edge anAnalyzer;
const TopoDS_Vertex aFirstVertex = anAnalyzer.FirstVertex(anEdge);
const TopoDS_Vertex aLastVertex = anAnalyzer.LastVertex(anEdge);
EXPECT_FALSE(aFirstVertex.IsNull());
EXPECT_FALSE(aLastVertex.IsNull());
}
TEST(ShapeAnalysis_EdgeTest, IsClosed_OpenEdge)
{
BRepBuilderAPI_MakeEdge aMakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(10.0, 0.0, 0.0));
ASSERT_TRUE(aMakeEdge.IsDone());
const TopoDS_Edge& anEdge = aMakeEdge.Edge();
ShapeAnalysis_Edge anAnalyzer;
EXPECT_FALSE(anAnalyzer.IsClosed3d(anEdge));
}
TEST(ShapeAnalysis_EdgeTest, IsClosed_ClosedEdge)
{
occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp_Ax2(gp_Pnt(0.0, 0.0, 0.0), gp::DZ()), 5.0);
BRepBuilderAPI_MakeEdge aMakeEdge(aCircle);
ASSERT_TRUE(aMakeEdge.IsDone());
const TopoDS_Edge& anEdge = aMakeEdge.Edge();
ShapeAnalysis_Edge anAnalyzer;
EXPECT_TRUE(anAnalyzer.IsClosed3d(anEdge));
}
TEST(ShapeAnalysis_EdgeTest, IsSeam_NonSeam)
{
BRepPrimAPI_MakeBox aMakeBox(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone());
TopExp_Explorer aFaceExp(aBox, TopAbs_FACE);
ASSERT_TRUE(aFaceExp.More());
const TopoDS_Face& aFace = TopoDS::Face(aFaceExp.Current());
TopExp_Explorer anEdgeExp(aFace, TopAbs_EDGE);
ASSERT_TRUE(anEdgeExp.More());
const TopoDS_Edge& anEdge = TopoDS::Edge(anEdgeExp.Current());
ShapeAnalysis_Edge anAnalyzer;
EXPECT_FALSE(anAnalyzer.IsSeam(anEdge, aFace));
}
@@ -0,0 +1,94 @@
// 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 <BRep_Builder.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <gp_Pnt.hxx>
#include <Precision.hxx>
#include <ShapeExtend_Status.hxx>
#include <ShapeFix_Shape.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(ShapeFix_ShapeTest, FixValidBox)
{
BRepPrimAPI_MakeBox aMakeBox(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone());
occ::handle<ShapeFix_Shape> aFixer = new ShapeFix_Shape(aBox);
aFixer->Perform();
const TopoDS_Shape aResult = aFixer->Shape();
ASSERT_FALSE(aResult.IsNull());
BRepCheck_Analyzer anAnalyzer(aResult);
EXPECT_TRUE(anAnalyzer.IsValid());
}
TEST(ShapeFix_ShapeTest, StatusAfterFix)
{
BRepPrimAPI_MakeBox aMakeBox(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone());
occ::handle<ShapeFix_Shape> aFixer = new ShapeFix_Shape(aBox);
aFixer->Perform();
// A valid box should not require any failure-level fixes
EXPECT_FALSE(aFixer->Status(ShapeExtend_FAIL));
}
TEST(ShapeFix_ShapeTest, SetPrecision)
{
occ::handle<ShapeFix_Shape> aFixer = new ShapeFix_Shape();
const double aPrecision = 0.01;
const double aMinTolerance = 0.001;
const double aMaxTolerance = 0.1;
aFixer->SetPrecision(aPrecision);
aFixer->SetMinTolerance(aMinTolerance);
aFixer->SetMaxTolerance(aMaxTolerance);
EXPECT_NEAR(aFixer->Precision(), aPrecision, Precision::Confusion());
EXPECT_NEAR(aFixer->MinTolerance(), aMinTolerance, Precision::Confusion());
EXPECT_NEAR(aFixer->MaxTolerance(), aMaxTolerance, Precision::Confusion());
}
TEST(ShapeFix_ShapeTest, FixCompound)
{
BRepPrimAPI_MakeBox aMakeBox1(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox1 = aMakeBox1.Shape();
ASSERT_TRUE(aMakeBox1.IsDone());
BRepPrimAPI_MakeBox aMakeBox2(gp_Pnt(20.0, 0.0, 0.0), 5.0, 5.0, 5.0);
const TopoDS_Shape& aBox2 = aMakeBox2.Shape();
ASSERT_TRUE(aMakeBox2.IsDone());
BRep_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
aBuilder.Add(aCompound, aBox1);
aBuilder.Add(aCompound, aBox2);
occ::handle<ShapeFix_Shape> aFixer = new ShapeFix_Shape(aCompound);
aFixer->Perform();
const TopoDS_Shape aResult = aFixer->Shape();
ASSERT_FALSE(aResult.IsNull());
BRepCheck_Analyzer anAnalyzer(aResult);
EXPECT_TRUE(anAnalyzer.IsValid());
}
@@ -0,0 +1,106 @@
// 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 <BRepBuilderAPI_Copy.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRepGProp.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <gp_Pnt.hxx>
#include <GProp_GProps.hxx>
#include <Precision.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(BRepBuilderAPI_CopyTest, CopyIsValid)
{
BRepPrimAPI_MakeBox aMakeBox(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
BRepBuilderAPI_Copy aCopier(aBox);
const TopoDS_Shape& aCopy = aCopier.Shape();
ASSERT_FALSE(aCopy.IsNull()) << "Copied shape is null";
BRepCheck_Analyzer anAnalyzer(aCopy);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Copied shape should be valid";
}
TEST(BRepBuilderAPI_CopyTest, CopyVolume)
{
BRepPrimAPI_MakeBox aMakeBox(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
GProp_GProps aOriginalProps;
BRepGProp::VolumeProperties(aBox, aOriginalProps);
double anOriginalVolume = aOriginalProps.Mass();
BRepBuilderAPI_Copy aCopier(aBox);
const TopoDS_Shape& aCopy = aCopier.Shape();
ASSERT_FALSE(aCopy.IsNull()) << "Copied shape is null";
GProp_GProps aCopyProps;
BRepGProp::VolumeProperties(aCopy, aCopyProps);
double aCopyVolume = aCopyProps.Mass();
EXPECT_NEAR(aCopyVolume, anOriginalVolume, Precision::Confusion())
<< "Copy volume should match original";
}
TEST(BRepBuilderAPI_CopyTest, CopyIsDistinct)
{
BRepPrimAPI_MakeBox aMakeBox(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
BRepBuilderAPI_Copy aCopier(aBox);
const TopoDS_Shape& aCopy = aCopier.Shape();
ASSERT_FALSE(aCopy.IsNull()) << "Copied shape is null";
EXPECT_FALSE(aCopy.IsEqual(aBox)) << "Copy should not be equal to original (different TShape)";
}
TEST(BRepBuilderAPI_CopyTest, CopyGeomTrue)
{
BRepPrimAPI_MakeBox aMakeBox(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
BRepBuilderAPI_Copy aCopier(aBox, true);
const TopoDS_Shape& aCopy = aCopier.Shape();
ASSERT_FALSE(aCopy.IsNull()) << "Copied shape is null";
GProp_GProps aOriginalProps;
BRepGProp::VolumeProperties(aBox, aOriginalProps);
GProp_GProps aCopyProps;
BRepGProp::VolumeProperties(aCopy, aCopyProps);
EXPECT_NEAR(aCopyProps.Mass(), aOriginalProps.Mass(), Precision::Confusion())
<< "Deep copy volume should match original";
}
TEST(BRepBuilderAPI_CopyTest, CopyGeomFalse)
{
BRepPrimAPI_MakeBox aMakeBox(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
BRepBuilderAPI_Copy aCopier(aBox, false);
const TopoDS_Shape& aCopy = aCopier.Shape();
ASSERT_FALSE(aCopy.IsNull()) << "Copied shape is null";
BRepCheck_Analyzer anAnalyzer(aCopy);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Shallow copy should produce a valid shape";
}
@@ -0,0 +1,132 @@
// 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 <BRep_Tool.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepGProp.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Line.hxx>
#include <gp_Ax2.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <GProp_GProps.hxx>
#include <Precision.hxx>
#include <TopExp.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <gtest/gtest.h>
TEST(BRepBuilderAPI_MakeEdgeTest, LinearEdge_TwoPoints)
{
gp_Pnt aP1(0.0, 0.0, 0.0);
gp_Pnt aP2(10.0, 0.0, 0.0);
BRepBuilderAPI_MakeEdge aMakeEdge(aP1, aP2);
ASSERT_TRUE(aMakeEdge.IsDone()) << "Linear edge creation failed";
TopoDS_Edge anEdge = aMakeEdge.Edge();
ASSERT_FALSE(anEdge.IsNull()) << "Resulting edge is null";
// Verify edge length
GProp_GProps aProps;
BRepGProp::LinearProperties(anEdge, aProps);
EXPECT_NEAR(aProps.Mass(), 10.0, Precision::Confusion()) << "Edge length should be 10";
}
TEST(BRepBuilderAPI_MakeEdgeTest, CircularEdge_Full)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Circle> aCircle = new Geom_Circle(anAxis, 5.0);
BRepBuilderAPI_MakeEdge aMakeEdge(aCircle);
ASSERT_TRUE(aMakeEdge.IsDone()) << "Full circular edge creation failed";
TopoDS_Edge anEdge = aMakeEdge.Edge();
ASSERT_FALSE(anEdge.IsNull());
// Full circle length = 2*PI*R
GProp_GProps aProps;
BRepGProp::LinearProperties(anEdge, aProps);
EXPECT_NEAR(aProps.Mass(), 2.0 * M_PI * 5.0, Precision::Confusion());
}
TEST(BRepBuilderAPI_MakeEdgeTest, CircularEdge_Trimmed)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Circle> aCircle = new Geom_Circle(anAxis, 5.0);
// Half circle: 0 to PI
BRepBuilderAPI_MakeEdge aMakeEdge(aCircle, 0.0, M_PI);
ASSERT_TRUE(aMakeEdge.IsDone()) << "Trimmed circular edge creation failed";
TopoDS_Edge anEdge = aMakeEdge.Edge();
ASSERT_FALSE(anEdge.IsNull());
// Half circle length = PI*R
GProp_GProps aProps;
BRepGProp::LinearProperties(anEdge, aProps);
EXPECT_NEAR(aProps.Mass(), M_PI * 5.0, Precision::Confusion());
}
TEST(BRepBuilderAPI_MakeEdgeTest, EdgeFromLine_WithBounds)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
BRepBuilderAPI_MakeEdge aMakeEdge(aLine, 0.0, 7.0);
ASSERT_TRUE(aMakeEdge.IsDone()) << "Edge from line with bounds failed";
TopoDS_Edge anEdge = aMakeEdge.Edge();
ASSERT_FALSE(anEdge.IsNull());
GProp_GProps aProps;
BRepGProp::LinearProperties(anEdge, aProps);
EXPECT_NEAR(aProps.Mass(), 7.0, Precision::Confusion());
}
TEST(BRepBuilderAPI_MakeEdgeTest, VertexExtraction)
{
gp_Pnt aP1(0.0, 0.0, 0.0);
gp_Pnt aP2(10.0, 0.0, 0.0);
BRepBuilderAPI_MakeEdge aMakeEdge(aP1, aP2);
ASSERT_TRUE(aMakeEdge.IsDone());
TopoDS_Edge anEdge = aMakeEdge.Edge();
TopoDS_Vertex aV1, aV2;
TopExp::Vertices(anEdge, aV1, aV2);
ASSERT_FALSE(aV1.IsNull()) << "First vertex is null";
ASSERT_FALSE(aV2.IsNull()) << "Last vertex is null";
gp_Pnt aFirstPnt = BRep_Tool::Pnt(aV1);
gp_Pnt aLastPnt = BRep_Tool::Pnt(aV2);
EXPECT_TRUE(aFirstPnt.IsEqual(aP1, Precision::Confusion()));
EXPECT_TRUE(aLastPnt.IsEqual(aP2, Precision::Confusion()));
}
TEST(BRepBuilderAPI_MakeEdgeTest, ToleranceCheck)
{
gp_Pnt aP1(0.0, 0.0, 0.0);
gp_Pnt aP2(10.0, 0.0, 0.0);
BRepBuilderAPI_MakeEdge aMakeEdge(aP1, aP2);
ASSERT_TRUE(aMakeEdge.IsDone());
TopoDS_Edge anEdge = aMakeEdge.Edge();
double aTol = BRep_Tool::Tolerance(anEdge);
EXPECT_GT(aTol, 0.0) << "Edge tolerance should be positive";
EXPECT_LE(aTol, Precision::Confusion()) << "Edge tolerance should not exceed confusion";
}
@@ -0,0 +1,116 @@
// 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 <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRepGProp.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_Plane.hxx>
#include <gp_Ax2.hxx>
#include <gp_Ax3.hxx>
#include <gp_Dir.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <GProp_GProps.hxx>
#include <Precision.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Wire.hxx>
#include <gtest/gtest.h>
TEST(BRepBuilderAPI_MakeFaceTest, FaceFromPlane)
{
gp_Pln aPln(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
BRepBuilderAPI_MakeFace aMakeFace(aPln);
ASSERT_TRUE(aMakeFace.IsDone()) << "Face from plane creation failed";
TopoDS_Face aFace = aMakeFace.Face();
ASSERT_FALSE(aFace.IsNull()) << "Resulting face is null";
}
TEST(BRepBuilderAPI_MakeFaceTest, FaceFromWire)
{
// Create a rectangular wire in XY plane
gp_Pnt aP1(0.0, 0.0, 0.0);
gp_Pnt aP2(10.0, 0.0, 0.0);
gp_Pnt aP3(10.0, 5.0, 0.0);
gp_Pnt aP4(0.0, 5.0, 0.0);
TopoDS_Edge anE1 = BRepBuilderAPI_MakeEdge(aP1, aP2).Edge();
TopoDS_Edge anE2 = BRepBuilderAPI_MakeEdge(aP2, aP3).Edge();
TopoDS_Edge anE3 = BRepBuilderAPI_MakeEdge(aP3, aP4).Edge();
TopoDS_Edge anE4 = BRepBuilderAPI_MakeEdge(aP4, aP1).Edge();
BRepBuilderAPI_MakeWire aMakeWire;
aMakeWire.Add(anE1);
aMakeWire.Add(anE2);
aMakeWire.Add(anE3);
aMakeWire.Add(anE4);
ASSERT_TRUE(aMakeWire.IsDone()) << "Wire creation failed";
BRepBuilderAPI_MakeFace aMakeFace(aMakeWire.Wire());
ASSERT_TRUE(aMakeFace.IsDone()) << "Face from wire creation failed";
TopoDS_Face aFace = aMakeFace.Face();
ASSERT_FALSE(aFace.IsNull());
BRepCheck_Analyzer anAnalyzer(aFace);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Face from wire is not valid";
// Area should be 10 * 5 = 50
GProp_GProps aProps;
BRepGProp::SurfaceProperties(aFace, aProps);
EXPECT_NEAR(aProps.Mass(), 50.0, Precision::Confusion());
}
TEST(BRepBuilderAPI_MakeFaceTest, FaceFromGeomPlane_WithBounds)
{
occ::handle<Geom_Plane> aGeomPlane = new Geom_Plane(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
BRepBuilderAPI_MakeFace aMakeFace(aGeomPlane, 0.0, 10.0, 0.0, 5.0, Precision::Confusion());
ASSERT_TRUE(aMakeFace.IsDone()) << "Face from Geom_Plane with bounds failed";
TopoDS_Face aFace = aMakeFace.Face();
ASSERT_FALSE(aFace.IsNull());
BRepCheck_Analyzer anAnalyzer(aFace);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Bounded face is not valid";
GProp_GProps aProps;
BRepGProp::SurfaceProperties(aFace, aProps);
EXPECT_NEAR(aProps.Mass(), 50.0, Precision::Confusion());
}
TEST(BRepBuilderAPI_MakeFaceTest, FaceFromCylindricalSurface)
{
gp_Ax3 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_CylindricalSurface> aCylSurf = new Geom_CylindricalSurface(anAxis, 5.0);
// Create a bounded face: U from 0 to 2*PI, V from 0 to 10
BRepBuilderAPI_MakeFace aMakeFace(aCylSurf, 0.0, 2.0 * M_PI, 0.0, 10.0, Precision::Confusion());
ASSERT_TRUE(aMakeFace.IsDone()) << "Face from cylindrical surface failed";
TopoDS_Face aFace = aMakeFace.Face();
ASSERT_FALSE(aFace.IsNull());
BRepCheck_Analyzer anAnalyzer(aFace);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Cylindrical face is not valid";
// Area of cylinder: 2*PI*R*H = 2*PI*5*10 = 100*PI
GProp_GProps aProps;
BRepGProp::SurfaceProperties(aFace, aProps);
EXPECT_NEAR(aProps.Mass(), 2.0 * M_PI * 5.0 * 10.0, 0.01);
}
@@ -0,0 +1,135 @@
// 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 <BRepBuilderAPI_Transform.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRepGProp.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <GProp_GProps.hxx>
#include <Precision.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(BRepBuilderAPI_TransformTest, Translate)
{
BRepPrimAPI_MakeBox aMakeBox(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
gp_Trsf aTrsf;
aTrsf.SetTranslation(gp_Vec(100.0, 0.0, 0.0));
BRepBuilderAPI_Transform aTransform(aBox, aTrsf);
const TopoDS_Shape& aResult = aTransform.Shape();
ASSERT_FALSE(aResult.IsNull()) << "Transformed shape is null";
GProp_GProps aProps;
BRepGProp::VolumeProperties(aResult, aProps);
gp_Pnt aCenterOfMass = aProps.CentreOfMass();
EXPECT_NEAR(aCenterOfMass.X(), 105.0, Precision::Confusion())
<< "Center of mass X should be shifted by 100";
EXPECT_NEAR(aCenterOfMass.Y(), 5.0, Precision::Confusion());
EXPECT_NEAR(aCenterOfMass.Z(), 5.0, Precision::Confusion());
}
TEST(BRepBuilderAPI_TransformTest, Rotate)
{
BRepPrimAPI_MakeBox aMakeBox(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
gp_Trsf aTrsf;
gp_Ax1 aZAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
aTrsf.SetRotation(aZAxis, M_PI / 2.0);
BRepBuilderAPI_Transform aTransform(aBox, aTrsf);
const TopoDS_Shape& aResult = aTransform.Shape();
ASSERT_FALSE(aResult.IsNull()) << "Transformed shape is null";
GProp_GProps aProps;
BRepGProp::VolumeProperties(aResult, aProps);
gp_Pnt aCenterOfMass = aProps.CentreOfMass();
EXPECT_NEAR(aCenterOfMass.X(), -5.0, Precision::Confusion())
<< "Center of mass X should be ~-5 after 90deg rotation";
EXPECT_NEAR(aCenterOfMass.Y(), 5.0, Precision::Confusion())
<< "Center of mass Y should be ~5 after 90deg rotation";
}
TEST(BRepBuilderAPI_TransformTest, Scale)
{
BRepPrimAPI_MakeBox aMakeBox(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
gp_Trsf aTrsf;
aTrsf.SetScale(gp_Pnt(0.0, 0.0, 0.0), 2.0);
BRepBuilderAPI_Transform aTransform(aBox, aTrsf);
const TopoDS_Shape& aResult = aTransform.Shape();
ASSERT_FALSE(aResult.IsNull()) << "Transformed shape is null";
GProp_GProps aProps;
BRepGProp::VolumeProperties(aResult, aProps);
double aVolume = aProps.Mass();
EXPECT_NEAR(aVolume, 8000.0, Precision::Confusion())
<< "Volume should be 8x original (2^3 * 1000)";
}
TEST(BRepBuilderAPI_TransformTest, Mirror)
{
BRepPrimAPI_MakeBox aMakeBox(gp_Pnt(10.0, 0.0, 0.0), 10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
gp_Trsf aTrsf;
gp_Ax2 aYZPlane(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
aTrsf.SetMirror(aYZPlane);
BRepBuilderAPI_Transform aTransform(aBox, aTrsf);
const TopoDS_Shape& aResult = aTransform.Shape();
ASSERT_FALSE(aResult.IsNull()) << "Transformed shape is null";
GProp_GProps aProps;
BRepGProp::VolumeProperties(aResult, aProps);
gp_Pnt aCenterOfMass = aProps.CentreOfMass();
EXPECT_LT(aCenterOfMass.X(), 0.0)
<< "Center of mass X should be negative after mirroring through YZ plane";
}
TEST(BRepBuilderAPI_TransformTest, ShapeValidity)
{
BRepPrimAPI_MakeBox aMakeBox(10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
gp_Trsf aTrsf;
aTrsf.SetTranslation(gp_Vec(50.0, 50.0, 50.0));
BRepBuilderAPI_Transform aTransform(aBox, aTrsf);
const TopoDS_Shape& aResult = aTransform.Shape();
ASSERT_FALSE(aResult.IsNull()) << "Transformed shape is null";
BRepCheck_Analyzer anAnalyzer(aResult);
EXPECT_TRUE(anAnalyzer.IsValid()) << "Transformed shape should be valid";
}
@@ -0,0 +1,83 @@
// 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 <BRepClass3d_SolidClassifier.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <gp_Pnt.hxx>
#include <Precision.hxx>
#include <TopAbs_State.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(BRepClass3d_SolidClassifierTest, PointInside_Box)
{
BRepPrimAPI_MakeBox aMakeBox(gp_Pnt(0.0, 0.0, 0.0), 10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
BRepClass3d_SolidClassifier aClassifier(aBox);
aClassifier.Perform(gp_Pnt(5.0, 5.0, 5.0), Precision::Confusion());
EXPECT_EQ(aClassifier.State(), TopAbs_IN) << "Point (5,5,5) should be inside the box";
}
TEST(BRepClass3d_SolidClassifierTest, PointOutside_Box)
{
BRepPrimAPI_MakeBox aMakeBox(gp_Pnt(0.0, 0.0, 0.0), 10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
BRepClass3d_SolidClassifier aClassifier(aBox);
aClassifier.Perform(gp_Pnt(20.0, 20.0, 20.0), Precision::Confusion());
EXPECT_EQ(aClassifier.State(), TopAbs_OUT) << "Point (20,20,20) should be outside the box";
}
TEST(BRepClass3d_SolidClassifierTest, PointOnFace_Box)
{
BRepPrimAPI_MakeBox aMakeBox(gp_Pnt(0.0, 0.0, 0.0), 10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
BRepClass3d_SolidClassifier aClassifier(aBox);
aClassifier.Perform(gp_Pnt(5.0, 5.0, 0.0), Precision::Confusion());
EXPECT_EQ(aClassifier.State(), TopAbs_ON)
<< "Point (5,5,0) should be on the bottom face of the box";
}
TEST(BRepClass3d_SolidClassifierTest, PointInside_Sphere)
{
BRepPrimAPI_MakeSphere aMakeSphere(10.0);
const TopoDS_Shape& aSphere = aMakeSphere.Shape();
ASSERT_TRUE(aMakeSphere.IsDone()) << "Sphere creation failed";
BRepClass3d_SolidClassifier aClassifier(aSphere);
aClassifier.Perform(gp_Pnt(0.0, 0.0, 0.0), Precision::Confusion());
EXPECT_EQ(aClassifier.State(), TopAbs_IN) << "Origin should be inside the sphere";
}
TEST(BRepClass3d_SolidClassifierTest, PerformInfinitePoint)
{
BRepPrimAPI_MakeBox aMakeBox(gp_Pnt(0.0, 0.0, 0.0), 10.0, 10.0, 10.0);
const TopoDS_Shape& aBox = aMakeBox.Shape();
ASSERT_TRUE(aMakeBox.IsDone()) << "Box creation failed";
BRepClass3d_SolidClassifier aClassifier(aBox);
aClassifier.PerformInfinitePoint(Precision::Confusion());
EXPECT_EQ(aClassifier.State(), TopAbs_OUT) << "Infinite point should be outside the box";
}
@@ -0,0 +1,117 @@
// 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 <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepGProp.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <gp_Pnt.hxx>
#include <GProp_GProps.hxx>
#include <Precision.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <gtest/gtest.h>
TEST(BRepGPropTest, LinearProperties_EdgeLength)
{
gp_Pnt aP1(0.0, 0.0, 0.0);
gp_Pnt aP2(3.0, 4.0, 0.0);
BRepBuilderAPI_MakeEdge aMakeEdge(aP1, aP2);
ASSERT_TRUE(aMakeEdge.IsDone());
GProp_GProps aProps;
BRepGProp::LinearProperties(aMakeEdge.Edge(), aProps);
EXPECT_NEAR(aProps.Mass(), 5.0, Precision::Confusion()) << "Edge length should be 5";
}
TEST(BRepGPropTest, SurfaceProperties_BoxFaceArea)
{
BRepPrimAPI_MakeBox aBox(10.0, 20.0, 30.0);
TopoDS_Shape aShape = aBox.Shape();
ASSERT_TRUE(aBox.IsDone());
// Total surface area = 2*(10*20 + 10*30 + 20*30) = 2*(200+300+600) = 2200
GProp_GProps aProps;
BRepGProp::SurfaceProperties(aShape, aProps);
EXPECT_NEAR(aProps.Mass(), 2200.0, Precision::Confusion());
}
TEST(BRepGPropTest, VolumeProperties_UnitBox)
{
BRepPrimAPI_MakeBox aBox(1.0, 1.0, 1.0);
TopoDS_Shape aShape = aBox.Shape();
ASSERT_TRUE(aBox.IsDone());
GProp_GProps aProps;
BRepGProp::VolumeProperties(aShape, aProps);
EXPECT_NEAR(aProps.Mass(), 1.0, Precision::Confusion()) << "Unit box volume should be 1";
}
TEST(BRepGPropTest, VolumeProperties_Sphere)
{
const double aRadius = 5.0;
BRepPrimAPI_MakeSphere aSphere(aRadius);
TopoDS_Shape aShape = aSphere.Shape();
ASSERT_TRUE(aSphere.IsDone());
GProp_GProps aProps;
BRepGProp::VolumeProperties(aShape, aProps);
double anExpectedVolume = (4.0 / 3.0) * M_PI * aRadius * aRadius * aRadius;
EXPECT_NEAR(aProps.Mass(), anExpectedVolume, 0.01) << "Sphere volume mismatch";
}
TEST(BRepGPropTest, VolumeProperties_BoxCenterOfMass)
{
// Box from (0,0,0) to (10,10,10)
BRepPrimAPI_MakeBox aBox(10.0, 10.0, 10.0);
TopoDS_Shape aShape = aBox.Shape();
ASSERT_TRUE(aBox.IsDone());
GProp_GProps aProps;
BRepGProp::VolumeProperties(aShape, aProps);
gp_Pnt aCOM = aProps.CentreOfMass();
// Center of mass should be at (5, 5, 5)
EXPECT_NEAR(aCOM.X(), 5.0, Precision::Confusion());
EXPECT_NEAR(aCOM.Y(), 5.0, Precision::Confusion());
EXPECT_NEAR(aCOM.Z(), 5.0, Precision::Confusion());
}
TEST(BRepGPropTest, LinearProperties_SkipShared)
{
BRepPrimAPI_MakeBox aBox(10.0, 10.0, 10.0);
TopoDS_Shape aShape = aBox.Shape();
ASSERT_TRUE(aBox.IsDone());
// With SkipShared = false, shared edges are counted multiple times
GProp_GProps aPropsNotSkipped;
BRepGProp::LinearProperties(aShape, aPropsNotSkipped, false);
// With SkipShared = true, each edge is counted once
GProp_GProps aPropsSkipped;
BRepGProp::LinearProperties(aShape, aPropsSkipped, true);
// Box has 12 edges, each of length 10 = total 120
EXPECT_NEAR(aPropsSkipped.Mass(), 120.0, Precision::Confusion())
<< "Total edge length of 10x10x10 box with SkipShared=true should be 120";
// Without SkipShared, each edge is counted for each face it belongs to (2 faces per edge)
// So total = 240
EXPECT_NEAR(aPropsNotSkipped.Mass(), 240.0, Precision::Confusion())
<< "Total edge length with SkipShared=false should be double";
}
@@ -2,7 +2,13 @@
set(OCCT_TKTopAlgo_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
set(OCCT_TKTopAlgo_GTests_FILES
BRepBuilderAPI_Copy_Test.cxx
BRepBuilderAPI_MakeEdge_Test.cxx
BRepBuilderAPI_MakeFace_Test.cxx
BRepBuilderAPI_MakeWire_Test.cxx
BRepBuilderAPI_Transform_Test.cxx
BRepClass3d_SolidClassifier_Test.cxx
BRepGProp_Test.cxx
BRepLib_MakeWire_Test.cxx
BRepOffsetAPI_ThruSections_Test.cxx
)
@@ -0,0 +1,160 @@
// 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 <BRep_Tool.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
#include <gp.hxx>
#include <gp_Ax2.hxx>
#include <gp_Pnt.hxx>
#include <Precision.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <gtest/gtest.h>
TEST(BRep_Tool_Test, Pnt_FromVertex)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_VERTEX);
ASSERT_TRUE(anExp.More());
const TopoDS_Vertex& aVertex = TopoDS::Vertex(anExp.Current());
gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
// The point coordinates should be within the box bounds [0,10] x [0,20] x [0,30]
EXPECT_GE(aPnt.X(), -Precision::Confusion());
EXPECT_LE(aPnt.X(), 10.0 + Precision::Confusion());
EXPECT_GE(aPnt.Y(), -Precision::Confusion());
EXPECT_LE(aPnt.Y(), 20.0 + Precision::Confusion());
EXPECT_GE(aPnt.Z(), -Precision::Confusion());
EXPECT_LE(aPnt.Z(), 30.0 + Precision::Confusion());
}
TEST(BRep_Tool_Test, Tolerance_Vertex)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_VERTEX);
ASSERT_TRUE(anExp.More());
const TopoDS_Vertex& aVertex = TopoDS::Vertex(anExp.Current());
double aTol = BRep_Tool::Tolerance(aVertex);
EXPECT_GE(aTol, 0.0);
}
TEST(BRep_Tool_Test, Tolerance_Edge)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_EDGE);
ASSERT_TRUE(anExp.More());
const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
double aTol = BRep_Tool::Tolerance(anEdge);
EXPECT_GE(aTol, 0.0);
}
TEST(BRep_Tool_Test, Tolerance_Face)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_FACE);
ASSERT_TRUE(anExp.More());
const TopoDS_Face& aFace = TopoDS::Face(anExp.Current());
double aTol = BRep_Tool::Tolerance(aFace);
EXPECT_GE(aTol, 0.0);
}
TEST(BRep_Tool_Test, Curve_FromEdge)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_EDGE);
ASSERT_TRUE(anExp.More());
const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
double aFirst = 0.0;
double aLast = 0.0;
occ::handle<Geom_Curve> aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
EXPECT_FALSE(aCurve.IsNull()) << "Curve from a box edge should not be null";
EXPECT_LT(aFirst, aLast) << "First parameter should be less than last parameter";
}
TEST(BRep_Tool_Test, Surface_FromFace)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_FACE);
ASSERT_TRUE(anExp.More());
const TopoDS_Face& aFace = TopoDS::Face(anExp.Current());
occ::handle<Geom_Surface> aSurface = BRep_Tool::Surface(aFace);
EXPECT_FALSE(aSurface.IsNull()) << "Surface from a box face should not be null";
}
TEST(BRep_Tool_Test, IsClosed_CircleEdge)
{
occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp_Ax2(gp_Pnt(0.0, 0.0, 0.0), gp::DZ()), 5.0);
BRepBuilderAPI_MakeEdge anEdgeMaker(aCircle);
ASSERT_TRUE(anEdgeMaker.IsDone());
const TopoDS_Edge& anEdge = anEdgeMaker.Edge();
EXPECT_TRUE(BRep_Tool::IsClosed(anEdge)) << "A full circle edge should be closed";
}
TEST(BRep_Tool_Test, IsClosed_LineEdge)
{
BRepBuilderAPI_MakeEdge anEdgeMaker(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(10.0, 0.0, 0.0));
ASSERT_TRUE(anEdgeMaker.IsDone());
const TopoDS_Edge& anEdge = anEdgeMaker.Edge();
EXPECT_FALSE(BRep_Tool::IsClosed(anEdge)) << "A line segment edge should not be closed";
}
TEST(BRep_Tool_Test, Degenerated)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_EDGE);
ASSERT_TRUE(anExp.More());
const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
EXPECT_FALSE(BRep_Tool::Degenerated(anEdge)) << "Box edges should not be degenerated";
}
@@ -2,7 +2,9 @@
set(OCCT_TKBRep_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
set(OCCT_TKBRep_GTests_FILES
BRep_Tool_Test.cxx
BRepAdaptor_CompCurve_Test.cxx
TopExp_Test.cxx
TopoDS_Builder_Test.cxx
TopoDS_Edge_Test.cxx
TopoDS_Iterator_Test.cxx
@@ -0,0 +1,152 @@
// 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 <BRepPrimAPI_MakeBox.hxx>
#include <gp_Pnt.hxx>
#include <NCollection_IndexedDataMap.hxx>
#include <NCollection_IndexedMap.hxx>
#include <NCollection_List.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_ShapeMapHasher.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <gtest/gtest.h>
TEST(TopExp_Test, MapShapes_Faces)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> aFaceMap;
TopExp::MapShapes(aBox, TopAbs_FACE, aFaceMap);
EXPECT_EQ(aFaceMap.Extent(), 6) << "A box should have exactly 6 faces";
}
TEST(TopExp_Test, MapShapes_Edges)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> anEdgeMap;
TopExp::MapShapes(aBox, TopAbs_EDGE, anEdgeMap);
EXPECT_EQ(anEdgeMap.Extent(), 12) << "A box should have exactly 12 edges";
}
TEST(TopExp_Test, MapShapes_Vertices)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> aVertexMap;
TopExp::MapShapes(aBox, TopAbs_VERTEX, aVertexMap);
EXPECT_EQ(aVertexMap.Extent(), 8) << "A box should have exactly 8 vertices";
}
TEST(TopExp_Test, FirstVertex_LastVertex)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_EDGE);
ASSERT_TRUE(anExp.More());
const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
TopoDS_Vertex aFirstVertex = TopExp::FirstVertex(anEdge);
TopoDS_Vertex aLastVertex = TopExp::LastVertex(anEdge);
EXPECT_FALSE(aFirstVertex.IsNull()) << "First vertex should not be null";
EXPECT_FALSE(aLastVertex.IsNull()) << "Last vertex should not be null";
EXPECT_FALSE(aFirstVertex.IsSame(aLastVertex))
<< "First and last vertices of a box edge should be distinct";
}
TEST(TopExp_Test, Vertices)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
TopExp_Explorer anExp(aBox, TopAbs_EDGE);
ASSERT_TRUE(anExp.More());
const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
TopoDS_Vertex aV1, aV2;
TopExp::Vertices(anEdge, aV1, aV2);
EXPECT_FALSE(aV1.IsNull()) << "First vertex from Vertices() should not be null";
EXPECT_FALSE(aV2.IsNull()) << "Second vertex from Vertices() should not be null";
}
TEST(TopExp_Test, CommonVertex)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> anEdgeMap;
TopExp::MapShapes(aBox, TopAbs_EDGE, anEdgeMap);
ASSERT_GE(anEdgeMap.Extent(), 2);
// Find two adjacent edges (sharing a common vertex)
bool isFound = false;
for (int i = 1; i <= anEdgeMap.Extent() && !isFound; ++i)
{
const TopoDS_Edge& anEdge1 = TopoDS::Edge(anEdgeMap(i));
for (int j = i + 1; j <= anEdgeMap.Extent() && !isFound; ++j)
{
const TopoDS_Edge& anEdge2 = TopoDS::Edge(anEdgeMap(j));
TopoDS_Vertex aCommonVertex;
if (TopExp::CommonVertex(anEdge1, anEdge2, aCommonVertex))
{
EXPECT_FALSE(aCommonVertex.IsNull()) << "Common vertex should not be null";
isFound = true;
}
}
}
EXPECT_TRUE(isFound) << "Should find at least one pair of adjacent edges in a box";
}
TEST(TopExp_Test, MapShapesAndAncestors)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
NCollection_IndexedDataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>
anEdgeFaceMap;
TopExp::MapShapesAndAncestors(aBox, TopAbs_EDGE, TopAbs_FACE, anEdgeFaceMap);
EXPECT_EQ(anEdgeFaceMap.Extent(), 12) << "A box should have 12 edges in the ancestor map";
// Each edge of a box is shared by exactly 2 faces
for (int i = 1; i <= anEdgeFaceMap.Extent(); ++i)
{
const NCollection_List<TopoDS_Shape>& aFaceList = anEdgeFaceMap(i);
EXPECT_EQ(aFaceList.Extent(), 2) << "Each box edge should be shared by exactly 2 faces";
}
}
@@ -6,9 +6,12 @@ set(OCCT_TKG3d_GTests_FILES
Geom_BezierSurface_Test.cxx
Geom_BSplineCurve_Test.cxx
Geom_BSplineSurface_Test.cxx
Geom_Circle_Test.cxx
Geom_CurveEval_Test.cxx
Geom_Line_Test.cxx
Geom_OffsetCurve_Test.cxx
Geom_OffsetSurface_Test.cxx
Geom_Plane_Test.cxx
Geom_SurfaceEval_Test.cxx
GeomAdaptor_Curve_Test.cxx
GeomAPI_ExtremaCurveCurve_Test.cxx
@@ -0,0 +1,135 @@
// 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 <Geom_Circle.hxx>
#include <gp_Ax2.hxx>
#include <gp_Circ.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(Geom_CircleTest, Constructor)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Circle> aCircle = new Geom_Circle(anAxis, 5.0);
ASSERT_FALSE(aCircle.IsNull());
EXPECT_NEAR(aCircle->Radius(), 5.0, Precision::Confusion());
}
TEST(Geom_CircleTest, Center)
{
gp_Pnt aCenter(1.0, 2.0, 3.0);
gp_Ax2 anAxis(aCenter, gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Circle> aCircle = new Geom_Circle(anAxis, 5.0);
EXPECT_TRUE(aCircle->Circ().Location().IsEqual(aCenter, Precision::Confusion()));
}
TEST(Geom_CircleTest, D0Evaluation)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Circle> aCircle = new Geom_Circle(anAxis, 1.0);
gp_Pnt aPnt;
// At parameter 0: point should be (1,0,0) for unit circle in XY plane
aCircle->D0(0.0, aPnt);
EXPECT_NEAR(aPnt.X(), 1.0, Precision::Confusion());
EXPECT_NEAR(aPnt.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aPnt.Z(), 0.0, Precision::Confusion());
// At parameter PI/2: point should be (0,1,0)
aCircle->D0(M_PI_2, aPnt);
EXPECT_NEAR(aPnt.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aPnt.Y(), 1.0, Precision::Confusion());
EXPECT_NEAR(aPnt.Z(), 0.0, Precision::Confusion());
// At parameter PI: point should be (-1,0,0)
aCircle->D0(M_PI, aPnt);
EXPECT_NEAR(aPnt.X(), -1.0, Precision::Confusion());
EXPECT_NEAR(aPnt.Y(), 0.0, Precision::Confusion());
// At parameter 3*PI/2: point should be (0,-1,0)
aCircle->D0(3.0 * M_PI_2, aPnt);
EXPECT_NEAR(aPnt.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aPnt.Y(), -1.0, Precision::Confusion());
}
TEST(Geom_CircleTest, D1Evaluation)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Circle> aCircle = new Geom_Circle(anAxis, 1.0);
gp_Pnt aPnt;
gp_Vec aV1;
// At parameter 0: tangent should be (0,1,0) for unit circle
aCircle->D1(0.0, aPnt, aV1);
EXPECT_NEAR(aV1.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aV1.Y(), 1.0, Precision::Confusion());
EXPECT_NEAR(aV1.Z(), 0.0, Precision::Confusion());
}
TEST(Geom_CircleTest, D2Evaluation)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Circle> aCircle = new Geom_Circle(anAxis, 1.0);
gp_Pnt aPnt;
gp_Vec aV1, aV2;
// At parameter 0: second derivative should be (-1,0,0) pointing toward center
aCircle->D2(0.0, aPnt, aV1, aV2);
EXPECT_NEAR(aV2.X(), -1.0, Precision::Confusion());
EXPECT_NEAR(aV2.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aV2.Z(), 0.0, Precision::Confusion());
}
TEST(Geom_CircleTest, Reverse)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Circle> aCircle = new Geom_Circle(anAxis, 1.0);
double aParam = M_PI_4;
double aReversedParam = aCircle->ReversedParameter(aParam);
// For a circle: reversed parameter = 2*PI - U
EXPECT_NEAR(aReversedParam, 2.0 * M_PI - aParam, Precision::Confusion());
}
TEST(Geom_CircleTest, Transform)
{
gp_Ax2 anAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Circle> aCircle = new Geom_Circle(anAxis, 5.0);
gp_Trsf aTrsf;
aTrsf.SetScale(gp_Pnt(0.0, 0.0, 0.0), 2.0);
aCircle->Transform(aTrsf);
EXPECT_NEAR(aCircle->Radius(), 10.0, Precision::Confusion());
}
TEST(Geom_CircleTest, Copy)
{
gp_Ax2 anAxis(gp_Pnt(1.0, 2.0, 3.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Circle> aCircle = new Geom_Circle(anAxis, 7.0);
occ::handle<Geom_Geometry> aCopy = aCircle->Copy();
ASSERT_FALSE(aCopy.IsNull());
occ::handle<Geom_Circle> aCopyCircle = occ::down_cast<Geom_Circle>(aCopy);
ASSERT_FALSE(aCopyCircle.IsNull());
EXPECT_NEAR(aCopyCircle->Radius(), 7.0, Precision::Confusion());
EXPECT_TRUE(
aCopyCircle->Circ().Location().IsEqual(gp_Pnt(1.0, 2.0, 3.0), Precision::Confusion()));
}
@@ -0,0 +1,119 @@
// 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 <Geom_Line.hxx>
#include <gp_Ax1.hxx>
#include <gp_Dir.hxx>
#include <gp_Lin.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(Geom_LineTest, ConstructFromAx1)
{
gp_Ax1 anAx1(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
occ::handle<Geom_Line> aLine = new Geom_Line(anAx1);
ASSERT_FALSE(aLine.IsNull());
gp_Pnt aLoc = aLine->Lin().Location();
EXPECT_TRUE(aLoc.IsEqual(gp_Pnt(0.0, 0.0, 0.0), Precision::Confusion()));
}
TEST(Geom_LineTest, ConstructFromPointAndDir)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(1.0, 2.0, 3.0), gp_Dir(0.0, 0.0, 1.0));
ASSERT_FALSE(aLine.IsNull());
gp_Pnt aLoc = aLine->Lin().Location();
EXPECT_TRUE(aLoc.IsEqual(gp_Pnt(1.0, 2.0, 3.0), Precision::Confusion()));
EXPECT_TRUE(aLine->Lin().Direction().IsEqual(gp_Dir(0.0, 0.0, 1.0), Precision::Angular()));
}
TEST(Geom_LineTest, D0Evaluation)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Pnt aPnt;
aLine->D0(5.0, aPnt);
EXPECT_NEAR(aPnt.X(), 5.0, Precision::Confusion());
EXPECT_NEAR(aPnt.Y(), 0.0, Precision::Confusion());
EXPECT_NEAR(aPnt.Z(), 0.0, Precision::Confusion());
}
TEST(Geom_LineTest, D1Evaluation)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 1.0, 0.0));
gp_Pnt aPnt;
gp_Vec aV1;
aLine->D1(3.0, aPnt, aV1);
EXPECT_NEAR(aPnt.Y(), 3.0, Precision::Confusion());
// First derivative is the direction vector (constant for a line)
EXPECT_NEAR(aV1.X(), 0.0, Precision::Confusion());
EXPECT_NEAR(aV1.Y(), 1.0, Precision::Confusion());
EXPECT_NEAR(aV1.Z(), 0.0, Precision::Confusion());
}
TEST(Geom_LineTest, D2Evaluation)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Pnt aPnt;
gp_Vec aV1, aV2;
aLine->D2(1.0, aPnt, aV1, aV2);
// Second derivative of a line is zero
EXPECT_NEAR(aV2.Magnitude(), 0.0, Precision::Confusion());
}
TEST(Geom_LineTest, InfiniteParameters)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
EXPECT_EQ(aLine->FirstParameter(), -Precision::Infinite());
EXPECT_EQ(aLine->LastParameter(), Precision::Infinite());
}
TEST(Geom_LineTest, Reverse)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
aLine->Reverse();
EXPECT_TRUE(aLine->Lin().Direction().IsEqual(gp_Dir(-1.0, 0.0, 0.0), Precision::Angular()));
}
TEST(Geom_LineTest, Reversed)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
occ::handle<Geom_Curve> aReversed = aLine->Reversed();
ASSERT_FALSE(aReversed.IsNull());
occ::handle<Geom_Line> aRevLine = occ::down_cast<Geom_Line>(aReversed);
ASSERT_FALSE(aRevLine.IsNull());
EXPECT_TRUE(aRevLine->Lin().Direction().IsEqual(gp_Dir(-1.0, 0.0, 0.0), Precision::Angular()));
}
TEST(Geom_LineTest, Transform)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
gp_Trsf aTrsf;
aTrsf.SetTranslation(gp_Vec(0.0, 0.0, 5.0));
aLine->Transform(aTrsf);
EXPECT_NEAR(aLine->Lin().Location().Z(), 5.0, Precision::Confusion());
}
TEST(Geom_LineTest, Copy)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(1.0, 2.0, 3.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Geometry> aCopy = aLine->Copy();
ASSERT_FALSE(aCopy.IsNull());
occ::handle<Geom_Line> aCopyLine = occ::down_cast<Geom_Line>(aCopy);
ASSERT_FALSE(aCopyLine.IsNull());
EXPECT_TRUE(aCopyLine->Lin().Location().IsEqual(gp_Pnt(1.0, 2.0, 3.0), Precision::Confusion()));
}
@@ -0,0 +1,111 @@
// 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 <Geom_Curve.hxx>
#include <Geom_Line.hxx>
#include <Geom_Plane.hxx>
#include <gp_Ax3.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(Geom_PlaneTest, ConstructFromAx3)
{
gp_Ax3 anAx3(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Plane> aPlane = new Geom_Plane(anAx3);
ASSERT_FALSE(aPlane.IsNull());
EXPECT_TRUE(aPlane->Location().IsEqual(gp_Pnt(0.0, 0.0, 0.0), Precision::Confusion()));
}
TEST(Geom_PlaneTest, ConstructFromPointAndDir)
{
occ::handle<Geom_Plane> aPlane = new Geom_Plane(gp_Pnt(1.0, 2.0, 3.0), gp_Dir(0.0, 0.0, 1.0));
ASSERT_FALSE(aPlane.IsNull());
EXPECT_TRUE(aPlane->Location().IsEqual(gp_Pnt(1.0, 2.0, 3.0), Precision::Confusion()));
}
TEST(Geom_PlaneTest, D0Evaluation)
{
occ::handle<Geom_Plane> aPlane = new Geom_Plane(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Pnt aPnt;
// XY plane at origin: D0(U,V) = (U,V,0) for default axis
aPlane->D0(3.0, 4.0, aPnt);
EXPECT_NEAR(aPnt.X(), 3.0, Precision::Confusion());
EXPECT_NEAR(aPnt.Y(), 4.0, Precision::Confusion());
EXPECT_NEAR(aPnt.Z(), 0.0, Precision::Confusion());
}
TEST(Geom_PlaneTest, Coefficients)
{
occ::handle<Geom_Plane> aPlane = new Geom_Plane(gp_Pnt(0.0, 0.0, 5.0), gp_Dir(0.0, 0.0, 1.0));
double anA, aB, aC, aD;
aPlane->Coefficients(anA, aB, aC, aD);
EXPECT_NEAR(anA, 0.0, Precision::Confusion());
EXPECT_NEAR(aB, 0.0, Precision::Confusion());
EXPECT_NEAR(aC, 1.0, Precision::Confusion());
EXPECT_NEAR(aD, -5.0, Precision::Confusion());
}
TEST(Geom_PlaneTest, UIso)
{
occ::handle<Geom_Plane> aPlane = new Geom_Plane(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Curve> aUIso = aPlane->UIso(2.0);
ASSERT_FALSE(aUIso.IsNull());
// UIso at U=2 on XY plane should be a line at x=2, varying in Y
occ::handle<Geom_Line> aLine = occ::down_cast<Geom_Line>(aUIso);
ASSERT_FALSE(aLine.IsNull());
gp_Pnt aPnt;
aLine->D0(0.0, aPnt);
EXPECT_NEAR(aPnt.X(), 2.0, Precision::Confusion());
}
TEST(Geom_PlaneTest, VIso)
{
occ::handle<Geom_Plane> aPlane = new Geom_Plane(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Curve> aVIso = aPlane->VIso(3.0);
ASSERT_FALSE(aVIso.IsNull());
// VIso at V=3 on XY plane should be a line at y=3, varying in X
occ::handle<Geom_Line> aLine = occ::down_cast<Geom_Line>(aVIso);
ASSERT_FALSE(aLine.IsNull());
gp_Pnt aPnt;
aLine->D0(0.0, aPnt);
EXPECT_NEAR(aPnt.Y(), 3.0, Precision::Confusion());
}
TEST(Geom_PlaneTest, Transform)
{
occ::handle<Geom_Plane> aPlane = new Geom_Plane(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0));
gp_Trsf aTrsf;
aTrsf.SetTranslation(gp_Vec(0.0, 0.0, 10.0));
aPlane->Transform(aTrsf);
EXPECT_NEAR(aPlane->Location().Z(), 10.0, Precision::Confusion());
}
TEST(Geom_PlaneTest, Copy)
{
occ::handle<Geom_Plane> aPlane = new Geom_Plane(gp_Pnt(1.0, 2.0, 3.0), gp_Dir(0.0, 0.0, 1.0));
occ::handle<Geom_Geometry> aCopy = aPlane->Copy();
ASSERT_FALSE(aCopy.IsNull());
occ::handle<Geom_Plane> aCopyPlane = occ::down_cast<Geom_Plane>(aCopy);
ASSERT_FALSE(aCopyPlane.IsNull());
EXPECT_TRUE(aCopyPlane->Location().IsEqual(gp_Pnt(1.0, 2.0, 3.0), Precision::Confusion()));
}
@@ -4,7 +4,9 @@ set(OCCT_TKGeomBase_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
set(OCCT_TKGeomBase_GTests_FILES
BndLib_Test.cxx
Extrema_ExtPC_Test.cxx
GCPnts_AbscissaPoint_Test.cxx
GeomConvert_CompCurveToBSplineCurve_Test.cxx
GeomConvert_Test.cxx
Hermit_Test.cxx
IntAna_IntQuadQuad_Test.cxx
)
@@ -0,0 +1,80 @@
// 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 <GCPnts_AbscissaPoint.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Line.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <gp_Ax2.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(GCPnts_AbscissaPointTest, LineLength)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
GeomAdaptor_Curve anAdaptor(aLine, 0.0, 10.0);
const double aLength = GCPnts_AbscissaPoint::Length(anAdaptor);
EXPECT_NEAR(aLength, 10.0, Precision::Confusion());
}
TEST(GCPnts_AbscissaPointTest, CircleArcLength)
{
occ::handle<Geom_Circle> aCircle =
new Geom_Circle(gp_Ax2(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 1.0);
GeomAdaptor_Curve anAdaptor(aCircle, 0.0, M_PI);
const double aLength = GCPnts_AbscissaPoint::Length(anAdaptor);
EXPECT_NEAR(aLength, M_PI, Precision::Confusion());
}
TEST(GCPnts_AbscissaPointTest, FullCircleLength)
{
occ::handle<Geom_Circle> aCircle =
new Geom_Circle(gp_Ax2(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 5.0);
GeomAdaptor_Curve anAdaptor(aCircle, 0.0, 2.0 * M_PI);
const double aLength = GCPnts_AbscissaPoint::Length(anAdaptor);
EXPECT_NEAR(aLength, 2.0 * M_PI * 5.0, Precision::Confusion());
}
TEST(GCPnts_AbscissaPointTest, ParameterAtAbscissa_Line)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
GeomAdaptor_Curve anAdaptor(aLine, 0.0, 10.0);
GCPnts_AbscissaPoint anAbscissa(anAdaptor, 5.0, 0.0);
ASSERT_TRUE(anAbscissa.IsDone());
const double aParam = anAbscissa.Parameter();
EXPECT_NEAR(aParam, 5.0, Precision::Confusion());
}
TEST(GCPnts_AbscissaPointTest, ParameterAtAbscissa_Circle)
{
occ::handle<Geom_Circle> aCircle =
new Geom_Circle(gp_Ax2(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 1.0);
GeomAdaptor_Curve anAdaptor(aCircle, 0.0, 2.0 * M_PI);
GCPnts_AbscissaPoint anAbscissa(anAdaptor, M_PI / 2.0, 0.0);
ASSERT_TRUE(anAbscissa.IsDone());
const double aParam = anAbscissa.Parameter();
EXPECT_NEAR(aParam, M_PI / 2.0, Precision::Confusion());
}
@@ -0,0 +1,78 @@
// 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 <Geom_BSplineCurve.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Line.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GeomConvert.hxx>
#include <gp.hxx>
#include <gp_Ax2.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <Precision.hxx>
#include <gtest/gtest.h>
TEST(GeomConvertTest, CircleToBSpline)
{
occ::handle<Geom_Circle> aCircle =
new Geom_Circle(gp_Ax2(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(0.0, 0.0, 1.0)), 5.0);
occ::handle<Geom_BSplineCurve> aBSpline = GeomConvert::CurveToBSplineCurve(aCircle);
ASSERT_FALSE(aBSpline.IsNull());
gp_Pnt aOrigPnt;
aCircle->D0(0.0, aOrigPnt);
gp_Pnt aBSplinePnt;
aBSpline->D0(0.0, aBSplinePnt);
EXPECT_NEAR(aOrigPnt.Distance(aBSplinePnt), 0.0, Precision::Confusion());
}
TEST(GeomConvertTest, LineToBSpline)
{
occ::handle<Geom_Line> aLine = new Geom_Line(gp_Pnt(0.0, 0.0, 0.0), gp_Dir(1.0, 0.0, 0.0));
occ::handle<Geom_TrimmedCurve> aTrimmed = new Geom_TrimmedCurve(aLine, 0.0, 10.0);
occ::handle<Geom_BSplineCurve> aBSpline = GeomConvert::CurveToBSplineCurve(aTrimmed);
ASSERT_FALSE(aBSpline.IsNull());
gp_Pnt aPnt;
aBSpline->D0(5.0, aPnt);
const gp_Pnt anExpectedPnt(5.0, 0.0, 0.0);
EXPECT_NEAR(aPnt.Distance(anExpectedPnt), 0.0, Precision::Confusion());
}
TEST(GeomConvertTest, PlaneToBSplineSurface)
{
occ::handle<Geom_Plane> aPlane = new Geom_Plane(gp::XOY());
occ::handle<Geom_RectangularTrimmedSurface> aTrimmed =
new Geom_RectangularTrimmedSurface(aPlane, 0.0, 10.0, 0.0, 10.0);
occ::handle<Geom_BSplineSurface> aBSurf = GeomConvert::SurfaceToBSplineSurface(aTrimmed);
ASSERT_FALSE(aBSurf.IsNull());
gp_Pnt aPnt;
aBSurf->D0(5.0, 5.0, aPnt);
const gp_Pnt anExpectedPnt(5.0, 5.0, 0.0);
EXPECT_NEAR(aPnt.Distance(anExpectedPnt), 0.0, Precision::Confusion());
}
@@ -24,9 +24,9 @@
// Helper to create a simple rational BSpline curve (degree 2, 3 poles)
// with weights that produce distinct endpoint weight values.
static Handle(Geom_BSplineCurve) MakeRationalBSpline3D(const double theW1,
const double theW2,
const double theW3)
static occ::handle<Geom_BSplineCurve> MakeRationalBSpline3D(const double theW1,
const double theW2,
const double theW3)
{
NCollection_Array1<gp_Pnt> aPoles(1, 3);
aPoles(1) = gp_Pnt(0.0, 0.0, 0.0);
@@ -50,9 +50,9 @@ static Handle(Geom_BSplineCurve) MakeRationalBSpline3D(const double theW1,
}
// Helper to create a simple rational BSpline 2D curve (degree 2, 3 poles).
static Handle(Geom2d_BSplineCurve) MakeRationalBSpline2D(const double theW1,
const double theW2,
const double theW3)
static occ::handle<Geom2d_BSplineCurve> MakeRationalBSpline2D(const double theW1,
const double theW2,
const double theW3)
{
NCollection_Array1<gp_Pnt2d> aPoles(1, 3);
aPoles(1) = gp_Pnt2d(0.0, 0.0);
@@ -78,9 +78,9 @@ static Handle(Geom2d_BSplineCurve) MakeRationalBSpline2D(const double theW1,
TEST(HermitTest, Solution3D_UniformWeights_ReturnsValidCurve)
{
// Uniform weights => weight function is constant 1.0 everywhere
Handle(Geom_BSplineCurve) aBS = MakeRationalBSpline3D(1.0, 1.0, 1.0);
occ::handle<Geom_BSplineCurve> aBS = MakeRationalBSpline3D(1.0, 1.0, 1.0);
Handle(Geom2d_BSplineCurve) aResult = Hermit::Solution(aBS);
occ::handle<Geom2d_BSplineCurve> aResult = Hermit::Solution(aBS);
ASSERT_FALSE(aResult.IsNull());
EXPECT_GE(aResult->NbPoles(), 4);
@@ -97,9 +97,9 @@ TEST(HermitTest, Solution3D_UniformWeights_ReturnsValidCurve)
TEST(HermitTest, Solution3D_DistinctWeights_ReturnsValidCurve)
{
// Different weights at endpoints: w(0)=2, w(1)=3
Handle(Geom_BSplineCurve) aBS = MakeRationalBSpline3D(2.0, 1.5, 3.0);
occ::handle<Geom_BSplineCurve> aBS = MakeRationalBSpline3D(2.0, 1.5, 3.0);
Handle(Geom2d_BSplineCurve) aResult = Hermit::Solution(aBS);
occ::handle<Geom2d_BSplineCurve> aResult = Hermit::Solution(aBS);
ASSERT_FALSE(aResult.IsNull());
@@ -114,9 +114,9 @@ TEST(HermitTest, Solution3D_DistinctWeights_ReturnsValidCurve)
TEST(HermitTest, Solution3D_HighWeightRatio_Endpoint)
{
// Large weight ratio: w(0) small, w(1) large - tests the Pole0 < Pole3 branch
Handle(Geom_BSplineCurve) aBS = MakeRationalBSpline3D(0.5, 1.0, 5.0);
occ::handle<Geom_BSplineCurve> aBS = MakeRationalBSpline3D(0.5, 1.0, 5.0);
Handle(Geom2d_BSplineCurve) aResult = Hermit::Solution(aBS);
occ::handle<Geom2d_BSplineCurve> aResult = Hermit::Solution(aBS);
ASSERT_FALSE(aResult.IsNull());
@@ -131,9 +131,9 @@ TEST(HermitTest, Solution3D_HighWeightRatio_Endpoint)
TEST(HermitTest, Solution3D_ReversedWeightRatio_Endpoint)
{
// Reversed ratio: w(0) large, w(1) small - tests the Pole0 > Pole3 branch
Handle(Geom_BSplineCurve) aBS = MakeRationalBSpline3D(5.0, 1.0, 0.5);
occ::handle<Geom_BSplineCurve> aBS = MakeRationalBSpline3D(5.0, 1.0, 0.5);
Handle(Geom2d_BSplineCurve) aResult = Hermit::Solution(aBS);
occ::handle<Geom2d_BSplineCurve> aResult = Hermit::Solution(aBS);
ASSERT_FALSE(aResult.IsNull());
@@ -147,9 +147,9 @@ TEST(HermitTest, Solution3D_ReversedWeightRatio_Endpoint)
TEST(HermitTest, Solution3D_PositivePoles)
{
// The result curve should have all positive Y coordinates (positive denominator)
Handle(Geom_BSplineCurve) aBS = MakeRationalBSpline3D(2.0, 3.0, 1.5);
occ::handle<Geom_BSplineCurve> aBS = MakeRationalBSpline3D(2.0, 3.0, 1.5);
Handle(Geom2d_BSplineCurve) aResult = Hermit::Solution(aBS);
occ::handle<Geom2d_BSplineCurve> aResult = Hermit::Solution(aBS);
ASSERT_FALSE(aResult.IsNull());
for (int i = 1; i <= aResult->NbPoles(); ++i)
@@ -160,9 +160,9 @@ TEST(HermitTest, Solution3D_PositivePoles)
TEST(HermitTest, Solution2D_UniformWeights_ReturnsValidCurve)
{
Handle(Geom2d_BSplineCurve) aBS = MakeRationalBSpline2D(1.0, 1.0, 1.0);
occ::handle<Geom2d_BSplineCurve> aBS = MakeRationalBSpline2D(1.0, 1.0, 1.0);
Handle(Geom2d_BSplineCurve) aResult = Hermit::Solution(aBS);
occ::handle<Geom2d_BSplineCurve> aResult = Hermit::Solution(aBS);
ASSERT_FALSE(aResult.IsNull());
@@ -175,9 +175,9 @@ TEST(HermitTest, Solution2D_UniformWeights_ReturnsValidCurve)
TEST(HermitTest, Solution2D_DistinctWeights_ReturnsValidCurve)
{
Handle(Geom2d_BSplineCurve) aBS = MakeRationalBSpline2D(2.0, 1.5, 3.0);
occ::handle<Geom2d_BSplineCurve> aBS = MakeRationalBSpline2D(2.0, 1.5, 3.0);
Handle(Geom2d_BSplineCurve) aResult = Hermit::Solution(aBS);
occ::handle<Geom2d_BSplineCurve> aResult = Hermit::Solution(aBS);
ASSERT_FALSE(aResult.IsNull());
@@ -191,9 +191,9 @@ TEST(HermitTest, Solution2D_DistinctWeights_ReturnsValidCurve)
TEST(HermitTest, Solution2D_HighWeightRatio_Endpoint)
{
// Large ratio tests the Pole0 < Pole3 branch in 2D PolyTest
Handle(Geom2d_BSplineCurve) aBS = MakeRationalBSpline2D(0.5, 1.0, 5.0);
occ::handle<Geom2d_BSplineCurve> aBS = MakeRationalBSpline2D(0.5, 1.0, 5.0);
Handle(Geom2d_BSplineCurve) aResult = Hermit::Solution(aBS);
occ::handle<Geom2d_BSplineCurve> aResult = Hermit::Solution(aBS);
ASSERT_FALSE(aResult.IsNull());
@@ -206,7 +206,7 @@ TEST(HermitTest, Solution2D_HighWeightRatio_Endpoint)
TEST(HermitTest, Solutionbis_UniformWeights_KnotsUnchanged)
{
Handle(Geom_BSplineCurve) aBS = MakeRationalBSpline3D(1.0, 1.0, 1.0);
occ::handle<Geom_BSplineCurve> aBS = MakeRationalBSpline3D(1.0, 1.0, 1.0);
double aKnotmin = 0.0;
double aKnotmax = 1.0;
@@ -222,7 +222,7 @@ TEST(HermitTest, Solutionbis_UniformWeights_KnotsUnchanged)
TEST(HermitTest, Solutionbis_DistinctWeights_ReturnsValidKnots)
{
Handle(Geom_BSplineCurve) aBS = MakeRationalBSpline3D(2.0, 1.5, 3.0);
occ::handle<Geom_BSplineCurve> aBS = MakeRationalBSpline3D(2.0, 1.5, 3.0);
double aKnotmin = 0.0;
double aKnotmax = 1.0;
@@ -237,9 +237,9 @@ TEST(HermitTest, Solutionbis_DistinctWeights_ReturnsValidKnots)
TEST(HermitTest, Solution3D_Symmetric_WeightsProduceSymmetricResult)
{
// Symmetric weights: w(0) == w(1), so a(0) == a(1)
Handle(Geom_BSplineCurve) aBS = MakeRationalBSpline3D(2.0, 1.0, 2.0);
occ::handle<Geom_BSplineCurve> aBS = MakeRationalBSpline3D(2.0, 1.0, 2.0);
Handle(Geom2d_BSplineCurve) aResult = Hermit::Solution(aBS);
occ::handle<Geom2d_BSplineCurve> aResult = Hermit::Solution(aBS);
ASSERT_FALSE(aResult.IsNull());