diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index f756cfcf4c..1d9f981a6a 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -578,7 +578,7 @@ inline double ray_mesh_intersect(const Vec3d& s, // samples: how many rays will be shot // safety distance: This will be added to the radiuses to have a safety distance // from the mesh. -double pinhead_mesh_intersect(const Vec3d& s_original, +double pinhead_mesh_intersect(const Vec3d& s, const Vec3d& dir, double r_pin, double r_back, @@ -597,8 +597,6 @@ double pinhead_mesh_intersect(const Vec3d& s_original, // Move away slightly from the touching point to avoid raycasting on the // inner surface of the mesh. - Vec3d s = s_original + r_pin * dir; - Vec3d v = dir; // Our direction (axis) Vec3d c = s + width * dir; @@ -634,15 +632,20 @@ double pinhead_mesh_intersect(const Vec3d& s_original, s(Y) + rpscos * a(Y) + rpssin * b(Y), s(Z) + rpscos * a(Z) + rpssin * b(Z)); + // Point ps is not on mesh but can be inside or outside as well. This + // would cause many problems with ray-casting. So we query the closest + // point on the mesh to this. + auto result = m.signed_distance(ps); + // This is the point on the circle on the back sphere Vec3d p(c(X) + rpbcos * a(X) + rpbsin * b(X), c(Y) + rpbcos * a(Y) + rpbsin * b(Y), c(Z) + rpbcos * a(Z) + rpbsin * b(Z)); - if(m.inside(ps) && m.inside(p)) { - Vec3d n = (p - ps).normalized(); - phi = m.query_ray_hit(ps, n); - } else phi = std::numeric_limits::infinity(); + if(!m.inside(p)) { + Vec3d n = (p - result.point_on_mesh() + 0.01 * dir).normalized(); + phi = m.query_ray_hit(result.point_on_mesh(), n); + } else phi = 0; } auto mit = std::min_element(phis.begin(), phis.end()); @@ -650,7 +653,7 @@ double pinhead_mesh_intersect(const Vec3d& s_original, return *mit; } -double bridge_mesh_intersect(const Vec3d& s_original, +double bridge_mesh_intersect(const Vec3d& s, const Vec3d& dir, double r, const EigenMesh3D& m, @@ -658,7 +661,7 @@ double bridge_mesh_intersect(const Vec3d& s_original, double safety_distance = 0.05) { // helper vector calculations - Vec3d s = s_original + r*dir; Vec3d a(0, 1, 0), b; + Vec3d a(0, 1, 0), b; a(Z) = -(dir(X)*a(X) + dir(Y)*a(Y)) / dir(Z); b = a.cross(dir); @@ -680,8 +683,9 @@ double bridge_mesh_intersect(const Vec3d& s_original, s(Y) + rcos * a(Y) + rsin * b(Y), s(Z) + rcos * a(Z) + rsin * b(Z)); - if(m.inside(p)) phi = m.query_ray_hit(p, dir); - else phi = std::numeric_limits::infinity(); + auto result = m.signed_distance(p); + + phi = m.query_ray_hit(result.point_on_mesh() + 0.05*dir, dir); } auto mit = std::min_element(phis.begin(), phis.end()); @@ -1190,6 +1194,8 @@ bool SLASupportTree::generate(const PointSet &points, std::sin(azimuth) * std::sin(polar), std::cos(polar)); + nn.normalize(); + // save the head (pinpoint) position Vec3d hp = filt_pts.row(i); diff --git a/src/libslic3r/SLA/SLASupportTree.hpp b/src/libslic3r/SLA/SLASupportTree.hpp index ac7d7cab87..e13dd8c764 100644 --- a/src/libslic3r/SLA/SLASupportTree.hpp +++ b/src/libslic3r/SLA/SLASupportTree.hpp @@ -130,9 +130,26 @@ public: // Casting a ray on the mesh, returns the distance where the hit occures. double query_ray_hit(const Vec3d &s, const Vec3d &dir) const; + class si_result { + double m_value; + int m_fidx; + Vec3d m_p; + si_result(double val, int i, const Vec3d& c): + m_value(val), m_fidx(i), m_p(c) {} + friend class EigenMesh3D; + public: + + si_result() = delete; + + double value() const { return m_value; } + operator double() const { return m_value; } + const Vec3d& point_on_mesh() const { return m_p; } + int F_idx() const { return m_fidx; } + }; + // The signed distance from a point to the mesh. Outputs the distance, // the index of the triangle and the closest point in mesh coordinate space. - std::tuple signed_distance(const Vec3d& p) const; + si_result signed_distance(const Vec3d& p) const; bool inside(const Vec3d& p) const; }; diff --git a/src/libslic3r/SLA/SLASupportTreeIGL.cpp b/src/libslic3r/SLA/SLASupportTreeIGL.cpp index 358d9dc9c3..b84e66e41c 100644 --- a/src/libslic3r/SLA/SLASupportTreeIGL.cpp +++ b/src/libslic3r/SLA/SLASupportTreeIGL.cpp @@ -166,10 +166,12 @@ double EigenMesh3D::query_ray_hit(const Vec3d &s, const Vec3d &dir) const return double(hit.t); } -std::tuple -EigenMesh3D::signed_distance(const Vec3d &/*p*/) const { - // TODO: implement - return std::make_tuple(0.0, 0, Vec3d()); +EigenMesh3D::si_result EigenMesh3D::signed_distance(const Vec3d &p) const { + double sign = 0; double sqdst = 0; int i = 0; Vec3d c; + igl::signed_distance_winding_number(*m_aabb, m_V, m_F, m_aabb->windtree, + p, sign, sqdst, i, c); + + return si_result(sign * std::sqrt(sqdst), i, c); } bool EigenMesh3D::inside(const Vec3d &p) const {