mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 17:11:59 +08:00

first SLA Z correction prototype Change Z correction controlling parameter to integer layer count Add z correction mm conversion text as description label under Z correction Fixed a crash when switching pages in material tab
131 lines
3.5 KiB
C++
131 lines
3.5 KiB
C++
#include "ZCorrection.hpp"
|
|
|
|
#include "Execution/ExecutionTBB.hpp"
|
|
|
|
#include "libslic3r/ClipperUtils.hpp"
|
|
|
|
namespace Slic3r { namespace sla {
|
|
|
|
std::vector<ExPolygons> apply_zcorrection(
|
|
const std::vector<ExPolygons> &slices, size_t layers)
|
|
{
|
|
return zcorr_detail::apply_zcorrection(ex_tbb, slices, layers);
|
|
}
|
|
|
|
std::vector<ExPolygons> apply_zcorrection(const std::vector<ExPolygons> &slices,
|
|
const std::vector<float> &grid,
|
|
float depth)
|
|
{
|
|
return zcorr_detail::apply_zcorrection(ex_tbb, slices, grid, depth);
|
|
}
|
|
|
|
namespace zcorr_detail {
|
|
|
|
DepthMap create_depthmap(const std::vector<ExPolygons> &slices,
|
|
const std::vector<float> &grid,
|
|
size_t max_depth)
|
|
{
|
|
struct DepthPoly {
|
|
size_t depth = 0;
|
|
ExPolygons contour;
|
|
};
|
|
|
|
DepthMap ret;
|
|
|
|
if (slices.empty() || slices.size() != grid.size())
|
|
return ret;
|
|
|
|
size_t depth_limit = max_depth > 0 ? max_depth : slices.size();
|
|
ret.resize(slices.size());
|
|
|
|
ret.front() = DepthMapLayer{ {size_t{0}, slices.front()} };
|
|
|
|
for (size_t i = 0; i < slices.size() - 1; ++i) {
|
|
DepthMapLayer &depths_current = ret[i];
|
|
DepthMapLayer &depths_nxt = ret[i + 1];
|
|
|
|
for (const auto &[depth, cntrs] : depths_current) {
|
|
DepthPoly common;
|
|
|
|
common.contour = intersection_ex(slices[i + 1], cntrs);
|
|
common.depth = std::min(depth_limit, depth + 1);
|
|
|
|
DepthPoly overhangs;
|
|
overhangs.contour = diff_ex(slices[i + 1], cntrs);
|
|
|
|
if (!common.contour.empty()) {
|
|
std::copy(common.contour.begin(), common.contour.end(),
|
|
std::back_inserter(depths_nxt[common.depth]));
|
|
}
|
|
|
|
if (!overhangs.contour.empty()) {
|
|
std::copy(overhangs.contour.begin(), overhangs.contour.end(),
|
|
std::back_inserter(depths_nxt[overhangs.depth]));
|
|
}
|
|
}
|
|
|
|
for(auto &[i, cntrs] : depths_nxt) {
|
|
depths_nxt[i] = union_ex(cntrs);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void apply_zcorrection(DepthMap &dmap, size_t layers)
|
|
{
|
|
for (size_t lyr = 0; lyr < dmap.size(); ++lyr) {
|
|
size_t threshold = std::min(lyr, layers);
|
|
|
|
auto &dlayer = dmap[lyr];
|
|
|
|
for (auto it = dlayer.begin(); it != dlayer.end();)
|
|
if (it->first < threshold)
|
|
it = dlayer.erase(it);
|
|
else
|
|
++it;
|
|
}
|
|
}
|
|
|
|
ExPolygons merged_layer(const DepthMapLayer &dlayer)
|
|
{
|
|
using namespace Slic3r;
|
|
|
|
ExPolygons out;
|
|
for (auto &[i, cntrs] : dlayer) {
|
|
std::copy(cntrs.begin(), cntrs.end(), std::back_inserter(out));
|
|
}
|
|
|
|
out = union_ex(out);
|
|
|
|
return out;
|
|
}
|
|
|
|
std::vector<ExPolygons> depthmap_to_slices(const DepthMap &dm)
|
|
{
|
|
auto out = reserve_vector<ExPolygons>(dm.size());
|
|
for (const auto &dlayer : dm) {
|
|
out.emplace_back(merged_layer(dlayer));
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
ExPolygons intersect_layers(const std::vector<ExPolygons> &slices,
|
|
size_t layer_from, size_t layers_down)
|
|
{
|
|
size_t drill_to = std::min(layer_from, layers_down);
|
|
auto drill_to_layer = static_cast<int>(layer_from - drill_to);
|
|
|
|
ExPolygons merged_lyr = slices[layer_from];
|
|
for (int i = layer_from; i >= drill_to_layer; --i)
|
|
merged_lyr = intersection_ex(merged_lyr, slices[i]);
|
|
|
|
return merged_lyr;
|
|
}
|
|
|
|
} // namespace zcorr_detail
|
|
|
|
} // namespace sla
|
|
} // namespace Slic3r
|