From 73452fd79db41286e6c04658edf6b0e15ce8f008 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 6 Jun 2018 18:24:42 +0200 Subject: [PATCH] More progress on 'wipe into dedicated object' feature (e.g. new value in object settings) --- xs/src/libslic3r/GCode.cpp | 27 +++++++++++++++++---------- xs/src/libslic3r/GCode.hpp | 8 ++++++-- xs/src/libslic3r/Print.cpp | 27 +++++++++++++-------------- xs/src/libslic3r/PrintConfig.cpp | 10 ++++++++++ xs/src/libslic3r/PrintConfig.hpp | 6 ++++-- xs/src/slic3r/GUI/Preset.cpp | 2 +- xs/src/slic3r/GUI/Tab.cpp | 1 + 7 files changed, 52 insertions(+), 29 deletions(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 28a8d2e525..92898c8204 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -1407,7 +1407,7 @@ void GCode::process_layer( auto objects_by_extruder_it = by_extruder.find(extruder_id); if (objects_by_extruder_it == by_extruder.end()) continue; - for (const ObjectByExtruder &object_by_extruder : objects_by_extruder_it->second) { + for (ObjectByExtruder &object_by_extruder : objects_by_extruder_it->second) { const size_t layer_id = &object_by_extruder - objects_by_extruder_it->second.data(); const PrintObject *print_object = layers[layer_id].object(); if (print_object == nullptr) @@ -1440,7 +1440,7 @@ void GCode::process_layer( object_by_extruder.support->chained_path_from(m_last_pos, false, object_by_extruder.support_extrusion_role)); m_layer = layers[layer_id].layer(); } - for (const ObjectByExtruder::Island &island : object_by_extruder.islands) { + for (ObjectByExtruder::Island &island : object_by_extruder.islands) { if (print.config.infill_first) { gcode += this->extrude_infill(print, island.by_region_per_copy(copy_id)); gcode += this->extrude_perimeters(print, island.by_region_per_copy(copy_id), lower_layer_edge_grids[layer_id]); @@ -2511,23 +2511,30 @@ Point GCode::gcode_to_point(const Pointf &point) const } -// Goes through by_region std::vector and returns only a subvector of entities to be printed in usual time +// Goes through by_region std::vector and returns ref a subvector of entities to be printed in usual time // i.e. not when it's going to be done during infill wiping -std::vector GCode::ObjectByExtruder::Island::by_region_per_copy(unsigned int copy) const +const std::vector& GCode::ObjectByExtruder::Island::by_region_per_copy(unsigned int copy) { - std::vector out; - for (auto& reg : by_region) { - out.push_back(ObjectByExtruder::Island::Region()); + if (copy == last_copy) + return by_region_per_copy_cache; + else { + by_region_per_copy_cache.clear(); + last_copy = copy; + } + + //std::vector out; + for (const auto& reg : by_region) { + by_region_per_copy_cache.push_back(ObjectByExtruder::Island::Region()); //out.back().perimeters.append(reg.perimeters); // we will print all perimeters there are if (!reg.infills_per_copy_ids.empty()) { for (unsigned int i=0; i> infills_per_copy_ids; // indices of infill.entities that are not part of infill wiping (an element for each object copy) std::vector> perimeters_per_copy_ids; // indices of infill.entities that are not part of infill wiping (an element for each object copy) }; - std::vector by_region; - std::vector by_region_per_copy(unsigned int copy) const; // returns only extrusions that are NOT printed during wiping into infill for this copy + std::vector by_region; // all extrusions for this island, grouped by regions + const std::vector& by_region_per_copy(unsigned int copy); // returns reference to subvector of by_region (only extrusions that are NOT printed during wiping into infill for this copy) + + private: + std::vector by_region_per_copy_cache; // caches vector generated by function above to avoid copying and recalculating + unsigned int last_copy = (unsigned int)(-1); // index of last copy that by_region_per_copy was called for }; std::vector islands; }; diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index 4b52e25070..940bdc2a2e 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -1210,7 +1210,19 @@ float Print::mark_wiping_infill(const ToolOrdering::LayerTools& layer_tools, uns continue; } - //if (object.wipe_into_perimeters) + ExtrusionEntityCollection& eec = this_layer->regions[region_id]->fills; + for (ExtrusionEntity* ee : eec.entities) { // iterate through all infill Collections + auto* fill = dynamic_cast(ee); + if (fill->role() == erTopSolidInfill || fill->role() == erGapFill) continue; // these cannot be changed - it is / may be visible + if (volume_to_wipe <= 0.f) + break; + if (!fill->is_extruder_overridden(copy) && fill->total_volume() > min_infill_volume) { // this infill will be used to wipe this extruder + fill->set_extruder_override(copy, new_extruder); + volume_to_wipe -= fill->total_volume(); + } + } + + if (objects[i]->config.wipe_into_objects) { ExtrusionEntityCollection& eec = this_layer->regions[region_id]->perimeters; for (ExtrusionEntity* ee : eec.entities) { // iterate through all perimeter Collections @@ -1223,19 +1235,6 @@ float Print::mark_wiping_infill(const ToolOrdering::LayerTools& layer_tools, uns } } } - - - ExtrusionEntityCollection& eec = this_layer->regions[region_id]->fills; - for (ExtrusionEntity* ee : eec.entities) { // iterate through all infill Collections - auto* fill = dynamic_cast(ee); - if (fill->role() == erTopSolidInfill || fill->role() == erGapFill) continue; // these cannot be changed - it is / may be visible - if (volume_to_wipe <= 0.f) - break; - if (!fill->is_extruder_overridden(copy) && fill->total_volume() > min_infill_volume) { // this infill will be used to wipe this extruder - fill->set_extruder_override(copy, new_extruder); - volume_to_wipe -= fill->total_volume(); - } - } } } } diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index bf9421f9da..98b111a4d0 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -1893,6 +1893,16 @@ PrintConfigDef::PrintConfigDef() def->cli = "wipe-into-infill!"; def->default_value = new ConfigOptionBool(true); + def = this->add("wipe_into_objects", coBool); + def->category = L("Extruders"); + def->label = L("Wiping into objects"); + def->tooltip = L("Objects will be used to wipe the nozzle after a toolchange to save material " + "that would otherwise end up in the wipe tower and decrease print time. " + "Colours of the objects will be mixed as a result. (This setting is usually " + "used on per-object basis.)"); + def->cli = "wipe-into-objects!"; + def->default_value = new ConfigOptionBool(false); + def = this->add("wipe_tower_bridging", coFloat); def->label = L("Maximal bridging distance"); def->tooltip = L("Maximal distance between supports on sparse infill sections. "); diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 1b73c31b30..f638a7674d 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -336,7 +336,8 @@ public: ConfigOptionBool support_material_with_sheath; ConfigOptionFloatOrPercent support_material_xy_spacing; ConfigOptionFloat xy_size_compensation; - + ConfigOptionBool wipe_into_objects; + protected: void initialize(StaticCacheBase &cache, const char *base_ptr) { @@ -372,6 +373,7 @@ protected: OPT_PTR(support_material_threshold); OPT_PTR(support_material_with_sheath); OPT_PTR(xy_size_compensation); + OPT_PTR(wipe_into_objects); } }; @@ -414,7 +416,7 @@ public: ConfigOptionFloatOrPercent top_infill_extrusion_width; ConfigOptionInt top_solid_layers; ConfigOptionFloatOrPercent top_solid_infill_speed; - + protected: void initialize(StaticCacheBase &cache, const char *base_ptr) { diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index e483381acd..84f6855335 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -298,7 +298,7 @@ const std::vector& Preset::print_options() "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", "top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects", "elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y", - "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", "wipe_into_infill", "compatible_printers", + "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", "wipe_into_infill", "wipe_into_objects", "compatible_printers", "compatible_printers_condition","inherits" }; return s_opts; diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index c94307aa46..4974e93773 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -946,6 +946,7 @@ void TabPrint::build() optgroup->append_single_option_line("wipe_tower_rotation_angle"); optgroup->append_single_option_line("wipe_tower_bridging"); optgroup->append_single_option_line("wipe_into_infill"); + optgroup->append_single_option_line("wipe_into_objects"); optgroup = page->new_optgroup(_(L("Advanced"))); optgroup->append_single_option_line("interface_shells");