mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-10-03 18:06:32 +08:00
Throw a runtime error if the number of solid layers grows above the total possible layers.
Edit the loop syntax to need the current shell thickness to be less than the minimum to add more layers (avoid infinite loop). Add test to cover normal operation and regression for this layer arrangement. Fixes #5019
This commit is contained in:
parent
5d371aab0b
commit
c61c25b15b
@ -1,6 +1,7 @@
|
||||
#include <catch.hpp>
|
||||
#include <string>
|
||||
#include "test_data.hpp"
|
||||
#include "Log.hpp"
|
||||
#include "libslic3r.h"
|
||||
|
||||
using namespace Slic3r::Test;
|
||||
@ -77,3 +78,101 @@ SCENARIO("PrintObject: object layer heights") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("PrintObject: minimum horizontal shells") {
|
||||
GIVEN("20mm cube and default initial config, initial layer height of 0.1mm") {
|
||||
auto config {Slic3r::Config::new_from_defaults()};
|
||||
TestMesh m { TestMesh::cube_20x20x20 };
|
||||
Slic3r::Model model;
|
||||
|
||||
config->set("nozzle_diameter", "3");
|
||||
config->set("bottom_solid_layers", 1);
|
||||
config->set("perimeters", 1);
|
||||
config->set("first_layer_height", 0.1);
|
||||
config->set("layer_height", 0.1);
|
||||
config->set("fill_density", "0%");
|
||||
config->set("min_top_bottom_shell_thickness", 1.0);
|
||||
|
||||
WHEN("min shell thickness is 1.0 with layer height of 0.1") {
|
||||
config->set("min_top_bottom_shell_thickness", 1.0);
|
||||
auto print {Slic3r::Test::init_print({m}, model, config)};
|
||||
slic3r_log->set_level(log_t::DEBUG);
|
||||
print->objects[0]->prepare_infill();
|
||||
for (int i = 0; i < 12; i++)
|
||||
print->objects[0]->layers[i]->make_fills();
|
||||
THEN("Layers 0-9 are solid (Z < 1.0) (all fill_surfaces are solid)") {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
CHECK(print->objects[0]->layers[i]->print_z <= (i+1 * 0.1));
|
||||
for (auto* r : print->objects[0]->layers[i]->regions) {
|
||||
for (auto s : r->fill_surfaces) {
|
||||
REQUIRE(s.is_solid());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AND_THEN("Layer 10 (Z > 1.0) is not solid.") {
|
||||
for (auto* r : print->objects[0]->layers[10]->regions) {
|
||||
bool all_solid = true;
|
||||
for (auto s : r->fill_surfaces) {
|
||||
REQUIRE(!s.is_solid());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
WHEN("min shell thickness is 1.22 with layer height of 0.1") {
|
||||
config->set("min_top_bottom_shell_thickness", 1.22);
|
||||
config->set("layer_height", 0.1);
|
||||
auto print {Slic3r::Test::init_print({m}, model, config)};
|
||||
slic3r_log->set_level(log_t::DEBUG);
|
||||
print->objects[0]->prepare_infill();
|
||||
for (int i = 0; i < 20; i++)
|
||||
print->objects[0]->layers[i]->make_fills();
|
||||
AND_THEN("Layers 0-12 are solid (bottom of layer >= 1.22) (all fill_surfaces are solid)") {
|
||||
for (int i = 0; i < 13; i++) {
|
||||
CHECK(print->objects[0]->layers[i]->print_z <= (i+1 * 0.1));
|
||||
for (auto* r : print->objects[0]->layers[i]->regions) {
|
||||
for (auto s : r->fill_surfaces) {
|
||||
REQUIRE(s.is_solid());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AND_THEN("Layer 13 (Z > 1.0) is not solid.") {
|
||||
for (auto* r : print->objects[0]->layers[13]->regions) {
|
||||
bool all_solid = true;
|
||||
for (auto s : r->fill_surfaces) {
|
||||
REQUIRE(!s.is_solid());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
WHEN("min shell thickness is 1.22 14 bottom layers") {
|
||||
config->set("min_top_bottom_shell_thickness", 1.22);
|
||||
config->set("bottom_solid_layers", 14);
|
||||
config->set("layer_height", 0.1);
|
||||
auto print {Slic3r::Test::init_print({m}, model, config)};
|
||||
slic3r_log->set_level(log_t::DEBUG);
|
||||
print->objects[0]->prepare_infill();
|
||||
for (int i = 0; i < 20; i++)
|
||||
print->objects[0]->layers[i]->make_fills();
|
||||
AND_THEN("Layers 0-13 are solid (bottom of layer >= 1.22) (all fill_surfaces are solid)") {
|
||||
for (int i = 0; i < 14; i++) {
|
||||
CHECK(print->objects[0]->layers[i]->print_z <= (i+1 * 0.1));
|
||||
for (auto* r : print->objects[0]->layers[i]->regions) {
|
||||
for (auto s : r->fill_surfaces) {
|
||||
REQUIRE(s.is_solid());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AND_THEN("Layer 14 is not solid.") {
|
||||
for (auto* r : print->objects[0]->layers[14]->regions) {
|
||||
bool all_solid = true;
|
||||
for (auto s : r->fill_surfaces) {
|
||||
REQUIRE(!s.is_solid());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@ -1537,16 +1538,28 @@ PrintObject::_discover_external_horizontal_shells(LayerRegion* layerm, const siz
|
||||
std::cout << "Layer " << i << " has " << (type == stTop ? "top" : "bottom") << " surfaces" << std::endl;
|
||||
#endif
|
||||
|
||||
auto solid_layers = type == stTop
|
||||
size_t solid_layers = type == stTop
|
||||
? region_config.top_solid_layers()
|
||||
: region_config.bottom_solid_layers();
|
||||
solid_layers = min(solid_layers, this->layers.size());
|
||||
|
||||
if (region_config.min_top_bottom_shell_thickness() > 0) {
|
||||
auto current_shell_thickness = static_cast<coordf_t>(solid_layers) * this->get_layer(i)->height;
|
||||
const auto min_shell_thickness = region_config.min_top_bottom_shell_thickness();
|
||||
while (std::abs(min_shell_thickness - current_shell_thickness) > Slic3r::Geometry::epsilon) {
|
||||
Slic3r::Log::debug("vertical_shell_thickness") << "Initial shell thickness for layer " << i << " "
|
||||
<< current_shell_thickness << " "
|
||||
<< "Minimum: " << min_shell_thickness << "\n";
|
||||
while (std::abs(min_shell_thickness - current_shell_thickness) > Slic3r::Geometry::epsilon && current_shell_thickness < min_shell_thickness) {
|
||||
solid_layers++;
|
||||
current_shell_thickness = static_cast<coordf_t>(solid_layers) * this->get_layer(i)->height;
|
||||
Slic3r::Log::debug("vertical_shell_thickness") << "Solid layer count: "
|
||||
<< solid_layers << "; "
|
||||
<< "current_shell_thickness: "
|
||||
<< current_shell_thickness
|
||||
<< "\n";
|
||||
if (solid_layers > this->layers.size()) {
|
||||
throw std::runtime_error("Infinite loop when determining vertical shell thickness");
|
||||
}
|
||||
}
|
||||
}
|
||||
_discover_neighbor_horizontal_shells(layerm, i, region_id, type, solid, solid_layers);
|
||||
|
Loading…
x
Reference in New Issue
Block a user