From 457afca5de3359703df88105acc7600a3da9e505 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 27 Jul 2022 11:45:42 +0200 Subject: [PATCH] Measuring: added getters for circle visualization --- src/libslic3r/Measure.cpp | 11 ++++++++++- src/libslic3r/Measure.hpp | 8 +++++++- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 22 +++++++++++++++++++--- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index a8ee3d326..724f4ab80 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -262,7 +262,7 @@ void MeasuringImpl::extract_features() for (const auto& [start_idx, end_idx] : circles) { std::pair center_and_radius = get_center_and_radius(border, start_idx, end_idx, trafo); plane.surface_features.emplace_back(std::unique_ptr( - new Circle(center_and_radius.first, center_and_radius.second))); + new Circle(center_and_radius.first, center_and_radius.second, plane.normal))); } } @@ -382,6 +382,15 @@ double Measuring::get_distance(const SurfaceFeature* feature, const Vec3d* pt) Eigen::ParametrizedLine line(s, (e-s).normalized()); return line.distance(*pt); } + else if (feature->get_type() == SurfaceFeatureType::Circle) { + const Circle* circle = static_cast(feature); + // Find a plane containing normal, center and the point. + const Vec3d& c = circle->get_center(); + const Vec3d& n = circle->get_normal(); + Eigen::Hyperplane circle_plane(n, c); + Vec3d proj = circle_plane.projection(*pt); + return std::sqrt( std::pow((proj - c).norm() - circle->get_radius(), 2.) + (*pt - proj).squaredNorm()); + } return std::numeric_limits::max(); } diff --git a/src/libslic3r/Measure.hpp b/src/libslic3r/Measure.hpp index 1360b47ff..0455291bf 100644 --- a/src/libslic3r/Measure.hpp +++ b/src/libslic3r/Measure.hpp @@ -28,22 +28,28 @@ public: class Edge : public SurfaceFeature { public: Edge(const Vec3d& start, const Vec3d& end) : m_start{start}, m_end{end} {} + Edge(const Vec3d& start, const Vec3d& end, const Vec3d& pin) : m_start{start}, m_end{end}, + m_pin{std::unique_ptr(new Vec3d(pin))} {} SurfaceFeatureType get_type() const override { return SurfaceFeatureType::Edge; } std::pair get_edge() const { return std::make_pair(m_start, m_end); } private: Vec3d m_start; Vec3d m_end; + std::unique_ptr m_pin; }; class Circle : public SurfaceFeature { public: - Circle(const Vec3d& center, double radius) : m_center{center}, m_radius{radius} {} + Circle(const Vec3d& center, double radius, const Vec3d& normal) + : m_center{center}, m_radius{radius}, m_normal{normal} {} SurfaceFeatureType get_type() const override { return SurfaceFeatureType::Circle; } Vec3d get_center() const { return m_center; } double get_radius() const { return m_radius; } + Vec3d get_normal() const { return m_normal; } private: Vec3d m_center; double m_radius; + Vec3d m_normal; }; class Plane : public SurfaceFeature { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index a8b257a93..44dd44cc5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -174,12 +174,28 @@ void GLGizmoMeasure::on_render() if (feature->get_type() == Measure::SurfaceFeatureType::Circle) { const auto* circle = static_cast(feature); - Transform3d view_feature_matrix = view_model_matrix * Transform3d(Eigen::Translation3d(circle->get_center())); - view_feature_matrix = view_model_matrix * Transform3d(Eigen::Translation3d(circle->get_center())); + const Vec3d& c = circle->get_center(); + const Vec3d& n = circle->get_normal(); + Transform3d view_feature_matrix = view_model_matrix * Transform3d(Eigen::Translation3d(c)); view_feature_matrix.scale(0.5); shader->set_uniform("view_model_matrix", view_feature_matrix); - m_vbo_sphere.set_color(ColorRGBA(0.f, 1.f, 0.f, 1.f)); + m_vbo_sphere.set_color(ColorRGBA(0.8f, 0.2f, 0.2f, 1.f)); m_vbo_sphere.render(); + + // Now draw the circle itself - let's take a funny shortcut: + Vec3d rad = n.cross(Vec3d::UnitX()); + if (rad.squaredNorm() < 0.1) + rad = n.cross(Vec3d::UnitY()); + rad *= circle->get_radius() * rad.norm(); + const int N = 20; + for (int i=0; iset_uniform("view_model_matrix", view_feature_matrix); + m_vbo_sphere.render(); + } } else if (feature->get_type() == Measure::SurfaceFeatureType::Edge) { const auto* edge = static_cast(feature);