Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_sinking_objects_collision
This commit is contained in:
commit
a9ca63d344
@ -1563,14 +1563,16 @@ namespace rotcalip {
|
|||||||
using int256_t = boost::multiprecision::int256_t;
|
using int256_t = boost::multiprecision::int256_t;
|
||||||
using int128_t = boost::multiprecision::int128_t;
|
using int128_t = boost::multiprecision::int128_t;
|
||||||
|
|
||||||
inline int128_t magnsq(const Point &p)
|
template<class Scalar = int64_t>
|
||||||
|
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<class Scalar = int64_t>
|
||||||
|
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<class Scalar = int64_t>
|
template<class Scalar = int64_t>
|
||||||
@ -1676,7 +1678,6 @@ bool intersects(const Polygon &A, const Polygon &B)
|
|||||||
// Establish starting antipodals as extremes in XY plane. Use the
|
// Establish starting antipodals as extremes in XY plane. Use the
|
||||||
// easily obtainable bounding boxes to check if A and B is disjoint
|
// easily obtainable bounding boxes to check if A and B is disjoint
|
||||||
// and return false if the are.
|
// and return false if the are.
|
||||||
|
|
||||||
struct BB
|
struct BB
|
||||||
{
|
{
|
||||||
size_t xmin = 0, xmax = 0, ymin = 0, ymax = 0;
|
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_a = dotperp( dir, ref_a - A[ia]) > 0;
|
||||||
bool is_left_b = dotperp(-dir, ref_b - B[ib]) > 0;
|
bool is_left_b = dotperp(-dir, ref_b - B[ib]) > 0;
|
||||||
|
|
||||||
// If both reference points are on the left (or right) of the
|
// If both reference points are on the left (or right) of their
|
||||||
// support line and the opposite support line is to the righ (or
|
// respective support lines and the opposite support line is to
|
||||||
// left), the divisor line is found. We only test the reference
|
// the right (or left), the divisor line is found. We only test
|
||||||
// point, as by definition, if that is on one side, all the other
|
// the reference point, as by definition, if that is on one side,
|
||||||
// points must be on the same side of a support line.
|
// 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]);
|
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
|
// The caliper lines are collinear, not just parallel
|
||||||
|
found_divisor = (is_left_a && is_left_b) || (!is_left_a && !is_left_b);
|
||||||
// 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;
|
|
||||||
|
|
||||||
} else if (d > 0) { // B is to the left of (A, A+1)
|
} else if (d > 0) { // B is to the left of (A, A+1)
|
||||||
found_divisor = !is_left_a && !is_left_b;
|
found_divisor = !is_left_a && !is_left_b;
|
||||||
} else { // B is to the right of (A, A+1)
|
} else { // B is to the right of (A, A+1)
|
||||||
|
@ -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());
|
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
|
} } // namespace Slicer::Geometry
|
||||||
|
|
||||||
|
@ -4179,12 +4179,14 @@ void Plater::priv::on_right_click(RBtnEvent& evt)
|
|||||||
if (printer_technology == ptSLA)
|
if (printer_technology == ptSLA)
|
||||||
menu = menus.sla_object_menu();
|
menu = menus.sla_object_menu();
|
||||||
else {
|
else {
|
||||||
|
const Selection& selection = get_selection();
|
||||||
// show "Object menu" for each one or several FullInstance instead of FullObject
|
// show "Object menu" for each one or several FullInstance instead of FullObject
|
||||||
const bool is_some_full_instances = get_selection().is_single_full_instance() ||
|
const bool is_some_full_instances = selection.is_single_full_instance() ||
|
||||||
get_selection().is_single_full_object() ||
|
selection.is_single_full_object() ||
|
||||||
get_selection().is_multiple_full_instance();
|
selection.is_multiple_full_instance();
|
||||||
menu = is_some_full_instances ? menus.object_menu() :
|
const bool is_part = selection.is_single_volume() || selection.is_single_modifier();
|
||||||
get_selection().is_single_volume() ? menus.part_menu() : menus.multi_selection_menu();
|
menu = is_some_full_instances ? menus.object_menu() :
|
||||||
|
is_part ? menus.part_menu() : menus.multi_selection_menu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,7 +470,7 @@ TEST_CASE("Convex polygon intersection on two disjoint squares", "[Geometry][Rot
|
|||||||
|
|
||||||
bool is_inters = Geometry::intersects(A, B);
|
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]") {
|
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);
|
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]") {
|
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);
|
A.scale(1. / SCALING_FACTOR);
|
||||||
|
|
||||||
Polygon B = A;
|
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);
|
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]") {
|
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);
|
REQUIRE(is_inters == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only for benchmarking
|
//// Only for benchmarking
|
||||||
//static Polygon gen_convex_poly(std::mt19937_64 &rg, size_t point_cnt)
|
//static Polygon gen_convex_poly(std::mt19937_64 &rg, size_t point_cnt)
|
||||||
//{
|
//{
|
||||||
// std::uniform_int_distribution<coord_t> dist(0, 100);
|
// std::uniform_int_distribution<coord_t> 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 TEST_CNT = 1000;
|
||||||
// constexpr size_t POINT_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;
|
// Benchmark bench;
|
||||||
|
|
||||||
// auto tests = reserve_vector<std::pair<Polygon, Polygon>>(TEST_CNT);
|
// auto tests = reserve_vector<std::pair<Polygon, Polygon>>(TEST_CNT);
|
||||||
@ -567,11 +574,12 @@ TEST_CASE("Convex polygon intersection on two overlapping squares", "[Geometry][
|
|||||||
|
|
||||||
// REQUIRE(results.size() == expects.size());
|
// REQUIRE(results.size() == expects.size());
|
||||||
|
|
||||||
|
// auto seedstr = std::to_string(seed);
|
||||||
// for (size_t i = 0; i < results.size(); ++i) {
|
// for (size_t i = 0; i < results.size(); ++i) {
|
||||||
// // std::cout << expects[i] << " ";
|
// // std::cout << expects[i] << " ";
|
||||||
|
|
||||||
// if (results[i] != 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].first, "blue");
|
||||||
// svg.draw(tests[i].second, "green");
|
// svg.draw(tests[i].second, "green");
|
||||||
// svg.Close();
|
// svg.Close();
|
||||||
|
Loading…
Reference in New Issue
Block a user