update test

This commit is contained in:
QIDI TECH
2024-11-09 14:59:54 +08:00
parent c9ec3da208
commit cb4f6b9da4
35 changed files with 1372 additions and 6272 deletions

View File

@@ -43,8 +43,8 @@ add_executable(${_TEST_NAME}_tests
test_jump_point_search.cpp
test_support_spots_generator.cpp
test_layer_region.cpp
../data/prusaparts.cpp
../data/prusaparts.hpp
../data/qidiparts.cpp
../data/qidiparts.hpp
test_static_map.cpp
)

View File

@@ -744,6 +744,7 @@ TEST_CASE("Arachne - #10034 - Degenerated Voronoi diagram - That wasn't fixed by
export_perimeters_to_svg(debug_out_path("arachne-degenerated-diagram-10034-rotation-not-works.svg"), polygons, perimeters, union_ex(wall_tool_paths.getInnerContour()));
#endif
}
TEST_CASE("Arachne - SPE-1837 - No perimeters generated", "[ArachneNoPerimetersGeneratedSPE1837]") {
Polygon poly_0 = {
Point( 10000000, 10000000),
@@ -762,4 +763,87 @@ TEST_CASE("Arachne - SPE-1837 - No perimeters generated", "[ArachneNoPerimetersG
std::vector<Arachne::VariableWidthLines> perimeters = wall_tool_paths.getToolPaths();
REQUIRE(!perimeters.empty());
}
}
TEST_CASE("Arachne - SPE-2298 - Missing twin edge", "[ArachneMissingTwinEdgeSPE2298]") {
Polygon poly_0 = {
Point(45275325, -26003582),
Point(46698318, -24091837),
Point(45534079, - 7648226),
Point(44427730, 6913138),
Point(42406709, 31931594),
Point(42041617, 31895427),
Point(42556409, 25628802),
Point(43129149, 18571997),
Point(44061956, 6884616),
Point(44482729, 1466404),
Point(45172290, - 7674740),
Point(46329004, -23890062),
Point(46303776, -23895512),
Point(45146815, - 7676652),
Point(44457276, 1464203),
Point(44036504, 6882422),
Point(43103702, 18569730),
Point(42015592, 31899494),
Point(41650258, 31866937),
Point(44100538, 1436619)
};
Polygons polygons = {poly_0};
coord_t ext_perimeter_spacing = 407079;
coord_t perimeter_spacing = 407079;
coord_t inset_count = 1;
Arachne::WallToolPaths wall_tool_paths(polygons, ext_perimeter_spacing, perimeter_spacing, inset_count, 0, 0.2, PrintObjectConfig::defaults(), PrintConfig::defaults());
wall_tool_paths.generate();
std::vector<Arachne::VariableWidthLines> perimeters = wall_tool_paths.getToolPaths();
REQUIRE(!perimeters.empty());
}
TEST_CASE("Arachne - SPE-2298 - Missing twin edge - 2", "[ArachneMissingTwinEdge2SPE2298]") {
Polygon poly_0 = {
Point(-8908308, -51405945),
Point(-12709229, -51250796),
Point(-12746335, -51233657),
Point(-12830242, -51142897),
Point(-12826443, -51134671),
Point(-13181213, -51120650),
Point(-13184646, -51206854),
Point(-19253324, -50972142),
Point(-19253413, -50972139),
Point(-20427346, -50924668),
Point(-20427431, -50924664),
Point(-25802429, -50698485),
Point(-25802568, -50698481),
Point(-28983179, -50556020),
Point(-28984425, -50555950),
Point(-29799753, -50499586),
Point(-29801136, -50499472),
Point(-29856539, -50494137),
Point(-29857834, -50493996),
Point(-30921022, -50364409),
Point(-30922312, -50364235),
Point(-31012584, -50350908),
Point(-31022222, -50358055),
Point(-31060596, -50368155),
Point(-31429495, -50322406),
Point(-31460950, -50531962),
Point(-31194587, -50578945),
Point(-30054463, -50718244),
Point(-28903516, -50799260),
Point(-14217296, -51420133),
Point(-8916965, -51624212)
};
Polygons polygons = {poly_0};
coord_t ext_perimeter_spacing = 407079;
coord_t perimeter_spacing = 407079;
coord_t inset_count = 1;
Arachne::WallToolPaths wall_tool_paths(polygons, ext_perimeter_spacing, perimeter_spacing, inset_count, 0, 0.2, PrintObjectConfig::defaults(), PrintConfig::defaults());
wall_tool_paths.generate();
std::vector<Arachne::VariableWidthLines> perimeters = wall_tool_paths.getToolPaths();
REQUIRE(!perimeters.empty());
}

View File

@@ -2,8 +2,8 @@
#include "libslic3r/Config.hpp"
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/LocalesUtils.hpp"
#include <LocalesUtils.hpp>
#include <cereal/types/polymorphic.hpp>
#include <cereal/types/string.hpp>
#include <cereal/types/vector.hpp>
@@ -247,6 +247,7 @@ TEST_CASE("Config serialization of multiple values", "[Config]"){
CHECK(config.option<ConfigOptionStrings>("filament_notes")->values == data.values);
}
}
SCENARIO("Generic config validation performs as expected.", "[Config]") {
GIVEN("A config generated from default options") {
Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config();

View File

@@ -101,7 +101,8 @@ std::string get_font_filepath() {
return resource_dir + "fonts/NotoSans-Regular.ttf";
}
#include "imgui/imstb_truetype.h"
// Explicit horror include (used to be implicit) - libslic3r "officialy" does not depend on imgui.
#include "../../bundled_deps/imgui/imgui/imstb_truetype.h" // stbtt_fontinfo
TEST_CASE("Read glyph C shape from font, stb library calls ONLY", "[Emboss]") {
std::string font_path = get_font_filepath();
char letter = 'C';
@@ -262,6 +263,7 @@ TEST_CASE("Heal of 'i' in ALIENATO.TTF", "[Emboss]")
auto a = heal_and_check(polygons);
Polygons scaled_shape = polygons; // copy
double text_shape_scale = 0.001; // Emboss.cpp --> SHAPE_SCALE
scale(scaled_shape, 1 / text_shape_scale);
auto b = heal_and_check(scaled_shape);
@@ -310,6 +312,7 @@ TEST_CASE("Heal of overlaping contour", "[Emboss]"){
ExPolygons shapes = {ExPolygon{contour}};
CHECK(Emboss::heal_expolygons(shapes));
}
TEST_CASE("Heal of points close to line", "[Emboss]")
{
std::string file_name = "points_close_to_line.svg";
@@ -530,10 +533,10 @@ TEST_CASE("UndoRedo TextConfiguration serialization", "[Emboss]")
TextConfiguration tc;
tc.text = "Dovede-li se člověk zasmát sám sobě, nevyjde ze smíchu po celý život.";
EmbossStyle& es = tc.style;
es.name = "Seneca";
es.path = "Simply the best";
es.type = EmbossStyle::Type::file_path;
FontProp &fp = es.prop;
es.name = "Seneca";
es.path = "Simply the best";
es.type = EmbossStyle::Type::file_path;
FontProp &fp = es.prop;
fp.char_gap = 3;
fp.line_gap = 7;
fp.boldness = 2.3f;
@@ -543,8 +546,7 @@ TEST_CASE("UndoRedo TextConfiguration serialization", "[Emboss]")
std::stringstream ss; // any stream can be used
{
cereal::BinaryOutputArchive oarchive(ss); // Create an output archive
cereal::BinaryOutputArchive oarchive(ss); // Create an output archive
oarchive(tc);
} // archive goes out of scope, ensuring all contents are flushed

View File

@@ -12,7 +12,6 @@
#include "libslic3r/ShortestPath.hpp"
//#include <random>
//#include "libnest2d/tools/benchmark.h"
#include "libslic3r/SVG.hpp"
#include "../data/qidiparts.hpp"
@@ -230,6 +229,7 @@ SCENARIO("Circle Fit, 3 points", "[Geometry]") {
}
}
}
SCENARIO("Circle Fit, TaubinFit with Newton's method", "[Geometry]") {
GIVEN("A vector of Vec2ds arranged in a half-circle with approximately the same distance R from some point") {
Vec2d expected_center(-6, 0);
@@ -369,6 +369,7 @@ SCENARIO("Circle Fit, least squares by decomposition or by solving normal equati
}
}
}
TEST_CASE("smallest_enclosing_circle_welzl", "[Geometry]") {
// Some random points in plane.
Points pts {

View File

@@ -75,26 +75,13 @@ struct LayerRegionFixture {
TEST_CASE_METHOD(LayerRegionFixture, "test the surface expansion", "[LayerRegion]") {
const double custom_angle{1.234f};
// w36
/* const Surfaces result{expand_merge_surfaces(
const Surfaces result{expand_merge_surfaces(
surfaces, stBottomBridge,
expansion_zones,
closing_radius,
custom_angle
)};*/
// w36
const Surfaces result{expand_merge_surfaces(
surfaces, stBottomBridge,
shells,
expansion_params_into_solid_infill,
sparse,
expansion_params_into_sparse_infill,
closing_radius
)};
if constexpr (export_svgs) {
SVG svg("general_expansion.svg", BoundingBox{
Point{scaled(-3.0), scaled(-1.0)},
@@ -125,13 +112,9 @@ TEST_CASE_METHOD(LayerRegionFixture, "test the surface expansion", "[LayerRegion
}
TEST_CASE_METHOD(LayerRegionFixture, "test the bridge expansion with the bridge angle detection", "[LayerRegion]") {
// w36
Surfaces result{expand_bridges_detect_orientations(
surfaces,
shells,
expansion_params_into_solid_infill,
sparse,
expansion_params_into_sparse_infill,
expansion_zones,
closing_radius
)};
@@ -148,7 +131,7 @@ TEST_CASE_METHOD(LayerRegionFixture, "test the bridge expansion with the bridge
}
REQUIRE(result.size() == 2);
CHECK(result.at(0).bridge_angle == Approx(1.5707963268));
CHECK(std::fmod(result.at(1).bridge_angle, M_PI) == Approx(0.0));
CHECK(std::fmod(result.at(1).bridge_angle, M_PI) == Approx(0.0));
CHECK(result.at(0).expolygon.contour.size() == 22);
CHECK(result.at(1).expolygon.contour.size() == 14);

View File

@@ -72,6 +72,7 @@ TEST_CASE_METHOD(PolylineTestCase, "Split at first point", "[Polyline]") {
CHECK(p1.size() == 1);
CHECK(p2.size() == 4);
}
SCENARIO("Simplify polyne, template", "[Polyline]")
{
Points polyline{ {0,0}, {1000,0}, {2000,0}, {2000,1000}, {2000,2000}, {1000,2000}, {0,2000}, {0,1000}, {0,0} };
@@ -90,6 +91,7 @@ SCENARIO("Simplify polyne, template", "[Polyline]")
}
}
}
SCENARIO("Simplify polyline", "[Polyline]")
{
GIVEN("polyline 1") {
@@ -110,6 +112,7 @@ SCENARIO("Simplify polyline", "[Polyline]")
}
}
}
GIVEN("polyline 3") {
auto polyline = Polyline{ {0,0}, {100,0}, {50,10} };
WHEN("simplified with Douglas-Peucker") {

View File

@@ -1,4 +1,5 @@
#include <catch2/catch.hpp>
#include <igl/qslim.h>
#include <test_utils.hpp>
#include <libslic3r/QuadricEdgeCollapse.hpp>
@@ -239,7 +240,6 @@ TEST_CASE("Simplify frog_legs.obj to 5% by Quadric edge collapse", "[its][quadri
Private::is_better_similarity(mesh.its, its, Private::frog_leg_5);
}
#include <libigl/igl/qslim.h>
TEST_CASE("Simplify frog_legs.obj to 5% by IGL/qslim", "[]")
{
std::string obj_filename = "frog_legs.obj";

View File

@@ -5,16 +5,15 @@
using namespace Slic3r;
using namespace SupportSpotsGenerator;
namespace Rectangle {
const float width = 10;
const float height = 20;
const Polygon polygon = {
scaled(Vec2f{-width / 2, -height / 2}),
scaled(Vec2f{width / 2, -height / 2}),
scaled(Vec2f{width / 2, height / 2}),
scaled(Vec2f{-width / 2, height / 2})
};
const float width = 10;
const float height = 20;
const Polygon polygon = {
scaled(Vec2f{-width / 2, -height / 2}),
scaled(Vec2f{width / 2, -height / 2}),
scaled(Vec2f{width / 2, height / 2}),
scaled(Vec2f{-width / 2, height / 2})
};
}
TEST_CASE("Numerical integral over polygon calculation compared with exact solution.", "[SupportSpotsGenerator]") {
@@ -77,7 +76,6 @@ TEST_CASE("Moment values and ratio check.", "[SupportSpotsGenerator]") {
}
TEST_CASE("Moments calculation for rotated axis.", "[SupportSpotsGenerator]") {
Polygon polygon = {
scaled(Vec2f{6.362284076172198, 138.9674202217155}),
scaled(Vec2f{97.48779843751677, 106.08136606617076}),

View File

@@ -1,21 +1,17 @@
#include <catch2/catch.hpp>
#include <test_utils.hpp>
#include <libslic3r/Polygon.hpp>
#include <libslic3r/Polyline.hpp>
#include <libslic3r/EdgeGrid.hpp>
#include <libslic3r/Geometry.hpp>
#include "libslic3r/Geometry/VoronoiUtilsCgal.hpp"
#include <libslic3r/Geometry/VoronoiOffset.hpp>
#include <libslic3r/Geometry/VoronoiVisualUtils.hpp>
#include <numeric>
// #define VORONOI_DEBUG_OUT
//#define VORONOI_DEBUG_OUT
#ifdef VORONOI_DEBUG_OUT
#include <libslic3r/VoronoiVisualUtils.hpp>
#include <libslic3r/Geometry/VoronoiVisualUtils.hpp>
#include <libslic3r/Utils.hpp>
#endif
using boost::polygon::voronoi_builder;
@@ -340,7 +336,7 @@ TEST_CASE("Voronoi division by zero 12903", "[Voronoi]")
// Funny sample from a dental industry?
// Vojtech confirms this test fails and rightly so, because the input data contain self intersections.
// This test is suppressed.
TEST_CASE("Voronoi NaN coordinates 12139", "[Voronoi][!hide][!mayfail]")
TEST_CASE("Voronoi NaN coordinates 12139", "[Voronoi]")
{
Lines lines = {
{ { 260500,1564400 }, { 261040,1562960 } },
@@ -1924,23 +1920,6 @@ TEST_CASE("Voronoi skeleton", "[VoronoiSkeleton]")
REQUIRE(! skeleton_edges.empty());
}
// Simple detection with complexity N^2 if there is any point in the input polygons that doesn't have Voronoi vertex.
[[maybe_unused]] static bool has_missing_voronoi_vertices(const Polygons &polygons, const VD &vd)
{
auto are_equal = [](const VD::vertex_type v, const Point &p) { return (Vec2d(v.x(), v.y()) - p.cast<double>()).norm() <= SCALED_EPSILON; };
Points poly_points = to_points(polygons);
std::vector<bool> found_vertices(poly_points.size());
for (const Point &point : poly_points)
for (const auto &vertex : vd.vertices())
if (are_equal(vertex, point)) {
found_vertices[&point - &poly_points.front()] = true;
break;
}
return std::find(found_vertices.begin(), found_vertices.end(), false) != found_vertices.end();
}
// This case is composed of one square polygon, and one of the edges is divided into two parts by a point that lies on this edge.
// In some applications, this point is unnecessary and can be removed (merge two parts to one edge). But for the case of
// multi-material segmentation, these points are necessary. In this case, Voronoi vertex for the point, which divides the edge
@@ -1955,12 +1934,9 @@ TEST_CASE("Voronoi missing vertex 1", "[VoronoiMissingVertex1]")
{-25000000, 25000000},
{-25000000, -25000000},
{-12412500, -25000000},
// {- 1650000, -25000000},
{ 25000000, -25000000}
};
// poly.rotate(PI / 6);
REQUIRE(poly.area() > 0.);
REQUIRE(intersecting_edges({poly}).empty());
@@ -1971,7 +1947,7 @@ TEST_CASE("Voronoi missing vertex 1", "[VoronoiMissingVertex1]")
dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex1-out.svg").c_str(), vd, Points(), lines);
#endif
// REQUIRE(!has_missing_voronoi_vertices({poly}, vd));
REQUIRE(vd.is_valid());
}
// This case is composed of two square polygons (contour and hole), and again one of the edges is divided into two parts by a
@@ -1998,8 +1974,6 @@ TEST_CASE("Voronoi missing vertex 2", "[VoronoiMissingVertex2]")
}
};
// polygons_rotate(poly, PI / 6);
double area = std::accumulate(poly.begin(), poly.end(), 0., [](double a, auto &poly) { return a + poly.area(); });
REQUIRE(area > 0.);
REQUIRE(intersecting_edges(poly).empty());
@@ -2011,7 +1985,7 @@ TEST_CASE("Voronoi missing vertex 2", "[VoronoiMissingVertex2]")
dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex2-out.svg").c_str(), vd, Points(), lines);
#endif
// REQUIRE(!has_missing_voronoi_vertices(poly, vd));
REQUIRE(vd.is_valid());
}
// This case is composed of two polygons, and again one of the edges is divided into two parts by a point that lies on this edge,
@@ -2042,9 +2016,6 @@ TEST_CASE("Voronoi missing vertex 3", "[VoronoiMissingVertex3]")
REQUIRE(area > 0.);
REQUIRE(intersecting_edges(poly).empty());
// polygons_rotate(poly, PI/180);
// polygons_rotate(poly, PI/6);
VD vd;
Lines lines = to_lines(poly);
vd.construct_voronoi(lines.begin(), lines.end());
@@ -2052,7 +2023,7 @@ TEST_CASE("Voronoi missing vertex 3", "[VoronoiMissingVertex3]")
dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex3-out.svg").c_str(), vd, Points(), lines);
#endif
// REQUIRE(!has_missing_voronoi_vertices(poly, vd));
REQUIRE(vd.is_valid());
}
TEST_CASE("Voronoi missing vertex 4", "[VoronoiMissingVertex4]")
@@ -2097,6 +2068,9 @@ TEST_CASE("Voronoi missing vertex 4", "[VoronoiMissingVertex4]")
dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex4-1-out.svg").c_str(), vd_1, Points(), lines_1);
dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex4-2-out.svg").c_str(), vd_2, Points(), lines_2);
#endif
REQUIRE(vd_1.is_valid());
REQUIRE(vd_2.is_valid());
}
// In this case, the Voronoi vertex (146873, -146873) is included twice.
@@ -2117,8 +2091,6 @@ TEST_CASE("Duplicate Voronoi vertices", "[Voronoi]")
{ 25000000, 10790627},
};
// poly.rotate(PI / 6);
REQUIRE(poly.area() > 0.);
REQUIRE(intersecting_edges({poly}).empty());
@@ -2129,16 +2101,7 @@ TEST_CASE("Duplicate Voronoi vertices", "[Voronoi]")
dump_voronoi_to_svg(debug_out_path("voronoi-duplicate-vertices-out.svg").c_str(), vd, Points(), lines);
#endif
[[maybe_unused]] auto has_duplicate_vertices = [](const VD &vd) -> bool {
std::vector<Vec2d> vertices;
for (const auto &vertex : vd.vertices())
vertices.emplace_back(Vec2d(vertex.x(), vertex.y()));
std::sort(vertices.begin(), vertices.end(), [](const Vec2d &l, const Vec2d &r) { return l.x() < r.x() || (l.x() == r.x() && l.y() < r.y()); });
return std::unique(vertices.begin(), vertices.end()) != vertices.end();
};
// REQUIRE(!has_duplicate_vertices(vd));
REQUIRE(vd.is_valid());
}
// In this case, there are three very close Voronoi vertices like in the previous test case after rotation. There is also one
@@ -2157,8 +2120,6 @@ TEST_CASE("Intersecting Voronoi edges", "[Voronoi]")
{ 25000000, - 146873},
};
// poly.rotate(PI / 6);
REQUIRE(poly.area() > 0.);
REQUIRE(intersecting_edges({poly}).empty());
@@ -2169,38 +2130,7 @@ TEST_CASE("Intersecting Voronoi edges", "[Voronoi]")
dump_voronoi_to_svg(debug_out_path("voronoi-intersecting-edges-out.svg").c_str(), vd, Points(), lines);
#endif
[[maybe_unused]] auto has_intersecting_edges = [](const Polygon &poly, const VD &vd) -> bool {
BoundingBox bbox = get_extents(poly);
const double bbox_dim_max = double(std::max(bbox.size().x(), bbox.size().y()));
std::vector<Voronoi::Internal::segment_type> segments;
for (const Line &line : to_lines(poly))
segments.emplace_back(Voronoi::Internal::point_type(double(line.a.x()), double(line.a.y())),
Voronoi::Internal::point_type(double(line.b.x()), double(line.b.y())));
Lines edges;
for (const auto &edge : vd.edges())
if (edge.cell()->source_index() < edge.twin()->cell()->source_index()) {
if (edge.is_finite()) {
edges.emplace_back(Point(coord_t(edge.vertex0()->x()), coord_t(edge.vertex0()->y())),
Point(coord_t(edge.vertex1()->x()), coord_t(edge.vertex1()->y())));
} else if (edge.is_infinite()) {
std::vector<Voronoi::Internal::point_type> samples;
Voronoi::Internal::clip_infinite_edge(poly.points, segments, edge, bbox_dim_max, &samples);
if (!samples.empty())
edges.emplace_back(Point(coord_t(samples[0].x()), coord_t(samples[0].y())), Point(coord_t(samples[1].x()), coord_t(samples[1].y())));
}
}
Point intersect_point;
for (auto first_it = edges.begin(); first_it != edges.end(); ++first_it)
for (auto second_it = first_it + 1; second_it != edges.end(); ++second_it)
if (first_it->intersection(*second_it, &intersect_point) && first_it->a != intersect_point && first_it->b != intersect_point)
return true;
return false;
};
// REQUIRE(!has_intersecting_edges(poly, vd));
REQUIRE(vd.is_valid());
}
// In this case resulting Voronoi diagram is not planar. This case was distilled from GH issue #8474.
@@ -2219,8 +2149,6 @@ TEST_CASE("Non-planar voronoi diagram", "[VoronoiNonPlanar]")
{ 5500000, 40000000},
};
// poly.rotate(PI / 6);
REQUIRE(poly.area() > 0.);
REQUIRE(intersecting_edges({poly}).empty());
@@ -2231,7 +2159,7 @@ TEST_CASE("Non-planar voronoi diagram", "[VoronoiNonPlanar]")
dump_voronoi_to_svg(debug_out_path("voronoi-non-planar-out.svg").c_str(), vd, Points(), lines);
#endif
// REQUIRE(Geometry::VoronoiUtilsCgal::is_voronoi_diagram_planar_intersection(vd));
REQUIRE(vd.is_valid());
}
// This case is extracted from SPE-1729, where several ExPolygon with very thin lines
@@ -2288,4 +2216,69 @@ TEST_CASE("Invalid Voronoi diagram - Thin lines - SPE-1729", "[InvalidVoronoiDia
#endif
// REQUIRE(vd.is_valid());
}
}
TEST_CASE("Voronoi cell doesn't contain a source point - SPE-2298", "[VoronoiCellSourcePointSPE2298]")
{
Polygon polygon = {
{ 9854534, -39739718}, {- 4154002, -34864557}, {-13073118, -31802214},
{-21265508, -29026626}, {-31388055, -25645073}, {-32409943, -25279942},
{-33418087, -24864987}, {-34400568, -24404312}, {-35354754, -23899358},
{-36278795, -23351325}, {-37170015, -22762146}, {-38025776, -22134628},
{-38845825, -21468175}, {-39627905, -20764801}, {-40370549, -20026061},
{-41072075, -19253859}, {-41731000, -18450032}, {-42345940, -17616466},
{-42915530, -16755283}, {-43438684, -15868338}, {-43914245, -14957822},
{-44341235, -14025879}, {-44718686, -13074712}, {-45045890, -12106566},
{-45322386, -11123499}, {-45547674, -10127656}, {-45721021, - 9121581},
{-45842174, - 8107658}, {-45910990, - 7088089}, {-45927405, - 6065217},
{-45891432, - 5041288}, {-45803222, - 4018728}, {-45663042, - 2999801},
{-45471245, - 1986784}, {-45230690, - 991761}, {-38655400, 23513180},
{-38366034, 24494742}, {-38025334, 25467666}, {-37636844, 26420074},
{-37200678, 27349843}, {-36718169, 28254419}, {-36191104, 29131704},
{-35620587, 29979748}, {-35007621, 30796895}, {-34353751, 31580950},
{-33660293, 32330182}, {-32928806, 33042775}, {-32160862, 33717057},
{-31358104, 34351432}, {-30522331, 34944323}, {-29655434, 35494277},
{-28759338, 35999922}, {-27835963, 36460011}, {-26921721, 36858494},
{-25914008, 37239556}, {-24919466, 37557049}, {-24204878, 37746930},
{-22880526, 38041931}, {-21833362, 38209050}, {-21449204, 38252031},
{-20775657, 38324377}, {-19711119, 38387480}, {-18638667, 38398812},
{-17762260, 38366962}, {-16480321, 38266321}, {-15396213, 38120856},
{-14327987, 37925343}, {- 5801522, 36175494}, { 7791637, 33457589},
{ 15887399, 31878986}, { 28428609, 29478881}, { 28438392, 29512722},
{ 27850323, 29743358}, { 27058729, 29970066}, { 14135560, 32452875},
{ 6101685, 34019760}, {- 5352362, 36305237}, {-14423391, 38160442},
{-15528705, 38361745}, {-16625379, 38507834}, {-17721787, 38600631},
{-18812787, 38641330}, {-19563804, 38633844}, {-20975692, 38563412},
{-22036069, 38446419}, {-23087710, 38277136}, {-24123993, 38056689},
{-25141240, 37786307}, {-26138324, 37466465}, {-26851801, 37197652},
{-28067514, 36680229}, {-28988984, 36219404}, {-29886302, 35711371},
{-30754551, 35158840}, {-31124518, 34896643}, {-31589528, 34564743},
{-32392776, 33928220}, {-33161225, 33251721}, {-33454722, 32966117},
{-33891684, 32538320}, {-34585318, 31787066}, {-35239508, 31000793},
{-35527715, 30616853}, {-35851756, 30182731}, {-36422833, 29331982},
{-36950377, 28452000}, {-37265788, 27860633}, {-37432874, 27545549},
{-37870512, 26612217}, {-38261423, 25655915}, {-38581885, 24744387},
{-38902507, 23671594}, {-45523689, - 1006672}, {-45770290, - 2026713},
{-45963584, - 3043930}, {-46104330, - 4066310}, {-46192377, - 5092635},
{-46228310, - 6120019}, {-46211987, - 7145807}, {-46143426, - 8167812},
{-46022719, - 9183674}, {-45850055, -10191399}, {-45625772, -11188531},
{-45350245, -12172975}, {-45023965, -13142600}, {-44647538, -14095222},
{-44221691, -15028602}, {-43747176, -15940794}, {-43224933, -16829570},
{-42655872, -17693052}, {-42041183, -18529065}, {-41381752, -19335983},
{-40677899, -20112975}, {-39932077, -20856972}, {-39145730, -21566171},
{-38320552, -22238686}, {-37458030, -22872953}, {-36560036, -23467217},
{-35627745, -24020614}, {-34662272, -24532977}, {-33667551, -25000722},
{-32645434, -25422669}, {-31588226, -25801077}, {-24380013, -28208306},
{-24380013, -28208306}, {-13354262, -31942517}, {-13354261, -31942515},
{-2032305, -35842454}, { 8025116, -39348505}, { 8820397, -39587703},
{ 9636283, -39751794}, { 9847092, -39773278}};
VD vd;
Lines lines = to_lines(polygon);
vd.construct_voronoi(lines.begin(), lines.end());
#ifdef VORONOI_DEBUG_OUT
// dump_voronoi_to_svg(debug_out_path("voronoi-cell-source-point-spe2298.svg").c_str(), vd, Points(), lines);
#endif
REQUIRE(vd.is_valid());
}