new cheaper constructor for DynamicPrintConfig from FullPrintConfig:

DynamicPrintConfig::full_print_config()
new cheaper constructors of DynamicConfig / DynamicPrintConfig from ConfigBase
Unit tests: ported test_model from upstream Slic3r, thanks @lordofhyphens
Unit tests refactored to use less autos and initializer lists for readibility,
DynamicPrintConfig is handled by value, not by shared pointer.
This commit is contained in:
bubnikv 2019-10-16 11:16:50 +02:00
parent 90d5712091
commit 69c8b1cd21
12 changed files with 190 additions and 107 deletions

View File

@ -668,6 +668,12 @@ void ConfigBase::null_nullables()
} }
} }
DynamicConfig::DynamicConfig(const ConfigBase& rhs, const t_config_option_keys& keys)
{
for (const t_config_option_key& opt_key : keys)
this->options[opt_key] = std::unique_ptr<ConfigOption>(rhs.option(opt_key)->clone());
}
bool DynamicConfig::operator==(const DynamicConfig &rhs) const bool DynamicConfig::operator==(const DynamicConfig &rhs) const
{ {
auto it1 = this->options.begin(); auto it1 = this->options.begin();

View File

@ -1580,8 +1580,10 @@ class DynamicConfig : public virtual ConfigBase
{ {
public: public:
DynamicConfig() {} DynamicConfig() {}
DynamicConfig(const DynamicConfig& other) { *this = other; } DynamicConfig(const DynamicConfig &rhs) { *this = rhs; }
DynamicConfig(DynamicConfig&& other) : options(std::move(other.options)) { other.options.clear(); } DynamicConfig(DynamicConfig &&rhs) : options(std::move(rhs.options)) { rhs.options.clear(); }
explicit DynamicConfig(const ConfigBase &rhs, const t_config_option_keys &keys);
explicit DynamicConfig(const ConfigBase& rhs) : DynamicConfig(rhs, rhs.keys()) {}
virtual ~DynamicConfig() override { clear(); } virtual ~DynamicConfig() override { clear(); }
// Copy a content of one DynamicConfig to another DynamicConfig. // Copy a content of one DynamicConfig to another DynamicConfig.

View File

@ -2898,9 +2898,13 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
const PrintConfigDef print_config_def; const PrintConfigDef print_config_def;
DynamicPrintConfig* DynamicPrintConfig::new_from_defaults() DynamicPrintConfig DynamicPrintConfig::full_print_config()
{
return DynamicPrintConfig((const PrintRegionConfig&)FullPrintConfig::defaults());
}
DynamicPrintConfig::DynamicPrintConfig(const StaticPrintConfig& rhs) : DynamicConfig(rhs, rhs.keys_ref())
{ {
return new_from_defaults_keys(FullPrintConfig::defaults().keys());
} }
DynamicPrintConfig* DynamicPrintConfig::new_from_defaults_keys(const std::vector<std::string> &keys) DynamicPrintConfig* DynamicPrintConfig::new_from_defaults_keys(const std::vector<std::string> &keys)

View File

@ -214,6 +214,8 @@ private:
// This definition is constant. // This definition is constant.
extern const PrintConfigDef print_config_def; extern const PrintConfigDef print_config_def;
class StaticPrintConfig;
// Slic3r dynamic configuration, used to override the configuration // Slic3r dynamic configuration, used to override the configuration
// per object, per modification volume or per printing material. // per object, per modification volume or per printing material.
// The dynamic configuration is also used to store user modifications of the print global parameters, // The dynamic configuration is also used to store user modifications of the print global parameters,
@ -224,9 +226,11 @@ class DynamicPrintConfig : public DynamicConfig
{ {
public: public:
DynamicPrintConfig() {} DynamicPrintConfig() {}
DynamicPrintConfig(const DynamicPrintConfig &other) : DynamicConfig(other) {} DynamicPrintConfig(const DynamicPrintConfig &rhs) : DynamicConfig(rhs) {}
explicit DynamicPrintConfig(const StaticPrintConfig &rhs);
explicit DynamicPrintConfig(const ConfigBase &rhs) : DynamicConfig(rhs) {}
static DynamicPrintConfig* new_from_defaults(); static DynamicPrintConfig full_print_config();
static DynamicPrintConfig* new_from_defaults_keys(const std::vector<std::string> &keys); static DynamicPrintConfig* new_from_defaults_keys(const std::vector<std::string> &keys);
// Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here. // Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here.
@ -262,6 +266,8 @@ public:
// Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here. // Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here.
const ConfigDef* def() const override { return &print_config_def; } const ConfigDef* def() const override { return &print_config_def; }
// Reference to the cached list of keys.
virtual const t_config_option_keys& keys_ref() const = 0;
protected: protected:
// Verify whether the opt_key has not been obsoleted or renamed. // Verify whether the opt_key has not been obsoleted or renamed.
@ -350,6 +356,7 @@ public: \
{ return s_cache_##CLASS_NAME.optptr(opt_key, this); } \ { return s_cache_##CLASS_NAME.optptr(opt_key, this); } \
/* Overrides ConfigBase::keys(). Collect names of all configuration values maintained by this configuration store. */ \ /* Overrides ConfigBase::keys(). Collect names of all configuration values maintained by this configuration store. */ \
t_config_option_keys keys() const override { return s_cache_##CLASS_NAME.keys(); } \ t_config_option_keys keys() const override { return s_cache_##CLASS_NAME.keys(); } \
const t_config_option_keys& keys_ref() const override { return s_cache_##CLASS_NAME.keys(); } \
static const CLASS_NAME& defaults() { initialize_cache(); return s_cache_##CLASS_NAME.defaults(); } \ static const CLASS_NAME& defaults() { initialize_cache(); return s_cache_##CLASS_NAME.defaults(); } \
private: \ private: \
static void initialize_cache() \ static void initialize_cache() \

View File

@ -5,6 +5,7 @@ add_executable(${_TEST_NAME}_tests
test_data.hpp test_data.hpp
test_flow.cpp test_flow.cpp
test_gcodewriter.cpp test_gcodewriter.cpp
test_model.cpp
test_skirt_brim.cpp test_skirt_brim.cpp
test_trianglemesh.cpp test_trianglemesh.cpp
) )

View File

@ -212,15 +212,15 @@ static bool verbose_gcode()
return s == "1" || s == "on" || s == "yes"; return s == "1" || s == "on" || s == "yes";
} }
std::shared_ptr<Print> init_print(std::initializer_list<TestMesh> meshes, Slic3r::Model& model, std::shared_ptr<DynamicPrintConfig> _config, bool comments) std::shared_ptr<Print> init_print(std::initializer_list<TestMesh> meshes, Slic3r::Model& model, const Slic3r::DynamicPrintConfig &config_in, bool comments)
{ {
std::shared_ptr<DynamicPrintConfig> config(Slic3r::DynamicPrintConfig::new_from_defaults()); DynamicPrintConfig config = DynamicPrintConfig::full_print_config();
config->apply(*_config); config.apply(config_in);
if (verbose_gcode()) if (verbose_gcode())
config->set_key_value("gcode_comments", new ConfigOptionBool(true)); config.set_key_value("gcode_comments", new ConfigOptionBool(true));
std::shared_ptr<Print> print {std::make_shared<Slic3r::Print>()}; std::shared_ptr<Print> print(std::make_shared<Slic3r::Print>());
for (const TestMesh &t : meshes) { for (const TestMesh &t : meshes) {
ModelObject *object = model.add_object(); ModelObject *object = model.add_object();
@ -229,28 +229,28 @@ std::shared_ptr<Print> init_print(std::initializer_list<TestMesh> meshes, Slic3r
object->add_instance(); object->add_instance();
} }
model.arrange_objects(PrintConfig::min_object_distance(config.get())); model.arrange_objects(PrintConfig::min_object_distance(&config));
model.center_instances_around_point(Slic3r::Vec2d(100,100)); model.center_instances_around_point(Slic3r::Vec2d(100,100));
for (ModelObject *mo : model.objects) { for (ModelObject *mo : model.objects) {
mo->ensure_on_bed(); mo->ensure_on_bed();
print->auto_assign_extruders(mo); print->auto_assign_extruders(mo);
} }
print->apply(model, *config); print->apply(model, config);
print->validate(); print->validate();
print->set_status_silent(); print->set_status_silent();
return print; return print;
} }
std::shared_ptr<Print> init_print(std::initializer_list<TriangleMesh> meshes, Slic3r::Model& model, std::shared_ptr<DynamicPrintConfig> _config, bool comments) std::shared_ptr<Print> init_print(std::initializer_list<TriangleMesh> meshes, Slic3r::Model& model, const DynamicPrintConfig &config_in, bool comments)
{ {
std::shared_ptr<DynamicPrintConfig> config(Slic3r::DynamicPrintConfig::new_from_defaults()); DynamicPrintConfig config = DynamicPrintConfig::full_print_config();
config->apply(*_config); config.apply(config_in);
if (verbose_gcode()) if (verbose_gcode())
config->set_key_value("gcode_comments", new ConfigOptionBool(true)); config.set_key_value("gcode_comments", new ConfigOptionBool(true));
std::shared_ptr<Print> print { std::make_shared<Slic3r::Print>() }; std::shared_ptr<Print> print(std::make_shared<Slic3r::Print>());
for (const TriangleMesh &t : meshes) { for (const TriangleMesh &t : meshes) {
ModelObject *object = model.add_object(); ModelObject *object = model.add_object();
@ -258,14 +258,14 @@ std::shared_ptr<Print> init_print(std::initializer_list<TriangleMesh> meshes, Sl
object->add_volume(t); object->add_volume(t);
object->add_instance(); object->add_instance();
} }
model.arrange_objects(PrintConfig::min_object_distance(config.get())); model.arrange_objects(PrintConfig::min_object_distance(&config));
model.center_instances_around_point(Slic3r::Vec2d(100, 100)); model.center_instances_around_point(Slic3r::Vec2d(100, 100));
for (ModelObject *mo : model.objects) { for (ModelObject *mo : model.objects) {
mo->ensure_on_bed(); mo->ensure_on_bed();
print->auto_assign_extruders(mo); print->auto_assign_extruders(mo);
} }
print->apply(model, *config); print->apply(model, config);
print->validate(); print->validate();
print->set_status_silent(); print->set_status_silent();
return print; return print;
@ -307,7 +307,7 @@ void add_testmesh_to_model(Slic3r::Model& result, const std::string& model_name,
SCENARIO("init_print functionality") { SCENARIO("init_print functionality") {
GIVEN("A default config") { GIVEN("A default config") {
std::shared_ptr<Slic3r::DynamicPrintConfig> config(Slic3r::DynamicPrintConfig::new_from_defaults()); Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config();
std::stringstream gcode; std::stringstream gcode;
WHEN("init_print is called with a single mesh.") { WHEN("init_print is called with a single mesh.") {
Slic3r::Model model; Slic3r::Model model;

View File

@ -66,8 +66,8 @@ bool _equiv(const T& a, const T& b, double epsilon) { return abs(a - b) < epsilo
Slic3r::Model model(const std::string& model_name, TriangleMesh&& _mesh); Slic3r::Model model(const std::string& model_name, TriangleMesh&& _mesh);
std::shared_ptr<Print> init_print(std::initializer_list<TestMesh> meshes, Slic3r::Model& model, std::shared_ptr<Slic3r::DynamicPrintConfig> _config = std::shared_ptr<Slic3r::DynamicPrintConfig>(Slic3r::DynamicPrintConfig::new_from_defaults()), bool comments = false); std::shared_ptr<Print> init_print(std::initializer_list<TestMesh> meshes, Slic3r::Model& model, const Slic3r::DynamicPrintConfig &config_in = Slic3r::DynamicPrintConfig::full_print_config(), bool comments = false);
std::shared_ptr<Print> init_print(std::initializer_list<TriangleMesh> meshes, Slic3r::Model& model, std::shared_ptr<Slic3r::DynamicPrintConfig> _config = std::shared_ptr<Slic3r::DynamicPrintConfig>(Slic3r::DynamicPrintConfig::new_from_defaults()), bool comments = false); std::shared_ptr<Print> init_print(std::initializer_list<TriangleMesh> meshes, Slic3r::Model& model, const Slic3r::DynamicPrintConfig &config_in = Slic3r::DynamicPrintConfig::full_print_config(), bool comments = false);
std::string gcode(std::shared_ptr<Print> print); std::string gcode(std::shared_ptr<Print> print);

View File

@ -18,22 +18,22 @@ using namespace Slic3r;
SCENARIO("Extrusion width specifics", "[!mayfail]") { SCENARIO("Extrusion width specifics", "[!mayfail]") {
GIVEN("A config with a skirt, brim, some fill density, 3 perimeters, and 1 bottom solid layer and a 20mm cube mesh") { GIVEN("A config with a skirt, brim, some fill density, 3 perimeters, and 1 bottom solid layer and a 20mm cube mesh") {
// this is a sharedptr // this is a sharedptr
std::shared_ptr<DynamicPrintConfig> config(Slic3r::DynamicPrintConfig::new_from_defaults()); DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config();
config->opt_int("skirts") = 1; config.opt_int("skirts") = 1;
config->opt_float("brim_width") = 2.; config.opt_float("brim_width") = 2.;
config->opt_int("perimeters") = 3; config.opt_int("perimeters") = 3;
config->set_deserialize("fill_density", "40%"); config.set_deserialize("fill_density", "40%");
config->set_deserialize("first_layer_height", "100%"); config.set_deserialize("first_layer_height", "100%");
WHEN("first layer width set to 2mm") { WHEN("first layer width set to 2mm") {
Slic3r::Model model; Slic3r::Model model;
config->set_deserialize("first_layer_extrusion_width", "2"); config.set_deserialize("first_layer_extrusion_width", "2");
std::shared_ptr<Print> print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); std::shared_ptr<Print> print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config);
std::vector<double> E_per_mm_bottom; std::vector<double> E_per_mm_bottom;
std::string gcode = Test::gcode(print); std::string gcode = Test::gcode(print);
Slic3r::GCodeReader parser; Slic3r::GCodeReader parser;
const double layer_height = config->opt_float("layer_height"); const double layer_height = config.opt_float("layer_height");
parser.parse_buffer(gcode, [&E_per_mm_bottom, layer_height] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) parser.parse_buffer(gcode, [&E_per_mm_bottom, layer_height] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
{ {
if (self.z() == Approx(layer_height).margin(0.01)) { // only consider first layer if (self.z() == Approx(layer_height).margin(0.01)) { // only consider first layer

View File

@ -0,0 +1,61 @@
#include <catch2/catch.hpp>
#include "libslic3r/libslic3r.h"
#include "libslic3r/Model.hpp"
#include <boost/nowide/cstdio.hpp>
#include <boost/filesystem.hpp>
#include "test_data.hpp"
using namespace Slic3r;
using namespace Slic3r::Test;
SCENARIO("Model construction", "[Model]") {
GIVEN("A Slic3r Model") {
Slic3r::Model model;
Slic3r::TriangleMesh sample_mesh = Slic3r::make_cube(20,20,20);
Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config();
Slic3r::Print print;
WHEN("Model object is added") {
Slic3r::ModelObject *model_object = model.add_object();
THEN("Model object list == 1") {
REQUIRE(model.objects.size() == 1);
}
model_object->add_volume(sample_mesh);
THEN("Model volume list == 1") {
REQUIRE(model_object->volumes.size() == 1);
}
THEN("Model volume is a part") {
REQUIRE(model_object->volumes.front()->is_model_part());
}
THEN("Mesh is equivalent to input mesh.") {
REQUIRE(! sample_mesh.its.vertices.empty());
const std::vector<Vec3f>& mesh_vertices = model_object->volumes.front()->mesh().its.vertices;
Vec3f mesh_offset = model_object->volumes.front()->source.mesh_offset.cast<float>();
for (size_t i = 0; i < sample_mesh.its.vertices.size(); ++ i) {
const Vec3f &p1 = sample_mesh.its.vertices[i];
const Vec3f p2 = mesh_vertices[i] + mesh_offset;
REQUIRE((p2 - p1).norm() < EPSILON);
}
}
Slic3r::ModelInstance *model_instance = model_object->add_instance();
model.arrange_objects(PrintConfig::min_object_distance(&config));
model.center_instances_around_point(Slic3r::Vec2d(100, 100));
model_object->ensure_on_bed();
print.auto_assign_extruders(model_object);
THEN("Print works?") {
print.set_status_silent();
print.apply(model, config);
print.process();
boost::filesystem::path temp = boost::filesystem::unique_path();
print.export_gcode(temp.string(), nullptr);
REQUIRE(boost::filesystem::exists(temp));
REQUIRE(boost::filesystem::is_regular_file(temp));
REQUIRE(boost::filesystem::file_size(temp) > 0);
boost::nowide::remove(temp.string().c_str());
}
}
}
}

View File

@ -30,16 +30,16 @@ int get_brim_tool(std::string &gcode, Slic3r::GCodeReader& parser) {
} }
TEST_CASE("Skirt height is honored") { TEST_CASE("Skirt height is honored") {
std::shared_ptr<Slic3r::DynamicPrintConfig> config(Slic3r::DynamicPrintConfig::new_from_defaults()); DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config();
config->opt_int("skirts") = 1; config.opt_int("skirts") = 1;
config->opt_int("skirt_height") = 5; config.opt_int("skirt_height") = 5;
config->opt_int("perimeters") = 0; config.opt_int("perimeters") = 0;
config->opt_float("support_material_speed") = 99; config.opt_float("support_material_speed") = 99;
// avoid altering speeds unexpectedly // avoid altering speeds unexpectedly
config->set_deserialize("cooling", "0"); config.set_deserialize("cooling", "0");
config->set_deserialize("first_layer_speed", "100%"); config.set_deserialize("first_layer_speed", "100%");
double support_speed = config->opt<Slic3r::ConfigOptionFloat>("support_material_speed")->value * MM_PER_MIN; double support_speed = config.opt<Slic3r::ConfigOptionFloat>("support_material_speed")->value * MM_PER_MIN;
std::map<double, bool> layers_with_skirt; std::map<double, bool> layers_with_skirt;
std::string gcode; std::string gcode;
@ -62,7 +62,7 @@ TEST_CASE("Skirt height is honored") {
} }
}); });
REQUIRE(layers_with_skirt.size() == (size_t)config->opt_int("skirt_height")); REQUIRE(layers_with_skirt.size() == (size_t)config.opt_int("skirt_height"));
} }
SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") {
@ -70,28 +70,28 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") {
Slic3r::Model model; Slic3r::Model model;
std::string gcode; std::string gcode;
GIVEN("A default configuration") { GIVEN("A default configuration") {
std::shared_ptr<Slic3r::DynamicPrintConfig> config(Slic3r::DynamicPrintConfig::new_from_defaults()); DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config();
config->set_num_extruders(4); config.set_num_extruders(4);
config->opt_float("support_material_speed") = 99; config.opt_float("support_material_speed") = 99;
config->set_deserialize("first_layer_height", "0.3"); config.set_deserialize("first_layer_height", "0.3");
config->set_deserialize("gcode_comments", "1"); config.set_deserialize("gcode_comments", "1");
// avoid altering speeds unexpectedly // avoid altering speeds unexpectedly
config->set_deserialize("cooling", "0"); config.set_deserialize("cooling", "0");
config->set_deserialize("first_layer_speed", "100%"); config.set_deserialize("first_layer_speed", "100%");
// remove noise from top/solid layers // remove noise from top/solid layers
config->opt_int("top_solid_layers") = 0; config.opt_int("top_solid_layers") = 0;
config->opt_int("bottom_solid_layers") = 1; config.opt_int("bottom_solid_layers") = 1;
WHEN("Brim width is set to 5") { WHEN("Brim width is set to 5") {
config->opt_int("perimeters") = 0; config.opt_int("perimeters") = 0;
config->opt_int("skirts") = 0; config.opt_int("skirts") = 0;
config->opt_float("brim_width") = 5; config.opt_float("brim_width") = 5;
THEN("Brim is generated") { THEN("Brim is generated") {
auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config);
gcode = Slic3r::Test::gcode(print); gcode = Slic3r::Test::gcode(print);
bool brim_generated = false; bool brim_generated = false;
double support_speed = config->opt<Slic3r::ConfigOptionFloat>("support_material_speed")->value * MM_PER_MIN; double support_speed = config.opt<Slic3r::ConfigOptionFloat>("support_material_speed")->value * MM_PER_MIN;
parser.parse_buffer(gcode, [&brim_generated, support_speed] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) parser.parse_buffer(gcode, [&brim_generated, support_speed] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
{ {
if (self.z() == Approx(0.3) || line.new_Z(self) == Approx(0.3)) { if (self.z() == Approx(0.3) || line.new_Z(self) == Approx(0.3)) {
@ -105,8 +105,8 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") {
} }
WHEN("Skirt area is smaller than the brim") { WHEN("Skirt area is smaller than the brim") {
config->opt_int("skirts") = 1; config.opt_int("skirts") = 1;
config->opt_float("brim_width") = 10; config.opt_float("brim_width") = 10;
auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config);
THEN("Gcode generates") { THEN("Gcode generates") {
REQUIRE(! Slic3r::Test::gcode(print).empty()); REQUIRE(! Slic3r::Test::gcode(print).empty());
@ -114,8 +114,8 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") {
} }
WHEN("Skirt height is 0 and skirts > 0") { WHEN("Skirt height is 0 and skirts > 0") {
config->opt_int("skirts") = 2; config.opt_int("skirts") = 2;
config->opt_int("skirt_height") = 0; config.opt_int("skirt_height") = 0;
auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config);
THEN("Gcode generates") { THEN("Gcode generates") {
@ -124,34 +124,34 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") {
} }
WHEN("Perimeter extruder = 2 and support extruders = 3") { WHEN("Perimeter extruder = 2 and support extruders = 3") {
config->opt_int("skirts") = 0; config.opt_int("skirts") = 0;
config->opt_float("brim_width") = 5; config.opt_float("brim_width") = 5;
config->opt_int("perimeter_extruder") = 2; config.opt_int("perimeter_extruder") = 2;
config->opt_int("support_material_extruder") = 3; config.opt_int("support_material_extruder") = 3;
THEN("Brim is printed with the extruder used for the perimeters of first object") { THEN("Brim is printed with the extruder used for the perimeters of first object") {
auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config);
gcode = Slic3r::Test::gcode(print); gcode = Slic3r::Test::gcode(print);
int tool = get_brim_tool(gcode, parser); int tool = get_brim_tool(gcode, parser);
REQUIRE(tool == config->opt_int("perimeter_extruder") - 1); REQUIRE(tool == config.opt_int("perimeter_extruder") - 1);
} }
} }
WHEN("Perimeter extruder = 2, support extruders = 3, raft is enabled") { WHEN("Perimeter extruder = 2, support extruders = 3, raft is enabled") {
config->opt_int("skirts") = 0; config.opt_int("skirts") = 0;
config->opt_float("brim_width") = 5; config.opt_float("brim_width") = 5;
config->opt_int("perimeter_extruder") = 2; config.opt_int("perimeter_extruder") = 2;
config->opt_int("support_material_extruder") = 3; config.opt_int("support_material_extruder") = 3;
config->opt_int("raft_layers") = 1; config.opt_int("raft_layers") = 1;
THEN("brim is printed with same extruder as skirt") { THEN("brim is printed with same extruder as skirt") {
auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config);
gcode = Slic3r::Test::gcode(print); gcode = Slic3r::Test::gcode(print);
int tool = get_brim_tool(gcode, parser); int tool = get_brim_tool(gcode, parser);
REQUIRE(tool == config->opt_int("support_material_extruder") - 1); REQUIRE(tool == config.opt_int("support_material_extruder") - 1);
} }
} }
WHEN("brim width to 1 with layer_width of 0.5") { WHEN("brim width to 1 with layer_width of 0.5") {
config->opt_int("skirts") = 0; config.opt_int("skirts") = 0;
config->set_deserialize("first_layer_extrusion_width", "0.5"); config.set_deserialize("first_layer_extrusion_width", "0.5");
config->opt_float("brim_width") = 1; config.opt_float("brim_width") = 1;
THEN("2 brim lines") { THEN("2 brim lines") {
Slic3r::Model model; Slic3r::Model model;
@ -163,11 +163,11 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") {
#if 0 #if 0
WHEN("brim ears on a square") { WHEN("brim ears on a square") {
config->opt_int("skirts") = 0); config.opt_int("skirts") = 0);
config->set_deserialize("first_layer_extrusion_width", "0.5"); config.set_deserialize("first_layer_extrusion_width", "0.5");
config->opt_float("brim_width") = 1; config.opt_float("brim_width") = 1;
config->set("brim_ears", true); config.set("brim_ears", true);
config->set("brim_ears_max_angle", 91); config.set("brim_ears_max_angle", 91);
Slic3r::Model model; Slic3r::Model model;
auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config);
@ -179,11 +179,11 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") {
} }
WHEN("brim ears on a square but with a too small max angle") { WHEN("brim ears on a square but with a too small max angle") {
config->set("skirts", 0); config.set("skirts", 0);
config->set("first_layer_extrusion_width", 0.5); config.set("first_layer_extrusion_width", 0.5);
config->set("brim_width", 1); config.set("brim_width", 1);
config->set("brim_ears", true); config.set("brim_ears", true);
config->set("brim_ears_max_angle", 89); config.set("brim_ears_max_angle", 89);
THEN("no brim") { THEN("no brim") {
Slic3r::Model model; Slic3r::Model model;
@ -195,25 +195,25 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") {
#endif #endif
WHEN("Object is plated with overhang support and a brim") { WHEN("Object is plated with overhang support and a brim") {
config->opt_float("layer_height") = 0.4; config.opt_float("layer_height") = 0.4;
config->set_deserialize("first_layer_height", "0.4"); config.set_deserialize("first_layer_height", "0.4");
config->opt_int("skirts") = 1; config.opt_int("skirts") = 1;
config->opt_float("skirt_distance") = 0; config.opt_float("skirt_distance") = 0;
config->opt_float("support_material_speed") = 99; config.opt_float("support_material_speed") = 99;
config->opt_int("perimeter_extruder") = 1; config.opt_int("perimeter_extruder") = 1;
config->opt_int("support_material_extruder") = 2; config.opt_int("support_material_extruder") = 2;
config->opt_int("infill_extruder") = 3; // ensure that a tool command gets emitted. config.opt_int("infill_extruder") = 3; // ensure that a tool command gets emitted.
config->set_deserialize("cooling", "0"); // to prevent speeds to be altered config.set_deserialize("cooling", "0"); // to prevent speeds to be altered
config->set_deserialize("first_layer_speed", "100%"); // to prevent speeds to be altered config.set_deserialize("first_layer_speed", "100%"); // to prevent speeds to be altered
Slic3r::Model model; Slic3r::Model model;
auto print = Slic3r::Test::init_print({TestMesh::overhang}, model, config); auto print = Slic3r::Test::init_print({TestMesh::overhang}, model, config);
print->process(); print->process();
// config->set("support_material", true); // to prevent speeds to be altered // config.set("support_material", true); // to prevent speeds to be altered
THEN("skirt length is large enough to contain object with support") { THEN("skirt length is large enough to contain object with support") {
CHECK(config->opt_bool("support_material")); // test is not valid if support material is off CHECK(config.opt_bool("support_material")); // test is not valid if support material is off
double skirt_length = 0.0; double skirt_length = 0.0;
Points extrusion_points; Points extrusion_points;
int tool = -1; int tool = -1;
@ -221,18 +221,18 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") {
auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config);
std::string gcode = Slic3r::Test::gcode(print); std::string gcode = Slic3r::Test::gcode(print);
double support_speed = config->opt<ConfigOptionFloat>("support_material_speed")->value * MM_PER_MIN; double support_speed = config.opt<ConfigOptionFloat>("support_material_speed")->value * MM_PER_MIN;
parser.parse_buffer(gcode, [config, &extrusion_points, &tool, &skirt_length, support_speed] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) parser.parse_buffer(gcode, [config, &extrusion_points, &tool, &skirt_length, support_speed] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
{ {
// std::cerr << line.cmd() << "\n"; // std::cerr << line.cmd() << "\n";
if (boost::starts_with(line.cmd(), "T")) { if (boost::starts_with(line.cmd(), "T")) {
tool = atoi(line.cmd().data() + 1); tool = atoi(line.cmd().data() + 1);
} else if (self.z() == Approx(config->opt<ConfigOptionFloat>("first_layer_height")->value)) { } else if (self.z() == Approx(config.opt<ConfigOptionFloat>("first_layer_height")->value)) {
// on first layer // on first layer
if (line.extruding(self) && line.dist_XY(self) > 0) { if (line.extruding(self) && line.dist_XY(self) > 0) {
float speed = ( self.f() > 0 ? self.f() : line.new_F(self)); float speed = ( self.f() > 0 ? self.f() : line.new_F(self));
// std::cerr << "Tool " << tool << "\n"; // std::cerr << "Tool " << tool << "\n";
if (speed == Approx(support_speed) && tool == config->opt_int("perimeter_extruder") - 1) { if (speed == Approx(support_speed) && tool == config.opt_int("perimeter_extruder") - 1) {
// Skirt uses first material extruder, support material speed. // Skirt uses first material extruder, support material speed.
skirt_length += line.dist_XY(self); skirt_length += line.dist_XY(self);
} else { } else {
@ -252,7 +252,7 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") {
} }
} }
WHEN("Large minimum skirt length is used.") { WHEN("Large minimum skirt length is used.") {
config->opt_float("min_skirt_length") = 20; config.opt_float("min_skirt_length") = 20;
Slic3r::Model model; Slic3r::Model model;
auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config);
THEN("Gcode generation doesn't crash") { THEN("Gcode generation doesn't crash") {

View File

@ -384,13 +384,13 @@ SCENARIO( "TriangleMeshSlicer: Cut behavior.") {
#ifdef TEST_PERFORMANCE #ifdef TEST_PERFORMANCE
TEST_CASE("Regression test for issue #4486 - files take forever to slice") { TEST_CASE("Regression test for issue #4486 - files take forever to slice") {
TriangleMesh mesh; TriangleMesh mesh;
std::shared_ptr<Slic3r::DynamicPrintConfig> config = Slic3r::DynamicPrintConfig::new_from_defaults(); DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config();
mesh.ReadSTLFile(std::string(testfile_dir) + "test_trianglemesh/4486/100_000.stl"); mesh.ReadSTLFile(std::string(testfile_dir) + "test_trianglemesh/4486/100_000.stl");
mesh.repair(); mesh.repair();
config->set("layer_height", 500); config.set("layer_height", 500);
config->set("first_layer_height", 250); config.set("first_layer_height", 250);
config->set("nozzle_diameter", 500); config.set("nozzle_diameter", 500);
Slic3r::Model model; Slic3r::Model model;
auto print = Slic3r::Test::init_print({mesh}, model, config); auto print = Slic3r::Test::init_print({mesh}, model, config);
@ -411,14 +411,14 @@ TEST_CASE("Regression test for issue #4486 - files take forever to slice") {
#ifdef BUILD_PROFILE #ifdef BUILD_PROFILE
TEST_CASE("Profile test for issue #4486 - files take forever to slice") { TEST_CASE("Profile test for issue #4486 - files take forever to slice") {
TriangleMesh mesh; TriangleMesh mesh;
std::shared_ptr<Slic3r::DynamicPrintConfig> config = Slic3r::DynamicPrintConfig::new_from_defaults(); DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config();
mesh.ReadSTLFile(std::string(testfile_dir) + "test_trianglemesh/4486/10_000.stl"); mesh.ReadSTLFile(std::string(testfile_dir) + "test_trianglemesh/4486/10_000.stl");
mesh.repair(); mesh.repair();
config->set("layer_height", 500); config.set("layer_height", 500);
config->set("first_layer_height", 250); config.set("first_layer_height", 250);
config->set("nozzle_diameter", 500); config.set("nozzle_diameter", 500);
config->set("fill_density", "5%"); config.set("fill_density", "5%");
Slic3r::Model model; Slic3r::Model model;
auto print = Slic3r::Test::init_print({mesh}, model, config); auto print = Slic3r::Test::init_print({mesh}, model, config);

View File

@ -9,6 +9,8 @@
DynamicPrintConfig(); DynamicPrintConfig();
~DynamicPrintConfig(); ~DynamicPrintConfig();
static DynamicPrintConfig* new_from_defaults(); static DynamicPrintConfig* new_from_defaults();
DynamicPrintConfig* DynamicPrintConfig::new_from_defaults()
%code{% RETVAL = DynamicPrintConfig::new_from_defaults_keys(FullPrintConfig::defaults().keys()); %};
static DynamicPrintConfig* new_from_defaults_keys(std::vector<std::string> keys); static DynamicPrintConfig* new_from_defaults_keys(std::vector<std::string> keys);
DynamicPrintConfig* clone() %code{% RETVAL = new DynamicPrintConfig(*THIS); %}; DynamicPrintConfig* clone() %code{% RETVAL = new DynamicPrintConfig(*THIS); %};
DynamicPrintConfig* clone_only(std::vector<std::string> keys) DynamicPrintConfig* clone_only(std::vector<std::string> keys)