Refactoring and performance optimization for support trees in SLA

This commit is contained in:
tamasmeszaros 2022-05-11 12:08:32 +02:00
parent 60cd7d4561
commit d23f9d7674
36 changed files with 2995 additions and 2627 deletions

View file

@ -8,7 +8,7 @@
// Need the cylinder method for the the drainholes in hollowing step
#include <libslic3r/SLA/SupportTreeBuilder.hpp>
#include <libslic3r/SLA/Concurrency.hpp>
#include <libslic3r/Execution/ExecutionTBB.hpp>
#include <libslic3r/SLA/Pad.hpp>
#include <libslic3r/SLA/SupportPointGenerator.hpp>
@ -546,12 +546,13 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po)
std::vector<ExPolygons> interior_slices = slice_mesh_ex(interiormesh, slice_grid, params, thr);
sla::ccr::for_each(size_t(0), interior_slices.size(),
[&po, &interior_slices] (size_t i) {
const ExPolygons &slice = interior_slices[i];
po.m_model_slices[i] =
diff_ex(po.m_model_slices[i], slice);
});
execution::for_each(
ex_tbb, size_t(0), interior_slices.size(),
[&po, &interior_slices](size_t i) {
const ExPolygons &slice = interior_slices[i];
po.m_model_slices[i] = diff_ex(po.m_model_slices[i], slice);
},
execution::max_concurrency(ex_tbb));
}
auto mit = slindex_it;
@ -621,16 +622,17 @@ void SLAPrint::Steps::support_points(SLAPrintObject &po)
// Construction of this object does the calculation.
throw_if_canceled();
sla::SupportPointGenerator auto_supports(
po.m_supportdata->emesh, po.get_model_slices(), heights, config,
[this]() { throw_if_canceled(); }, statuscb);
po.m_supportdata->input.emesh, po.get_model_slices(),
heights, config, [this]() { throw_if_canceled(); }, statuscb);
// Now let's extract the result.
const std::vector<sla::SupportPoint>& points = auto_supports.output();
throw_if_canceled();
po.m_supportdata->pts = points;
po.m_supportdata->input.pts = points;
BOOST_LOG_TRIVIAL(debug) << "Automatic support points: "
<< po.m_supportdata->pts.size();
BOOST_LOG_TRIVIAL(debug)
<< "Automatic support points: "
<< po.m_supportdata->input.pts.size();
// Using RELOAD_SLA_SUPPORT_POINTS to tell the Plater to pass
// the update status to GLGizmoSlaSupports
@ -639,7 +641,7 @@ void SLAPrint::Steps::support_points(SLAPrintObject &po)
} else {
// There are either some points on the front-end, or the user
// removed them on purpose. No calculation will be done.
po.m_supportdata->pts = po.transformed_support_points();
po.m_supportdata->input.pts = po.transformed_support_points();
}
}
@ -647,19 +649,22 @@ void SLAPrint::Steps::support_tree(SLAPrintObject &po)
{
if(!po.m_supportdata) return;
sla::PadConfig pcfg = make_pad_cfg(po.m_config);
// sla::PadConfig pcfg = make_pad_cfg(po.m_config);
if (pcfg.embed_object)
po.m_supportdata->emesh.ground_level_offset(pcfg.wall_thickness_mm);
// if (pcfg.embed_object)
// po.m_supportdata->emesh.ground_level_offset(pcfg.wall_thickness_mm);
// If the zero elevation mode is engaged, we have to filter out all the
// points that are on the bottom of the object
if (is_zero_elevation(po.config())) {
remove_bottom_points(po.m_supportdata->pts,
float(po.m_supportdata->emesh.ground_level() + EPSILON));
remove_bottom_points(po.m_supportdata->input.pts,
float(
po.m_supportdata->input.emesh.ground_level() +
EPSILON));
}
po.m_supportdata->cfg = make_support_cfg(po.m_config);
po.m_supportdata->input.cfg = make_support_cfg(po.m_config);
po.m_supportdata->input.pad_cfg = make_pad_cfg(po.m_config);
// po.m_supportdata->emesh.load_holes(po.transformed_drainhole_points());
// scaling for the sub operations
@ -689,7 +694,7 @@ void SLAPrint::Steps::support_tree(SLAPrintObject &po)
report_status(-1, L("Visualizing supports"));
BOOST_LOG_TRIVIAL(debug) << "Processed support point count "
<< po.m_supportdata->pts.size();
<< po.m_supportdata->input.pts.size();
// Check the mesh for later troubleshooting.
if(po.support_mesh().empty())
@ -705,31 +710,34 @@ void SLAPrint::Steps::generate_pad(SLAPrintObject &po) {
if(po.m_config.pad_enable.getBool()) {
// Get the distilled pad configuration from the config
// (Again, despite it was retrieved in the previous step. Note that
// on a param change event, the previous step might not be executed
// depending on the specific parameter that has changed).
sla::PadConfig pcfg = make_pad_cfg(po.m_config);
po.m_supportdata->input.pad_cfg = pcfg;
ExPolygons bp; // This will store the base plate of the pad.
double pad_h = pcfg.full_height();
const TriangleMesh &trmesh = po.transformed_mesh();
// if (!po.m_config.supports_enable.getBool() || pcfg.embed_object) {
// // No support (thus no elevation) or zero elevation mode
// // we sometimes call it "builtin pad" is enabled so we will
// // get a sample from the bottom of the mesh and use it for pad
// // creation.
// sla::pad_blueprint(trmesh.its, bp, float(pad_h),
// float(po.m_config.layer_height.getFloat()),
// [this](){ throw_if_canceled(); });
// }
if (!po.m_config.supports_enable.getBool() || pcfg.embed_object) {
// No support (thus no elevation) or zero elevation mode
// we sometimes call it "builtin pad" is enabled so we will
// get a sample from the bottom of the mesh and use it for pad
// creation.
sla::pad_blueprint(trmesh.its, bp, float(pad_h),
float(po.m_config.layer_height.getFloat()),
[this](){ throw_if_canceled(); });
}
sla::JobController ctl;
ctl.stopcondition = [this]() { return canceled(); };
ctl.cancelfn = [this]() { throw_if_canceled(); };
po.m_supportdata->create_pad(ctl);
po.m_supportdata->create_pad(bp, pcfg);
if (!validate_pad(po.m_supportdata->support_tree_ptr->retrieve_mesh(sla::MeshType::Pad), pcfg))
if (!validate_pad(po.m_supportdata->pad_mesh.its, pcfg))
throw Slic3r::SlicingError(
L("No pad can be generated for this model with the "
"current configuration"));
} else if(po.m_supportdata && po.m_supportdata->support_tree_ptr) {
po.m_supportdata->support_tree_ptr->remove_pad();
} else if(po.m_supportdata) {
po.m_supportdata->pad_mesh = {};
}
throw_if_canceled();
@ -748,13 +756,18 @@ void SLAPrint::Steps::slice_supports(SLAPrintObject &po) {
if (!po.m_config.supports_enable.getBool() && !po.m_config.pad_enable.getBool())
return;
if(sd && sd->support_tree_ptr) {
if(sd) {
auto heights = reserve_vector<float>(po.m_slice_index.size());
for(auto& rec : po.m_slice_index) heights.emplace_back(rec.slice_level());
sd->support_slices = sd->support_tree_ptr->slice(
heights, float(po.config().slice_closing_radius.value));
sla::JobController ctl;
ctl.stopcondition = [this]() { return canceled(); };
ctl.cancelfn = [this]() { throw_if_canceled(); };
sd->support_slices =
sla::slice(sd->tree_mesh.its, sd->pad_mesh.its, heights,
float(po.config().slice_closing_radius.value), ctl);
}
for (size_t i = 0; i < sd->support_slices.size() && i < po.m_slice_index.size(); ++i)
@ -910,8 +923,8 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
const double delta_fade_time = (init_exp_time - exp_time) / (fade_layers_cnt + 1);
double fade_layer_time = init_exp_time;
sla::ccr::SpinningMutex mutex;
using Lock = std::lock_guard<sla::ccr::SpinningMutex>;
execution::SpinningMutex<ExecutionTBB> mutex;
using Lock = std::lock_guard<decltype(mutex)>;
// Going to parallel:
auto printlayerfn = [this,
@ -1027,7 +1040,8 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
// sequential version for debugging:
// for(size_t i = 0; i < m_printer_input.size(); ++i) printlayerfn(i);
sla::ccr::for_each(size_t(0), printer_input.size(), printlayerfn);
execution::for_each(ex_tbb, size_t(0), printer_input.size(), printlayerfn,
execution::max_concurrency(ex_tbb));
auto SCALING2 = SCALING_FACTOR * SCALING_FACTOR;
print_statistics.support_used_material = supports_volume * SCALING2;
@ -1066,8 +1080,7 @@ void SLAPrint::Steps::rasterize()
double increment = (slot * sd) / m_print->m_printer_input.size();
double dstatus = current_status();
sla::ccr::SpinningMutex slck;
using Lock = std::lock_guard<sla::ccr::SpinningMutex>;
execution::SpinningMutex<ExecutionTBB> slck;
// procedure to process one height level. This will run in parallel
auto lvlfn =
@ -1082,7 +1095,7 @@ void SLAPrint::Steps::rasterize()
// Status indication guarded with the spinlock
{
Lock lck(slck);
std::lock_guard lck(slck);
dstatus += increment;
double st = std::round(dstatus);
if(st > pst) {