diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index 049f0e08f..af881b184 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -1563,14 +1563,16 @@ namespace rotcalip { using int256_t = boost::multiprecision::int256_t; using int128_t = boost::multiprecision::int128_t; -inline int128_t magnsq(const Point &p) +template +inline Scalar magnsq(const Point &p) { - return int128_t(p.x()) * p.x() + int64_t(p.y()) * p.y(); + return Scalar(p.x()) * p.x() + Scalar(p.y()) * p.y(); } -inline int128_t dot(const Point &a, const Point &b) +template +inline Scalar dot(const Point &a, const Point &b) { - return int128_t(a.x()) * b.x() + int64_t(a.y()) * b.y(); + return Scalar(a.x()) * b.x() + Scalar(a.y()) * b.y(); } template @@ -1676,7 +1678,6 @@ bool intersects(const Polygon &A, const Polygon &B) // Establish starting antipodals as extremes in XY plane. Use the // easily obtainable bounding boxes to check if A and B is disjoint // and return false if the are. - struct BB { size_t xmin = 0, xmax = 0, ymin = 0, ymax = 0; @@ -1733,24 +1734,18 @@ bool intersects(const Polygon &A, const Polygon &B) bool is_left_a = dotperp( dir, ref_a - A[ia]) > 0; bool is_left_b = dotperp(-dir, ref_b - B[ib]) > 0; - // If both reference points are on the left (or right) of the - // support line and the opposite support line is to the righ (or - // left), the divisor line is found. We only test the reference - // point, as by definition, if that is on one side, all the other - // points must be on the same side of a support line. + // If both reference points are on the left (or right) of their + // respective support lines and the opposite support line is to + // the right (or left), the divisor line is found. We only test + // the reference point, as by definition, if that is on one side, + // all the other points must be on the same side of a support + // line. If the support lines are collinear, the polygons must be + // on the same side of their respective support lines. auto d = dotperp(dir, B[ib] - A[ia]); - if (d == 0 && ((is_left_a && is_left_b) || (!is_left_a && !is_left_b))) { + if (d == 0) { // The caliper lines are collinear, not just parallel - - // Check if the lines are overlapping and if they do ignore the divisor - Point a = A[ia], b = A[(ia + 1) % A.size()]; - if (b < a) std::swap(a, b); - Point c = B[ib], d = B[(ib + 1) % B.size()]; - if (d < c) std::swap(c, d); - - found_divisor = b < c; - + found_divisor = (is_left_a && is_left_b) || (!is_left_a && !is_left_b); } else if (d > 0) { // B is to the left of (A, A+1) found_divisor = !is_left_a && !is_left_b; } else { // B is to the right of (A, A+1) diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index 4a4b76b17..49886d4b8 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -561,7 +561,9 @@ inline bool is_rotation_ninety_degrees(const Vec3d &rotation) return is_rotation_ninety_degrees(rotation.x()) && is_rotation_ninety_degrees(rotation.y()) && is_rotation_ninety_degrees(rotation.z()); } -bool intersects(const Polygon &convex_poly1, const Polygon &convex_poly2); +// Returns true if the intersection of the two convex polygons A and B +// is not an empty set. +bool intersects(const Polygon &A, const Polygon &B); } } // namespace Slicer::Geometry diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b28c1e8f9..334c7039f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4179,12 +4179,14 @@ void Plater::priv::on_right_click(RBtnEvent& evt) if (printer_technology == ptSLA) menu = menus.sla_object_menu(); else { + const Selection& selection = get_selection(); // show "Object menu" for each one or several FullInstance instead of FullObject - const bool is_some_full_instances = get_selection().is_single_full_instance() || - get_selection().is_single_full_object() || - get_selection().is_multiple_full_instance(); - menu = is_some_full_instances ? menus.object_menu() : - get_selection().is_single_volume() ? menus.part_menu() : menus.multi_selection_menu(); + const bool is_some_full_instances = selection.is_single_full_instance() || + selection.is_single_full_object() || + selection.is_multiple_full_instance(); + const bool is_part = selection.is_single_volume() || selection.is_single_modifier(); + menu = is_some_full_instances ? menus.object_menu() : + is_part ? menus.part_menu() : menus.multi_selection_menu(); } } diff --git a/tests/libslic3r/test_geometry.cpp b/tests/libslic3r/test_geometry.cpp index 308e29fca..b183de1b4 100644 --- a/tests/libslic3r/test_geometry.cpp +++ b/tests/libslic3r/test_geometry.cpp @@ -470,7 +470,7 @@ TEST_CASE("Convex polygon intersection on two disjoint squares", "[Geometry][Rot bool is_inters = Geometry::intersects(A, B); - REQUIRE(is_inters != true); + REQUIRE(is_inters == false); } TEST_CASE("Convex polygon intersection on two intersecting squares", "[Geometry][Rotcalip]") { @@ -494,7 +494,7 @@ TEST_CASE("Convex polygon intersection on two squares touching one edge", "[Geom bool is_inters = Geometry::intersects(A, B); - REQUIRE(is_inters == true); + REQUIRE(is_inters == false); } TEST_CASE("Convex polygon intersection on two squares touching one vertex", "[Geometry][Rotcalip]") { @@ -502,11 +502,16 @@ TEST_CASE("Convex polygon intersection on two squares touching one vertex", "[Ge A.scale(1. / SCALING_FACTOR); Polygon B = A; - B.translate(10 / SCALING_FACTOR, 10); + B.translate(10 / SCALING_FACTOR, 10 / SCALING_FACTOR); + + SVG svg{std::string("one_vertex_touch") + ".svg"}; + svg.draw(A, "blue"); + svg.draw(B, "green"); + svg.Close(); bool is_inters = Geometry::intersects(A, B); - REQUIRE(is_inters == true); + REQUIRE(is_inters == false); } TEST_CASE("Convex polygon intersection on two overlapping squares", "[Geometry][Rotcalip]") { @@ -520,7 +525,7 @@ TEST_CASE("Convex polygon intersection on two overlapping squares", "[Geometry][ REQUIRE(is_inters == true); } -// Only for benchmarking +//// Only for benchmarking //static Polygon gen_convex_poly(std::mt19937_64 &rg, size_t point_cnt) //{ // std::uniform_int_distribution dist(0, 100); @@ -540,7 +545,9 @@ TEST_CASE("Convex polygon intersection on two overlapping squares", "[Geometry][ // constexpr size_t TEST_CNT = 1000; // constexpr size_t POINT_CNT = 1000; -// std::mt19937_64 rg{std::random_device{}()}; +// auto seed = std::random_device{}(); +//// unsigned long seed = 2525634386; +// std::mt19937_64 rg{seed}; // Benchmark bench; // auto tests = reserve_vector>(TEST_CNT); @@ -567,11 +574,12 @@ TEST_CASE("Convex polygon intersection on two overlapping squares", "[Geometry][ // REQUIRE(results.size() == expects.size()); +// auto seedstr = std::to_string(seed); // for (size_t i = 0; i < results.size(); ++i) { // // std::cout << expects[i] << " "; // if (results[i] != expects[i]) { -// SVG svg{std::string("fail") + std::to_string(i) + ".svg"}; +// SVG svg{std::string("fail_seed") + seedstr + "_" + std::to_string(i) + ".svg"}; // svg.draw(tests[i].first, "blue"); // svg.draw(tests[i].second, "green"); // svg.Close();