From 96d5c8c35d37f734a1548a02d7e2648e50db8d76 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 6 Feb 2020 14:09:48 +0100 Subject: [PATCH 1/3] Add elephant foot compensation to SLA print Work in progress Convert efc input to the right scaling Apply EFC on the slice index to make it visible in the preview. --- src/libslic3r/ElephantFootCompensation.cpp | 21 ++++++++++++++++++--- src/libslic3r/ElephantFootCompensation.hpp | 2 ++ src/libslic3r/PrintConfig.cpp | 10 ++++++++++ src/libslic3r/PrintConfig.hpp | 2 ++ src/libslic3r/SLAPrint.cpp | 1 + src/libslic3r/SLAPrintSteps.cpp | 15 +++++++++++++++ src/slic3r/GUI/Preset.cpp | 1 + src/slic3r/GUI/Tab.cpp | 3 ++- 8 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/ElephantFootCompensation.cpp b/src/libslic3r/ElephantFootCompensation.cpp index 2694b5e8a..a19aa2687 100644 --- a/src/libslic3r/ElephantFootCompensation.cpp +++ b/src/libslic3r/ElephantFootCompensation.cpp @@ -524,11 +524,10 @@ static inline void smooth_compensation_banded(const Points &contour, float band, } } -ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow &external_perimeter_flow, const double compensation) +ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, double min_contour_width, const double compensation) { - // The contour shall be wide enough to apply the external perimeter plus compensation on both sides. - double min_contour_width = double(external_perimeter_flow.scaled_width() + external_perimeter_flow.scaled_spacing()); double scaled_compensation = scale_(compensation); + min_contour_width = scale_(min_contour_width); double min_contour_width_compensated = min_contour_width + 2. * scaled_compensation; // Make the search radius a bit larger for the averaging in contour_distance over a fan of rays to work. double search_radius = min_contour_width_compensated + min_contour_width * 0.5; @@ -597,6 +596,13 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow & return out; } +ExPolygon elephant_foot_compensation(const ExPolygon &input, const Flow &external_perimeter_flow, const double compensation) +{ + // The contour shall be wide enough to apply the external perimeter plus compensation on both sides. + double min_contour_width = double(external_perimeter_flow.width + external_perimeter_flow.spacing()); + return elephant_foot_compensation(input, min_contour_width, compensation); +} + ExPolygons elephant_foot_compensation(const ExPolygons &input, const Flow &external_perimeter_flow, const double compensation) { ExPolygons out; @@ -606,4 +612,13 @@ ExPolygons elephant_foot_compensation(const ExPolygons &input, const Flow &exter return out; } +ExPolygons elephant_foot_compensation(const ExPolygons &input, double min_contour_width, const double compensation) +{ + ExPolygons out; + out.reserve(input.size()); + for (const ExPolygon &expoly : input) + out.emplace_back(elephant_foot_compensation(expoly, min_contour_width, compensation)); + return out; +} + } // namespace Slic3r diff --git a/src/libslic3r/ElephantFootCompensation.hpp b/src/libslic3r/ElephantFootCompensation.hpp index 0119df1af..beb17d10b 100644 --- a/src/libslic3r/ElephantFootCompensation.hpp +++ b/src/libslic3r/ElephantFootCompensation.hpp @@ -8,6 +8,8 @@ namespace Slic3r { class Flow; +ExPolygon elephant_foot_compensation(const ExPolygon &input, double min_countour_width, const double compensation); +ExPolygons elephant_foot_compensation(const ExPolygons &input, double min_countour_width, const double compensation); ExPolygon elephant_foot_compensation(const ExPolygon &input, const Flow &external_perimeter_flow, const double compensation); ExPolygons elephant_foot_compensation(const ExPolygons &input, const Flow &external_perimeter_flow, const double compensation); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 36d56c4c1..dfea714a8 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2442,6 +2442,16 @@ void PrintConfigDef::init_sla_params() "to the sign of the correction."); def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0.0)); + + def = this->add("elefant_foot_compensation", coFloat); + def->label = L("Elephant foot compensation"); + def->category = L("Advanced"); + def->tooltip = L("The first layer will be shrunk in the XY plane by the configured value " + "to compensate for the 1st layer squish aka an Elephant Foot effect."); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0.2)); def = this->add("gamma_correction", coFloat); def->label = L("Printer gamma correction"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index c854feafc..f320b3da5 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1175,6 +1175,7 @@ public: ConfigOptionBool display_mirror_y; ConfigOptionFloats relative_correction; ConfigOptionFloat absolute_correction; + ConfigOptionFloat elefant_foot_compensation; ConfigOptionFloat gamma_correction; ConfigOptionFloat fast_tilt_time; ConfigOptionFloat slow_tilt_time; @@ -1198,6 +1199,7 @@ protected: OPT_PTR(display_orientation); OPT_PTR(relative_correction); OPT_PTR(absolute_correction); + OPT_PTR(elefant_foot_compensation); OPT_PTR(gamma_correction); OPT_PTR(fast_tilt_time); OPT_PTR(slow_tilt_time); diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 06c4f687b..4bfc77c80 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -785,6 +785,7 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector #include +#include + #include // For geometry algorithms with native Clipper types (no copies and conversions) @@ -238,6 +240,13 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po) auto mit = slindex_it; double doffs = m_print->m_printer_config.absolute_correction.getFloat(); coord_t clpr_offs = scaled(doffs); + + if (!po.m_model_height_levels.empty() && po.m_model_height_levels[0] < ilh) { + auto &first_sl = po.m_model_slices[0]; + double compensation = m_print->m_printer_config.elefant_foot_compensation.getFloat(); + first_sl = elephant_foot_compensation(first_sl, 0., compensation); + } + for(size_t id = 0; id < po.m_model_slices.size() && mit != po.m_slice_index.end(); id++) @@ -449,6 +458,12 @@ void SLAPrint::Steps::slice_supports(SLAPrintObject &po) { sd->support_slices = sd->support_tree_ptr->slice( heights, float(po.config().slice_closing_radius.value)); + + if (!heights.empty() && heights[0] < ilh) { + auto &first_sl = sd->support_slices[0]; + double compensation = m_print->m_printer_config.elefant_foot_compensation.getFloat(); + first_sl = elephant_foot_compensation(first_sl, 0., compensation); + } } double doffs = m_print->m_printer_config.absolute_correction.getFloat(); diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 6f379aa39..f9191b2e7 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -557,6 +557,7 @@ const std::vector& Preset::sla_printer_options() "fast_tilt_time", "slow_tilt_time", "area_fill", "relative_correction", "absolute_correction", + "elefant_foot_compensation", "gamma_correction", "min_exposure_time", "max_exposure_time", "min_initial_exposure_time", "max_initial_exposure_time", diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index c5c6dc466..1b46ed755 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2112,8 +2112,9 @@ void TabPrinter::build_sla() } optgroup->append_line(line); optgroup->append_single_option_line("absolute_correction"); + optgroup->append_single_option_line("elefant_foot_compensation"); optgroup->append_single_option_line("gamma_correction"); - + optgroup = page->new_optgroup(_(L("Exposure"))); optgroup->append_single_option_line("min_exposure_time"); optgroup->append_single_option_line("max_exposure_time"); From 41d77b492c26c76c9d34552a0fded919fc57e4bb Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 6 Feb 2020 16:28:02 +0100 Subject: [PATCH 2/3] Added new parameter elefant_foot_min_width --- src/libslic3r/PrintConfig.cpp | 9 +++++++++ src/libslic3r/PrintConfig.hpp | 2 ++ src/libslic3r/SLAPrint.cpp | 1 + src/libslic3r/SLAPrintSteps.cpp | 19 ++++++++++++++----- src/libslic3r/SLAPrintSteps.hpp | 2 ++ src/slic3r/GUI/Preset.cpp | 1 + src/slic3r/GUI/Tab.cpp | 1 + 7 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index dfea714a8..353a0ae83 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2452,6 +2452,15 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.2)); + + def = this->add("elefant_foot_min_width", coFloat); + def->label = L("Elefant foot minimum width"); + def->category = L("Advanced"); + def->tooltip = L("Minimum with of features to maintain when doing EFC"); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0.2)); def = this->add("gamma_correction", coFloat); def->label = L("Printer gamma correction"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index f320b3da5..8c6710dad 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1176,6 +1176,7 @@ public: ConfigOptionFloats relative_correction; ConfigOptionFloat absolute_correction; ConfigOptionFloat elefant_foot_compensation; + ConfigOptionFloat elefant_foot_min_width; ConfigOptionFloat gamma_correction; ConfigOptionFloat fast_tilt_time; ConfigOptionFloat slow_tilt_time; @@ -1200,6 +1201,7 @@ protected: OPT_PTR(relative_correction); OPT_PTR(absolute_correction); OPT_PTR(elefant_foot_compensation); + OPT_PTR(elefant_foot_min_width); OPT_PTR(gamma_correction); OPT_PTR(fast_tilt_time); OPT_PTR(slow_tilt_time); diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 4bfc77c80..0b26af983 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -786,6 +786,7 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vectorm_printer_config.elefant_foot_compensation.getFloat(); + first_sl = elephant_foot_compensation(first_sl, 0., compensation); + } +} + void SLAPrint::Steps::hollow_model(SLAPrintObject &po) { po.m_hollowing_data.reset(); @@ -241,11 +254,7 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po) double doffs = m_print->m_printer_config.absolute_correction.getFloat(); coord_t clpr_offs = scaled(doffs); - if (!po.m_model_height_levels.empty() && po.m_model_height_levels[0] < ilh) { - auto &first_sl = po.m_model_slices[0]; - double compensation = m_print->m_printer_config.elefant_foot_compensation.getFloat(); - first_sl = elephant_foot_compensation(first_sl, 0., compensation); - } + for(size_t id = 0; id < po.m_model_slices.size() && mit != po.m_slice_index.end(); diff --git a/src/libslic3r/SLAPrintSteps.hpp b/src/libslic3r/SLAPrintSteps.hpp index 0418072cf..b5cb8accc 100644 --- a/src/libslic3r/SLAPrintSteps.hpp +++ b/src/libslic3r/SLAPrintSteps.hpp @@ -43,6 +43,8 @@ private: bool canceled() const { return m_print->canceled(); } void initialize_printer_input(); + void apply_elefant_foot_compensation(SLAPrintObject &po, SliceOrigin o); + public: Steps(SLAPrint *print); diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index f9191b2e7..cedf3d5f8 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -558,6 +558,7 @@ const std::vector& Preset::sla_printer_options() "relative_correction", "absolute_correction", "elefant_foot_compensation", + "elefant_foot_min_width", "gamma_correction", "min_exposure_time", "max_exposure_time", "min_initial_exposure_time", "max_initial_exposure_time", diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 1b46ed755..72ee827eb 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2113,6 +2113,7 @@ void TabPrinter::build_sla() optgroup->append_line(line); optgroup->append_single_option_line("absolute_correction"); optgroup->append_single_option_line("elefant_foot_compensation"); + optgroup->append_single_option_line("elefant_foot_min_width"); optgroup->append_single_option_line("gamma_correction"); optgroup = page->new_optgroup(_(L("Exposure"))); From 6deb6a776d38eacf22bd3da78c4546dd5e3a8ccb Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 14 Feb 2020 10:17:55 +0100 Subject: [PATCH 3/3] Do EFC for the first faded layers of SLA, interpolate efc parameters Compensated slices have negative orientation... Move efc to common params Fix elefant foot compensation reversed contours Remove redundant assertions and don't apply absolute correction if zero --- src/libslic3r/ElephantFootCompensation.cpp | 4 + src/libslic3r/PrintConfig.cpp | 30 +++----- src/libslic3r/SLAPrint.cpp | 3 +- src/libslic3r/SLAPrint.hpp | 4 + src/libslic3r/SLAPrintSteps.cpp | 73 ++++++++++--------- src/libslic3r/SLAPrintSteps.hpp | 2 +- .../test_elephant_foot_compensation.cpp | 33 ++++++--- 7 files changed, 80 insertions(+), 69 deletions(-) diff --git a/src/libslic3r/ElephantFootCompensation.cpp b/src/libslic3r/ElephantFootCompensation.cpp index a19aa2687..130f1b58f 100644 --- a/src/libslic3r/ElephantFootCompensation.cpp +++ b/src/libslic3r/ElephantFootCompensation.cpp @@ -592,6 +592,10 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, double min_c assert(out_vec.size() == 1); } } + + // FIXME: orientations are messed up (Tamas) + out.contour.make_counter_clockwise(); + for (auto &h : out.holes) h.make_clockwise(); return out; } diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 353a0ae83..61875fc57 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -113,6 +113,16 @@ void PrintConfigDef::init_common_params() "If left blank, the default OS CA certificate repository is used."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("")); + + def = this->add("elefant_foot_compensation", coFloat); + def->label = L("Elephant foot compensation"); + def->category = L("Advanced"); + def->tooltip = L("The first layer will be shrunk in the XY plane by the configured value " + "to compensate for the 1st layer squish aka an Elephant Foot effect."); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0.2)); } void PrintConfigDef::init_fff_params() @@ -371,16 +381,6 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->set_default_value(new ConfigOptionFloat(6)); - def = this->add("elefant_foot_compensation", coFloat); - def->label = L("Elephant foot compensation"); - def->category = L("Advanced"); - def->tooltip = L("The first layer will be shrunk in the XY plane by the configured value " - "to compensate for the 1st layer squish aka an Elephant Foot effect."); - def->sidetext = L("mm"); - def->min = 0; - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloat(0)); - def = this->add("end_gcode", coString); def->label = L("End G-code"); def->tooltip = L("This end procedure is inserted at the end of the output file. " @@ -2443,16 +2443,6 @@ void PrintConfigDef::init_sla_params() def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0.0)); - def = this->add("elefant_foot_compensation", coFloat); - def->label = L("Elephant foot compensation"); - def->category = L("Advanced"); - def->tooltip = L("The first layer will be shrunk in the XY plane by the configured value " - "to compensate for the 1st layer squish aka an Elephant Foot effect."); - def->sidetext = L("mm"); - def->min = 0; - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloat(0.2)); - def = this->add("elefant_foot_min_width", coFloat); def->label = L("Elefant foot minimum width"); def->category = L("Advanced"); diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 0b26af983..cca0abd5c 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1089,8 +1089,7 @@ const std::vector &SLAPrintObject::get_support_slices() const const ExPolygons &SliceRecord::get_slice(SliceOrigin o) const { - size_t idx = o == soModel ? m_model_slices_idx : - m_support_slices_idx; + size_t idx = o == soModel ? m_model_slices_idx : m_support_slices_idx; if(m_po == nullptr) return EMPTY_SLICE; diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index c9f5198db..70f773f6b 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -152,6 +152,10 @@ public: } const ExPolygons& get_slice(SliceOrigin o) const; + size_t get_slice_idx(SliceOrigin o) const + { + return o == soModel ? m_model_slices_idx : m_support_slices_idx; + } }; private: diff --git a/src/libslic3r/SLAPrintSteps.cpp b/src/libslic3r/SLAPrintSteps.cpp index 777b6abed..01220a633 100644 --- a/src/libslic3r/SLAPrintSteps.cpp +++ b/src/libslic3r/SLAPrintSteps.cpp @@ -80,16 +80,37 @@ SLAPrint::Steps::Steps(SLAPrint *print) , objectstep_scale{(max_objstatus - min_objstatus) / (objcount * 100.0)} {} - -void SLAPrint::Steps::apply_elefant_foot_compensation(SLAPrintObject &po, SliceOrigin o) +void SLAPrint::Steps::apply_printer_corrections(SLAPrintObject &po, SliceOrigin o) { + if (o == soSupport && !po.m_supportdata) return; + auto faded_lyrs = size_t(po.m_config.faded_layers.getInt()); + double min_w = m_print->m_printer_config.elefant_foot_min_width.getFloat() / 2.; + double start_efc = m_print->m_printer_config.elefant_foot_compensation.getFloat(); + + double doffs = m_print->m_printer_config.absolute_correction.getFloat(); + coord_t clpr_offs = scaled(doffs); + faded_lyrs = std::min(po.m_slice_index.size(), faded_lyrs); - if (!po.m_model_height_levels.empty() && po.m_model_height_levels[0] < ilh) { - auto &first_sl = po.m_model_slices[0]; - double compensation = m_print->m_printer_config.elefant_foot_compensation.getFloat(); - first_sl = elephant_foot_compensation(first_sl, 0., compensation); + auto efc = [start_efc, faded_lyrs](size_t pos) { + return (faded_lyrs - 1 - pos) * start_efc / (faded_lyrs - 1); + }; + + std::vector &slices = o == soModel ? + po.m_model_slices : + po.m_supportdata->support_slices; + + if (clpr_offs != 0) for (size_t i = 0; i < po.m_slice_index.size(); ++i) { + size_t idx = po.m_slice_index[i].get_slice_idx(o); + if (idx < slices.size()) + slices[idx] = offset_ex(slices[idx], float(clpr_offs)); + } + + if (start_efc > 0.) for (size_t i = 0; i < faded_lyrs; ++i) { + size_t idx = po.m_slice_index[i].get_slice_idx(o); + if (idx < slices.size()) + slices[idx] = elephant_foot_compensation(slices[idx], min_w, efc(i)); } } @@ -251,23 +272,15 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po) } auto mit = slindex_it; - double doffs = m_print->m_printer_config.absolute_correction.getFloat(); - coord_t clpr_offs = scaled(doffs); - - - - for(size_t id = 0; + for (size_t id = 0; id < po.m_model_slices.size() && mit != po.m_slice_index.end(); - id++) - { - // We apply the printer correction offset here. - if(clpr_offs != 0) - po.m_model_slices[id] = - offset_ex(po.m_model_slices[id], float(clpr_offs)); - + id++) { mit->set_model_slice_idx(po, id); ++mit; } + // We apply the printer correction offset here. + apply_printer_corrections(po, soModel); + if(po.m_config.supports_enable.getBool() || po.m_config.pad_enable.getBool()) { po.m_supportdata.reset(new SLAPrintObject::SupportData(mesh)); @@ -464,27 +477,15 @@ void SLAPrint::Steps::slice_supports(SLAPrintObject &po) { auto heights = reserve_vector(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)); - - if (!heights.empty() && heights[0] < ilh) { - auto &first_sl = sd->support_slices[0]; - double compensation = m_print->m_printer_config.elefant_foot_compensation.getFloat(); - first_sl = elephant_foot_compensation(first_sl, 0., compensation); - } + heights, float(po.config().slice_closing_radius.value)); } - double doffs = m_print->m_printer_config.absolute_correction.getFloat(); - coord_t clpr_offs = scaled(doffs); - - for (size_t i = 0; i < sd->support_slices.size() && i < po.m_slice_index.size(); ++i) { - // We apply the printer correction offset here. - if (clpr_offs != 0) - sd->support_slices[i] = offset_ex(sd->support_slices[i], float(clpr_offs)); - + for (size_t i = 0; i < sd->support_slices.size() && i < po.m_slice_index.size(); ++i) po.m_slice_index[i].set_support_slice_idx(po, i); - } + + apply_printer_corrections(po, soSupport); // Using RELOAD_SLA_PREVIEW to tell the Plater to pass the update // status to the 3D preview to load the SLA slices. diff --git a/src/libslic3r/SLAPrintSteps.hpp b/src/libslic3r/SLAPrintSteps.hpp index b5cb8accc..d3341bc14 100644 --- a/src/libslic3r/SLAPrintSteps.hpp +++ b/src/libslic3r/SLAPrintSteps.hpp @@ -43,7 +43,7 @@ private: bool canceled() const { return m_print->canceled(); } void initialize_printer_input(); - void apply_elefant_foot_compensation(SLAPrintObject &po, SliceOrigin o); + void apply_printer_corrections(SLAPrintObject &po, SliceOrigin o); public: Steps(SLAPrint *print); diff --git a/tests/libslic3r/test_elephant_foot_compensation.cpp b/tests/libslic3r/test_elephant_foot_compensation.cpp index 98ec5df52..616c0c6ad 100644 --- a/tests/libslic3r/test_elephant_foot_compensation.cpp +++ b/tests/libslic3r/test_elephant_foot_compensation.cpp @@ -413,6 +413,19 @@ static ExPolygon contour_with_hole() return out; } +static bool is_valid_orientation(const ExPolygon &p) +{ + bool ret = p.contour.is_counter_clockwise(); + for (auto &h : p.holes) ret = ret && h.is_clockwise(); + return ret; +} + +static bool is_efc_result_smaller(const ExPolygon &efc, const ExPolygon &orig) +{ + double efc_area = efc.area(); + return efc_area > 0. && efc_area < orig.area() && is_valid_orientation(efc); +} + SCENARIO("Elephant foot compensation", "[ElephantFoot]") { GIVEN("Contour with hole") { @@ -426,7 +439,7 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") { { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); #endif /* TESTS_EXPORT_SVGS */ THEN("area of the compensated polygon is smaller") { - REQUIRE(expoly_compensated.area() < expoly.area()); + REQUIRE(is_efc_result_smaller(expoly_compensated, expoly)); } } } @@ -456,7 +469,7 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") { { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); #endif /* TESTS_EXPORT_SVGS */ THEN("area of the compensated polygon is smaller") { - REQUIRE(expoly_compensated.area() < expoly.area()); + REQUIRE(is_efc_result_smaller(expoly_compensated, expoly)); } } } @@ -471,7 +484,7 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") { { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); #endif /* TESTS_EXPORT_SVGS */ THEN("area of the compensated polygon is smaller") { - REQUIRE(expoly_compensated.area() < expoly.area()); + REQUIRE(is_efc_result_smaller(expoly_compensated, expoly)); } } } @@ -523,7 +536,7 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") { { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); #endif /* TESTS_EXPORT_SVGS */ THEN("area of the compensated polygon is smaller") { - REQUIRE(expoly_compensated.area() < expoly.area()); + REQUIRE(is_efc_result_smaller(expoly_compensated, expoly)); } } WHEN("Fully compensated") { @@ -534,7 +547,7 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") { { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); #endif /* TESTS_EXPORT_SVGS */ THEN("area of the compensated polygon is smaller") { - REQUIRE(expoly_compensated.area() < expoly.area()); + REQUIRE(is_efc_result_smaller(expoly_compensated, expoly)); } } } @@ -549,7 +562,7 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") { { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); #endif /* TESTS_EXPORT_SVGS */ THEN("area of the compensated polygon is smaller") { - REQUIRE(expoly_compensated.area() < expoly.area()); + REQUIRE(is_efc_result_smaller(expoly_compensated, expoly)); } } } @@ -566,7 +579,7 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") { { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); #endif /* TESTS_EXPORT_SVGS */ THEN("area of the compensated polygon is smaller") { - REQUIRE(expoly_compensated.area() < expoly.area()); + REQUIRE(is_efc_result_smaller(expoly_compensated, expoly)); } } WHEN("Fully compensated") { @@ -577,7 +590,7 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") { { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); #endif /* TESTS_EXPORT_SVGS */ THEN("area of the compensated polygon is smaller") { - REQUIRE(expoly_compensated.area() < expoly.area()); + REQUIRE(is_efc_result_smaller(expoly_compensated, expoly)); } } WHEN("Brutally compensated") { @@ -588,7 +601,7 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") { { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); #endif /* TESTS_EXPORT_SVGS */ THEN("area of the compensated polygon is smaller") { - REQUIRE(expoly_compensated.area() < expoly.area()); + REQUIRE(is_efc_result_smaller(expoly_compensated, expoly)); } } } @@ -603,7 +616,7 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") { { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); #endif /* TESTS_EXPORT_SVGS */ THEN("area of the compensated polygon is smaller") { - REQUIRE(expoly_compensated.area() < expoly.area()); + REQUIRE(is_efc_result_smaller(expoly_compensated, expoly)); } } }