diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index dfb6ce76b..6c60dba24 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1574,6 +1574,7 @@ void GCode::process_layer( if (m_enable_analyzer && layer_tools.has_wipe_tower && m_wipe_tower) m_last_analyzer_extrusion_role = erWipeTower; + // Extrude skirt with the extruder of the 1st region. if (extrude_skirt) { auto loops_it = skirt_loops_per_extruder.find(extruder_id); if (loops_it != skirt_loops_per_extruder.end()) { @@ -1601,7 +1602,7 @@ void GCode::process_layer( } // Extrude brim with the extruder of the 1st region. - if (! m_brim_done) { + if (!m_brim_done) { this->set_origin(0., 0.); m_avoid_crossing_perimeters.use_external_mp = true; for (const ExtrusionEntity *ee : print.brim().entities) @@ -1611,6 +1612,21 @@ void GCode::process_layer( // Allow a straight travel move to the first object point. m_avoid_crossing_perimeters.disable_once = true; } + //extrude object-only skirt & brim & first extruder + if (single_object_idx != size_t(-1) && !layers.front().object()->brim().empty() + && extruder_id == layer_tools.extruders.front()) { + const PrintObject *print_object = layers.front().object(); + this->set_origin(unscale(print_object->copies()[single_object_idx])); + + for (const ExtrusionEntity *ee : print_object->skirt().entities) + gcode += this->extrude_entity(*ee, "skirt", m_config.support_material_speed.value); + + m_avoid_crossing_perimeters.use_external_mp = true; + for (const ExtrusionEntity *ee : print_object->brim().entities) + gcode += this->extrude_entity(*ee, "brim", m_config.support_material_speed.value); + m_avoid_crossing_perimeters.use_external_mp = false; + m_avoid_crossing_perimeters.disable_once = true; + } auto objects_by_extruder_it = by_extruder.find(extruder_id); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index af68e2e56..477286875 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1519,10 +1519,15 @@ void Print::process() this->set_status(88, "Generating skirt"); if (config().complete_objects){ for (PrintObject *obj : m_objects){ - this->_make_skirt({ obj }); + //create a skirt "pattern" (one per object) + const Points copies = obj->copies(); + obj->m_copies.clear(); + obj->m_copies.emplace_back(); + this->_make_skirt({ obj }, obj->m_skirt); + obj->m_copies = copies; } } else { - this->_make_skirt(m_objects); + this->_make_skirt(m_objects, m_skirt); } } this->set_done(psSkirt); @@ -1533,16 +1538,21 @@ void Print::process() this->set_status(88, "Generating brim"); if (config().complete_objects){ for (PrintObject *obj : m_objects){ + //create a brim "pattern" (one per object) + const Points copies = obj->copies(); + obj->m_copies.clear(); + obj->m_copies.emplace_back(); if (config().brim_ears) - this->_make_brim_ears({ obj }); + this->_make_brim_ears({ obj }, obj->m_brim); else - this->_make_brim({ obj }); + this->_make_brim({ obj }, obj->m_brim); + obj->m_copies = copies; } } else { if (config().brim_ears) - this->_make_brim_ears(m_objects); + this->_make_brim_ears(m_objects, m_brim); else - this->_make_brim(m_objects); + this->_make_brim(m_objects, m_brim); } } @@ -1581,7 +1591,7 @@ void Print::export_gcode(const std::string &path_template, GCodePreviewData *pre gcode.do_export(this, path.c_str(), preview_data); } -void Print::_make_skirt(const PrintObjectPtrs &objects) +void Print::_make_skirt(const PrintObjectPtrs &objects, ExtrusionEntityCollection &out) { // First off we need to decide how tall the skirt must be. // The skirt_height option from config is expressed in layers, but our @@ -1696,7 +1706,7 @@ void Print::_make_skirt(const PrintObjectPtrs &objects) first_layer_height // this will be overridden at G-code export time ))); eloop.paths.back().polyline = loop.split_at_first_point(); - m_skirt.append(eloop); + out.append(eloop); if (m_config.min_skirt_length.value > 0) { // The skirt length is limited. Sum the total amount of filament length extruded, in mm. extruded_length[extruder_idx] += unscale(loop.length()) * extruders_e_per_mm[extruder_idx]; @@ -1716,10 +1726,10 @@ void Print::_make_skirt(const PrintObjectPtrs &objects) } } // Brims were generated inside out, reverse to print the outmost contour first. - m_skirt.reverse(); + out.reverse(); } -void Print::_make_brim(const PrintObjectPtrs &objects) { +void Print::_make_brim(const PrintObjectPtrs &objects, ExtrusionEntityCollection &out) { // Brim is only printed on first layer and uses perimeter extruder. Flow flow = this->brim_flow(); Polygons islands; @@ -1753,10 +1763,10 @@ void Print::_make_brim(const PrintObjectPtrs &objects) { loops = union_pt_chained(loops, false); std::reverse(loops.begin(), loops.end()); - extrusion_entities_append_loops(m_brim.entities, std::move(loops), erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(this->skirt_first_layer_height())); + extrusion_entities_append_loops(out.entities, std::move(loops), erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(this->skirt_first_layer_height())); } -void Print::_make_brim_ears(const PrintObjectPtrs &objects) { +void Print::_make_brim_ears(const PrintObjectPtrs &objects, ExtrusionEntityCollection &out) { Flow flow = this->brim_flow(); Points pt_ears; Polygons islands; @@ -1885,7 +1895,7 @@ void Print::_make_brim_ears(const PrintObjectPtrs &objects) { //push into extrusions extrusion_entities_append_paths( - m_brim.entities, + out.entities, lines_sorted, erSkirt, float(flow.mm3_per_mm()), diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 52015bd1b..60f6b68f7 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -144,6 +144,10 @@ public: std::vector slice_support_enforcers() const; std::vector slice_support_blockers() const; + /// skirts if done per copy and not per platter + const ExtrusionEntityCollection& skirt() const { return m_skirt; } + const ExtrusionEntityCollection& brim() const { return m_brim; } + protected: // to be called from Print only. friend class Print; @@ -202,6 +206,12 @@ private: LayerPtrs m_layers; SupportLayerPtrs m_support_layers; + + // Ordered collections of extrusion paths to build skirt loops and brim. + // have to be duplicated per copy + ExtrusionEntityCollection m_skirt; + ExtrusionEntityCollection m_brim; + std::vector _slice_region(size_t region_id, const std::vector &z, bool modifier); std::vector _slice_volumes(const std::vector &z, const std::vector &volumes) const; }; @@ -366,9 +376,9 @@ protected: private: bool invalidate_state_by_config_options(const std::vector &opt_keys); - void _make_skirt(const PrintObjectPtrs &objects); - void _make_brim(const PrintObjectPtrs &objects); - void _make_brim_ears(const PrintObjectPtrs &objects); + void _make_skirt(const PrintObjectPtrs &objects, ExtrusionEntityCollection &out); + void _make_brim(const PrintObjectPtrs &objects, ExtrusionEntityCollection &out); + void _make_brim_ears(const PrintObjectPtrs &objects, ExtrusionEntityCollection &out); void _make_wipe_tower(); void _simplify_slices(double distance);