diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index b27425ea9..ff07aa081 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -250,7 +250,7 @@ void MeasuringImpl::extract_features() // Add the circle and remember indices into borders. const auto& [center, radius] = get_center_and_radius(border, start_idx, i, trafo); circles_idxs.emplace_back(start_idx, i); - circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::optional(), radius)); + circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::nullopt, radius)); circle = false; } } @@ -269,7 +269,7 @@ void MeasuringImpl::extract_features() const Vec3d center = std::get<0>(circles[i].get_circle()); for (int j=(int)circles_idxs[i].first + 1; j<=(int)circles_idxs[i].second; ++j) plane.surface_features.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, - border[j-1], border[j], std::make_optional(center), 0.)); + border[j - 1], border[j], std::make_optional(center))); } else { // This will be handled just like a regular edge. circles_idxs.erase(circles_idxs.begin() + i); @@ -288,8 +288,8 @@ void MeasuringImpl::extract_features() for (int i=1; i (int)circles_idxs[cidx].first) i = circles_idxs[cidx++].second; - else plane.surface_features.emplace_back(SurfaceFeature( - SurfaceFeatureType::Edge, border[i-1], border[i], std::optional(), 0.)); + else + plane.surface_features.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, border[i - 1], border[i])); } // FIXME Throw away / do not create edges which are parts of circles or @@ -307,7 +307,7 @@ void MeasuringImpl::extract_features() // The last surface feature is the plane itself. plane.surface_features.emplace_back(SurfaceFeature(SurfaceFeatureType::Plane, - plane.normal, plane.borders.front().front(), std::optional(), i + 0.0001)); + plane.normal, plane.borders.front().front(), std::nullopt, i + 0.0001)); plane.borders.clear(); plane.borders.shrink_to_fit(); @@ -433,13 +433,12 @@ std::vector> Measuring::get_planes_triangle_indices() const static AngleAndPoints angle_edge_edge(const std::pair& e1, const std::pair& e2) { - Vec3d e1_unit = (e1.second - e1.first).normalized(); - Vec3d e2_unit = (e2.second - e2.first).normalized(); - const double dot = e1_unit.dot(e2_unit); - // are edges parallel ? - if (std::abs(std::abs(dot) - 1.0) < EPSILON) + if (are_parallel(e1, e2)) return AngleAndPoints(0.0, e1.first, Vec3d::UnitX(), Vec3d::UnitX(), 0., true); + Vec3d e1_unit = edge_direction(e1.first, e1.second); + Vec3d e2_unit = edge_direction(e2.first, e2.second); + // project edges on the plane defined by them Vec3d normal = e1_unit.cross(e2_unit).normalized(); const Eigen::Hyperplane plane(normal, e1.first); @@ -562,7 +561,7 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& std::vector distances; auto add_point_edge_distance = [&distances](const Vec3d& v, const std::pair& e) { - const MeasurementResult res = get_measurement(SurfaceFeature(v), SurfaceFeature(SurfaceFeatureType::Edge, e.first, e.second, std::optional(), 0.)); + const MeasurementResult res = get_measurement(SurfaceFeature(v), SurfaceFeature(SurfaceFeatureType::Edge, e.first, e.second)); double distance = res.distance_strict->dist; Vec3d v2 = res.distance_strict->to; diff --git a/src/libslic3r/Measure.hpp b/src/libslic3r/Measure.hpp index 4ac56a87f..1c51289e8 100644 --- a/src/libslic3r/Measure.hpp +++ b/src/libslic3r/Measure.hpp @@ -25,8 +25,8 @@ enum class SurfaceFeatureType : int { class SurfaceFeature { public: - SurfaceFeature(SurfaceFeatureType type, const Vec3d& pt1, const Vec3d& pt2, std::optional pt3, double value) - : m_type{type}, m_pt1{pt1}, m_pt2{pt2}, m_pt3{pt3}, m_value{value} {} + SurfaceFeature(SurfaceFeatureType type, const Vec3d& pt1, const Vec3d& pt2, std::optional pt3 = std::nullopt, double value = 0.0) + : m_type{ type }, m_pt1{ pt1 }, m_pt2{ pt2 }, m_pt3{ pt3 }, m_value{ value } {} explicit SurfaceFeature(const Vec3d& pt) : m_type{SurfaceFeatureType::Point}, m_pt1{pt} {} @@ -157,6 +157,9 @@ inline Vec3d plane_normal(const SurfaceFeature& plane) { inline bool are_parallel(const Vec3d& v1, const Vec3d& v2) { return std::abs(std::abs(v1.dot(v2)) - 1.0) < EPSILON; } inline bool are_perpendicular(const Vec3d& v1, const Vec3d& v2) { return std::abs(v1.dot(v2)) < EPSILON; } +inline bool are_parallel(const std::pair& e1, const std::pair& e2) { + return are_parallel(e1.second - e1.first, e2.second - e2.first); +} inline bool are_parallel(const SurfaceFeature& f1, const SurfaceFeature& f2) { if (f1.get_type() == SurfaceFeatureType::Edge && f2.get_type() == SurfaceFeatureType::Edge) return are_parallel(edge_direction(f1), edge_direction(f2)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 9a62a8c39..d6488b83a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -887,8 +887,6 @@ void GLGizmoMeasure::render_dimensioning() double draw_radius = force_radius ? *force_radius : radius; - const Vec3d normal = e1_unit.cross(e2_unit).normalized(); - if (!m_dimensioning.arc.is_initialized()) { const unsigned int resolution = std::max(2, 64 * angle / double(PI)); GLModel::Geometry init_data; @@ -898,6 +896,7 @@ void GLGizmoMeasure::render_dimensioning() init_data.reserve_indices(resolution + 1); // vertices + indices + const Vec3d normal = e1_unit.cross(e2_unit).normalized(); const double step = angle / double(resolution); for (unsigned int i = 0; i <= resolution; ++i) { const double a = step * double(i); @@ -943,16 +942,19 @@ void GLGizmoMeasure::render_dimensioning() 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); - std::pair e = f1.get_edge(); - const auto [idx, normal, origin] = f2.get_plane(); if (Measure::are_parallel(f1, f2) || Measure::are_perpendicular(f1, f2)) return; + const std::pair e = f1.get_edge(); + const auto [idx, normal, origin] = f2.get_plane(); + + // ensure the edge is pointing away from the intersection + // 1st calculate instersection between edge and plane const Eigen::Hyperplane plane(normal, origin); const Eigen::ParametrizedLine line = Eigen::ParametrizedLine::Through(e.first, e.second); const Vec3d inters = line.intersectionPoint(plane); - // ensure the edge is pointing away from the intersection + // then verify edge direction and revert it, if needed std::pair ecopy = e; if ((ecopy.first - inters).squaredNorm() > (ecopy.second - inters).squaredNorm()) std::swap(ecopy.first, ecopy.second); @@ -971,9 +973,9 @@ void GLGizmoMeasure::render_dimensioning() const Vec3d e1e2copy_mid = 0.5 * (ecopy.second + ecopy.first); const double radius = (inters - e1e2copy_mid).norm(); - arc_edge_edge(Measure::SurfaceFeature(Measure::SurfaceFeatureType::Edge, ecopy.second, ecopy.first, std::optional(), 0.), - Measure::SurfaceFeature(Measure::SurfaceFeatureType::Edge, edge_on_plane.second, edge_on_plane.first, std::optional(), 0.), - &radius); + arc_edge_edge(Measure::SurfaceFeature(Measure::SurfaceFeatureType::Edge, ecopy.first, ecopy.second), + Measure::SurfaceFeature(Measure::SurfaceFeatureType::Edge, edge_on_plane.first, edge_on_plane.second), + &radius); };