mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 20:29:04 +08:00
SLA z correction:
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
This commit is contained in:
parent
9c0cb3b47c
commit
ac2580caf0
@ -483,6 +483,8 @@ set(SLIC3R_SOURCES
|
|||||||
SLA/DefaultSupportTree.cpp
|
SLA/DefaultSupportTree.cpp
|
||||||
SLA/BranchingTreeSLA.hpp
|
SLA/BranchingTreeSLA.hpp
|
||||||
SLA/BranchingTreeSLA.cpp
|
SLA/BranchingTreeSLA.cpp
|
||||||
|
SLA/ZCorrection.hpp
|
||||||
|
SLA/ZCorrection.cpp
|
||||||
BranchingTree/BranchingTree.cpp
|
BranchingTree/BranchingTree.cpp
|
||||||
BranchingTree/BranchingTree.hpp
|
BranchingTree/BranchingTree.hpp
|
||||||
BranchingTree/PointCloud.cpp
|
BranchingTree/PointCloud.cpp
|
||||||
|
@ -609,6 +609,7 @@ static std::vector<std::string> s_Preset_sla_material_options {
|
|||||||
"material_print_speed",
|
"material_print_speed",
|
||||||
"area_fill",
|
"area_fill",
|
||||||
"default_sla_material_profile",
|
"default_sla_material_profile",
|
||||||
|
"zcorrection_layers",
|
||||||
"compatible_prints", "compatible_prints_condition",
|
"compatible_prints", "compatible_prints_condition",
|
||||||
"compatible_printers", "compatible_printers_condition", "inherits",
|
"compatible_printers", "compatible_printers_condition", "inherits",
|
||||||
|
|
||||||
|
@ -4042,6 +4042,14 @@ void PrintConfigDef::init_sla_params()
|
|||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionFloat(0.2));
|
def->set_default_value(new ConfigOptionFloat(0.2));
|
||||||
|
|
||||||
|
def = this->add("zcorrection_layers", coInt);
|
||||||
|
def->label = L("Z compensation");
|
||||||
|
def->category = L("Advanced");
|
||||||
|
def->tooltip = L("Number of layers to Z correct to avoid cross layer bleed");
|
||||||
|
def->min = 0;
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionInt(0));
|
||||||
|
|
||||||
def = this->add("gamma_correction", coFloat);
|
def = this->add("gamma_correction", coFloat);
|
||||||
def->label = L("Printer gamma correction");
|
def->label = L("Printer gamma correction");
|
||||||
def->full_label = L("Printer gamma correction");
|
def->full_label = L("Printer gamma correction");
|
||||||
|
@ -1174,6 +1174,8 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||||||
((ConfigOptionFloat, material_correction_y))
|
((ConfigOptionFloat, material_correction_y))
|
||||||
((ConfigOptionFloat, material_correction_z))
|
((ConfigOptionFloat, material_correction_z))
|
||||||
((ConfigOptionEnum<SLAMaterialSpeed>, material_print_speed))
|
((ConfigOptionEnum<SLAMaterialSpeed>, material_print_speed))
|
||||||
|
((ConfigOptionInt, zcorrection_layers))
|
||||||
|
|
||||||
((ConfigOptionFloatNullable, material_ow_support_pillar_diameter))
|
((ConfigOptionFloatNullable, material_ow_support_pillar_diameter))
|
||||||
((ConfigOptionFloatNullable, material_ow_branchingsupport_pillar_diameter))
|
((ConfigOptionFloatNullable, material_ow_branchingsupport_pillar_diameter))
|
||||||
((ConfigOptionFloatNullable, material_ow_support_head_front_diameter))
|
((ConfigOptionFloatNullable, material_ow_support_head_front_diameter))
|
||||||
|
130
src/libslic3r/SLA/ZCorrection.cpp
Normal file
130
src/libslic3r/SLA/ZCorrection.cpp
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#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
|
84
src/libslic3r/SLA/ZCorrection.hpp
Normal file
84
src/libslic3r/SLA/ZCorrection.hpp
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#ifndef ZCORRECTION_HPP
|
||||||
|
#define ZCORRECTION_HPP
|
||||||
|
|
||||||
|
#include "libslic3r/ExPolygon.hpp"
|
||||||
|
#include "libslic3r/Execution/Execution.hpp"
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
namespace sla {
|
||||||
|
|
||||||
|
std::vector<ExPolygons> apply_zcorrection(const std::vector<ExPolygons> &slices,
|
||||||
|
size_t layers);
|
||||||
|
|
||||||
|
std::vector<ExPolygons> apply_zcorrection(const std::vector<ExPolygons> &slices,
|
||||||
|
const std::vector<float> &grid,
|
||||||
|
float depth);
|
||||||
|
|
||||||
|
namespace zcorr_detail {
|
||||||
|
|
||||||
|
ExPolygons intersect_layers(const std::vector<ExPolygons> &slices,
|
||||||
|
size_t layer_from,
|
||||||
|
size_t layers_down);
|
||||||
|
|
||||||
|
template<class Ex>
|
||||||
|
std::vector<ExPolygons> apply_zcorrection(Ex ep,
|
||||||
|
const std::vector<ExPolygons> &slices,
|
||||||
|
size_t layers)
|
||||||
|
{
|
||||||
|
std::vector<ExPolygons> output(slices.size());
|
||||||
|
|
||||||
|
execution::for_each(ep, size_t{0}, slices.size(),
|
||||||
|
[&output, &slices, layers] (size_t lyr) {
|
||||||
|
output[lyr] = intersect_layers(slices, lyr, layers);
|
||||||
|
}, execution::max_concurrency(ep));
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t depth_to_layers(const std::vector<float> &grid,
|
||||||
|
size_t from_layer,
|
||||||
|
float depth)
|
||||||
|
{
|
||||||
|
size_t depth_layers = 0;
|
||||||
|
while (from_layer > depth_layers &&
|
||||||
|
grid[from_layer - depth_layers] > grid[from_layer] - depth)
|
||||||
|
depth_layers++;
|
||||||
|
|
||||||
|
return depth_layers;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Ex>
|
||||||
|
std::vector<ExPolygons> apply_zcorrection(Ex ep,
|
||||||
|
const std::vector<ExPolygons> &slices,
|
||||||
|
const std::vector<float> &grid,
|
||||||
|
float depth)
|
||||||
|
{
|
||||||
|
std::vector<ExPolygons> output(slices.size());
|
||||||
|
|
||||||
|
execution::for_each(ep, size_t{0}, slices.size(),
|
||||||
|
[&output, &slices, &grid, depth] (size_t lyr) {
|
||||||
|
output[lyr] = intersect_layers(slices, lyr,
|
||||||
|
depth_to_layers(grid, lyr, depth));
|
||||||
|
}, execution::max_concurrency(ep));
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
using DepthMapLayer = std::map<size_t, ExPolygons>;
|
||||||
|
using DepthMap = std::vector<DepthMapLayer>;
|
||||||
|
|
||||||
|
DepthMap create_depthmap(const std::vector<ExPolygons> &slices,
|
||||||
|
const std::vector<float> &grid, size_t max_depth = 0);
|
||||||
|
|
||||||
|
void apply_zcorrection(DepthMap &dmap, size_t layers);
|
||||||
|
|
||||||
|
ExPolygons merged_layer(const DepthMapLayer &dlayer);
|
||||||
|
|
||||||
|
std::vector<ExPolygons> depthmap_to_slices(const DepthMap &dm);
|
||||||
|
|
||||||
|
} // namespace zcorr_detail
|
||||||
|
|
||||||
|
} // namespace sla
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif // ZCORRECTION_HPP
|
@ -842,6 +842,7 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector<t_config_opt
|
|||||||
"absolute_correction"sv,
|
"absolute_correction"sv,
|
||||||
"elefant_foot_compensation"sv,
|
"elefant_foot_compensation"sv,
|
||||||
"elefant_foot_min_width"sv,
|
"elefant_foot_min_width"sv,
|
||||||
|
"zcorrection_layers"sv,
|
||||||
"gamma_correction"sv,
|
"gamma_correction"sv,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <libslic3r/Execution/ExecutionTBB.hpp>
|
#include <libslic3r/Execution/ExecutionTBB.hpp>
|
||||||
#include <libslic3r/SLA/Pad.hpp>
|
#include <libslic3r/SLA/Pad.hpp>
|
||||||
#include <libslic3r/SLA/SupportPointGenerator.hpp>
|
#include <libslic3r/SLA/SupportPointGenerator.hpp>
|
||||||
|
#include <libslic3r/SLA/ZCorrection.hpp>
|
||||||
|
|
||||||
#include <libslic3r/ElephantFootCompensation.hpp>
|
#include <libslic3r/ElephantFootCompensation.hpp>
|
||||||
#include <libslic3r/AABBTreeIndirect.hpp>
|
#include <libslic3r/AABBTreeIndirect.hpp>
|
||||||
@ -129,6 +130,11 @@ void SLAPrint::Steps::apply_printer_corrections(SLAPrintObject &po, SliceOrigin
|
|||||||
if (idx < slices.size())
|
if (idx < slices.size())
|
||||||
slices[idx] = elephant_foot_compensation(slices[idx], min_w, efc(i));
|
slices[idx] = elephant_foot_compensation(slices[idx], min_w, efc(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (o == soModel) { // Z correction applies only to the model slices
|
||||||
|
slices = sla::apply_zcorrection(slices,
|
||||||
|
m_print->m_material_config.zcorrection_layers.getInt());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
indexed_triangle_set SLAPrint::Steps::generate_preview_vdb(
|
indexed_triangle_set SLAPrint::Steps::generate_preview_vdb(
|
||||||
|
@ -5341,7 +5341,16 @@ void TabSLAMaterial::build()
|
|||||||
opt.opt.label = axis;
|
opt.opt.label = axis;
|
||||||
line.append_option(opt);
|
line.append_option(opt);
|
||||||
}
|
}
|
||||||
|
optgroup->append_line(line);
|
||||||
|
|
||||||
|
optgroup->append_single_option_line("zcorrection_layers");
|
||||||
|
|
||||||
|
line = Line{ "", "" };
|
||||||
|
line.full_width = 1;
|
||||||
|
// line.label_path = category_path + "recommended-thin-wall-thickness";
|
||||||
|
line.widget = [this](wxWindow* parent) {
|
||||||
|
return description_line_widget(parent, &m_z_correction_to_mm_description);
|
||||||
|
};
|
||||||
optgroup->append_line(line);
|
optgroup->append_line(line);
|
||||||
|
|
||||||
add_material_overrides_page();
|
add_material_overrides_page();
|
||||||
@ -5491,7 +5500,19 @@ void TabSLAMaterial::update()
|
|||||||
// m_update_cnt--;
|
// m_update_cnt--;
|
||||||
//
|
//
|
||||||
// if (m_update_cnt == 0)
|
// if (m_update_cnt == 0)
|
||||||
wxGetApp().mainframe->on_config_changed(m_config);
|
wxGetApp().mainframe->on_config_changed(m_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabSLAMaterial::update_description_lines()
|
||||||
|
{
|
||||||
|
if (m_active_page && m_active_page->title() == "Material" && m_z_correction_to_mm_description) {
|
||||||
|
auto cfg = m_preset_bundle->full_config();
|
||||||
|
double lh = cfg.opt_float("layer_height");
|
||||||
|
int zlayers = cfg.opt_int("zcorrection_layers");
|
||||||
|
m_z_correction_to_mm_description->SetText(GUI::format_wxstr(_L("Current Z correction depth is: %1% mm"), zlayers * lh));
|
||||||
|
}
|
||||||
|
|
||||||
|
Tab::update_description_lines();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabSLAMaterial::update_sla_prusa_specific_visibility()
|
void TabSLAMaterial::update_sla_prusa_specific_visibility()
|
||||||
@ -5519,6 +5540,8 @@ void TabSLAMaterial::clear_pages()
|
|||||||
|
|
||||||
for (auto& over_opt : m_overrides_options)
|
for (auto& over_opt : m_overrides_options)
|
||||||
over_opt.second = nullptr;
|
over_opt.second = nullptr;
|
||||||
|
|
||||||
|
m_z_correction_to_mm_description = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabSLAMaterial::msw_rescale()
|
void TabSLAMaterial::msw_rescale()
|
||||||
|
@ -571,6 +571,8 @@ class TabSLAMaterial : public Tab
|
|||||||
void update_material_overrides_page();
|
void update_material_overrides_page();
|
||||||
|
|
||||||
std::map<std::string, wxWindow*> m_overrides_options;
|
std::map<std::string, wxWindow*> m_overrides_options;
|
||||||
|
ogStaticText* m_z_correction_to_mm_description = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TabSLAMaterial(wxBookCtrlBase* parent) :
|
TabSLAMaterial(wxBookCtrlBase* parent) :
|
||||||
Tab(parent, _L("Materials"), Slic3r::Preset::TYPE_SLA_MATERIAL) {}
|
Tab(parent, _L("Materials"), Slic3r::Preset::TYPE_SLA_MATERIAL) {}
|
||||||
@ -586,6 +588,7 @@ public:
|
|||||||
void sys_color_changed() override;
|
void sys_color_changed() override;
|
||||||
bool supports_printer_technology(const PrinterTechnology tech) const override { return tech == ptSLA; }
|
bool supports_printer_technology(const PrinterTechnology tech) const override { return tech == ptSLA; }
|
||||||
void update_sla_prusa_specific_visibility() override;
|
void update_sla_prusa_specific_visibility() override;
|
||||||
|
void update_description_lines() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TabSLAPrint : public Tab
|
class TabSLAPrint : public Tab
|
||||||
|
@ -5,7 +5,8 @@ add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests_main.cpp
|
|||||||
sla_supptgen_tests.cpp
|
sla_supptgen_tests.cpp
|
||||||
sla_raycast_tests.cpp
|
sla_raycast_tests.cpp
|
||||||
sla_supptreeutils_tests.cpp
|
sla_supptreeutils_tests.cpp
|
||||||
sla_archive_readwrite_tests.cpp)
|
sla_archive_readwrite_tests.cpp
|
||||||
|
sla_zcorrection_tests.cpp)
|
||||||
|
|
||||||
# mold linker for successful linking needs also to link TBB library and link it before libslic3r.
|
# mold linker for successful linking needs also to link TBB library and link it before libslic3r.
|
||||||
target_link_libraries(${_TEST_NAME}_tests test_common TBB::tbb TBB::tbbmalloc libslic3r)
|
target_link_libraries(${_TEST_NAME}_tests test_common TBB::tbb TBB::tbbmalloc libslic3r)
|
||||||
|
123
tests/sla_print/sla_zcorrection_tests.cpp
Normal file
123
tests/sla_print/sla_zcorrection_tests.cpp
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
#include <catch2/catch.hpp>
|
||||||
|
#include <test_utils.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "libslic3r/TriangleMeshSlicer.hpp"
|
||||||
|
#include "libslic3r/SLA/ZCorrection.hpp"
|
||||||
|
#include "libslic3r/MTUtils.hpp"
|
||||||
|
#include "libslic3r/SVG.hpp"
|
||||||
|
|
||||||
|
void print_depthmap(std::string_view prefix,
|
||||||
|
const Slic3r::BoundingBox &bb,
|
||||||
|
const Slic3r::sla::zcorr_detail::DepthMap &dm)
|
||||||
|
{
|
||||||
|
using namespace Slic3r;
|
||||||
|
|
||||||
|
size_t cnt = 0;
|
||||||
|
for (const sla::zcorr_detail::DepthMapLayer &layer : dm) {
|
||||||
|
SVG svg(std::string(prefix) + std::to_string(cnt++) + ".svg", bb);
|
||||||
|
for (const auto &[depth, dpolys] : layer) {
|
||||||
|
svg.draw_outline(dpolys);
|
||||||
|
svg.draw(dpolys, "green", 1. + depth / 10.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Number of layers should be equal after z correction", "[ZCorr]")
|
||||||
|
{
|
||||||
|
using namespace Slic3r;
|
||||||
|
|
||||||
|
const size_t Layers = random_value(size_t{1}, size_t{100});
|
||||||
|
INFO("Layers = " << Layers);
|
||||||
|
|
||||||
|
float zcorr_depth = GENERATE(0.f, random_value(0.01f, 10.f));
|
||||||
|
|
||||||
|
std::vector<ExPolygons> slices(Layers);
|
||||||
|
std::vector<float> hgrid = grid(0.f, Layers * 1.f, 1.f);
|
||||||
|
|
||||||
|
std::vector<ExPolygons> output = sla::apply_zcorrection(slices, hgrid, zcorr_depth);
|
||||||
|
|
||||||
|
REQUIRE(slices.size() == output.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Testing DepthMap for a cube", "[ZCorr]")
|
||||||
|
{
|
||||||
|
using namespace Slic3r;
|
||||||
|
|
||||||
|
TriangleMesh mesh = load_model("20mm_cube.obj");
|
||||||
|
auto bb = bounding_box(mesh);
|
||||||
|
bb.offset(-0.1);
|
||||||
|
|
||||||
|
std::vector<float> hgrid = grid<float>(bb.min.z(), bb.max.z(), 1.f);
|
||||||
|
|
||||||
|
std::vector<ExPolygons> slices = slice_mesh_ex(mesh.its, hgrid, {});
|
||||||
|
|
||||||
|
sla::zcorr_detail::DepthMap dmap = sla::zcorr_detail::create_depthmap(slices, hgrid);
|
||||||
|
|
||||||
|
REQUIRE(dmap.size() == slices.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < slices.size(); ++i) {
|
||||||
|
const auto &dlayer = dmap[i];
|
||||||
|
const ExPolygons &slayer = slices[i];
|
||||||
|
REQUIRE(dlayer.size() == 1);
|
||||||
|
REQUIRE(dlayer.begin()->first == i);
|
||||||
|
double ad = area(dlayer.begin()->second);
|
||||||
|
double as = area(slayer);
|
||||||
|
REQUIRE(ad == Approx(as).margin(EPSILON));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Testing DepthMap for arbitrary shapes", "[ZCorr]")
|
||||||
|
{
|
||||||
|
using namespace Slic3r;
|
||||||
|
|
||||||
|
auto modelname = GENERATE("V_standing.obj", "A_upsidedown.obj");
|
||||||
|
|
||||||
|
TriangleMesh mesh = load_model(modelname);
|
||||||
|
auto bb = bounding_box(mesh);
|
||||||
|
bb.offset(-0.1);
|
||||||
|
|
||||||
|
std::vector<float> hgrid = grid<float>(bb.min.z(), bb.max.z(), 0.5f);
|
||||||
|
|
||||||
|
std::vector<ExPolygons> slices = slice_mesh_ex(mesh.its, hgrid, {});
|
||||||
|
|
||||||
|
size_t zcorr_layers = GENERATE(size_t{0}, random_value(size_t{1}, size_t{10}));
|
||||||
|
|
||||||
|
sla::zcorr_detail::DepthMap dmap =
|
||||||
|
sla::zcorr_detail::create_depthmap(slices, hgrid, zcorr_layers);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
print_depthmap("debug_dmap", scaled(to_2d(bb)), dmap);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
REQUIRE(dmap.size() == slices.size());
|
||||||
|
|
||||||
|
auto corrslices_fast = sla::apply_zcorrection(slices, zcorr_layers);
|
||||||
|
sla::zcorr_detail::apply_zcorrection(dmap, zcorr_layers);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < corrslices_fast.size(); ++i) {
|
||||||
|
ExPolygons dlayer = sla::zcorr_detail::merged_layer(dmap[i]);
|
||||||
|
const ExPolygons &slayer = corrslices_fast[i];
|
||||||
|
double ad = area(dlayer);
|
||||||
|
double as = area(slayer);
|
||||||
|
REQUIRE(ad == Approx(as).margin(EPSILON));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test depth to layers calculation", "[ZCorr]") {
|
||||||
|
using namespace Slic3r;
|
||||||
|
|
||||||
|
float layer_h = 0.5f;
|
||||||
|
std::vector<float> hgrid = grid(0.f, 100.f, layer_h);
|
||||||
|
|
||||||
|
float depth = GENERATE(0.f,
|
||||||
|
random_value(0.01f, 0.499f),
|
||||||
|
0.5f,
|
||||||
|
random_value(0.501f, 10.f));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < hgrid.size(); ++i) {
|
||||||
|
auto expected_lyrs = std::min(i, static_cast<size_t>(std::ceil(depth/layer_h)));
|
||||||
|
REQUIRE(sla::zcorr_detail::depth_to_layers(hgrid, i, depth) == expected_lyrs);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user