#ifndef slic3r_MeshUtils_hpp_ #define slic3r_MeshUtils_hpp_ #include "libslic3r/Point.hpp" #include "libslic3r/Geometry.hpp" #include "libslic3r/SLA/EigenMesh3D.hpp" #include namespace Slic3r { class TriangleMesh; class TriangleMeshSlicer; namespace GUI { struct Camera; class ClippingPlane { double m_data[4]; public: ClippingPlane() { m_data[0] = 0.0; m_data[1] = 0.0; m_data[2] = 1.0; m_data[3] = 0.0; } ClippingPlane(const Vec3d& direction, double offset) { Vec3d norm_dir = direction.normalized(); m_data[0] = norm_dir(0); m_data[1] = norm_dir(1); m_data[2] = norm_dir(2); m_data[3] = offset; } bool operator==(const ClippingPlane& cp) const { return m_data[0]==cp.m_data[0] && m_data[1]==cp.m_data[1] && m_data[2]==cp.m_data[2] && m_data[3]==cp.m_data[3]; } bool operator!=(const ClippingPlane& cp) const { return ! (*this==cp); } double distance(const Vec3d& pt) const { assert(is_approx(get_normal().norm(), 1.)); return (-get_normal().dot(pt) + m_data[3]); } bool is_point_clipped(const Vec3d& point) const { return distance(point) < 0.; } void set_normal(const Vec3d& normal) { for (size_t i=0; i<3; ++i) m_data[i] = normal(i); } void set_offset(double offset) { m_data[3] = offset; } Vec3d get_normal() const { return Vec3d(m_data[0], m_data[1], m_data[2]); } bool is_active() const { return m_data[3] != DBL_MAX; } static ClippingPlane ClipsNothing() { return ClippingPlane(Vec3d(0., 0., 1.), DBL_MAX); } const double* get_data() const { return m_data; } // Serialization through cereal library template void serialize( Archive & ar ) { ar( m_data[0], m_data[1], m_data[2], m_data[3] ); } }; class MeshClipper { public: void set_plane(const ClippingPlane& plane); void set_mesh(const TriangleMesh& mesh); void set_transformation(const Geometry::Transformation& trafo); const std::vector& get_triangles(); private: void recalculate_triangles(); Geometry::Transformation m_trafo; const TriangleMesh* m_mesh = nullptr; ClippingPlane m_plane; std::vector m_triangles2d; std::vector m_triangles3d; bool m_triangles_valid = false; std::unique_ptr m_tms; }; class MeshRaycaster { public: MeshRaycaster(const TriangleMesh& mesh) : m_mesh(&mesh), m_emesh(mesh) {} void set_transformation(const Geometry::Transformation& trafo); void set_camera(const Camera& camera); bool unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane = nullptr) const; std::vector get_unobscured_idxs(const Geometry::Transformation& trafo, const Camera& camera, const std::vector& points, const ClippingPlane* clipping_plane = nullptr) const; Vec3f get_closest_point(const Vec3f& point, Vec3f* normal = nullptr) const; private: sla::EigenMesh3D m_emesh; const TriangleMesh* m_mesh = nullptr; }; } // namespace GUI } // namespace Slic3r #endif // slic3r_MeshUtils_hpp_