Merge branch 'master' into fs_emboss
# Conflicts: # src/libslic3r/Technologies.hpp # src/slic3r/GUI/GLCanvas3D.cpp # src/slic3r/GUI/GUI_App.cpp
This commit is contained in:
commit
37961c36e8
38 changed files with 6137 additions and 5655 deletions
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <libslic3r/TriangleMesh.hpp>
|
||||
#include <libslic3r/AABBTreeIndirect.hpp>
|
||||
#include <libslic3r/AABBTreeLines.hpp>
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
|
@ -58,3 +59,287 @@ TEST_CASE("Building a tree over a box, ray caster and closest query", "[AABBIndi
|
|||
REQUIRE(closest_point.y() == Approx(0.5));
|
||||
REQUIRE(closest_point.z() == Approx(1.));
|
||||
}
|
||||
|
||||
TEST_CASE("Creating a several 2d lines, testing closest point query", "[AABBIndirect]")
|
||||
{
|
||||
std::vector<Linef> lines { };
|
||||
lines.push_back(Linef(Vec2d(0.0, 0.0), Vec2d(1.0, 0.0)));
|
||||
lines.push_back(Linef(Vec2d(1.0, 0.0), Vec2d(1.0, 1.0)));
|
||||
lines.push_back(Linef(Vec2d(1.0, 1.0), Vec2d(0.0, 1.0)));
|
||||
lines.push_back(Linef(Vec2d(0.0, 1.0), Vec2d(0.0, 0.0)));
|
||||
|
||||
auto tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(lines);
|
||||
|
||||
size_t hit_idx_out;
|
||||
Vec2d hit_point_out;
|
||||
auto sqr_dist = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, Vec2d(0.0, 0.0), hit_idx_out,
|
||||
hit_point_out);
|
||||
REQUIRE(sqr_dist == Approx(0.0));
|
||||
REQUIRE((hit_idx_out == 0 || hit_idx_out == 3));
|
||||
REQUIRE(hit_point_out.x() == Approx(0.0));
|
||||
REQUIRE(hit_point_out.y() == Approx(0.0));
|
||||
|
||||
sqr_dist = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, Vec2d(1.5, 0.5), hit_idx_out,
|
||||
hit_point_out);
|
||||
REQUIRE(sqr_dist == Approx(0.25));
|
||||
REQUIRE(hit_idx_out == 1);
|
||||
REQUIRE(hit_point_out.x() == Approx(1.0));
|
||||
REQUIRE(hit_point_out.y() == Approx(0.5));
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include "libslic3r/EdgeGrid.hpp"
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include <ratio>
|
||||
#include <chrono>
|
||||
TEST_CASE("AABBTreeLines vs SignedDistanceGrid time Benchmark", "[AABBIndirect]")
|
||||
{
|
||||
std::vector<Points> lines { Points { } };
|
||||
std::vector<Linef> linesf { };
|
||||
Vec2d prevf { };
|
||||
|
||||
// NOTE: max coord value of the lines is approx 83 mm
|
||||
for (int r = 1; r < 1000; ++r) {
|
||||
lines[0].push_back(Point::new_scale(Vec2d(exp(0.005f * r) * cos(r), exp(0.005f * r) * cos(r))));
|
||||
linesf.emplace_back(prevf, Vec2d(exp(0.005f * r) * cos(r), exp(0.005f * r) * cos(r)));
|
||||
prevf = linesf.back().b;
|
||||
}
|
||||
|
||||
int build_num = 10000;
|
||||
using namespace std::chrono;
|
||||
{
|
||||
std::cout << "building the tree " << build_num << " times..." << std::endl;
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
for (int i = 0; i < build_num; ++i) {
|
||||
volatile auto tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(linesf);
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
std::cout << "It took " << time_span.count() << " seconds." << std::endl << std::endl;
|
||||
|
||||
}
|
||||
{
|
||||
std::cout << "building the grid res 1mm ONLY " << build_num/100 << " !!! times..." << std::endl;
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
for (int i = 0; i < build_num/100; ++i) {
|
||||
EdgeGrid::Grid grid { };
|
||||
grid.create(lines, scaled(1.0), true);
|
||||
grid.calculate_sdf();
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
std::cout << "It took " << time_span.count() << " seconds." << std::endl << std::endl;
|
||||
}
|
||||
{
|
||||
std::cout << "building the grid res 10mm " << build_num << " times..." << std::endl;
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
for (int i = 0; i < build_num; ++i) {
|
||||
EdgeGrid::Grid grid { };
|
||||
grid.create(lines, scaled(10.0), true);
|
||||
grid.calculate_sdf();
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
std::cout << "It took " << time_span.count() << " seconds." << std::endl << std::endl;
|
||||
}
|
||||
|
||||
EdgeGrid::Grid grid10 { };
|
||||
grid10.create(lines, scaled(10.0), true);
|
||||
coord_t query10_res = scaled(10.0);
|
||||
grid10.calculate_sdf();
|
||||
|
||||
EdgeGrid::Grid grid1 { };
|
||||
grid1.create(lines, scaled(1.0), true);
|
||||
coord_t query1_res = scaled(1.0);
|
||||
grid1.calculate_sdf();
|
||||
|
||||
auto tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(linesf);
|
||||
|
||||
int query_num = 10000;
|
||||
Points query_points { };
|
||||
std::vector<Vec2d> query_pointsf { };
|
||||
for (int x = 0; x < query_num; ++x) {
|
||||
Vec2d qp { rand() / (double(RAND_MAX) + 1.0f) * 200.0 - 100.0, rand() / (double(RAND_MAX) + 1.0f) * 200.0
|
||||
- 100.0 };
|
||||
query_pointsf.push_back(qp);
|
||||
query_points.push_back(Point::new_scale(qp));
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "querying tree " << query_num << " times..." << std::endl;
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
for (const Vec2d &qp : query_pointsf) {
|
||||
size_t hit_idx_out;
|
||||
Vec2d hit_point_out;
|
||||
AABBTreeLines::squared_distance_to_indexed_lines(linesf, tree, qp, hit_idx_out, hit_point_out);
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
std::cout << "It took " << time_span.count() << " seconds." << std::endl << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "querying grid res 1mm " << query_num << " times..." << std::endl;
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
for (const Point &qp : query_points) {
|
||||
volatile auto dist = grid1.closest_point_signed_distance(qp, query1_res);
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
std::cout << "It took " << time_span.count() << " seconds." << std::endl << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "querying grid res 10mm " << query_num << " times..." << std::endl;
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
for (const Point &qp : query_points) {
|
||||
volatile auto dist = grid10.closest_point_signed_distance(qp, query10_res);
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
std::cout << "It took " << time_span.count() << " seconds." << std::endl << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "Test build and queries together - same number of contour points and query points" << std::endl << std::endl;
|
||||
|
||||
std::vector<int> point_counts { 100, 300, 500, 1000, 3000 };
|
||||
for (auto count : point_counts) {
|
||||
|
||||
std::vector<Points> lines { Points { } };
|
||||
std::vector<Linef> linesf { };
|
||||
Vec2d prevf { };
|
||||
Points query_points { };
|
||||
std::vector<Vec2d> query_pointsf { };
|
||||
|
||||
for (int x = 0; x < count; ++x) {
|
||||
Vec2d cp { rand() / (double(RAND_MAX) + 1.0f) * 200.0 - 100.0, rand() / (double(RAND_MAX) + 1.0f) * 200.0
|
||||
- 100.0 };
|
||||
lines[0].push_back(Point::new_scale(cp));
|
||||
linesf.emplace_back(prevf, cp);
|
||||
prevf = linesf.back().b;
|
||||
|
||||
Vec2d qp { rand() / (double(RAND_MAX) + 1.0f) * 200.0 - 100.0, rand() / (double(RAND_MAX) + 1.0f) * 200.0
|
||||
- 100.0 };
|
||||
query_pointsf.push_back(qp);
|
||||
query_points.push_back(Point::new_scale(qp));
|
||||
}
|
||||
|
||||
std::cout << "Test for point count: " << count << std::endl;
|
||||
{
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
auto tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(linesf);
|
||||
for (const Vec2d &qp : query_pointsf) {
|
||||
size_t hit_idx_out;
|
||||
Vec2d hit_point_out;
|
||||
AABBTreeLines::squared_distance_to_indexed_lines(linesf, tree, qp, hit_idx_out, hit_point_out);
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
std::cout << " Tree took " << time_span.count() << " seconds." << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
EdgeGrid::Grid grid1 { };
|
||||
grid1.create(lines, scaled(1.0), true);
|
||||
coord_t query1_res = scaled(1.0);
|
||||
grid1.calculate_sdf();
|
||||
for (const Point &qp : query_points) {
|
||||
volatile auto dist = grid1.closest_point_signed_distance(qp, query1_res);
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
std::cout << " Grid 1mm took " << time_span.count() << " seconds." << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
EdgeGrid::Grid grid10 { };
|
||||
grid10.create(lines, scaled(10.0), true);
|
||||
coord_t query10_res = scaled(10.0);
|
||||
grid10.calculate_sdf();
|
||||
for (const Point &qp : query_points) {
|
||||
volatile auto dist = grid10.closest_point_signed_distance(qp, query10_res);
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
std::cout << " Grid 10mm took " << time_span.count() << " seconds." << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::cout << "Test build and queries together - same number of contour points and query points" << std::endl <<
|
||||
"And with limited contour edge length to 4mm " << std::endl;
|
||||
for (auto count : point_counts) {
|
||||
|
||||
std::vector<Points> lines { Points { } };
|
||||
std::vector<Linef> linesf { };
|
||||
Vec2d prevf { };
|
||||
Points query_points { };
|
||||
std::vector<Vec2d> query_pointsf { };
|
||||
|
||||
for (int x = 0; x < count; ++x) {
|
||||
Vec2d cp { rand() / (double(RAND_MAX) + 1.0f) * 200.0 - 100.0, rand() / (double(RAND_MAX) + 1.0f) * 200.0
|
||||
- 100.0 };
|
||||
Vec2d contour = prevf + cp.normalized()*4.0; // limits the cnotour edge len to 4mm
|
||||
lines[0].push_back(Point::new_scale(contour));
|
||||
linesf.emplace_back(prevf, contour);
|
||||
prevf = linesf.back().b;
|
||||
|
||||
Vec2d qp { rand() / (double(RAND_MAX) + 1.0f) * 200.0 - 100.0, rand() / (double(RAND_MAX) + 1.0f) * 200.0
|
||||
- 100.0 };
|
||||
query_pointsf.push_back(qp);
|
||||
query_points.push_back(Point::new_scale(qp));
|
||||
}
|
||||
|
||||
std::cout << "Test for point count: " << count << std::endl;
|
||||
{
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
auto tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(linesf);
|
||||
for (const Vec2d &qp : query_pointsf) {
|
||||
size_t hit_idx_out;
|
||||
Vec2d hit_point_out;
|
||||
AABBTreeLines::squared_distance_to_indexed_lines(linesf, tree, qp, hit_idx_out, hit_point_out);
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
std::cout << " Tree took " << time_span.count() << " seconds." << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
EdgeGrid::Grid grid1 { };
|
||||
grid1.create(lines, scaled(1.0), true);
|
||||
coord_t query1_res = scaled(1.0);
|
||||
grid1.calculate_sdf();
|
||||
for (const Point &qp : query_points) {
|
||||
volatile auto dist = grid1.closest_point_signed_distance(qp, query1_res);
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
std::cout << " Grid 1mm took " << time_span.count() << " seconds." << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
high_resolution_clock::time_point t1 = high_resolution_clock::now();
|
||||
EdgeGrid::Grid grid10 { };
|
||||
grid10.create(lines, scaled(10.0), true);
|
||||
coord_t query10_res = scaled(10.0);
|
||||
grid10.calculate_sdf();
|
||||
for (const Point &qp : query_points) {
|
||||
volatile auto dist = grid10.closest_point_signed_distance(qp, query10_res);
|
||||
}
|
||||
high_resolution_clock::time_point t2 = high_resolution_clock::now();
|
||||
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
|
||||
std::cout << " Grid 10mm took " << time_span.count() << " seconds." << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -54,18 +54,9 @@ TEST_CASE("astar algorithm test over 3D point grid", "[AStar]") {
|
|||
|
||||
auto pgrid = point_grid(ex_seq, vol, {0.1f, 0.1f, 0.1f});
|
||||
|
||||
size_t target = pgrid.point_count() - 1;
|
||||
|
||||
std::cout << "Tracing route to " << pgrid.get_coord(target).transpose() << std::endl;
|
||||
PointGridTracer pgt{pgrid, pgrid.point_count() - 1};
|
||||
std::vector<size_t> out;
|
||||
bool found = astar::search_route(pgt, size_t(0), std::back_inserter(out));
|
||||
|
||||
std::cout << "Route taken: ";
|
||||
for (size_t i : out) {
|
||||
std::cout << "(" << pgrid.get_coord(i).transpose() << ") ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
REQUIRE(found);
|
||||
}
|
||||
|
|
|
@ -325,9 +325,9 @@ static void recreate_object_from_rasters(const std::string &objname, float lh) {
|
|||
double disp_w = 120.96;
|
||||
double disp_h = 68.04;
|
||||
|
||||
#ifndef NDEBUG
|
||||
size_t cntr = 0;
|
||||
#endif
|
||||
//#ifndef NDEBUG
|
||||
// size_t cntr = 0;
|
||||
//#endif
|
||||
for (ExPolygons &layer : layers) {
|
||||
auto rst = create_raster(res, disp_w, disp_h);
|
||||
|
||||
|
@ -335,11 +335,11 @@ static void recreate_object_from_rasters(const std::string &objname, float lh) {
|
|||
rst.draw(island);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
std::fstream out(objname + std::to_string(cntr) + ".png", std::ios::out);
|
||||
out << rst.encode(sla::PNGRasterEncoder{});
|
||||
out.close();
|
||||
#endif
|
||||
//#ifndef NDEBUG
|
||||
// std::fstream out(objname + std::to_string(cntr) + ".png", std::ios::out);
|
||||
// out << rst.encode(sla::PNGRasterEncoder{});
|
||||
// out.close();
|
||||
//#endif
|
||||
|
||||
ExPolygons layer_ = sla::raster_to_polygons(rst);
|
||||
// float delta = scaled(std::min(rst.pixel_dimensions().h_mm,
|
||||
|
@ -347,19 +347,19 @@ static void recreate_object_from_rasters(const std::string &objname, float lh) {
|
|||
|
||||
// layer_ = expolygons_simplify(layer_, delta);
|
||||
|
||||
#ifndef NDEBUG
|
||||
SVG svg(objname + std::to_string(cntr) + ".svg", BoundingBox(Point{0, 0}, Point{scaled(disp_w), scaled(disp_h)}));
|
||||
svg.draw(layer_);
|
||||
svg.draw(layer, "green");
|
||||
svg.Close();
|
||||
#endif
|
||||
//#ifndef NDEBUG
|
||||
// SVG svg(objname + std::to_string(cntr) + ".svg", BoundingBox(Point{0, 0}, Point{scaled(disp_w), scaled(disp_h)}));
|
||||
// svg.draw(layer_);
|
||||
// svg.draw(layer, "green");
|
||||
// svg.Close();
|
||||
//#endif
|
||||
|
||||
double layera = 0., layera_ = 0.;
|
||||
for (auto &p : layer) layera += p.area();
|
||||
for (auto &p : layer_) layera_ += p.area();
|
||||
#ifndef NDEBUG
|
||||
std::cout << cntr++ << std::endl;
|
||||
#endif
|
||||
//#ifndef NDEBUG
|
||||
// std::cout << cntr++ << std::endl;
|
||||
//#endif
|
||||
double diff = std::abs(layera_ - layera);
|
||||
REQUIRE((diff <= 0.1 * layera || diff < scaled<double>(1.) * scaled<double>(1.)));
|
||||
|
||||
|
|
|
@ -346,25 +346,36 @@ TEST_CASE("Mutable priority queue - first pop", "[MutableSkipHeapPriorityQueue]"
|
|||
size_t id;
|
||||
float val;
|
||||
};
|
||||
size_t count = 50000;
|
||||
static constexpr const size_t count = 50000;
|
||||
std::vector<size_t> idxs(count, {0});
|
||||
std::vector<bool> dels(count, false);
|
||||
auto q = make_miniheap_mutable_priority_queue<MyValue, 16, true>(
|
||||
[&](MyValue &v, size_t idx) {
|
||||
idxs[v.id] = idx;
|
||||
},
|
||||
[&idxs](MyValue &v, size_t idx) { idxs[v.id] = idx; },
|
||||
[](MyValue &l, MyValue &r) { return l.val < r.val; });
|
||||
q.reserve(count);
|
||||
for (size_t id = 0; id < count; id++) {
|
||||
MyValue mv{ id, rand() / 100.f };
|
||||
q.push(mv);
|
||||
using QueueType = decltype(q);
|
||||
THEN("Skip queue has 0th element unused, 1st element is the top of the queue.") {
|
||||
CHECK(QueueType::address::is_padding(0));
|
||||
CHECK(!QueueType::address::is_padding(1));
|
||||
}
|
||||
q.reserve(count);
|
||||
for (size_t id = 0; id < count; ++ id)
|
||||
q.push({ id, rand() / 100.f });
|
||||
MyValue v = q.top(); // copy
|
||||
THEN("Element at the top of the queue has a valid ID.") {
|
||||
CHECK(v.id >= 0);
|
||||
CHECK(v.id < count);
|
||||
}
|
||||
THEN("Element at the top of the queue has its position stored in idxs.") {
|
||||
CHECK(idxs[v.id] == 1);
|
||||
}
|
||||
MyValue it = q.top(); // copy
|
||||
q.pop();
|
||||
// is valid id (no initial value default value)
|
||||
CHECK(it.id != 0);
|
||||
// is first item in queue valid value
|
||||
CHECK(idxs[0] != std::numeric_limits<size_t>::max());
|
||||
THEN("Element removed from the queue has its position in idxs reset to invalid.") {
|
||||
CHECK(idxs[v.id] == q.invalid_id());
|
||||
}
|
||||
THEN("Element was removed from the queue, new top of the queue has its index set correctly.") {
|
||||
CHECK(q.top().id >= 0);
|
||||
CHECK(q.top().id < count);
|
||||
CHECK(idxs[q.top().id] == 1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Mutable priority queue complex", "[MutableSkipHeapPriorityQueue]")
|
||||
|
@ -382,23 +393,23 @@ TEST_CASE("Mutable priority queue complex", "[MutableSkipHeapPriorityQueue]")
|
|||
q.reserve(count);
|
||||
|
||||
auto rand_val = [&]()->float { return (rand() % 53) / 10.f; };
|
||||
size_t ord = 0;
|
||||
for (size_t id = 0; id < count; id++) {
|
||||
MyValue mv;
|
||||
mv.id = ord++;
|
||||
mv.val = rand_val();
|
||||
q.push(mv);
|
||||
}
|
||||
for (size_t id = 0; id < count; ++ id)
|
||||
q.push({ id, rand_val() });
|
||||
|
||||
auto check = [&]()->bool{
|
||||
for (size_t i = 0; i < idxs.size(); ++i) {
|
||||
if (dels[i]) continue;
|
||||
size_t qid = idxs[i];
|
||||
if (qid > 3*count) {
|
||||
return false;
|
||||
}
|
||||
MyValue &mv = q[qid];
|
||||
if (mv.id != i) {
|
||||
return false; // ERROR
|
||||
if (dels[i]) {
|
||||
if (idxs[i] != q.invalid_id())
|
||||
return false; // ERROR
|
||||
} else {
|
||||
size_t qid = idxs[i];
|
||||
if (qid >= q.heap_size()) {
|
||||
return false; // ERROR
|
||||
}
|
||||
MyValue &mv = q[qid];
|
||||
if (mv.id != i) {
|
||||
return false; // ERROR
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -406,6 +417,7 @@ TEST_CASE("Mutable priority queue complex", "[MutableSkipHeapPriorityQueue]")
|
|||
|
||||
CHECK(check()); // initial check
|
||||
|
||||
// Generate an element ID of an elmenet, which was not yet deleted, thus it is still valid.
|
||||
auto get_valid_id = [&]()->int {
|
||||
int id = 0;
|
||||
do {
|
||||
|
@ -413,23 +425,28 @@ TEST_CASE("Mutable priority queue complex", "[MutableSkipHeapPriorityQueue]")
|
|||
} while (dels[id]);
|
||||
return id;
|
||||
};
|
||||
|
||||
// Remove first 100 elements from the queue of 5000 elements, cross-validate indices.
|
||||
// Re-enter every 20th element back to the queue.
|
||||
for (size_t i = 0; i < 100; i++) {
|
||||
MyValue it = q.top(); // copy
|
||||
MyValue v = q.top(); // copy
|
||||
q.pop();
|
||||
dels[it.id] = true;
|
||||
dels[v.id] = true;
|
||||
CHECK(check());
|
||||
if (i % 20 == 0) {
|
||||
it.val = rand_val();
|
||||
q.push(it);
|
||||
dels[it.id] = false;
|
||||
v.val = rand_val();
|
||||
q.push(v);
|
||||
dels[v.id] = false;
|
||||
CHECK(check());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove some valid element from the queue.
|
||||
int id = get_valid_id();
|
||||
CHECK(idxs[id] != q.invalid_id());
|
||||
q.remove(idxs[id]);
|
||||
dels[id] = true;
|
||||
CHECK(check());
|
||||
// and change 5 random elements and reorder them in the queue.
|
||||
for (size_t j = 0; j < 5; j++) {
|
||||
int id = get_valid_id();
|
||||
size_t qid = idxs[id];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue