diff --git a/src/libslic3r/SLA/SLAAutoSupports.cpp b/src/libslic3r/SLA/SLAAutoSupports.cpp index 8f8d5673a7..ee87c6b663 100644 --- a/src/libslic3r/SLA/SLAAutoSupports.cpp +++ b/src/libslic3r/SLA/SLAAutoSupports.cpp @@ -13,8 +13,9 @@ namespace Slic3r { -SLAAutoSupports::SLAAutoSupports(const TriangleMesh& mesh, const sla::EigenMesh3D& emesh, const std::vector& slices, const std::vector& heights, const Config& config) -: m_config(config), m_V(emesh.V), m_F(emesh.F) +SLAAutoSupports::SLAAutoSupports(const TriangleMesh& mesh, const sla::EigenMesh3D& emesh, const std::vector& slices, const std::vector& heights, + const Config& config, std::function throw_on_cancel) +: m_config(config), m_V(emesh.V), m_F(emesh.F), m_throw_on_cancel(throw_on_cancel) { // FIXME: It might be safer to get rid of the rand() calls altogether, because it is probably // not always thread-safe and can be slow if it is. @@ -28,8 +29,10 @@ SLAAutoSupports::SLAAutoSupports(const TriangleMesh& mesh, const sla::EigenMesh3 // Uniformly cover each of the islands with support points. for (const auto& island : islands) { std::vector points = uniformly_cover(island); + m_throw_on_cancel(); project_upward_onto_mesh(points); m_output.insert(m_output.end(), points.begin(), points.end()); + m_throw_on_cancel(); } // We are done with the islands. Let's sprinkle the rest of the mesh. @@ -111,7 +114,14 @@ void SLAAutoSupports::sprinkle_mesh(const TriangleMesh& mesh) // Angle at which the density reaches zero: const float threshold_angle = std::min(M_PI_2, M_PI_4 * acos(0.f/m_config.density_at_horizontal) / acos(m_config.density_at_45/m_config.density_at_horizontal)); + size_t cancel_test_cntr = 0; while (refused_points < refused_limit) { + if (++ cancel_test_cntr == 500) { + // Don't call the cancellation routine too often as the multi-core cache synchronization + // may be pretty expensive. + m_throw_on_cancel(); + cancel_test_cntr = 0; + } // Place a random point on the mesh and calculate corresponding facet's normal: Eigen::VectorXi FI; Eigen::MatrixXd B; @@ -249,6 +259,7 @@ std::vector> SLAAutoSupports::find_islands(const s //if (!islands.empty()) // output_expolygons(islands, "islands" + layer_num_str + ".svg"); #endif /* SLA_AUTOSUPPORTS_DEBUG */ + m_throw_on_cancel(); } return islands; diff --git a/src/libslic3r/SLA/SLAAutoSupports.hpp b/src/libslic3r/SLA/SLAAutoSupports.hpp index 08dc452360..311d7b0c73 100644 --- a/src/libslic3r/SLA/SLAAutoSupports.hpp +++ b/src/libslic3r/SLA/SLAAutoSupports.hpp @@ -17,7 +17,8 @@ public: float minimal_z; }; - SLAAutoSupports(const TriangleMesh& mesh, const sla::EigenMesh3D& emesh, const std::vector& slices, const std::vector& heights, const Config& config); + SLAAutoSupports(const TriangleMesh& mesh, const sla::EigenMesh3D& emesh, const std::vector& slices, + const std::vector& heights, const Config& config, std::function throw_on_cancel); const std::vector& output() { return m_output; } private: @@ -38,6 +39,7 @@ private: #endif /* SLA_AUTOSUPPORTS_DEBUG */ SLAAutoSupports::Config m_config; + std::function m_throw_on_cancel; const Eigen::MatrixXd& m_V; const Eigen::MatrixXi& m_F; }; diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index afb9c6f871..85b63a24c3 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -514,6 +514,7 @@ void SLAPrint::process() float(po.get_elevation()), ilh, float(lh)); + this->throw_if_canceled(); SLAAutoSupports::Config config; const SLAPrintObjectConfig& cfg = po.config(); config.minimal_z = float(cfg.support_minimal_z); @@ -521,14 +522,17 @@ void SLAPrint::process() config.density_at_horizontal = cfg.support_density_at_horizontal / 10000.f; // Construction of this object does the calculation. + this->throw_if_canceled(); SLAAutoSupports auto_supports(po.transformed_mesh(), po.m_supportdata->emesh, po.get_model_slices(), heights, - config); + config, + [this]() { throw_if_canceled(); }); // Now let's extract the result. const std::vector& points = auto_supports.output(); + this->throw_if_canceled(); po.m_supportdata->support_points = sla::to_point_set(points); } else {