Refactoring and performance optimization for support trees in SLA
This commit is contained in:
parent
60cd7d4561
commit
d23f9d7674
36 changed files with 2995 additions and 2627 deletions
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue