Skip to content

Commit

Permalink
Merge pull request #67 from WisdomToNorth/master
Browse files Browse the repository at this point in the history
Fix bug and maintain gtest
  • Loading branch information
jbuckmccready authored Aug 28, 2024
2 parents 4dcfe08 + ff21645 commit 31a0129
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 25 deletions.
10 changes: 7 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ if (NOT DEFINED PROJECT_NAME)
endif()

project(CavalierContours VERSION 0.1)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
enable_language(C)

# Allow super-projects to override options
if (POLICY CMP0077)
Expand All @@ -18,6 +20,10 @@ endif ()
# Build options
option(CAVC_HEADER_ONLY "C++ header only library of CavalierContours, if ON then no library is built" OFF)
option(CAVC_BUILD_SHARED_LIB "Build the C API CavalierContours dynamic shared library (SET OFF for static library)" ON)
if (NOT_SUBPROJECT AND NOT CAVC_HEADER_ONLY)
include(GoogleTest)
enable_testing()
endif()

if(CAVC_HEADER_ONLY)
set(CAVC_CPP_HEADER_ONLY_LIB ${PROJECT_NAME})
Expand Down Expand Up @@ -67,7 +73,5 @@ if (NOT_SUBPROJECT AND NOT CAVC_HEADER_ONLY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
add_subdirectory(examples)
find_package(GTest REQUIRED)
include(GoogleTest)
enable_testing()
add_subdirectory(tests)
endif()
5 changes: 5 additions & 0 deletions include/cavc/polyline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ template <typename Real> AABB<Real> getExtents(Polyline<Real> const &pline) {
Real endAngle = angle(arc.center, v2.pos());
Real sweepAngle = utils::deltaAngle(startAngle, endAngle);

// handle special case of half circle, or more than half circle
if ((sweepAngle > 0.0) && (v1.bulge() < 0.0)) {
sweepAngle = sweepAngle - 2.0 * utils::pi<Real>();
}

Real arcXMin, arcYMin, arcXMax, arcYMax;

// crosses PI/2
Expand Down
1 change: 1 addition & 0 deletions tests/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ macro(cavc_add_test name)
gtest_add_tests(TARGET ${name} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
endmacro()

cavc_add_test(TEST_sample)
cavc_add_test(TEST_cavc_pline)
cavc_add_test(TEST_cavc_pline_function)
cavc_add_test(TEST_cavc_parallel_offset)
Expand Down
51 changes: 31 additions & 20 deletions tests/tests/TEST_cavc_combine_plines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,46 @@ static std::vector<CombinePlinesTestCase> createSimpleCases() {
std::vector<cavc_vertex> plineBVertexes = {{3, -10, 0}, {6, -10, 0}, {6, 10, 0}, {3, 10, 0}};
cavc_pline *plineA = plineFromVertexes(plineAVertexes, true);
cavc_pline *plineB = plineFromVertexes(plineBVertexes, true);
// Union
std::vector<PolylineProperties> expectedRemaining;
expectedRemaining.emplace_back(10, 109.15381629282, 52.324068506275, 0, -10, 10, 10);
std::vector<PolylineProperties> expectedSubtracted;

// Union
expectedRemaining.emplace_back(10, 109.15381629282, 52.324068506275, 0, -10, 10, 10);
cases.emplace_back("circle_rectangle_union", 0, plineA, plineB, expectedRemaining,
expectedSubtracted);

// Exclude
expectedRemaining.clear();
expectedSubtracted.clear();
expectedRemaining.emplace_back(3, 19.816835628274, 20.757946197186, 0, -4, 3, 5.5825756949558);
expectedRemaining.emplace_back(3, 29.336980664548, 23.492343031178, 6, -3.8989794855664, 10, 6);

// Exclude
expectedRemaining.emplace_back(3, 29.336980664548, 23.492343031178, 6, -3.8989794855664, 10,
5.898979485566356);
expectedRemaining.emplace_back(3, 19.816835628274, 20.757946197186, 0, -3.582575694955841, 3,
5.5825756949558);
cases.emplace_back("circle_rectangle_exclude", 1, plineA, plineB, expectedRemaining,
expectedSubtracted);

// Intersect
expectedRemaining.clear();
expectedSubtracted.clear();

// Intersect
expectedRemaining.emplace_back(4, 29.386000046924, 25.091858029623, 3, -4, 6, 6);
cases.emplace_back("circle_rectangle_intersect", 2, plineA, plineB, expectedRemaining,
expectedSubtracted);
expectedRemaining.clear();
expectedSubtracted.clear();

// XOR
expectedRemaining.clear();
expectedRemaining.emplace_back(3, 19.816835628274, 20.757946197186, 0, -4, 3, 5.5825756949558);

expectedRemaining.emplace_back(3, 19.816835628274, 20.757946197186, 0, -3.582575694955841, 3,
5.5825756949558);
expectedRemaining.emplace_back(4, -18.306999976538, 18.582818653767, 3, -10, 6,
-3.5825756949558);
expectedRemaining.emplace_back(3, 29.336980664548, 23.492343031178, 6, -3.8989794855664, 10, 6);
expectedRemaining.emplace_back(3, 29.336980664548, 23.492343031178, 6, -3.8989794855664, 10,
5.898979485566356);
expectedRemaining.emplace_back(4, -12.306999976538, 14.582818653767, 3, 5.5825756949558, 6, 10);
expectedSubtracted.clear();
cases.emplace_back("circle_rectangle_xor", 3, plineA, plineB, expectedRemaining,
expectedSubtracted);
expectedRemaining.clear();
expectedSubtracted.clear();
}

return cases;
Expand All @@ -101,42 +109,44 @@ static std::vector<CombinePlinesTestCase> createCoincidentCases() {
{0.25, 0.295, -0.414214}, {0.255, 0.29, 0}, {0.255, 0.24, -0.414214}, {0.25, 0.235, 0}};
cavc_pline *plineA = plineFromVertexes(plineAVertexes, true);
cavc_pline *plineB = plineFromVertexes(plineBVertexes, true);

// Union
std::vector<PolylineProperties> expectedRemaining;
expectedRemaining.emplace_back(12, -0.032967809756574, 1.6071238962168, -0.255, -0.005, 0.255,
0.295);
std::vector<PolylineProperties> expectedSubtracted;
cases.emplace_back("coincident_case1_union", 0, plineA, plineB, expectedRemaining,
expectedSubtracted);

// Exclude
expectedRemaining.clear();
expectedSubtracted.clear();

// Exclude A from B
expectedRemaining.emplace_back(4, -0.0023892699081699, 0.49570796326795, -0.105, -0.005, -0.095,
0.235);
cases.emplace_back("coincident_case1_excludeAFromB", 1, plineA, plineB, expectedRemaining,
expectedSubtracted);

expectedRemaining.clear();
expectedSubtracted.clear();

// Exclude B from A
expectedRemaining.emplace_back(10, -0.030578539848405, 1.1314159329489, -0.255, 0.235, 0.255,
0.295);
cases.emplace_back("coincident_case1_excludeBFromA", 1, plineB, plineA, expectedRemaining,
expectedSubtracted);

// Intersect
expectedRemaining.clear();
expectedSubtracted.clear();

// Intersect
cases.emplace_back("coincident_case1_intersect", 2, plineA, plineB, expectedRemaining,
expectedSubtracted);
expectedRemaining.clear();
expectedSubtracted.clear();

// XOR
expectedRemaining.clear();
expectedRemaining.emplace_back(4, -0.0023892699081699, 0.49570796326795, -0.105, -0.005, -0.095,
0.235);
expectedRemaining.emplace_back(10, 0.030578539848405, 1.1314159329489, -0.255, 0.235, 0.255,
0.295);
expectedSubtracted.clear();
cases.emplace_back("coincident_case1_xor", 3, plineA, plineB, expectedRemaining,
expectedSubtracted);
}
Expand Down Expand Up @@ -202,7 +212,7 @@ class cavc_combine_plinesTests : public t::TestWithParam<CombinePlinesTestCase>
INSTANTIATE_TEST_SUITE_P(simple_cases, cavc_combine_plinesTests, t::ValuesIn(simpleCases));
INSTANTIATE_TEST_SUITE_P(coincident_cases, cavc_combine_plinesTests, t::ValuesIn(coincidentCases));

TEST_P(cavc_combine_plinesTests, DISABLED_combine_plines_test) {
TEST_P(cavc_combine_plinesTests, combine_plines_test) {
CombinePlinesTestCase const &testCase = GetParam();
cavc_pline_list *remaining = nullptr;
cavc_pline_list *subtracted = nullptr;
Expand All @@ -218,6 +228,7 @@ TEST_P(cavc_combine_plinesTests, DISABLED_combine_plines_test) {
cavc_pline *pline = cavc_pline_list_get(remaining, i);
remainingProperties.emplace_back(pline);
}

ASSERT_THAT(remainingProperties,
t::UnorderedPointwise(EqIgnoreSignOfArea(), testCase.expectedRemaining));

Expand Down
4 changes: 2 additions & 2 deletions tests/tests/TEST_cavc_pline_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ TEST_P(cavc_plineFunctionTests, cavc_get_winding_number) {
ASSERT_THAT(windingNumberResults, t::Pointwise(t::Eq(), testCase.windingNumberResults));
}

TEST_P(cavc_plineFunctionTests, DISABLED_cavc_get_extents) {
TEST_P(cavc_plineFunctionTests, cavc_get_extents) {
cavc_plineFunctionsTestCase const &testCase = GetParam();
if (testCase.skipExtentsTest()) {
GTEST_SKIP();
Expand Down Expand Up @@ -692,7 +692,7 @@ TEST_P(cavc_plineFunctionTests, cavc_parallel_offset) {
}
}

TEST_P(cavc_plineFunctionTests, DISABLED_combine_with_self_invariants) {
TEST_P(cavc_plineFunctionTests, combine_with_self_invariants) {
cavc_plineFunctionsTestCase const &testCase = GetParam();
if (!testCase.isClosed()) {
GTEST_SKIP();
Expand Down
68 changes: 68 additions & 0 deletions tests/tests/TEST_sample.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <gmock/gmock.h>
#include <vector>

#include <gtest/gtest.h>

#include "c_api_include/cavaliercontours.h"
#include "c_api_test_helpers.hpp"
#include "cavc/polyline.hpp"

// Use basic gtest rather than gmock to make debug easier
TEST(basic, basic_extent) {
cavc_real minX;
cavc_real minY;
cavc_real maxX;
cavc_real maxY;
// Quad Circle
std::vector<cavc_vertex> plineAVertexes = {{1.0, 0.00, -0.4142135623730951}, {0.0, -1.0, 0.00}};
cavc_pline *plineA = plineFromVertexes(plineAVertexes, true);
cavc_get_extents(plineA, &minX, &minY, &maxX, &maxY);
EXPECT_NEAR(minX, 0, 1e-15);
EXPECT_NEAR(minY, -1, 1e-15);
EXPECT_NEAR(maxX, 1, 1e-15);
EXPECT_NEAR(maxY, 0, 1e-15);

// Half circle cw
std::vector<cavc_vertex> plineBVertexes = {{1.0, 0.00, -1.00}, {0.0, 0.00, 0.00}};
cavc_pline *plineB1 = plineFromVertexes(plineBVertexes, true);
cavc_get_extents(plineB1, &minX, &minY, &maxX, &maxY);
EXPECT_NEAR(minX, 0, 1e-15);
EXPECT_NEAR(minY, -0.5, 1e-15);
EXPECT_NEAR(maxX, 1, 1e-15);
EXPECT_NEAR(maxY, 0, 1e-15);

// Half circle ccw
plineBVertexes.front().bulge = 1;
cavc_pline *plineB2 = plineFromVertexes(plineBVertexes, true);
cavc_get_extents(plineB2, &minX, &minY, &maxX, &maxY);
EXPECT_NEAR(minX, 0, 1e-15);
EXPECT_NEAR(minY, 0, 1e-15);
EXPECT_NEAR(maxX, 1, 1e-15);
EXPECT_NEAR(maxY, 0.5, 1e-15);

// Half circle ccw
std::vector<cavc_vertex> plineCVertexes = {
{0.0, 0.00, 1.00},
{0.0, 1.00, 0.00},
};
cavc_pline *plineC1 = plineFromVertexes(plineCVertexes, true);
cavc_get_extents(plineC1, &minX, &minY, &maxX, &maxY);
EXPECT_NEAR(minX, 0, 1e-15);
EXPECT_NEAR(minY, 0, 1e-15);
EXPECT_NEAR(maxX, 0.5, 1e-15);
EXPECT_NEAR(maxY, 1, 1e-15);

// Half circle cw
plineCVertexes.front().bulge = -1;
cavc_pline *plineC2 = plineFromVertexes(plineCVertexes, true);
cavc_get_extents(plineC2, &minX, &minY, &maxX, &maxY);
EXPECT_NEAR(minX, -0.5, 1e-15);
EXPECT_NEAR(minY, 0, 1e-15);
EXPECT_NEAR(maxX, 0, 1e-15);
EXPECT_NEAR(maxY, 1, 1e-15);
}

int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
27 changes: 27 additions & 0 deletions tests/tests/testhelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,31 @@ inline std::ostream &operator<<(std::ostream &os, PolylineProperties const &p) {
<< ", maxX: " << p.maxX << ", maxY: " << p.maxY << " }";
return os;
}

// Custom function to print differences
void PrintDiff(const PolylineProperties &expected, const PolylineProperties &actual) {
if (expected.vertexCount != actual.vertexCount) {
std::cout << "vertexCount: expected " << expected.vertexCount << ", actual "
<< actual.vertexCount << "\n";
}
if (!fuzzyEqual(expected.area, actual.area)) {
std::cout << "area: expected " << expected.area << ", actual " << actual.area << "\n";
}
if (!fuzzyEqual(expected.pathLength, actual.pathLength)) {
std::cout << "pathLength: expected " << expected.pathLength << ", actual " << actual.pathLength
<< "\n";
}
if (!fuzzyEqual(expected.minX, actual.minX)) {
std::cout << "minX: expected " << expected.minX << ", actual " << actual.minX << "\n";
}
if (!fuzzyEqual(expected.minY, actual.minY)) {
std::cout << "minY: expected " << expected.minY << ", actual " << actual.minY << "\n";
}
if (!fuzzyEqual(expected.maxX, actual.maxX)) {
std::cout << "maxX: expected " << expected.maxX << ", actual " << actual.maxX << "\n";
}
if (!fuzzyEqual(expected.maxY, actual.maxY)) {
std::cout << "maxY: expected " << expected.maxY << ", actual " << actual.maxY << "\n";
}
}
#endif // CAVC_TESTHELPERS_HPP

0 comments on commit 31a0129

Please sign in to comment.