mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-29 19:53:44 -06:00 
			
		
		
		
	Ported test_support_material from upstream Slic3r.
Reworked the FFF testing framework & ConfigBase::set_deserialize() for more compact tests: set_deserialize() now accepts list of key / value pairs. Fixed an incorrect assert in LayerRegion.
This commit is contained in:
		
							parent
							
								
									0ee78543a4
								
							
						
					
					
						commit
						c228a49fe0
					
				
					 13 changed files with 769 additions and 536 deletions
				
			
		|  | @ -438,6 +438,14 @@ bool ConfigBase::set_deserialize(const t_config_option_key &opt_key_src, const s | |||
|     return this->set_deserialize_raw(opt_key, value, append); | ||||
| } | ||||
| 
 | ||||
| bool ConfigBase::set_deserialize(std::initializer_list<SetDeserializeItem> items) | ||||
| { | ||||
| 	bool deserialized = true; | ||||
| 	for (const SetDeserializeItem &item : items) | ||||
| 		deserialized &= this->set_deserialize(item.opt_key, item.opt_value, item.append); | ||||
| 	return deserialized; | ||||
| } | ||||
| 
 | ||||
| bool ConfigBase::set_deserialize_raw(const t_config_option_key &opt_key_src, const std::string &value, bool append) | ||||
| { | ||||
|     t_config_option_key opt_key = opt_key_src; | ||||
|  |  | |||
|  | @ -1554,6 +1554,8 @@ public: | |||
|     // Set a configuration value from a string, it will call an overridable handle_legacy() 
 | ||||
|     // to resolve renamed and removed configuration keys.
 | ||||
|     bool set_deserialize(const t_config_option_key &opt_key, const std::string &str, bool append = false); | ||||
|     struct SetDeserializeItem { std::string opt_key; std::string opt_value; bool append = false; }; | ||||
|     bool set_deserialize(std::initializer_list<SetDeserializeItem> items); | ||||
| 
 | ||||
|     double get_abs_value(const t_config_option_key &opt_key) const; | ||||
|     double get_abs_value(const t_config_option_key &opt_key, double ratio_over) const; | ||||
|  |  | |||
|  | @ -70,7 +70,7 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec | |||
|         fill_surfaces | ||||
|     ); | ||||
|      | ||||
|     if (this->layer()->lower_layer != NULL) | ||||
|     if (this->layer()->lower_layer != nullptr) | ||||
|         // Cummulative sum of polygons over all the regions.
 | ||||
|         g.lower_slices = &this->layer()->lower_layer->slices; | ||||
|      | ||||
|  | @ -130,7 +130,7 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly | |||
|                     bridges.emplace_back(surface); | ||||
|             } | ||||
|             if (surface.is_internal()) { | ||||
|             	assert(surface.surface_type == stInternal); | ||||
|             	assert(surface.surface_type == stInternal || surface.surface_type == stInternalSolid); | ||||
|             	if (! has_infill && lower_layer != nullptr) | ||||
|             		polygons_append(voids, surface.expolygon); | ||||
|             	internal.emplace_back(std::move(surface)); | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ add_executable(${_TEST_NAME}_tests | |||
| 	test_printgcode.cpp | ||||
| 	test_printobject.cpp | ||||
| 	test_skirt_brim.cpp | ||||
| 	test_support_material.cpp | ||||
| 	test_trianglemesh.cpp | ||||
| 	) | ||||
| target_link_libraries(${_TEST_NAME}_tests test_common libslic3r) | ||||
|  |  | |||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -1,12 +1,12 @@ | |||
| #ifndef SLIC3R_TEST_DATA_HPP | ||||
| #define SLIC3R_TEST_DATA_HPP | ||||
| 
 | ||||
| #include "libslic3r/Point.hpp" | ||||
| #include "libslic3r/TriangleMesh.hpp" | ||||
| #include "libslic3r/Config.hpp" | ||||
| #include "libslic3r/Geometry.hpp" | ||||
| #include "libslic3r/Model.hpp" | ||||
| #include "libslic3r/Point.hpp" | ||||
| #include "libslic3r/Print.hpp" | ||||
| #include "libslic3r/Config.hpp" | ||||
| #include "libslic3r/TriangleMesh.hpp" | ||||
| 
 | ||||
| #include <unordered_map> | ||||
| 
 | ||||
|  | @ -61,15 +61,24 @@ bool _equiv(const T& a, const T& b) { return std::abs(a - b) < EPSILON; } | |||
| template <typename T> | ||||
| bool _equiv(const T& a, const T& b, double epsilon) { return abs(a - b) < epsilon; } | ||||
| 
 | ||||
| //Slic3r::Model model(const std::string& model_name, TestMesh m, Vec3d translate = Vec3d(0,0,0), Vec3d scale = Vec3d(1.0,1.0,1.0));
 | ||||
| //Slic3r::Model model(const std::string& model_name, TestMesh m, Vec3d translate = Vec3d(0,0,0), double scale = 1.0);
 | ||||
| 
 | ||||
| Slic3r::Model model(const std::string& model_name, TriangleMesh&& _mesh); | ||||
| void init_print(std::vector<TriangleMesh> 		  &&meshes, Slic3r::Print &print, Slic3r::Model& model, const DynamicPrintConfig &config_in, bool comments = false); | ||||
| void init_print(std::initializer_list<TestMesh> 	meshes, Slic3r::Print &print, Slic3r::Model& model, const Slic3r::DynamicPrintConfig &config_in = Slic3r::DynamicPrintConfig::full_print_config(), bool comments = false); | ||||
| void init_print(std::initializer_list<TriangleMesh> meshes, Slic3r::Print &print, Slic3r::Model& model, const Slic3r::DynamicPrintConfig &config_in = Slic3r::DynamicPrintConfig::full_print_config(), bool comments = false); | ||||
| void init_print(std::initializer_list<TestMesh> 	meshes, Slic3r::Print &print, Slic3r::Model& model, std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items, bool comments = false); | ||||
| void init_print(std::initializer_list<TriangleMesh> meshes, Slic3r::Print &print, Slic3r::Model& model, std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items, 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, const Slic3r::DynamicPrintConfig &config_in = Slic3r::DynamicPrintConfig::full_print_config(), bool comments = false); | ||||
| void init_and_process_print(std::initializer_list<TestMesh> 	meshes, Slic3r::Print &print, const DynamicPrintConfig& config, bool comments = false); | ||||
| void init_and_process_print(std::initializer_list<TriangleMesh> meshes, Slic3r::Print &print, const DynamicPrintConfig& config, bool comments = false); | ||||
| void init_and_process_print(std::initializer_list<TestMesh> 	meshes, Slic3r::Print &print, std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items, bool comments = false); | ||||
| void init_and_process_print(std::initializer_list<TriangleMesh> meshes, Slic3r::Print &print, std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items, bool comments = false); | ||||
| 
 | ||||
| std::string gcode(std::shared_ptr<Print> print); | ||||
| std::string gcode(Print& print); | ||||
| 
 | ||||
| std::string slice(std::initializer_list<TestMesh> meshes, const DynamicPrintConfig &config, bool comments = false); | ||||
| std::string slice(std::initializer_list<TriangleMesh> meshes, const DynamicPrintConfig &config, bool comments = false); | ||||
| std::string slice(std::initializer_list<TestMesh> meshes, std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items, bool comments = false); | ||||
| std::string slice(std::initializer_list<TriangleMesh> meshes, std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items, bool comments = false); | ||||
| 
 | ||||
| } } // namespace Slic3r::Test
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,16 +19,19 @@ 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") { | ||||
|         // this is a sharedptr
 | ||||
|         DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); | ||||
|         config.opt_int("skirts") = 1; | ||||
|         config.opt_float("brim_width") = 2.; | ||||
|         config.opt_int("perimeters") = 3; | ||||
|         config.set_deserialize("fill_density", "40%"); | ||||
|         config.set_deserialize("first_layer_height", "100%"); | ||||
| 		config.set_deserialize({ | ||||
| 			{ "brim_width",			"2" }, | ||||
| 			{ "skirts",				"1" }, | ||||
| 			{ "perimeters",			"3" }, | ||||
| 			{ "fill_density",		"40%" }, | ||||
| 			{ "first_layer_height", "100%" } | ||||
| 			}); | ||||
| 
 | ||||
|         WHEN("first layer width set to 2mm") { | ||||
|             Slic3r::Model model; | ||||
|             config.set_deserialize("first_layer_extrusion_width", "2"); | ||||
|             std::shared_ptr<Print> print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|             Slic3r::Print print; | ||||
|             Slic3r::Test::init_print({TestMesh::cube_20x20x20}, print, model, config); | ||||
| 
 | ||||
|             std::vector<double> E_per_mm_bottom; | ||||
|             std::string gcode = Test::gcode(print); | ||||
|  |  | |||
|  | @ -10,31 +10,20 @@ using namespace Slic3r::Test; | |||
| 
 | ||||
| SCENARIO("PrintObject: Perimeter generation", "[PrintObject]") { | ||||
|     GIVEN("20mm cube and default config") { | ||||
|         Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); | ||||
|         TestMesh m = TestMesh::cube_20x20x20; | ||||
|         Slic3r::Model model; | ||||
|         size_t event_counter = 0; | ||||
|         std::string stage; | ||||
|         int value = 0; | ||||
|         auto callback = [&event_counter, &stage, &value] (int a, const char* b) { stage = std::string(b); ++ event_counter; value = a; }; | ||||
|         config.set_deserialize("fill_density", "0"); | ||||
| 
 | ||||
|         WHEN("make_perimeters() is called")  { | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({m}, model, config); | ||||
| 			print->process(); | ||||
| 			const PrintObject& object = *(print->objects().at(0)); | ||||
|             Slic3r::Print print; | ||||
|             Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { { "fill_density", "0" } }); | ||||
| 			const PrintObject &object = *print.objects().front(); | ||||
| 			THEN("67 layers exist in the model") { | ||||
|                 REQUIRE(object.layers().size() == 66); | ||||
|             } | ||||
|             THEN("Every layer in region 0 has 1 island of perimeters") { | ||||
|                 for (const Layer *layer : object.layers()) { | ||||
|                 for (const Layer *layer : object.layers()) | ||||
|                     REQUIRE(layer->regions().front()->perimeters.entities.size() == 1); | ||||
|                 } | ||||
|             } | ||||
|             THEN("Every layer in region 0 has 3 paths in its perimeters list.") { | ||||
|                 for (const Layer *layer : object.layers()) { | ||||
|                 for (const Layer *layer : object.layers()) | ||||
|                     REQUIRE(layer->regions().front()->perimeters.items_count() == 3); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -42,66 +31,59 @@ SCENARIO("PrintObject: Perimeter generation", "[PrintObject]") { | |||
| 
 | ||||
| SCENARIO("Print: Skirt generation", "[Print]") { | ||||
|     GIVEN("20mm cube and default config") { | ||||
|         Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); | ||||
|         TestMesh m = TestMesh::cube_20x20x20; | ||||
|         Slic3r::Model model; | ||||
|         std::string stage; | ||||
|         int value = 0; | ||||
|         config.opt_int("skirt_height") = 1; | ||||
|         config.opt_float("skirt_distance") = 1.f; | ||||
|         WHEN("Skirts is set to 2 loops")  { | ||||
|             config.opt_int("skirts") = 2; | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({m}, model, config); | ||||
| 			print->process(); | ||||
|             Slic3r::Print print; | ||||
|             Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { | ||||
|             	{ "skirt_height", 	"1" }, | ||||
|         		{ "skirt_distance", "1" }, | ||||
|         		{ "skirts", 		"2"} | ||||
|             }); | ||||
|             THEN("Skirt Extrusion collection has 2 loops in it") { | ||||
|                 REQUIRE(print->skirt().items_count() == 2); | ||||
|                 REQUIRE(print->skirt().flatten().entities.size() == 2); | ||||
|                 REQUIRE(print.skirt().items_count() == 2); | ||||
|                 REQUIRE(print.skirt().flatten().entities.size() == 2); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void test_is_solid_infill(std::shared_ptr<Slic3r::Print> p, size_t obj_id, size_t layer_id ) { | ||||
|     const PrintObject &obj = *(p->objects().at(obj_id)); | ||||
|     const Layer       &layer = *(obj.get_layer((int)layer_id)); | ||||
| 
 | ||||
|     // iterate over all of the regions in the layer
 | ||||
|     for (const LayerRegion *reg : layer.regions()) { | ||||
|         // for each region, iterate over the fill surfaces
 | ||||
|         for (const Surface& s : reg->fill_surfaces.surfaces) { | ||||
|             CHECK(s.is_solid()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| SCENARIO("Print: Changing number of solid surfaces does not cause all surfaces to become internal.", "[Print]") { | ||||
|     GIVEN("sliced 20mm cube and config with top_solid_surfaces = 2 and bottom_solid_surfaces = 1") { | ||||
|         Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); | ||||
|         TestMesh m = TestMesh::cube_20x20x20; | ||||
|         config.opt_int("top_solid_layers") = 2; | ||||
|         config.opt_int("bottom_solid_layers") = 1; | ||||
|         config.opt_float("layer_height") = 0.5; // get a known number of layers
 | ||||
|         config.set_deserialize("first_layer_height", "0.5"); | ||||
| 		config.set_deserialize({ | ||||
| 			{ "top_solid_layers",		"2" }, | ||||
| 			{ "bottom_solid_layers",	"1" }, | ||||
| 			{ "layer_height",			"0.5" }, // get a known number of layers
 | ||||
| 			{ "first_layer_height",		"0.5" } | ||||
| 			}); | ||||
|         Slic3r::Print print; | ||||
|         Slic3r::Model model; | ||||
|         std::string stage; | ||||
|         std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({m}, model, config); | ||||
|         print->process(); | ||||
|         Slic3r::Test::init_print({TestMesh::cube_20x20x20}, print, model, config); | ||||
|         // Precondition: Ensure that the model has 2 solid top layers (39, 38)
 | ||||
|         // and one solid bottom layer (0).
 | ||||
|         test_is_solid_infill(print, 0, 0); // should be solid
 | ||||
|         test_is_solid_infill(print, 0, 39); // should be solid
 | ||||
|         test_is_solid_infill(print, 0, 38); // should be solid
 | ||||
| 		auto test_is_solid_infill = [&print](size_t obj_id, size_t layer_id) { | ||||
| 		    const Layer &layer = *(print.objects().at(obj_id)->get_layer((int)layer_id)); | ||||
| 		    // iterate over all of the regions in the layer
 | ||||
| 		    for (const LayerRegion *region : layer.regions()) { | ||||
| 		        // for each region, iterate over the fill surfaces
 | ||||
| 		        for (const Surface &surface : region->fill_surfaces.surfaces) | ||||
| 		            CHECK(surface.is_solid()); | ||||
| 		    } | ||||
| 		}; | ||||
|         print.process(); | ||||
|         test_is_solid_infill(0,  0); // should be solid
 | ||||
|         test_is_solid_infill(0, 39); // should be solid
 | ||||
|         test_is_solid_infill(0, 38); // should be solid
 | ||||
|         WHEN("Model is re-sliced with top_solid_layers == 3") { | ||||
| 			config.opt_int("top_solid_layers") = 3; | ||||
| 			print->apply(model, config); | ||||
|             print->process(); | ||||
| 			print.apply(model, config); | ||||
|             print.process(); | ||||
|             THEN("Print object does not have 0 solid bottom layers.") { | ||||
|                 test_is_solid_infill(print, 0, 0); | ||||
|                 test_is_solid_infill(0, 0); | ||||
|             } | ||||
|             AND_THEN("Print object has 3 top solid layers") { | ||||
|                 test_is_solid_infill(print, 0, 39); | ||||
|                 test_is_solid_infill(print, 0, 38); | ||||
|                 test_is_solid_infill(print, 0, 37); | ||||
|                 test_is_solid_infill(0, 39); | ||||
|                 test_is_solid_infill(0, 38); | ||||
|                 test_is_solid_infill(0, 37); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -109,35 +91,36 @@ SCENARIO("Print: Changing number of solid surfaces does not cause all surfaces t | |||
| 
 | ||||
| SCENARIO("Print: Brim generation", "[Print]") { | ||||
|     GIVEN("20mm cube and default config, 1mm first layer width") { | ||||
|         Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); | ||||
|         TestMesh m = TestMesh::cube_20x20x20; | ||||
|         Slic3r::Model model; | ||||
|         std::string stage; | ||||
|         int value = 0; | ||||
|         config.set_deserialize("first_layer_extrusion_width", "1"); | ||||
|         WHEN("Brim is set to 3mm")  { | ||||
|             config.opt_float("brim_width") = 3; | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({m}, model, config); | ||||
|             print->process(); | ||||
| 	        Slic3r::Print print; | ||||
| 	        Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { | ||||
| 	        	{ "first_layer_extrusion_width", 	"1" }, | ||||
| 	        	{ "brim_width", 					"3" } | ||||
| 	        }); | ||||
|             THEN("Brim Extrusion collection has 3 loops in it") { | ||||
|                 REQUIRE(print->brim().items_count() == 3); | ||||
|                 REQUIRE(print.brim().items_count() == 3); | ||||
|             } | ||||
|         } | ||||
|         WHEN("Brim is set to 6mm")  { | ||||
|             config.opt_float("brim_width") = 6; | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({m}, model, config); | ||||
| 			print->process(); | ||||
| 	        Slic3r::Print print; | ||||
| 	        Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { | ||||
| 	        	{ "first_layer_extrusion_width", 	"1" }, | ||||
| 	        	{ "brim_width", 					"6" } | ||||
| 	        }); | ||||
|             THEN("Brim Extrusion collection has 6 loops in it") { | ||||
|                 REQUIRE(print->brim().items_count() == 6); | ||||
|                 REQUIRE(print.brim().items_count() == 6); | ||||
|             } | ||||
|         } | ||||
|         WHEN("Brim is set to 6mm, extrusion width 0.5mm")  { | ||||
|             config.opt_float("brim_width") = 6; | ||||
|             config.set_deserialize("first_layer_extrusion_width", "0.5"); | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({m}, model, config); | ||||
| 			print->process(); | ||||
| 	        Slic3r::Print print; | ||||
| 	        Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { | ||||
| 	        	{ "first_layer_extrusion_width", 	"1" }, | ||||
| 	        	{ "brim_width", 					"6" }, | ||||
| 	        	{ "first_layer_extrusion_width", 	"0.5" } | ||||
| 	        }); | ||||
| 			print.process(); | ||||
|             THEN("Brim Extrusion collection has 12 loops in it") { | ||||
|                 REQUIRE(print->brim().items_count() == 14); | ||||
|                 REQUIRE(print.brim().items_count() == 14); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -17,16 +17,16 @@ std::regex skirt_regex("G1 X[-0-9.]* Y[-0-9.]* E[-0-9.]* ; skirt"); | |||
| 
 | ||||
| SCENARIO( "PrintGCode basic functionality", "[PrintGCode]") { | ||||
|     GIVEN("A default configuration and a print test object") { | ||||
|         Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); | ||||
| 
 | ||||
|         WHEN("the output is executed with no support material") { | ||||
| 			config.set_deserialize("layer_height", "0.2"); | ||||
| 			config.set_deserialize("first_layer_height", "0.2"); | ||||
|             config.set_deserialize("first_layer_extrusion_width", "0"); | ||||
|             config.set_deserialize("gcode_comments", "1"); | ||||
|             config.set_deserialize("start_gcode", ""); | ||||
|             Slic3r::Print print; | ||||
|             Slic3r::Model model; | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|             Slic3r::Test::init_print({TestMesh::cube_20x20x20}, print, model, { | ||||
|                 { "layer_height",					"0.2" }, | ||||
|                 { "first_layer_height",				"0.2" }, | ||||
|                 { "first_layer_extrusion_width",	"0" }, | ||||
|                 { "gcode_comments",					"1" }, | ||||
|                 { "start_gcode",					"" } | ||||
|                 }); | ||||
|             std::string gcode = Slic3r::Test::gcode(print); | ||||
|             THEN("Some text output is generated.") { | ||||
|                 REQUIRE(gcode.size() > 0); | ||||
|  | @ -75,7 +75,7 @@ SCENARIO( "PrintGCode basic functionality", "[PrintGCode]") { | |||
|             THEN("final Z height is 20mm") { | ||||
|                 double final_z = 0.0; | ||||
|                 GCodeReader reader; | ||||
|                 reader.apply_config(print->config()); | ||||
|                 reader.apply_config(print.config()); | ||||
|                 reader.parse_buffer(gcode, [&final_z] (GCodeReader& self, const GCodeReader::GCodeLine& line) { | ||||
|                     final_z = std::max<double>(final_z, static_cast<double>(self.z())); // record the highest Z point we reach
 | ||||
|                 }); | ||||
|  | @ -83,16 +83,18 @@ SCENARIO( "PrintGCode basic functionality", "[PrintGCode]") { | |||
|             } | ||||
|         } | ||||
|         WHEN("output is executed with complete objects and two differently-sized meshes") { | ||||
|             Slic3r::Print print; | ||||
|             Slic3r::Model model; | ||||
|             config.set_deserialize("first_layer_extrusion_width", "0"); | ||||
|             config.set_deserialize("first_layer_height", "0.3"); | ||||
| 			config.set_deserialize("layer_height", "0.2"); | ||||
| 			config.set_deserialize("support_material", "0"); | ||||
|             config.set_deserialize("raft_layers", "0"); | ||||
|             config.set_deserialize("complete_objects", "1"); | ||||
|             config.set_deserialize("gcode_comments", "1"); | ||||
|             config.set_deserialize("between_objects_gcode", "; between-object-gcode"); | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({TestMesh::cube_20x20x20,TestMesh::cube_20x20x20}, model, config); | ||||
|             Slic3r::Test::init_print({TestMesh::cube_20x20x20,TestMesh::cube_20x20x20}, print, model, { | ||||
|                 { "first_layer_extrusion_width",    "0" }, | ||||
|                 { "first_layer_height",             "0.3" }, | ||||
|                 { "layer_height",                   "0.2" }, | ||||
|                 { "support_material",               "0" }, | ||||
|                 { "raft_layers",                    "0" }, | ||||
|                 { "complete_objects",               "1" }, | ||||
|                 { "gcode_comments",                 "1" }, | ||||
|                 { "between_objects_gcode",          "; between-object-gcode" } | ||||
|                 }); | ||||
|             std::string gcode = Slic3r::Test::gcode(print); | ||||
|             THEN("Some text output is generated.") { | ||||
|                 REQUIRE(gcode.size() > 0); | ||||
|  | @ -115,7 +117,7 @@ SCENARIO( "PrintGCode basic functionality", "[PrintGCode]") { | |||
|             THEN("final Z height is 20.1mm") { | ||||
|                 double final_z = 0.0; | ||||
|                 GCodeReader reader; | ||||
|                 reader.apply_config(print->config()); | ||||
|                 reader.apply_config(print.config()); | ||||
|                 reader.parse_buffer(gcode, [&final_z] (GCodeReader& self, const GCodeReader::GCodeLine& line) { | ||||
|                     final_z = std::max(final_z, static_cast<double>(self.z())); // record the highest Z point we reach
 | ||||
|                 }); | ||||
|  | @ -125,7 +127,7 @@ SCENARIO( "PrintGCode basic functionality", "[PrintGCode]") { | |||
|                 double final_z = 0.0; | ||||
|                 bool reset = false; | ||||
|                 GCodeReader reader; | ||||
|                 reader.apply_config(print->config()); | ||||
|                 reader.apply_config(print.config()); | ||||
|                 reader.parse_buffer(gcode, [&final_z, &reset] (GCodeReader& self, const GCodeReader::GCodeLine& line) { | ||||
|                     if (final_z > 0 && std::abs(self.z() - 0.3) < 0.01 ) { // saw higher Z before this, now it's lower
 | ||||
|                         reset = true; | ||||
|  | @ -139,7 +141,7 @@ SCENARIO( "PrintGCode basic functionality", "[PrintGCode]") { | |||
|                 double final_z = 0.0; | ||||
|                 bool reset = false; | ||||
|                 GCodeReader reader; | ||||
|                 reader.apply_config(print->config()); | ||||
|                 reader.apply_config(print.config()); | ||||
|                 reader.parse_buffer(gcode, [&final_z, &reset] (GCodeReader& self, const GCodeReader::GCodeLine& line) { | ||||
|                     if (final_z > 0 && std::abs(self.z() - 0.3) < 0.01 ) {  | ||||
|                         reset = (final_z > 20.0); | ||||
|  | @ -151,13 +153,12 @@ SCENARIO( "PrintGCode basic functionality", "[PrintGCode]") { | |||
|             } | ||||
|         } | ||||
|         WHEN("the output is executed with support material") { | ||||
|             Slic3r::Model model; | ||||
|             config.set_deserialize("first_layer_extrusion_width", "0"); | ||||
|             config.set_deserialize("support_material", "1"); | ||||
|             config.set_deserialize("raft_layers", "3"); | ||||
|             config.set_deserialize("gcode_comments", "1"); | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|             std::string gcode = Slic3r::Test::gcode(print); | ||||
|             std::string gcode = ::Test::slice({TestMesh::cube_20x20x20}, { | ||||
|                 { "first_layer_extrusion_width",    "0" }, | ||||
|                 { "support_material",               "1" }, | ||||
|                 { "raft_layers",                    "3" }, | ||||
|                 { "gcode_comments",                 "1" } | ||||
|                 }); | ||||
|             THEN("Some text output is generated.") { | ||||
|                 REQUIRE(gcode.size() > 0); | ||||
|             } | ||||
|  | @ -175,10 +176,9 @@ SCENARIO( "PrintGCode basic functionality", "[PrintGCode]") { | |||
|             } | ||||
|         } | ||||
|         WHEN("the output is executed with a separate first layer extrusion width") { | ||||
|             Slic3r::Model model; | ||||
|             config.set_deserialize("first_layer_extrusion_width", "0.5"); | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|             std::string gcode = Slic3r::Test::gcode(print); | ||||
| 			std::string gcode = ::Test::slice({ TestMesh::cube_20x20x20 }, { | ||||
|                 { "first_layer_extrusion_width", "0.5" } | ||||
|                 }); | ||||
|             THEN("Some text output is generated.") { | ||||
|                 REQUIRE(gcode.size() > 0); | ||||
|             } | ||||
|  | @ -193,48 +193,46 @@ SCENARIO( "PrintGCode basic functionality", "[PrintGCode]") { | |||
|             } | ||||
|         } | ||||
|         WHEN("Cooling is enabled and the fan is disabled.") { | ||||
|             config.set_deserialize("cooling", "1"); | ||||
|             config.set_deserialize("disable_fan_first_layers", "5"); | ||||
|             Slic3r::Model model; | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|             std::string gcode = Slic3r::Test::gcode(print); | ||||
| 			std::string gcode = ::Test::slice({ TestMesh::cube_20x20x20 }, { | ||||
| 				{ "cooling",                    "1" }, | ||||
|                 { "disable_fan_first_layers",   "5" } | ||||
|                 }); | ||||
|             THEN("GCode to disable fan is emitted."){ | ||||
|                 REQUIRE(gcode.find("M107") != std::string::npos); | ||||
|             } | ||||
|         } | ||||
|         WHEN("end_gcode exists with layer_num and layer_z") { | ||||
|             config.set_deserialize("end_gcode", "; Layer_num [layer_num]\n; Layer_z [layer_z]"); | ||||
|             config.set_deserialize("layer_height", "0.1"); | ||||
|             config.set_deserialize("first_layer_height", "0.1"); | ||||
| 
 | ||||
|             Slic3r::Model model; | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|             std::string gcode = Slic3r::Test::gcode(print); | ||||
| 			std::string gcode = ::Test::slice({ TestMesh::cube_20x20x20 }, { | ||||
| 				{ "end_gcode",              "; Layer_num [layer_num]\n; Layer_z [layer_z]" }, | ||||
|                 { "layer_height",           "0.1" }, | ||||
|                 { "first_layer_height",     "0.1" } | ||||
|                 }); | ||||
|             THEN("layer_num and layer_z are processed in the end gcode") { | ||||
|                 REQUIRE(gcode.find("; Layer_num 199") != std::string::npos); | ||||
|                 REQUIRE(gcode.find("; Layer_z 20") != std::string::npos); | ||||
|             } | ||||
|         } | ||||
|         WHEN("current_extruder exists in start_gcode") { | ||||
|             config.set_deserialize("start_gcode", "; Extruder [current_extruder]"); | ||||
|             { | ||||
|                 Slic3r::Model model; | ||||
|                 std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|                 std::string gcode = Slic3r::Test::gcode(print); | ||||
| 				std::string gcode = ::Test::slice({ TestMesh::cube_20x20x20 }, { | ||||
| 					{ "start_gcode", "; Extruder [current_extruder]" } | ||||
|                 }); | ||||
|                 THEN("current_extruder is processed in the start gcode and set for first extruder") { | ||||
|                     REQUIRE(gcode.find("; Extruder 0") != std::string::npos); | ||||
|                 } | ||||
|             } | ||||
| 			config.set_num_extruders(4); | ||||
| 			config.set_deserialize("infill_extruder", "2"); | ||||
| 			config.set_deserialize("solid_infill_extruder", "2"); | ||||
| 			config.set_deserialize("perimeter_extruder", "2"); | ||||
| 			config.set_deserialize("support_material_extruder", "2"); | ||||
| 			config.set_deserialize("support_material_interface_extruder", "2"); | ||||
| 			{ | ||||
|                 Slic3r::Model model; | ||||
|                 std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|                 std::string gcode = Slic3r::Test::gcode(print); | ||||
|                 DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); | ||||
|                 config.set_num_extruders(4); | ||||
|                 config.set_deserialize({  | ||||
|                     { "start_gcode",                    "; Extruder [current_extruder]" }, | ||||
|                     { "infill_extruder",                "2" }, | ||||
|                     { "solid_infill_extruder",          "2" }, | ||||
|                     { "perimeter_extruder",             "2" }, | ||||
|                     { "support_material_extruder",      "2" }, | ||||
|                     { "support_material_interface_extruder", "2" } | ||||
|                 }); | ||||
|                 std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, config); | ||||
|                 THEN("current_extruder is processed in the start gcode and set for second extruder") { | ||||
|                     REQUIRE(gcode.find("; Extruder 1") != std::string::npos); | ||||
|                 } | ||||
|  | @ -242,15 +240,13 @@ SCENARIO( "PrintGCode basic functionality", "[PrintGCode]") { | |||
|         } | ||||
| 
 | ||||
|         WHEN("layer_num represents the layer's index from z=0") { | ||||
| 			config.set_deserialize("complete_objects", "1"); | ||||
| 			config.set_deserialize("gcode_comments", "1"); | ||||
| 			config.set_deserialize("layer_gcode", ";Layer:[layer_num] ([layer_z] mm)"); | ||||
|             config.set_deserialize("layer_height", "1.0"); | ||||
|             config.set_deserialize("first_layer_height", "1.0"); | ||||
| 
 | ||||
|             Slic3r::Model model; | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({TestMesh::cube_20x20x20,TestMesh::cube_20x20x20}, model, config); | ||||
|             std::string gcode = Slic3r::Test::gcode(print); | ||||
| 			std::string gcode = ::Test::slice({ TestMesh::cube_20x20x20, TestMesh::cube_20x20x20 }, { | ||||
| 				{ "complete_objects",               "1" }, | ||||
|                 { "gcode_comments",                 "1" }, | ||||
|                 { "layer_gcode",                    ";Layer:[layer_num] ([layer_z] mm)" }, | ||||
|                 { "layer_height",                   "1.0" }, | ||||
|                 { "first_layer_height",             "1.0" } | ||||
|                 }); | ||||
| 			// End of the 1st object.
 | ||||
| 			size_t pos = gcode.find(";Layer:19 "); | ||||
| 			THEN("First and second object last layer is emitted") { | ||||
|  |  | |||
|  | @ -19,9 +19,10 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") { | |||
|         WHEN("generate_object_layers() is called for 2mm layer heights and nozzle diameter of 3mm") { | ||||
|             config.opt_float("nozzle_diameter", 0) = 3; | ||||
| 			config.opt_float("layer_height") = 2.0; | ||||
| 			std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({m}, model, config); | ||||
| 			print->process(); | ||||
| 			const std::vector<Slic3r::Layer*> &layers = print->objects().front()->layers(); | ||||
|             Slic3r::Print print; | ||||
|             Slic3r::Test::init_print({m}, print, model, config); | ||||
| 			print.process(); | ||||
| 			const std::vector<Slic3r::Layer*> &layers = print.objects().front()->layers(); | ||||
|             THEN("The output vector has 10 entries") { | ||||
|                 REQUIRE(layers.size() == 10); | ||||
|             } | ||||
|  | @ -36,9 +37,10 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") { | |||
|         WHEN("generate_object_layers() is called for 10mm layer heights and nozzle diameter of 11mm") { | ||||
|             config.opt_float("nozzle_diameter", 0) = 11; | ||||
| 			config.opt_float("layer_height") = 10; | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({m}, model, config); | ||||
| 			print->process(); | ||||
| 			const std::vector<Slic3r::Layer*> &layers = print->objects().front()->layers(); | ||||
|             Slic3r::Print print; | ||||
|             Slic3r::Test::init_print({m}, print, model, config); | ||||
| 			print.process(); | ||||
| 			const std::vector<Slic3r::Layer*> &layers = print.objects().front()->layers(); | ||||
| 			THEN("The output vector has 3 entries") { | ||||
|                 REQUIRE(layers.size() == 3); | ||||
|             } | ||||
|  | @ -52,9 +54,10 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") { | |||
|         WHEN("generate_object_layers() is called for 15mm layer heights and nozzle diameter of 16mm") { | ||||
|             config.opt_float("nozzle_diameter", 0) = 16; | ||||
|             config.opt_float("layer_height") = 15.0; | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({m}, model, config); | ||||
| 			print->process(); | ||||
| 			const std::vector<Slic3r::Layer*> &layers = print->objects().front()->layers(); | ||||
|             Slic3r::Print print; | ||||
|             Slic3r::Test::init_print({m}, print, model, config); | ||||
| 			print.process(); | ||||
| 			const std::vector<Slic3r::Layer*> &layers = print.objects().front()->layers(); | ||||
| 			THEN("The output vector has 2 entries") { | ||||
|                 REQUIRE(layers.size() == 2); | ||||
|             } | ||||
|  | @ -69,9 +72,10 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") { | |||
|         WHEN("generate_object_layers() is called for 15mm layer heights and nozzle diameter of 5mm") { | ||||
|             config.opt_float("nozzle_diameter", 0) = 5; | ||||
|             config.opt_float("layer_height") = 15.0; | ||||
|             std::shared_ptr<Slic3r::Print> print = Slic3r::Test::init_print({m}, model, config); | ||||
| 			print->process(); | ||||
| 			const std::vector<Slic3r::Layer*> &layers = print->objects().front()->layers(); | ||||
|             Slic3r::Print print; | ||||
|             Slic3r::Test::init_print({m}, print, model, config); | ||||
| 			print.process(); | ||||
| 			const std::vector<Slic3r::Layer*> &layers = print.objects().front()->layers(); | ||||
| 			THEN("The layer height is limited to 5mm.") { | ||||
|                 CHECK(layers.size() == 5); | ||||
|                 coordf_t last = 2.0; | ||||
|  |  | |||
|  | @ -12,240 +12,232 @@ using namespace Slic3r::Test; | |||
| using namespace Slic3r; | ||||
| 
 | ||||
| /// Helper method to find the tool used for the brim (always the first extrusion)
 | ||||
| int get_brim_tool(std::string &gcode, Slic3r::GCodeReader& parser) { | ||||
| static int get_brim_tool(const std::string &gcode) | ||||
| { | ||||
|     int brim_tool = -1; | ||||
|     int tool = -1; | ||||
| 
 | ||||
|     parser.parse_buffer(gcode, [&tool, &brim_tool] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) | ||||
|         { | ||||
|             // if the command is a T command, set the the current tool
 | ||||
|             if (boost::starts_with(line.cmd(), "T")) { | ||||
|                 tool = atoi(line.cmd().data() + 1); | ||||
|             } else if (line.cmd() == "G1" && line.extruding(self) && line.dist_XY(self) > 0 && brim_tool < 0) { | ||||
|                 brim_tool = tool; | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
| 	GCodeReader parser; | ||||
|     parser.parse_buffer(gcode, [&tool, &brim_tool] (Slic3r::GCodeReader &self, const Slic3r::GCodeReader::GCodeLine &line) | ||||
|     { | ||||
|         // if the command is a T command, set the the current tool
 | ||||
|         if (boost::starts_with(line.cmd(), "T")) { | ||||
|             tool = atoi(line.cmd().data() + 1); | ||||
|         } else if (line.cmd() == "G1" && line.extruding(self) && line.dist_XY(self) > 0 && brim_tool < 0) { | ||||
|             brim_tool = tool; | ||||
|         } | ||||
|     }); | ||||
|     return brim_tool; | ||||
| } | ||||
| 
 | ||||
| TEST_CASE("Skirt height is honored") { | ||||
|     DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); | ||||
|     config.opt_int("skirts") = 1; | ||||
|     config.opt_int("skirt_height") = 5; | ||||
|     config.opt_int("perimeters") = 0; | ||||
|     config.opt_float("support_material_speed") = 99; | ||||
|     config.set_deserialize({ | ||||
|     	{ "skirts",					"1" }, | ||||
|     	{ "skirt_height", 			"5" }, | ||||
|     	{ "perimeters", 			"0" }, | ||||
|     	{ "support_material_speed", "99" }, | ||||
| 		// avoid altering speeds unexpectedly
 | ||||
|     	{ "cooling", 				"0" }, | ||||
|     	{ "first_layer_speed", 		"100%" } | ||||
|     }); | ||||
| 
 | ||||
|     // avoid altering speeds unexpectedly
 | ||||
|     config.set_deserialize("cooling", "0"); | ||||
|     config.set_deserialize("first_layer_speed", "100%"); | ||||
|     double support_speed = config.opt<Slic3r::ConfigOptionFloat>("support_material_speed")->value * MM_PER_MIN; | ||||
| 	std::string gcode; | ||||
|     SECTION("printing a single object") { | ||||
|         gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, config); | ||||
|     } | ||||
|     SECTION("printing multiple objects") { | ||||
|         gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20, TestMesh::cube_20x20x20}, config); | ||||
|     } | ||||
| 
 | ||||
|     std::map<double, bool> layers_with_skirt; | ||||
| 	std::string gcode; | ||||
|     double support_speed = config.opt<Slic3r::ConfigOptionFloat>("support_material_speed")->value * MM_PER_MIN; | ||||
| 	GCodeReader parser; | ||||
|     Slic3r::Model model; | ||||
| 
 | ||||
|     SECTION("printing a single object") { | ||||
|         auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|         gcode = Slic3r::Test::gcode(print); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("printing multiple objects") { | ||||
|         auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20, TestMesh::cube_20x20x20}, model, config); | ||||
| 		gcode = Slic3r::Test::gcode(print); | ||||
|     } | ||||
|     parser.parse_buffer(gcode, [&layers_with_skirt, &support_speed] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) | ||||
|     { | ||||
|     parser.parse_buffer(gcode, [&layers_with_skirt, &support_speed] (Slic3r::GCodeReader &self, const Slic3r::GCodeReader::GCodeLine &line) { | ||||
|         if (line.extruding(self) && self.f() == Approx(support_speed)) { | ||||
|             layers_with_skirt[self.z()] = 1; | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     REQUIRE(layers_with_skirt.size() == (size_t)config.opt_int("skirt_height")); | ||||
| } | ||||
| 
 | ||||
| SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { | ||||
|     Slic3r::GCodeReader parser; | ||||
|     Slic3r::Model model; | ||||
| 	std::string gcode; | ||||
|     GIVEN("A default configuration") { | ||||
| 	    DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); | ||||
| 		config.set_num_extruders(4); | ||||
| 		config.opt_float("support_material_speed") = 99; | ||||
| 		config.set_deserialize("first_layer_height", "0.3"); | ||||
|         config.set_deserialize("gcode_comments", "1"); | ||||
| 
 | ||||
|         // avoid altering speeds unexpectedly
 | ||||
|         config.set_deserialize("cooling", "0"); | ||||
|         config.set_deserialize("first_layer_speed", "100%"); | ||||
|         // remove noise from top/solid layers
 | ||||
|         config.opt_int("top_solid_layers") = 0; | ||||
|         config.opt_int("bottom_solid_layers") = 1; | ||||
| 		config.set_deserialize({  | ||||
| 			{ "support_material_speed", 		"99" }, | ||||
| 			{ "first_layer_height", 			"0.3" }, | ||||
|         	{ "gcode_comments", 				"1" }, | ||||
|         	// avoid altering speeds unexpectedly
 | ||||
|         	{ "cooling", 						"0" }, | ||||
|         	{ "first_layer_speed", 				"100%" }, | ||||
|         	// remove noise from top/solid layers
 | ||||
|         	{ "top_solid_layers", 				"0" }, | ||||
|         	{ "bottom_solid_layers", 			"1" } | ||||
|         }); | ||||
| 
 | ||||
|         WHEN("Brim width is set to 5") { | ||||
| 			config.opt_int("perimeters") = 0; | ||||
| 			config.opt_int("skirts") = 0; | ||||
|             config.opt_float("brim_width") = 5; | ||||
|             THEN("Brim is generated") { | ||||
|                 auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|                 gcode = Slic3r::Test::gcode(print); | ||||
|         	config.set_deserialize({ | ||||
| 				{ "perimeters", 		"0" }, | ||||
| 				{ "skirts", 			"0" }, | ||||
| 				{ "brim_width", 		"5" } | ||||
| 			}); | ||||
| 			THEN("Brim is generated") { | ||||
| 		        std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, config); | ||||
|                 bool brim_generated = false; | ||||
|                 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) | ||||
|                     { | ||||
|                         if (self.z() == Approx(0.3) || line.new_Z(self) == Approx(0.3)) { | ||||
|                             if (line.extruding(self) && self.f() == Approx(support_speed)) { | ||||
|                                 brim_generated = true; | ||||
|                             } | ||||
| 			    Slic3r::GCodeReader parser; | ||||
|                 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 (line.extruding(self) && self.f() == Approx(support_speed)) { | ||||
|                             brim_generated = true; | ||||
|                         } | ||||
|                     }); | ||||
|                     } | ||||
|                 }); | ||||
|                 REQUIRE(brim_generated); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         WHEN("Skirt area is smaller than the brim") { | ||||
|             config.opt_int("skirts") = 1; | ||||
|             config.opt_float("brim_width") = 10; | ||||
|             auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|             config.set_deserialize({ | ||||
|             	{ "skirts", 	"1" }, | ||||
|             	{ "brim_width", "10"} | ||||
|             }); | ||||
|             THEN("Gcode generates") { | ||||
|                 REQUIRE(! Slic3r::Test::gcode(print).empty()); | ||||
|                 REQUIRE(! Slic3r::Test::slice({TestMesh::cube_20x20x20}, config).empty()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         WHEN("Skirt height is 0 and skirts > 0") { | ||||
| 			config.opt_int("skirts") = 2; | ||||
| 			config.opt_int("skirt_height") = 0; | ||||
| 
 | ||||
|             auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|             config.set_deserialize({ | ||||
|             	{ "skirts", 	  "2" }, | ||||
|             	{ "skirt_height", "0"} | ||||
|             }); | ||||
|             THEN("Gcode generates") { | ||||
|                 REQUIRE(! Slic3r::Test::gcode(print).empty()); | ||||
|                 REQUIRE(! Slic3r::Test::slice({TestMesh::cube_20x20x20}, config).empty()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         WHEN("Perimeter extruder = 2 and support extruders = 3") { | ||||
| 			config.opt_int("skirts") = 0; | ||||
| 			config.opt_float("brim_width") = 5; | ||||
| 			config.opt_int("perimeter_extruder") = 2; | ||||
| 			config.opt_int("support_material_extruder") = 3; | ||||
|             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); | ||||
|                 gcode = Slic3r::Test::gcode(print); | ||||
|                 int tool = get_brim_tool(gcode, parser); | ||||
| 		        std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, { | ||||
| 					{ "skirts", 					"0" }, | ||||
| 					{ "brim_width", 				"5" }, | ||||
| 					{ "perimeter_extruder", 		"2" }, | ||||
| 					{ "support_material_extruder", 	"3" } | ||||
| 		        }); | ||||
|                 int tool = get_brim_tool(gcode); | ||||
|                 REQUIRE(tool == config.opt_int("perimeter_extruder") - 1); | ||||
|             } | ||||
|         } | ||||
|         WHEN("Perimeter extruder = 2, support extruders = 3, raft is enabled") { | ||||
|             config.opt_int("skirts") = 0; | ||||
|             config.opt_float("brim_width") = 5; | ||||
|             config.opt_int("perimeter_extruder") = 2; | ||||
|             config.opt_int("support_material_extruder") = 3; | ||||
|             config.opt_int("raft_layers") = 1; | ||||
|             THEN("brim is printed with same extruder as skirt") { | ||||
|                 auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|                 gcode = Slic3r::Test::gcode(print); | ||||
|                 int tool = get_brim_tool(gcode, parser); | ||||
| 		        std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, { | ||||
| 		            { "skirts", 					"0" }, | ||||
| 		            { "brim_width", 				"5" }, | ||||
| 		            { "perimeter_extruder", 		"2" }, | ||||
| 		            { "support_material_extruder", 	"3" }, | ||||
| 		            { "raft_layers", 				"1" } | ||||
| 		        }); | ||||
|                 int tool = get_brim_tool(gcode); | ||||
|                 REQUIRE(tool == config.opt_int("support_material_extruder") - 1); | ||||
|             } | ||||
|         } | ||||
|         WHEN("brim width to 1 with layer_width of 0.5") { | ||||
| 			config.opt_int("skirts") = 0; | ||||
| 			config.set_deserialize("first_layer_extrusion_width", "0.5"); | ||||
| 			config.opt_float("brim_width") = 1; | ||||
| 			 | ||||
|         	config.set_deserialize({ | ||||
| 				{ "skirts", 						"0" }, | ||||
| 				{ "first_layer_extrusion_width", 	"0.5" }, | ||||
| 				{ "brim_width", 					"1" } | ||||
|         	});			 | ||||
|             THEN("2 brim lines") { | ||||
|                 Slic3r::Model model; | ||||
|                 auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|                 print->process(); | ||||
|                 REQUIRE(print->brim().entities.size() == 2); | ||||
| 		        Slic3r::Print print; | ||||
| 		        Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, config); | ||||
|                 REQUIRE(print.brim().entities.size() == 2); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| #if 0 | ||||
|         WHEN("brim ears on a square") { | ||||
| 			config.opt_int("skirts") = 0); | ||||
| 			config.set_deserialize("first_layer_extrusion_width", "0.5"); | ||||
| 			config.opt_float("brim_width") = 1; | ||||
|             config.set("brim_ears", true); | ||||
|             config.set("brim_ears_max_angle", 91); | ||||
| 			 | ||||
|             Slic3r::Model model; | ||||
|             auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|             print->process(); | ||||
| 
 | ||||
| 			config.set_deserialize({ | ||||
| 				{ "skirts",							"0" }, | ||||
| 				{ "first_layer_extrusion_width",	"0.5" }, | ||||
| 				{ "brim_width",						"1" }, | ||||
| 				{ "brim_ears",						"1" }, | ||||
| 				{ "brim_ears_max_angle",			"91" } | ||||
| 			}); | ||||
| 	        Slic3r::Print print; | ||||
| 	        Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, config); | ||||
|             THEN("Four brim ears") { | ||||
|                 REQUIRE(print->brim.size() == 4); | ||||
|                 REQUIRE(print.brim().entities.size() == 4); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         WHEN("brim ears on a square but with a too small max angle") { | ||||
|             config.set("skirts", 0); | ||||
|             config.set("first_layer_extrusion_width", 0.5); | ||||
|             config.set("brim_width", 1); | ||||
|             config.set("brim_ears", true); | ||||
|             config.set("brim_ears_max_angle", 89); | ||||
| 			 | ||||
| 			config.set_deserialize({ | ||||
| 				{ "skirts",							"0" }, | ||||
| 				{ "first_layer_extrusion_width",	"0.5" }, | ||||
| 				{ "brim_width",						"1" }, | ||||
| 				{ "brim_ears",						"1" }, | ||||
| 				{ "brim_ears_max_angle",			"89" } | ||||
| 				}); | ||||
|             THEN("no brim") { | ||||
|                 Slic3r::Model model; | ||||
|                 auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|                 print->process(); | ||||
|                 REQUIRE(print->brim.size() == 0); | ||||
| 		        Slic3r::Print print; | ||||
|                 Slic3r::Test::init_and_process_print({ TestMesh::cube_20x20x20 }, print, config); | ||||
|                 REQUIRE(print.brim().entities.size() == 0); | ||||
|             } | ||||
|         } | ||||
| #endif | ||||
| 
 | ||||
|         WHEN("Object is plated with overhang support and a brim") { | ||||
|             config.opt_float("layer_height") = 0.4; | ||||
|             config.set_deserialize("first_layer_height", "0.4"); | ||||
|             config.opt_int("skirts") = 1; | ||||
|             config.opt_float("skirt_distance") = 0; | ||||
|             config.opt_float("support_material_speed") = 99; | ||||
|             config.opt_int("perimeter_extruder") = 1; | ||||
|             config.opt_int("support_material_extruder") = 2; | ||||
|             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("first_layer_speed", "100%");		// to prevent speeds to be altered
 | ||||
|         	config.set_deserialize({ | ||||
| 	            { "layer_height", 				"0.4" }, | ||||
| 	            { "first_layer_height", 		"0.4" }, | ||||
| 	            { "skirts", 					"1" }, | ||||
| 	            { "skirt_distance", 			"0" }, | ||||
| 	            { "support_material_speed", 	"99" }, | ||||
| 	            { "perimeter_extruder", 		"1" }, | ||||
| 	            { "support_material_extruder", 	"2" }, | ||||
| 	            { "infill_extruder", 			"3" },			// ensure that a tool command gets emitted.
 | ||||
| 	            { "cooling", 					"0" },			// to prevent speeds to be altered
 | ||||
| 	            { "first_layer_speed", 			"100%" },		// to prevent speeds to be altered
 | ||||
|         	}); | ||||
| 
 | ||||
|             Slic3r::Model model; | ||||
|             auto print = Slic3r::Test::init_print({TestMesh::overhang}, model, config); | ||||
|             print->process(); | ||||
|             THEN("overhang generates?") { | ||||
|             	//FIXME does it make sense?
 | ||||
|                 REQUIRE(! Slic3r::Test::slice({TestMesh::overhang}, config).empty()); | ||||
|             } | ||||
| 
 | ||||
|             // config.set("support_material", true);      // to prevent speeds to be altered
 | ||||
| 
 | ||||
|             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
 | ||||
|                 double skirt_length = 0.0; | ||||
|                 Points extrusion_points; | ||||
|                 int tool = -1; | ||||
| 
 | ||||
|                 auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|                 std::string gcode = Slic3r::Test::gcode(print); | ||||
| 
 | ||||
| 				std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, config); | ||||
|                 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) | ||||
|                     { | ||||
|                         // std::cerr << line.cmd() << "\n";
 | ||||
| 						if (boost::starts_with(line.cmd(), "T")) { | ||||
| 							tool = atoi(line.cmd().data() + 1); | ||||
| 						} else if (self.z() == Approx(config.opt<ConfigOptionFloat>("first_layer_height")->value)) { | ||||
|                             // on first layer
 | ||||
| 							if (line.extruding(self) && line.dist_XY(self) > 0) { | ||||
|                                 float speed = ( self.f() > 0 ?  self.f() : line.new_F(self)); | ||||
|                                 // std::cerr << "Tool " << tool << "\n";
 | ||||
|                                 if (speed == Approx(support_speed) && tool == config.opt_int("perimeter_extruder") - 1) { | ||||
|                                     // Skirt uses first material extruder, support material speed.
 | ||||
|                                     skirt_length += line.dist_XY(self); | ||||
|                                 } else { | ||||
|                                     extrusion_points.push_back(Slic3r::Point::new_scale(line.new_X(self), line.new_Y(self))); | ||||
|                                 } | ||||
|                             } | ||||
| 				double skirt_length = 0.0; | ||||
| 				Points extrusion_points; | ||||
| 				int tool = -1; | ||||
| 				GCodeReader parser; | ||||
|                 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";
 | ||||
| 					if (boost::starts_with(line.cmd(), "T")) { | ||||
| 						tool = atoi(line.cmd().data() + 1); | ||||
| 					} else if (self.z() == Approx(config.opt<ConfigOptionFloat>("first_layer_height")->value)) { | ||||
|                         // on first layer
 | ||||
| 						if (line.extruding(self) && line.dist_XY(self) > 0) { | ||||
|                             float speed = ( self.f() > 0 ?  self.f() : line.new_F(self)); | ||||
|                             // std::cerr << "Tool " << tool << "\n";
 | ||||
|                             if (speed == Approx(support_speed) && tool == config.opt_int("perimeter_extruder") - 1) { | ||||
|                                 // Skirt uses first material extruder, support material speed.
 | ||||
|                                 skirt_length += line.dist_XY(self); | ||||
|                             } else | ||||
|                                 extrusion_points.push_back(Slic3r::Point::new_scale(line.new_X(self), line.new_Y(self))); | ||||
|                         } | ||||
| 
 | ||||
|                         if (self.z() == Approx(0.3) || line.new_Z(self) == Approx(0.3)) { | ||||
|                             if (line.extruding(self) && self.f() == Approx(support_speed)) { | ||||
|                             } | ||||
|                     } | ||||
|                     if (self.z() == Approx(0.3) || line.new_Z(self) == Approx(0.3)) { | ||||
|                         if (line.extruding(self) && self.f() == Approx(support_speed)) { | ||||
|                         } | ||||
|                     }); | ||||
|                     } | ||||
|                 }); | ||||
|                 Slic3r::Polygon convex_hull = Slic3r::Geometry::convex_hull(extrusion_points); | ||||
|                 double hull_perimeter = unscale<double>(convex_hull.split_at_first_point().length()); | ||||
|                 REQUIRE(skirt_length > hull_perimeter); | ||||
|  | @ -253,10 +245,8 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { | |||
|         } | ||||
|         WHEN("Large minimum skirt length is used.") { | ||||
|             config.opt_float("min_skirt_length") = 20; | ||||
|             Slic3r::Model model; | ||||
|             auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); | ||||
|             THEN("Gcode generation doesn't crash") { | ||||
|                 REQUIRE(! Slic3r::Test::gcode(print).empty()); | ||||
|                 REQUIRE(! Slic3r::Test::slice({TestMesh::cube_20x20x20}, config).empty()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
							
								
								
									
										233
									
								
								tests/fff_print/test_support_material.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								tests/fff_print/test_support_material.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,233 @@ | |||
| #include <catch2/catch.hpp> | ||||
| 
 | ||||
| #include "libslic3r/GCodeReader.hpp" | ||||
| 
 | ||||
| #include "test_data.hpp" // get access to init_print, etc
 | ||||
| 
 | ||||
| using namespace Slic3r::Test; | ||||
| using namespace Slic3r; | ||||
| 
 | ||||
| TEST_CASE("SupportMaterial: Three raft layers created", "[SupportMaterial]") | ||||
| { | ||||
| 	Slic3r::Print print; | ||||
| 	Slic3r::Test::init_and_process_print({ TestMesh::cube_20x20x20 }, print, { | ||||
| 		{ "support_material", "1" }, | ||||
| 		{ "raft_layers", "3" } | ||||
| 		}); | ||||
|     REQUIRE(print.objects().front()->support_layers().size() == 3); | ||||
| } | ||||
| 
 | ||||
| SCENARIO("SupportMaterial: support_layers_z and contact_distance", "[SupportMaterial]") | ||||
| { | ||||
|     // Box h = 20mm, hole bottom at 5mm, hole height 10mm (top edge at 15mm).
 | ||||
|     TriangleMesh mesh = Slic3r::Test::mesh(Slic3r::Test::TestMesh::cube_with_hole); | ||||
|     mesh.rotate_x(float(M_PI / 2)); | ||||
| 
 | ||||
| 	auto check = [](Slic3r::Print &print, bool &first_support_layer_height_ok, bool &layer_height_minimum_ok, bool &layer_height_maximum_ok, bool &top_spacing_ok) | ||||
| 	{ | ||||
| 		const std::vector<Slic3r::SupportLayer*> &support_layers = print.objects().front()->support_layers(); | ||||
| 
 | ||||
| 		first_support_layer_height_ok = support_layers.front()->print_z == print.default_object_config().first_layer_height.value; | ||||
| 
 | ||||
| 		layer_height_minimum_ok = true; | ||||
| 		layer_height_maximum_ok = true; | ||||
| 		double min_layer_height = print.config().min_layer_height.values.front(); | ||||
| 		double max_layer_height = print.config().nozzle_diameter.values.front(); | ||||
| 		if (print.config().max_layer_height.values.front() > EPSILON) | ||||
| 			max_layer_height = std::min(max_layer_height, print.config().max_layer_height.values.front()); | ||||
| 		for (size_t i = 1; i < support_layers.size(); ++ i) { | ||||
| 			if (support_layers[i]->print_z - support_layers[i - 1]->print_z < min_layer_height - EPSILON) | ||||
| 				layer_height_minimum_ok = false; | ||||
| 			if (support_layers[i]->print_z - support_layers[i - 1]->print_z > max_layer_height + EPSILON) | ||||
| 				layer_height_maximum_ok = false; | ||||
| 		} | ||||
| 
 | ||||
| #if 0 | ||||
| 		double expected_top_spacing = print.default_object_config().layer_height + print.config().nozzle_diameter.get_at(0); | ||||
| 		bool wrong_top_spacing = 0; | ||||
|         std::vector<coordf_t> top_z { 1.1 }; | ||||
| 		for (coordf_t top_z_el : top_z) { | ||||
| 			// find layer index of this top surface.
 | ||||
| 			size_t layer_id = -1; | ||||
| 			for (size_t i = 0; i < support_z.size(); ++ i) { | ||||
| 				if (abs(support_z[i] - top_z_el) < EPSILON) { | ||||
| 					layer_id = i; | ||||
| 					i = static_cast<int>(support_z.size()); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			// check that first support layer above this top surface (or the next one) is spaced with nozzle diameter
 | ||||
| 			if (abs(support_z[layer_id + 1] - support_z[layer_id] - expected_top_spacing) > EPSILON &&  | ||||
| 				abs(support_z[layer_id + 2] - support_z[layer_id] - expected_top_spacing) > EPSILON) { | ||||
| 				wrong_top_spacing = 1; | ||||
| 			} | ||||
| 		} | ||||
| 		d = ! wrong_top_spacing; | ||||
| #else | ||||
| 		top_spacing_ok = true; | ||||
| #endif | ||||
| 	}; | ||||
| 
 | ||||
|     GIVEN("A print object having one modelObject") { | ||||
|         WHEN("First layer height = 0.4") { | ||||
| 			Slic3r::Print print; | ||||
| 			Slic3r::Test::init_and_process_print({ mesh }, print, { | ||||
| 				{ "support_material",	"1" }, | ||||
| 				{ "layer_height",		"0.2" }, | ||||
| 				{ "first_layer_height", "0.4" }, | ||||
| 				}); | ||||
| 			bool a, b, c, d; | ||||
|             check(print, a, b, c, d); | ||||
|             THEN("First layer height is honored")					{ REQUIRE(a == true); } | ||||
|             THEN("No null or negative support layers")				{ REQUIRE(b == true); } | ||||
|             THEN("No layers thicker than nozzle diameter")			{ REQUIRE(c == true); } | ||||
| //            THEN("Layers above top surfaces are spaced correctly")	{ REQUIRE(d == true); }
 | ||||
|         } | ||||
|         WHEN("Layer height = 0.2 and, first layer height = 0.3") { | ||||
| 			Slic3r::Print print; | ||||
| 			Slic3r::Test::init_and_process_print({ mesh }, print, { | ||||
| 				{ "support_material",	"1" }, | ||||
| 				{ "layer_height",		"0.2" }, | ||||
| 				{ "first_layer_height", "0.3" }, | ||||
| 				}); | ||||
|             bool a, b, c, d; | ||||
|             check(print, a, b, c, d); | ||||
|             THEN("First layer height is honored")					{ REQUIRE(a == true); } | ||||
|             THEN("No null or negative support layers")				{ REQUIRE(b == true); } | ||||
|             THEN("No layers thicker than nozzle diameter")			{ REQUIRE(c == true); } | ||||
| //            THEN("Layers above top surfaces are spaced correctly")	{ REQUIRE(d == true); }
 | ||||
|         } | ||||
|         WHEN("Layer height = nozzle_diameter[0]") { | ||||
| 			Slic3r::Print print; | ||||
| 			Slic3r::Test::init_and_process_print({ mesh }, print, { | ||||
| 				{ "support_material",	"1" }, | ||||
| 				{ "layer_height",		"0.2" }, | ||||
| 				{ "first_layer_height", "0.3" }, | ||||
| 				}); | ||||
|             bool a, b, c, d; | ||||
|             check(print, a, b, c, d); | ||||
|             THEN("First layer height is honored")					{ REQUIRE(a == true); } | ||||
|             THEN("No null or negative support layers")				{ REQUIRE(b == true); } | ||||
|             THEN("No layers thicker than nozzle diameter")			{ REQUIRE(c == true); } | ||||
| //            THEN("Layers above top surfaces are spaced correctly")	{ REQUIRE(d == true); }
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #if 0 | ||||
| // Test 8.
 | ||||
| TEST_CASE("SupportMaterial: forced support is generated", "[SupportMaterial]") | ||||
| { | ||||
|     // Create a mesh & modelObject.
 | ||||
|     TriangleMesh mesh = TriangleMesh::make_cube(20, 20, 20); | ||||
| 
 | ||||
|     Model model = Model(); | ||||
|     ModelObject *object = model.add_object(); | ||||
|     object->add_volume(mesh); | ||||
|     model.add_default_instances(); | ||||
|     model.align_instances_to_origin(); | ||||
| 
 | ||||
|     Print print = Print(); | ||||
| 
 | ||||
|     std::vector<coordf_t> contact_z = {1.9}; | ||||
|     std::vector<coordf_t> top_z = {1.1}; | ||||
|     print.default_object_config.support_material_enforce_layers = 100; | ||||
|     print.default_object_config.support_material = 0; | ||||
|     print.default_object_config.layer_height = 0.2; | ||||
|     print.default_object_config.set_deserialize("first_layer_height", "0.3"); | ||||
| 
 | ||||
|     print.add_model_object(model.objects[0]); | ||||
|     print.objects.front()->_slice(); | ||||
| 
 | ||||
|     SupportMaterial *support = print.objects.front()->_support_material(); | ||||
|     auto support_z = support->support_layers_z(contact_z, top_z, print.default_object_config.layer_height); | ||||
| 
 | ||||
|     bool check = true; | ||||
|     for (size_t i = 1; i < support_z.size(); i++) { | ||||
|         if (support_z[i] - support_z[i - 1] <= 0) | ||||
|             check = false; | ||||
|     } | ||||
| 
 | ||||
|     REQUIRE(check == true); | ||||
| } | ||||
| 
 | ||||
| // TODO
 | ||||
| bool test_6_checks(Print& print) | ||||
| { | ||||
| 	bool has_bridge_speed = true; | ||||
| 
 | ||||
| 	// Pre-Processing.
 | ||||
| 	PrintObject* print_object = print.objects.front(); | ||||
| 	print_object->infill(); | ||||
| 	SupportMaterial* support_material = print.objects.front()->_support_material(); | ||||
| 	support_material->generate(print_object); | ||||
| 	// TODO but not needed in test 6 (make brims and make skirts).
 | ||||
| 
 | ||||
| 	// Exporting gcode.
 | ||||
| 	// TODO validation found in Simple.pm
 | ||||
| 
 | ||||
| 
 | ||||
| 	return has_bridge_speed; | ||||
| } | ||||
| 
 | ||||
| // Test 6.
 | ||||
| SCENARIO("SupportMaterial: Checking bridge speed", "[SupportMaterial]") | ||||
| { | ||||
|     GIVEN("Print object") { | ||||
|         // Create a mesh & modelObject.
 | ||||
|         TriangleMesh mesh = TriangleMesh::make_cube(20, 20, 20); | ||||
| 
 | ||||
|         Model model = Model(); | ||||
|         ModelObject *object = model.add_object(); | ||||
|         object->add_volume(mesh); | ||||
|         model.add_default_instances(); | ||||
|         model.align_instances_to_origin(); | ||||
| 
 | ||||
|         Print print = Print(); | ||||
|         print.config.brim_width = 0; | ||||
|         print.config.skirts = 0; | ||||
|         print.config.skirts = 0; | ||||
|         print.default_object_config.support_material = 1; | ||||
|         print.default_region_config.top_solid_layers = 0; // so that we don't have the internal bridge over infill.
 | ||||
|         print.default_region_config.bridge_speed = 99; | ||||
|         print.config.cooling = 0; | ||||
|         print.config.set_deserialize("first_layer_speed", "100%"); | ||||
| 
 | ||||
|         WHEN("support_material_contact_distance = 0.2") { | ||||
|             print.default_object_config.support_material_contact_distance = 0.2; | ||||
|             print.add_model_object(model.objects[0]); | ||||
| 
 | ||||
|             bool check = test_6_checks(print); | ||||
|             REQUIRE(check == true); // bridge speed is used.
 | ||||
|         } | ||||
| 
 | ||||
|         WHEN("support_material_contact_distance = 0") { | ||||
|             print.default_object_config.support_material_contact_distance = 0; | ||||
|             print.add_model_object(model.objects[0]); | ||||
| 
 | ||||
|             bool check = test_6_checks(print); | ||||
|             REQUIRE(check == true); // bridge speed is not used.
 | ||||
|         } | ||||
| 
 | ||||
|         WHEN("support_material_contact_distance = 0.2 & raft_layers = 5") { | ||||
|             print.default_object_config.support_material_contact_distance = 0.2; | ||||
|             print.default_object_config.raft_layers = 5; | ||||
|             print.add_model_object(model.objects[0]); | ||||
| 
 | ||||
|             bool check = test_6_checks(print); | ||||
|             REQUIRE(check == true); // bridge speed is used.
 | ||||
|         } | ||||
| 
 | ||||
|         WHEN("support_material_contact_distance = 0 & raft_layers = 5") { | ||||
|             print.default_object_config.support_material_contact_distance = 0; | ||||
|             print.default_object_config.raft_layers = 5; | ||||
|             print.add_model_object(model.objects[0]); | ||||
| 
 | ||||
|             bool check = test_6_checks(print); | ||||
| 
 | ||||
|             REQUIRE(check == true); // bridge speed is not used.
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | @ -392,12 +392,13 @@ TEST_CASE("Regression test for issue #4486 - files take forever to slice") { | |||
|     config.set("first_layer_height", 250); | ||||
|     config.set("nozzle_diameter", 500); | ||||
| 
 | ||||
|     Slic3r::Print print; | ||||
|     Slic3r::Model model; | ||||
|     auto print = Slic3r::Test::init_print({mesh}, model, config); | ||||
|     Slic3r::Test::init_print({mesh}, print, model, config); | ||||
| 
 | ||||
|     print->status_cb = [] (int ln, const std::string& msg) { Slic3r::Log::info("Print") << ln << " " << msg << "\n";}; | ||||
|     print.status_cb = [] (int ln, const std::string& msg) { Slic3r::Log::info("Print") << ln << " " << msg << "\n";}; | ||||
| 
 | ||||
|     std::future<void> fut = std::async([&print] () { print->process(); }); | ||||
|     std::future<void> fut = std::async([&print] () { print.process(); }); | ||||
|     std::chrono::milliseconds span {120000}; | ||||
|     bool timedout {false}; | ||||
|     if(fut.wait_for(span) == std::future_status::timeout) { | ||||
|  | @ -420,12 +421,13 @@ TEST_CASE("Profile test for issue #4486 - files take forever to slice") { | |||
|     config.set("nozzle_diameter", 500); | ||||
|     config.set("fill_density", "5%"); | ||||
| 
 | ||||
|     Slic3r::Print print; | ||||
|     Slic3r::Model model; | ||||
|     auto print = Slic3r::Test::init_print({mesh}, model, config); | ||||
|     Slic3r::Test::init_print({mesh}, print, model, config); | ||||
| 
 | ||||
|     print->status_cb = [] (int ln, const std::string& msg) { Slic3r::Log::info("Print") << ln << " " << msg << "\n";}; | ||||
|     print.status_cb = [] (int ln, const std::string& msg) { Slic3r::Log::info("Print") << ln << " " << msg << "\n";}; | ||||
| 
 | ||||
|     print->process(); | ||||
|     print.process(); | ||||
| 
 | ||||
|     REQUIRE(true); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv