Compare of Sampling method

This commit is contained in:
Filip Sykala 2021-04-20 08:31:43 +02:00 committed by Lukas Matena
parent 24208b4daa
commit 1c489806ff
8 changed files with 339 additions and 99 deletions

View File

@ -1,5 +1,5 @@
#include "ParabolaUtils.hpp"
#include "PointUtils.hpp"
using namespace Slic3r::sla;
double ParabolaUtils::length(const ParabolaSegment &parabola)
@ -79,6 +79,8 @@ void ParabolaUtils::draw(SVG & svg,
double discretization_step)
{
using VD = Slic3r::Geometry::VoronoiDiagram;
if (PointUtils::is_equal(parabola.from, parabola.to)) return;
std::vector<Voronoi::Internal::point_type> parabola_samples(
{parabola.from, parabola.to});

View File

@ -16,54 +16,61 @@ public:
// factory method to iniciate config
static SampleConfig create(const SupportPointGenerator::Config &config)
{
coord_t head_diameter = scale_(config.head_diameter);
coord_t min_distance = scale_(config.minimal_distance);
coord_t max_distance = 3 * min_distance;
coord_t sample_multiplicator = 10; // allign is made by selecting from samples
// TODO: find valid params !!!!
SampleConfig result;
result.max_distance = 100 * config.head_diameter;
result.max_distance = max_distance / sample_multiplicator;
result.half_distance = result.max_distance / 2;
result.head_radius = config.head_diameter / 2;
result.minimal_distance_from_outline = config.head_diameter / 2.;
result.head_radius = head_diameter / 2;
result.minimal_distance_from_outline = head_diameter / 2.;
result.minimal_support_distance = result.minimal_distance_from_outline +
result.half_distance;
result.max_length_for_one_support_point =
2 * result.minimal_distance_from_outline +
config.head_diameter;
head_diameter;
coord_t max_length_for_one_support_point =
2 * result.max_distance +
config.head_diameter +
2 * max_distance +
head_diameter +
2 * result.minimal_distance_from_outline;
if (result.max_length_for_one_support_point > max_length_for_one_support_point)
result.max_length_for_one_support_point = max_length_for_one_support_point;
coord_t min_length_for_one_support_point =
2 * config.head_diameter +
2 * head_diameter +
2 * result.minimal_distance_from_outline;
if (result.max_length_for_one_support_point < min_length_for_one_support_point)
result.max_length_for_one_support_point = min_length_for_one_support_point;
result.max_length_for_two_support_points =
2 * result.max_distance + 2 * config.head_diameter +
2 * max_distance + 2 * head_diameter +
2 * result.minimal_distance_from_outline;
coord_t max_length_for_two_support_points =
2 * result.max_distance +
2 * config.head_diameter +
2 * max_distance +
2 * head_diameter +
2 * result.minimal_distance_from_outline;
if (result.max_length_for_two_support_points > max_length_for_two_support_points)
result.max_length_for_two_support_points = max_length_for_two_support_points;
assert(result.max_length_for_two_support_points < result.max_length_for_one_support_point);
assert(result.max_length_for_two_support_points > result.max_length_for_one_support_point);
result.max_width_for_center_support_line = 2 * config.head_diameter;
coord_t min_width_for_center_support_line =
config.head_diameter + 2 * result.minimal_distance_from_outline;
result.max_width_for_center_support_line =
2 * head_diameter + 2 * result.minimal_distance_from_outline +
max_distance / 2;
coord_t min_width_for_center_support_line = head_diameter + 2 * result.minimal_distance_from_outline;
if (result.max_width_for_center_support_line < min_width_for_center_support_line)
result.max_width_for_center_support_line = min_width_for_center_support_line;
coord_t max_width_for_center_support_line = 2 * result.max_distance + config.head_diameter;
coord_t max_width_for_center_support_line = 2 * max_distance + head_diameter;
if (result.max_width_for_center_support_line > max_width_for_center_support_line)
result.max_width_for_center_support_line = max_width_for_center_support_line;
result.min_width_for_outline_support = result.max_width_for_center_support_line - 2 * config.head_diameter;
assert(result.min_width_for_outline_support >= result.max_width_for_center_support_line);
result.min_width_for_outline_support = result.max_width_for_center_support_line - 2 * head_diameter;
assert(result.min_width_for_outline_support <= result.max_width_for_center_support_line);
result.outline_sample_distance = result.max_distance;
result.outline_sample_distance = result.max_distance/20;
// Align support points
// TODO: propagate print resolution

View File

@ -16,11 +16,14 @@
#include <libslic3r/ClipperUtils.hpp> // allign
#include "libslic3r/SLA/SupportPointGenerator.hpp"
// comment definition of NDEBUG to enable assert()
//#define NDEBUG
#define SLA_SAMPLING_STORE_FIELD_TO_SVG
#define SLA_SAMPLING_STORE_VORONOI_GRAPH_TO_SVG
//#define SLA_SAMPLING_STORE_VORONOI_GRAPH_TO_SVG
//#define SLA_SAMPLING_STORE_FIELD_TO_SVG
//#define SLA_SAMPLING_STORE_POISSON_SAMPLING_TO_SVG
#include <cassert>
@ -28,6 +31,27 @@ using namespace Slic3r::sla;
std::vector<Slic3r::Vec2f> SampleIslandUtils::sample_expolygon(
const ExPolygon &expoly, float samples_per_mm2)
{
static const float mm2_area = scale_(1) * scale_(1);
// Equilateral triangle area = (side * height) / 2
float triangle_area = mm2_area / samples_per_mm2;
// Triangle area = sqrt(3) / 4 * "triangle side"
static const float coef1 = sqrt(3.) / 4.;
coord_t triangle_side = static_cast<coord_t>(
std::round(sqrt(triangle_area * coef1)));
Points points = sample_expolygon(expoly, triangle_side);
std::vector<Vec2f> result;
result.reserve(points.size());
std::transform(points.begin(), points.end(), std::back_inserter(result),
[](const Point &p) { return unscale(p).cast<float>(); });
return result;
}
Slic3r::Points SampleIslandUtils::sample_expolygon(const ExPolygon &expoly,
coord_t triangle_side)
{
const Points &points = expoly.contour.points;
assert(!points.empty());
@ -41,51 +65,45 @@ std::vector<Slic3r::Vec2f> SampleIslandUtils::sample_expolygon(
max_y = point.y();
}
static const float mm2_area = scale_(1) * scale_(1);
// Equilateral triangle area = (side * height) / 2
float triangle_area = mm2_area / samples_per_mm2;
// Triangle area = sqrt(3) / 4 * "triangle side"
static const float coef1 = sqrt(3.) / 4.;
coord_t triangle_side = static_cast<coord_t>(
std::round(sqrt(triangle_area * coef1)));
coord_t triangle_side_2 = triangle_side / 2;
coord_t triangle_side_2 = triangle_side / 2;
static const float coef2 = sqrt(3.) / 2.;
coord_t triangle_height = static_cast<coord_t>(
std::round(triangle_side * coef2));
coord_t triangle_height = static_cast<coord_t>(std::round(triangle_side * coef2));
// IMPROVE: use line end y
Lines lines = to_lines(expoly);
// remove lines with y direction
// remove lines paralel with axe x
lines.erase(std::remove_if(lines.begin(), lines.end(),
[](const Line &l) {
return l.a.y() == l.b.y();
}),
lines.end());
}), lines.end());
// change line direction from top to bottom
for (Line &line : lines)
if (line.a.y() > line.b.y()) std::swap(line.a, line.b);
// sort by a.y()
std::sort(lines.begin(), lines.end(),
[](const Line &l1, const Line &l2) -> bool {
return l1.a.y() < l2.a.y();
});
std::vector<Vec2f> out;
// size_t count_sample_lines = (max_y - min_y) / triangle_height;
// out.reserve(count_sample_lines * count_sample_lines);
// IMPROVE: guess size and reserve points
Points result;
size_t start_index = 0;
bool is_odd = false;
for (coord_t y = min_y + triangle_height / 2; y < max_y;
y += triangle_height) {
is_odd = !is_odd;
std::vector<coord_t> intersections;
for (auto line = std::begin(lines); line != std::end(lines); ++line) {
bool increase_start_index = true;
for (auto line = std::begin(lines)+start_index; line != std::end(lines); ++line) {
const Point &b = line->b;
if (b.y() <= y) {
// line = lines.erase(line);
// removing lines is slow, start index is faster
// line = lines.erase(line);
if (increase_start_index) ++start_index;
continue;
}
increase_start_index = false;
const Point &a = line->a;
if (a.y() >= y) break;
float y_range = static_cast<float>(b.y() - a.y());
@ -106,12 +124,12 @@ std::vector<Slic3r::Vec2f> SampleIslandUtils::sample_expolygon(
coord_t x = div * triangle_side;
if (is_odd) x -= triangle_side_2;
while (x < end_x) {
out.push_back(unscale(x, y).cast<float>());
result.emplace_back(x, y);
x += triangle_side;
}
}
}
return out;
return result;
}
std::unique_ptr<SupportIslandPoint> SampleIslandUtils::create_point(
@ -224,7 +242,14 @@ SupportIslandPoints SampleIslandUtils::sample_side_branch(
distance -= neighbor->length();
prev_node = node;
}
assert(fabs(distance - (sample_distance - cfg.side_distance)) < 1e-5);
//if (cfg.side_distance > sample_distance) {
// int count = static_cast<int>(std::floor(cfg.side_distance / sample_distance));
// for (int i = 0; i < count; ++i) {
// distance += sample_distance;
// result.pop_back();
// }
//}
//assert(fabs(distance - (sample_distance - cfg.side_distance)) < 1e-5);
result.back()->type = SupportIslandPoint::Type::center_line_end;
return std::move(result);
}
@ -777,8 +802,7 @@ SupportIslandPoints SampleIslandUtils::sample_expath(
center_starts.pop();
for (const CenterStart &start : new_starts) center_starts.push(start);
if (field_start.has_value()){ // exist new field start?
sample_field(field_start.value(), points, center_starts, done, lines, config);
field_start = {};
sample_field(*field_start, points, center_starts, done, lines, config);
}
}
return points;
@ -795,7 +819,23 @@ void SampleIslandUtils::sample_field(VoronoiGraph::Position &field_start,
SupportIslandPoints outline_support = sample_outline(field, config);
points.insert(points.end(), std::move_iterator(outline_support.begin()),
std::move_iterator(outline_support.end()));
// TODO: sample field inside
// Erode island to not sampled island around border,
// minimal value must be -config.minimal_distance_from_outline
Polygons polygons = offset(field.border, -2.f * config.minimal_distance_from_outline,
ClipperLib::jtSquare);
if (polygons.empty()) return;
ExPolygon inner(polygons.front());
for (size_t i = 1; i < polygons.size(); ++i) {
Polygon &hole = polygons[i];
inner.holes.push_back(hole);
}
Points inner_points = sample_expolygon(inner, config.max_distance);
std::transform(inner_points.begin(), inner_points.end(), std::back_inserter(points),
[](const Point &point) {
return std::make_unique<SupportIslandPoint>(
point, SupportIslandPoint::Type::inner);
});
}
std::vector<SampleIslandUtils::CenterStart> SampleIslandUtils::sample_center(
@ -919,6 +959,7 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
// line index, vector<next line index + 2x shortening points>
std::map<size_t, WideTinyChanges> wide_tiny_changes;
coord_t minimal_edge_length = std::max(config.max_distance / 2, 2*config.minimal_distance_from_outline);
// cut lines at place where neighbor has width = min_width_for_outline_support
// neighbor must be in direction from wide part to tiny part of island
auto add_wide_tiny_change =
@ -929,7 +970,7 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
// IMPROVE: check not only one neighbor but all path to edge
coord_t rest_size = static_cast<coord_t>(neighbor->length() * (1. - position.ratio));
if (VoronoiGraphUtils::is_last_neighbor(neighbor) &&
rest_size <= config.max_distance / 2)
rest_size <= minimal_edge_length)
return false; // no change only rich outline
// function to add sorted change from wide to tiny
@ -968,16 +1009,19 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
return true;
};
const VoronoiGraph::Node::Neighbor *neighbor = field_start.neighbor;
const VoronoiGraph::Node::Neighbor *twin_neighbor = VoronoiGraphUtils::get_twin(neighbor);
VoronoiGraph::Position position(twin_neighbor, 1. - field_start.ratio);
add_wide_tiny_change(position, neighbor->node);
const VoronoiGraph::Node::Neighbor *tiny_wide_neighbor = field_start.neighbor;
const VoronoiGraph::Node::Neighbor *wide_tiny_neighbor = VoronoiGraphUtils::get_twin(tiny_wide_neighbor);
VoronoiGraph::Position position(wide_tiny_neighbor, 1. - field_start.ratio);
add_wide_tiny_change(position, tiny_wide_neighbor->node);
std::set<const VoronoiGraph::Node*> done;
done.insert(twin_neighbor->node);
done.insert(wide_tiny_neighbor->node);
// prev node , node
using ProcessItem = std::pair<const VoronoiGraph::Node *, const VoronoiGraph::Node *>;
// initial proccess item from tiny part to wide part of island
ProcessItem start(wide_tiny_neighbor->node, tiny_wide_neighbor->node);
std::queue<ProcessItem> process;
process.push({twin_neighbor->node, neighbor->node});
process.push(start);
// all lines belongs to polygon
std::set<size_t> field_line_indexes;
@ -1051,6 +1095,14 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
}
}
if (no_change) break;
// Field ends with change into first index
if (!is_first && change_item->first == input_index &&
change_index == 0) {
return false;
} else {
is_first = false;
}
}
const WideTinyChange &change = changes[change_index];
// prevent double points
@ -1069,8 +1121,6 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
}
done.insert(index);
index = change.next_line_index;
// end of conture
if (!is_first && index == input_index) return false;
change_item = wide_tiny_changes.find(index);
}
return true;
@ -1080,8 +1130,8 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
points.reserve(field_line_indexes.size());
std::vector<size_t> outline_indexes;
outline_indexes.reserve(field_line_indexes.size());
size_t input_index1 = neighbor->edge->cell()->source_index();
size_t input_index2 = neighbor->edge->twin()->cell()->source_index();
size_t input_index1 = tiny_wide_neighbor->edge->cell()->source_index();
size_t input_index2 = tiny_wide_neighbor->edge->twin()->cell()->source_index();
size_t input_index = std::min(input_index1, input_index2);
size_t outline_index = input_index;
std::set<size_t> done_indexes;
@ -1129,6 +1179,16 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
SupportIslandPoints SampleIslandUtils::sample_outline(
const Field &field, const SampleConfig &config)
{
// TODO: fix it by neighbor line angles
// Do not create inner expoly and test all points to lay inside
Polygons polygons = offset(field.border,-config.minimal_distance_from_outline + 5, ClipperLib::jtSquare);
if (polygons.empty()) return {}; // no place for support point
ExPolygon inner(polygons.front());
for (size_t i = 1; i < polygons.size(); ++i) {
Polygon &hole = polygons[i];
inner.holes.push_back(hole);
}
coord_t sample_distance = config.outline_sample_distance;
coord_t outline_distance = config.minimal_distance_from_outline;
SupportIslandPoints result;
@ -1143,8 +1203,13 @@ SupportIslandPoints SampleIslandUtils::sample_outline(
do {
double ratio = (sample_distance - last_support) / line_length_double;
Point point = line.a + dir * ratio + move_from_outline;
result.emplace_back(std::make_unique<SupportOutlineIslandPoint>(
point, source_index, SupportIslandPoint::Type::outline));
// TODO: improve prevent sampling out of field near sharp corner
// use range for possible ratio
if (inner.contains(point))
result.emplace_back(std::make_unique<SupportOutlineIslandPoint>(
point, source_index, SupportIslandPoint::Type::outline));
last_support -= sample_distance;
} while (last_support + line_length > sample_distance);
}

View File

@ -32,6 +32,14 @@ public:
/// <returns>Samples - 2d unscaled coordinates [in mm]</returns>
static std::vector<Vec2f> sample_expolygon(const ExPolygon &expoly, float samples_per_mm2);
/// <summary>
/// Uniform sample expolygon area by points inside Equilateral triangle center
/// </summary>
/// <param name="expoly">Input area to sample.(scaled)</param>
/// <param name="triangle_side">Distance between samples.</param>
/// <returns>Uniform samples(scaled)</returns>
static Points sample_expolygon(const ExPolygon &expoly, coord_t triangle_side);
/// <summary>
/// Create support point on edge defined by neighbor
/// </summary>

View File

@ -7,6 +7,39 @@ SupportIslandPoint::SupportIslandPoint(Slic3r::Point point, Type type)
: point(std::move(point)), type(type)
{}
bool SupportIslandPoint::can_move(const Type &type)
{
// use shorter list
/*
static const std::set<Type> can_move({
Type::center_line,
Type::center_circle,
Type::center_circle_end,
Type::center_circle_end2,
Type::outline,
Type::inner
});
return can_move.find(type) != can_move.end();
/*/ // switch comment center
static const std::set<Type> cant_move({
Type::one_center_point,
Type::two_points,
Type::center_line_end,
Type::center_line_end2,
Type::center_line_end3,
Type::center_line_start
});
return cant_move.find(type) == cant_move.end();
//*/
}
bool SupportIslandPoint::can_move() const { return can_move(type); }
SupportCenterIslandPoint::SupportCenterIslandPoint(
Point point, VoronoiGraph::Position position, Type type)
: SupportIslandPoint(point, type), position(position)
{}
coord_t SupportIslandPoint::move(const Point &destination)
{
Point diff = destination - point;

View File

@ -11,8 +11,9 @@ namespace Slic3r::sla {
/// <summary>
/// DTO position with information about source of support point
/// </summary>
struct SupportIslandPoint
class SupportIslandPoint
{
public:
enum class Type: unsigned char {
one_center_point,
two_points,
@ -26,41 +27,41 @@ struct SupportIslandPoint
// need allign)
center_circle_end2, // circle finish by multi points (one end per
// circle - need allign)
outline, // keep position align with island outline
inner, // point inside wide part, without restriction on move
undefined
};
Type type;
Slic3r::Point point; // 2 coordinate point in a layer (in one slice)
Type type;
Point point;
//SupportIslandPoint() : point(0, 0), type(Type::undefined) {}
SupportIslandPoint(Slic3r::Point point, Type type = Type::undefined);
public:
/// <summary>
/// constructor
/// </summary>
/// <param name="point">coordinate point inside a layer (in one slice)</param>
/// <param name="type">type of support point</param>
SupportIslandPoint(Point point, Type type = Type::undefined);
/// <summary>
/// virtual destructor to be inheritable
/// </summary>
virtual ~SupportIslandPoint() = default;
static bool can_move(const Type &type)
{
// use shorter list
/*
static const std::set<Type> can_move({
Type::center_line,
Type::center_circle,
Type::center_circle_end,
Type::center_circle_end2});
return can_move.find(type) != can_move.end();
/*/ // switch comment center
static const std::set<Type> cant_move({
Type::one_center_point,
Type::two_points,
Type::center_line_end,
Type::center_line_end2,
Type::center_line_end3,
Type::center_line_start});
return cant_move.find(type) == cant_move.end();
//*/
}
virtual bool can_move() const { return can_move(type); }
/// <summary>
/// static function to decide if type is possible to move or not
/// </summary>
/// <param name="type">type to distinguish</param>
/// <returns>True when is possible to move, otherwise FALSE</returns>
static bool can_move(const Type &type);
/// <summary>
/// static function to decide if type is possible to move or not
/// </summary>
/// <param name="type">type to distinguish</param>
/// <returns>True when is possible to move, otherwise FALSE</returns>
virtual bool can_move() const;
/// <summary>
/// Move position of support point close to destination
@ -74,8 +75,13 @@ struct SupportIslandPoint
using SupportIslandPointPtr = std::unique_ptr<SupportIslandPoint>;
using SupportIslandPoints = std::vector<SupportIslandPointPtr>;
struct SupportCenterIslandPoint : public SupportIslandPoint
/// <summary>
/// DTO Support point laying on voronoi graph edge
/// Restriction to move only on Voronoi graph
/// </summary>
class SupportCenterIslandPoint : public SupportIslandPoint
{
public:
// Define position on voronoi graph
// Lose data when voronoi graph does NOT exist
VoronoiGraph::Position position;
@ -85,20 +91,26 @@ struct SupportCenterIslandPoint : public SupportIslandPoint
// TODO: should earn when created
const double max_distance = 1e6; // [in nm] --> 1 mm
SupportCenterIslandPoint(Slic3r::Point point,
public:
SupportCenterIslandPoint(Point point,
VoronoiGraph::Position position,
Type type = Type::center_line)
: SupportIslandPoint(point, type), position(position)
{}
Type type = Type::center_line);
bool can_move() const override{ return true; }
coord_t move(const Point &destination) override;
};
struct SupportOutlineIslandPoint : public SupportIslandPoint
/// <summary>
/// DTO Support point laying on Outline of island
/// Restriction to move only on outline
/// </summary>
class SupportOutlineIslandPoint : public SupportIslandPoint
{
public:
// index of line form island outline
size_t index;
public:
SupportOutlineIslandPoint(Slic3r::Point point,
size_t index,
Type type = Type::outline)

View File

@ -381,7 +381,7 @@ public:
const Lines & lines);
/// <summary>
/// calculate both point on source lines correspond to edge postion
/// Calculate both point on source lines correspond to edge postion
/// Faster way to get both point_on_line
/// </summary>
/// <param name="position">Position on edge</param>

View File

@ -546,9 +546,16 @@ TEST_CASE("speed sampling", "[SupGen]") {
TEST_CASE("Small islands should be supported in center", "[SupGen][VoronoiSkeleton]")
{
double size = 3e7;
double size = 3e7;
SampleConfig cfg = create_sample_config(size);
ExPolygons islands = createTestIslands(size);
// TODO: remove next 3 lines, debug sharp triangle
auto triangle = PolygonUtils::create_isosceles_triangle(8. * size, 40. * size);
islands = {ExPolygon(triangle)};
auto test_island = create_tiny_wide_test_2(3 * size, 2 / 3. * size);
islands = {test_island};
for (ExPolygon &island : islands) {
size_t debug_index = &island - &islands.front();
auto points = test_island_sampling(island, cfg);
@ -561,3 +568,109 @@ TEST_CASE("Small islands should be supported in center", "[SupGen][VoronoiSkelet
// points should be equal to pointsR
}
}
std::vector<Vec2f> sample_old(const ExPolygon &island)
{
// Create the support point generator
static TriangleMesh mesh;
static sla::IndexedMesh emesh{mesh};
static sla::SupportPointGenerator::Config autogencfg;
//autogencfg.minimal_distance = 8.f;
static sla::SupportPointGenerator generator{emesh, autogencfg, [] {}, [](int) {}};
// tear preasure
float tp = autogencfg.tear_pressure();
size_t layer_id = 13;
coordf_t print_z = 11.f;
SupportPointGenerator::MyLayer layer(layer_id, print_z);
ExPolygon poly = island;
BoundingBox bbox(island);
Vec2f centroid;
float area = island.area();
float h = 17.f;
sla::SupportPointGenerator::Structure s(layer, poly, bbox, centroid,area,h);
auto flag = sla::SupportPointGenerator::IslandCoverageFlags(
sla::SupportPointGenerator::icfIsNew | sla::SupportPointGenerator::icfWithBoundary);
SupportPointGenerator::PointGrid3D grid3d;
generator.uniformly_cover({island}, s, s.area * tp, grid3d, flag);
std::vector<Vec2f> result;
result.reserve(grid3d.grid.size());
for (auto g : grid3d.grid) {
const Vec3f &p = g.second.position;
Vec2f p2f(p.x(), p.y());
result.emplace_back(scale_(p2f));
}
return result;
}
#include <libslic3r/SLA/SupportIslands/SampleConfigFactory.hpp>
std::vector<Vec2f> sample_filip(const ExPolygon &island)
{
static SampleConfig cfg = create_sample_config(1e6);
SupportIslandPoints points = SupportPointGenerator::uniform_cover_island(island, cfg);
std::vector<Vec2f> result;
result.reserve(points.size());
for (auto &p : points) {
result.push_back(p->point.cast<float>());
}
return result;
}
void store_sample(const std::vector<Vec2f> &samples, const ExPolygon& island)
{
static int counter = 0;
BoundingBox bb(island);
SVG svg(("sample_"+std::to_string(counter++)+".svg").c_str(), bb);
double mm = scale_(1);
svg.draw(island, "lightgray");
for (const auto &s : samples) {
svg.draw(s.cast<coord_t>(), "blue", 0.2*mm);
}
// draw resolution
Point p(bb.min.x() + 1e6, bb.max.y() - 2e6);
svg.draw_text(p, (std::to_string(samples.size()) + " samples").c_str(), "black");
svg.draw_text(p - Point(0., 1.8e6), "Scale 1 cm ", "black");
Point start = p - Point(0., 2.3e6);
svg.draw(Line(start + Point(0., 5e5), start + Point(10*mm, 5e5)), "black", 2e5);
svg.draw(Line(start + Point(0., -5e5), start + Point(10*mm, -5e5)), "black", 2e5);
svg.draw(Line(start + Point(10*mm, 5e5), start + Point(10*mm, -5e5)), "black", 2e5);
for (int i=0; i<10;i+=2)
svg.draw(Line(start + Point(i*mm, 0.), start + Point((i+1)*mm, 0.)), "black", 1e6);
}
TEST_CASE("Compare sampling test")
{
enum class Sampling {
old,
filip
} sample_type = Sampling::old;
std::function<std::vector<Vec2f>(const ExPolygon &)> sample =
(sample_type == Sampling::old) ? sample_old :
(sample_type == Sampling::filip) ? sample_filip :
nullptr;
double size1 = 1e6;
double size2 = 3e6;
ExPolygons islands = createTestIslands(1e6);
ExPolygons islands_big = createTestIslands(3e6);
islands.insert(islands.end(), islands_big.begin(), islands_big.end());
islands = {ExPolygon(PolygonUtils::create_rect(size1 / 2, size1))};
for (ExPolygon &island : islands) {
size_t debug_index = &island - &islands.front();
auto samples = sample(island);
store_sample(samples, island);
double angle = 3.14 / 3; // cca 60 degree
island.rotate(angle);
samples = sample(island);
store_sample(samples, island);
}
}