From 305ea0da27ea499230d4f4d6ee7b7e929f60ecc3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 16 Nov 2022 12:04:38 +0100 Subject: [PATCH] Gizmo measure - Fixed angle for perpendicular edge-plane use case --- src/libslic3r/Measure.cpp | 53 +++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index ffb8f953a..8213f9778 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -29,6 +29,21 @@ static std::pair get_center_and_radius(const std::vector& return std::make_pair(trafo.inverse() * Vec3d(circle.center.x(), circle.center.y(), z), circle.radius); } +static std::array orthonormal_basis(const Vec3d& v) +{ + std::array ret; + ret[2] = v.normalized(); + int index; + ret[2].maxCoeff(&index); + switch (index) + { + case 0: { ret[0] = Vec3d(ret[2].y(), -ret[2].x(), 0.0).normalized(); break; } + case 1: { ret[0] = Vec3d(0.0, ret[2].z(), -ret[2].y()).normalized(); break; } + case 2: { ret[0] = Vec3d(-ret[2].z(), 0.0, ret[2].x()).normalized(); break; } + } + ret[1] = ret[2].cross(ret[0]).normalized(); + return ret; +} @@ -630,8 +645,8 @@ static AngleAndEdges angle_edge_edge(const std::pair& e1, const st static AngleAndEdges angle_edge_plane(const std::pair& e, const std::tuple& p) { const auto& [idx, normal, origin] = p; - const Vec3d e1e2_unit = edge_direction(e); - if (are_parallel(e1e2_unit, normal) || are_perpendicular(e1e2_unit, normal)) + Vec3d e1e2_unit = edge_direction(e); + if (are_perpendicular(e1e2_unit, normal)) return AngleAndEdges::Dummy; // ensure the edge is pointing away from the intersection @@ -643,8 +658,22 @@ static AngleAndEdges angle_edge_plane(const std::pair& e, const st // then verify edge direction and revert it, if needed Vec3d e1 = e.first; Vec3d e2 = e.second; - if ((e1 - inters).squaredNorm() > (e2 - inters).squaredNorm()) + if ((e1 - inters).squaredNorm() > (e2 - inters).squaredNorm()) { std::swap(e1, e2); + e1e2_unit = -e1e2_unit; + } + + if (are_parallel(e1e2_unit, normal)) { + const std::array basis = orthonormal_basis(e1e2_unit); + const double radius = (0.5 * (e1 + e2) - inters).norm(); + const Vec3d edge_on_plane_dir = (basis[1].dot(origin - inters) >= 0.0) ? basis[1] : -basis[1]; + std::pair edge_on_plane = std::make_pair(inters, inters + radius * edge_on_plane_dir); + if (!inters.isApprox(e1)) { + edge_on_plane.first += radius * edge_on_plane_dir; + edge_on_plane.second += radius * edge_on_plane_dir; + } + return AngleAndEdges(0.5 * double(PI), inters, std::make_pair(e1, e2), edge_on_plane, radius, inters.isApprox(e1)); + } const Vec3d e1e2 = e2 - e1; const double e1e2_len = e1e2.norm(); @@ -773,7 +802,8 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// - } else if (f1.get_type() == SurfaceFeatureType::Edge) { + } + else if (f1.get_type() == SurfaceFeatureType::Edge) { if (f2.get_type() == SurfaceFeatureType::Edge) { std::vector distances; @@ -900,21 +930,6 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& const Vec3d D = c1 - c0; if (!are_parallel(n0, n1)) { - auto orthonormal_basis = [](const Vec3d& v) { - std::array ret; - ret[2] = v.normalized(); - int index; - ret[2].maxCoeff(&index); - switch (index) - { - case 0: { ret[0] = Vec3d(ret[2].y(), -ret[2].x(), 0.0).normalized(); break; } - case 1: { ret[0] = Vec3d(0.0, ret[2].z(), -ret[2].y()).normalized(); break; } - case 2: { ret[0] = Vec3d(-ret[2].z(), 0.0, ret[2].x()).normalized(); break; } - } - ret[1] = ret[2].cross(ret[0]).normalized(); - return ret; - }; - // Get parameters for constructing the degree-8 polynomial phi. const double one = 1.0; const double two = 2.0;