diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index 852e9268c..ea6850325 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -708,7 +708,45 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& result.distance_infinite = std::make_optional(DistAndPoints{it->dist, it->from, it->to}); /////////////////////////////////////////////////////////////////////////// } else if (f2.get_type() == SurfaceFeatureType::Plane) { - result.distance_infinite = std::make_optional(DistAndPoints{0., Vec3d::Zero(), Vec3d::Zero()}); // TODO + assert(measuring != nullptr); + + const auto [from, to] = f1.get_edge(); + const auto [idx, normal, origin] = f2.get_plane(); + + const Vec3d edge_unit = (to - from).normalized(); + if (are_perpendicular(edge_unit, normal)) { + std::vector distances; + const Eigen::Hyperplane plane(normal, origin); + distances.push_back(DistAndPoints{ plane.absDistance(from), from, plane.projection(from) }); + distances.push_back(DistAndPoints{ plane.absDistance(to), to, plane.projection(to) }); + auto it = std::min_element(distances.begin(), distances.end(), + [](const DistAndPoints& item1, const DistAndPoints& item2) { + return item1.dist < item2.dist; + }); + result.distance_infinite = std::make_optional(DistAndPoints{ it->dist, it->from, it->to }); + } + else { + const std::vector& plane_features = measuring->get_plane_features(idx); + std::vector distances; + for (const SurfaceFeature& sf : plane_features) { + if (sf.get_type() == SurfaceFeatureType::Edge) { + const auto m = get_measurement(sf, f1); + if (!m.distance_infinite.has_value()) { + distances.clear(); + break; + } + else + distances.push_back(*m.distance_infinite); + } + } + if (!distances.empty()) { + auto it = std::min_element(distances.begin(), distances.end(), + [](const DistAndPoints& item1, const DistAndPoints& item2) { + return item1.dist < item2.dist; + }); + result.distance_infinite = std::make_optional(DistAndPoints{ it->dist, it->from, it->to }); + } + } result.angle = angle_edge_plane(f1.get_edge(), f2.get_plane()); } /////////////////////////////////////////////////////////////////////////// @@ -729,14 +767,23 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& const std::vector& plane_features = measuring->get_plane_features(idx2); std::vector distances; for (const SurfaceFeature& sf : plane_features) { - if (sf.get_type() == SurfaceFeatureType::Edge) - distances.push_back(*get_measurement(sf, f1).distance_infinite); + if (sf.get_type() == SurfaceFeatureType::Edge) { + const auto m = get_measurement(sf, f1); + if (!m.distance_infinite.has_value()) { + distances.clear(); + break; + } + else + distances.push_back(*m.distance_infinite); + } + } + if (!distances.empty()) { + auto it = std::min_element(distances.begin(), distances.end(), + [](const DistAndPoints& item1, const DistAndPoints& item2) { + return item1.dist < item2.dist; + }); + result.distance_infinite = std::make_optional(DistAndPoints{ it->dist, it->from, it->to }); } - auto it = std::min_element(distances.begin(), distances.end(), - [](const DistAndPoints& item1, const DistAndPoints& item2) { - return item1.dist < item2.dist; - }); - result.distance_infinite = std::make_optional(DistAndPoints{ it->dist, it->from, it->to }); } } /////////////////////////////////////////////////////////////////////////// diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 31ce08fa7..051a7ee40 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -891,13 +891,15 @@ void GLGizmoMeasure::render_dimensioning() auto arc_edge_edge = [this, shader](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2, double radius = 0.0) { assert(f1.get_type() == Measure::SurfaceFeatureType::Edge && f2.get_type() == Measure::SurfaceFeatureType::Edge); - const Measure::MeasurementResult res = Measure::get_measurement(f1, f2); - const double angle = res.angle->angle; - const Vec3d center = res.angle->center; - const std::pair e1 = res.angle->e1; - const std::pair e2 = res.angle->e2; - const double calc_radius = res.angle->radius; - const bool coplanar = res.angle->coplanar; + if (!m_measurement_result.angle.has_value()) + return; + + const double angle = m_measurement_result.angle->angle; + const Vec3d center = m_measurement_result.angle->center; + const std::pair e1 = m_measurement_result.angle->e1; + const std::pair e2 = m_measurement_result.angle->e2; + const double calc_radius = m_measurement_result.angle->radius; + const bool coplanar = m_measurement_result.angle->coplanar; if (std::abs(angle) < EPSILON || std::abs(calc_radius) < EPSILON) return; @@ -993,12 +995,15 @@ void GLGizmoMeasure::render_dimensioning() ImGui::PopStyleVar(); }; - auto arc_edge_plane = [arc_edge_edge](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2) { + auto arc_edge_plane = [this, arc_edge_edge](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2) { assert(f1.get_type() == Measure::SurfaceFeatureType::Edge && f2.get_type() == Measure::SurfaceFeatureType::Plane); - const Measure::MeasurementResult res = Measure::get_measurement(f1, f2); - const std::pair e1 = res.angle->e1; - const std::pair e2 = res.angle->e2; - const double calc_radius = res.angle->radius; + if (!m_measurement_result.angle.has_value()) + return; + + const std::pair e1 = m_measurement_result.angle->e1; + const std::pair e2 = m_measurement_result.angle->e2; + const double calc_radius = m_measurement_result.angle->radius; + if (calc_radius == 0.0) return; @@ -1006,12 +1011,12 @@ void GLGizmoMeasure::render_dimensioning() Measure::SurfaceFeature(Measure::SurfaceFeatureType::Edge, e2.first, e2.second), calc_radius); }; - auto arc_plane_plane = [arc_edge_edge](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2) { + auto arc_plane_plane = [this, arc_edge_edge](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2) { assert(f1.get_type() == Measure::SurfaceFeatureType::Plane && f2.get_type() == Measure::SurfaceFeatureType::Plane); - const Measure::MeasurementResult res = Measure::get_measurement(f1, f2); - const std::pair e1 = res.angle->e1; - const std::pair e2 = res.angle->e2; - const double calc_radius = res.angle->radius; + const std::pair e1 = m_measurement_result.angle->e1; + const std::pair e2 = m_measurement_result.angle->e2; + const double calc_radius = m_measurement_result.angle->radius; + if (calc_radius == 0.0) return;