diff options
Diffstat (limited to 'xs/src/libslic3r/Print.cpp')
-rw-r--r-- | xs/src/libslic3r/Print.cpp | 227 |
1 files changed, 115 insertions, 112 deletions
diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index 08802139d..c2fac891d 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -4,6 +4,7 @@ #include "Extruder.hpp" #include "Flow.hpp" #include "Geometry.hpp" +#include "I18N.hpp" #include "SupportMaterial.hpp" #include "GCode/WipeTowerPrusaMM.hpp" #include <algorithm> @@ -11,6 +12,10 @@ #include <boost/filesystem.hpp> #include <boost/lexical_cast.hpp> +//! macro used to mark string used at localization, +//! return same string +#define L(s) Slic3r::I18N::translate(s) + namespace Slic3r { template class PrintState<PrintStep, psCount>; @@ -66,6 +71,13 @@ bool Print::reload_model_instances() return invalidated; } +PrintObjectPtrs Print::get_printable_objects() const +{ + PrintObjectPtrs printable_objects(this->objects); + printable_objects.erase(std::remove_if(printable_objects.begin(), printable_objects.end(), [](PrintObject* o) { return !o->is_printable(); }), printable_objects.end()); + return printable_objects; +} + PrintRegion* Print::add_region() { regions.push_back(new PrintRegion(this)); @@ -116,7 +128,6 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option "gcode_comments", "gcode_flavor", "infill_acceleration", - "infill_first", "layer_gcode", "min_fan_speed", "max_fan_speed", @@ -143,6 +154,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option "retract_restart_extra", "retract_restart_extra_toolchange", "retract_speed", + "single_extruder_multi_material_priming", "slowdown_below_layer_time", "standby_temperature_delta", "start_gcode", @@ -154,12 +166,16 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option "use_relative_e_distances", "use_volumetric_e", "variable_layer_height", - "wipe" + "wipe", + "wipe_tower_x", + "wipe_tower_y", + "wipe_tower_rotation_angle" }; std::vector<PrintStep> steps; std::vector<PrintObjectStep> osteps; bool invalidated = false; + for (const t_config_option_key &opt_key : opt_keys) { if (steps_ignore.find(opt_key) != steps_ignore.end()) { // These options only affect G-code export or they are just notes without influence on the generated G-code, @@ -184,23 +200,28 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option || opt_key == "filament_soluble" || opt_key == "first_layer_temperature" || opt_key == "filament_loading_speed" + || opt_key == "filament_loading_speed_start" || opt_key == "filament_unloading_speed" + || opt_key == "filament_unloading_speed_start" || opt_key == "filament_toolchange_delay" + || opt_key == "filament_cooling_moves" + || opt_key == "filament_minimal_purge_on_wipe_tower" + || opt_key == "filament_cooling_initial_speed" + || opt_key == "filament_cooling_final_speed" || opt_key == "filament_ramming_parameters" || opt_key == "gcode_flavor" + || opt_key == "infill_first" || opt_key == "single_extruder_multi_material" || opt_key == "spiral_vase" || opt_key == "temperature" || opt_key == "wipe_tower" - || opt_key == "wipe_tower_x" - || opt_key == "wipe_tower_y" || opt_key == "wipe_tower_width" - || opt_key == "wipe_tower_rotation_angle" || opt_key == "wipe_tower_bridging" || opt_key == "wiping_volumes_matrix" || opt_key == "parking_pos_retraction" || opt_key == "cooling_tube_retraction" || opt_key == "cooling_tube_length" + || opt_key == "extra_loading_move" || opt_key == "z_offset") { steps.emplace_back(psWipeTower); } else if ( @@ -212,7 +233,6 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option osteps.emplace_back(posSupportMaterial); steps.emplace_back(psSkirt); steps.emplace_back(psBrim); - steps.emplace_back(psWipeTower); } else { // for legacy, if we can't handle this option let's invalidate all steps //FIXME invalidate all steps of all objects as well? @@ -342,9 +362,12 @@ void Print::add_model_object(ModelObject* model_object, int idx) // Invalidate all print steps. this->invalidate_all_steps(); - for (size_t volume_id = 0; volume_id < model_object->volumes.size(); ++ volume_id) { + size_t volume_id = 0; + for (const ModelVolume *volume : model_object->volumes) { + if (! volume->is_model_part() && ! volume->is_modifier()) + continue; // Get the config applied to this volume. - PrintRegionConfig config = this->_region_config_from_model_volume(*model_object->volumes[volume_id]); + PrintRegionConfig config = this->_region_config_from_model_volume(*volume); // Find an existing print region with the same config. size_t region_id = size_t(-1); for (size_t i = 0; i < this->regions.size(); ++ i) @@ -359,6 +382,7 @@ void Print::add_model_object(ModelObject* model_object, int idx) } // Assign volume to a region. object->add_region_volume(region_id, volume_id); + ++ volume_id; } // Apply config to print object. @@ -444,7 +468,7 @@ bool Print::apply_config(DynamicPrintConfig config) const ModelVolume &volume = *object->model_object()->volumes[volume_id]; if (this_region_config_set) { // If the new config for this volume differs from the other - // volume configs currently associated to this region, it means + // volume configs currently associated to this region, it means // the region subdivision does not make sense anymore. if (! this_region_config.equals(this->_region_config_from_model_volume(volume))) { rearrange_regions = true; @@ -521,11 +545,17 @@ std::string Print::validate() const BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config.max_print_height)); // Allow the objects to protrude below the print bed, only the part of the object above the print bed will be sliced. print_volume.min.z = -1e10; + unsigned int printable_count = 0; for (PrintObject *po : this->objects) { - if (!print_volume.contains(po->model_object()->tight_bounding_box(false))) - return "Some objects are outside of the print volume."; + po->model_object()->check_instances_print_volume_state(print_volume); + po->reload_model_instances(); + if (po->is_printable()) + ++printable_count; } + if (printable_count == 0) + return L("All objects are outside of the print volume."); + if (this->config.complete_objects) { // Check horizontal clearance. { @@ -550,7 +580,7 @@ std::string Print::validate() const Polygon p = convex_hull; p.translate(copy); if (! intersection(convex_hulls_other, p).empty()) - return "Some objects are too close; your extruder will collide with them."; + return L("Some objects are too close; your extruder will collide with them."); polygons_append(convex_hulls_other, p); } } @@ -565,7 +595,7 @@ std::string Print::validate() const // it will be printed as last one so its height doesn't matter. object_height.pop_back(); if (! object_height.empty() && object_height.back() > scale_(this->config.extruder_clearance_height.value)) - return "Some objects are too tall and cannot be printed without extruder collisions."; + return L("Some objects are too tall and cannot be printed without extruder collisions."); } } // end if (this->config.complete_objects) @@ -575,27 +605,22 @@ std::string Print::validate() const total_copies_count += object->copies().size(); // #4043 if (total_copies_count > 1 && ! this->config.complete_objects.value) - return "The Spiral Vase option can only be used when printing a single object."; + return L("The Spiral Vase option can only be used when printing a single object."); if (this->regions.size() > 1) - return "The Spiral Vase option can only be used when printing single material objects."; + return L("The Spiral Vase option can only be used when printing single material objects."); } if (this->config.single_extruder_multi_material) { for (size_t i=1; i<this->config.nozzle_diameter.values.size(); ++i) if (this->config.nozzle_diameter.values[i] != this->config.nozzle_diameter.values[i-1]) - return "All extruders must have the same diameter for single extruder multimaterial printer."; + return L("All extruders must have the same diameter for single extruder multimaterial printer."); } if (this->has_wipe_tower() && ! this->objects.empty()) { - #if 0 - for (auto dmr : this->config.nozzle_diameter.values) - if (std::abs(dmr - 0.4) > EPSILON) - return "The Wipe Tower is currently only supported for the 0.4mm nozzle diameter."; - #endif if (this->config.gcode_flavor != gcfRepRap && this->config.gcode_flavor != gcfMarlin) - return "The Wipe Tower is currently only supported for the Marlin and RepRap/Sprinter G-code flavors."; + return L("The Wipe Tower is currently only supported for the Marlin and RepRap/Sprinter G-code flavors."); if (! this->config.use_relative_e_distances) - return "The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1)."; + return L("The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1)."); SlicingParameters slicing_params0 = this->objects.front()->slicing_parameters(); const PrintObject* tallest_object = this->objects.front(); // let's find the tallest object @@ -607,13 +632,13 @@ std::string Print::validate() const SlicingParameters slicing_params = object->slicing_parameters(); if (std::abs(slicing_params.first_print_layer_height - slicing_params0.first_print_layer_height) > EPSILON || std::abs(slicing_params.layer_height - slicing_params0.layer_height ) > EPSILON) - return "The Wipe Tower is only supported for multiple objects if they have equal layer heigths"; + return L("The Wipe Tower is only supported for multiple objects if they have equal layer heigths"); if (slicing_params.raft_layers() != slicing_params0.raft_layers()) - return "The Wipe Tower is only supported for multiple objects if they are printed over an equal number of raft layers"; + return L("The Wipe Tower is only supported for multiple objects if they are printed over an equal number of raft layers"); if (object->config.support_material_contact_distance != this->objects.front()->config.support_material_contact_distance) - return "The Wipe Tower is only supported for multiple objects if they are printed with the same support_material_contact_distance"; + return L("The Wipe Tower is only supported for multiple objects if they are printed with the same support_material_contact_distance"); if (! equal_layering(slicing_params, slicing_params0)) - return "The Wipe Tower is only supported for multiple objects if they are sliced equally."; + return L("The Wipe Tower is only supported for multiple objects if they are sliced equally."); bool was_layer_height_profile_valid = object->layer_height_profile_valid; object->update_layer_height_profile(); object->layer_height_profile_valid = was_layer_height_profile_valid; @@ -637,13 +662,8 @@ std::string Print::validate() const failed = true; if (failed) - return "The Wipe tower is only supported if all objects have the same layer height profile"; + return L("The Wipe tower is only supported if all objects have the same layer height profile"); } - - /*for (size_t i = 5; i < object->layer_height_profile.size(); i += 2) - if (object->layer_height_profile[i-1] > slicing_params.object_print_z_min + EPSILON && - std::abs(object->layer_height_profile[i] - object->config.layer_height) > EPSILON) - return "The Wipe Tower is currently only supported with constant Z layer spacing. Layer editing is not allowed.";*/ } } @@ -651,7 +671,7 @@ std::string Print::validate() const // find the smallest nozzle diameter std::vector<unsigned int> extruders = this->extruders(); if (extruders.empty()) - return "The supplied settings will cause an empty print."; + return L("The supplied settings will cause an empty print."); std::vector<double> nozzle_diameters; for (unsigned int extruder_id : extruders) @@ -661,7 +681,7 @@ std::string Print::validate() const unsigned int total_extruders_count = this->config.nozzle_diameter.size(); for (const auto& extruder_idx : extruders) if ( extruder_idx >= total_extruders_count ) - return "One or more object were assigned an extruder that the printer does not have."; + return L("One or more object were assigned an extruder that the printer does not have."); for (PrintObject *object : this->objects) { if ((object->config.support_material_extruder == -1 || object->config.support_material_interface_extruder == -1) && @@ -670,13 +690,13 @@ std::string Print::validate() const // will be printed with the current tool without a forced tool change. Play safe, assert that all object nozzles // are of the same diameter. if (nozzle_diameters.size() > 1) - return "Printing with multiple extruders of differing nozzle diameters. " + return L("Printing with multiple extruders of differing nozzle diameters. " "If support is to be printed with the current extruder (support_material_extruder == 0 or support_material_interface_extruder == 0), " - "all nozzles have to be of the same diameter."; + "all nozzles have to be of the same diameter."); } // validate first_layer_height - double first_layer_height = object->config.get_abs_value("first_layer_height"); + double first_layer_height = object->config.get_abs_value(L("first_layer_height")); double first_layer_min_nozzle_diameter; if (object->config.raft_layers > 0) { // if we have raft layers, only support material extruder is used on first layer @@ -691,11 +711,11 @@ std::string Print::validate() const first_layer_min_nozzle_diameter = min_nozzle_diameter; } if (first_layer_height > first_layer_min_nozzle_diameter) - return "First layer height can't be greater than nozzle diameter"; + return L("First layer height can't be greater than nozzle diameter"); // validate layer_height if (object->config.layer_height.value > min_nozzle_diameter) - return "Layer height can't be greater than nozzle diameter"; + return L("Layer height can't be greater than nozzle diameter"); } } @@ -837,7 +857,7 @@ void Print::auto_assign_extruders(ModelObject* model_object) const for (size_t volume_id = 0; volume_id < model_object->volumes.size(); ++ volume_id) { ModelVolume *volume = model_object->volumes[volume_id]; //FIXME Vojtech: This assigns an extruder ID even to a modifier volume, if it has a material assigned. - if (! volume->material_id().empty() && ! volume->config.has("extruder")) + if ((volume->is_model_part() || volume->is_modifier()) && ! volume->material_id().empty() && ! volume->config.has("extruder")) volume->config.opt<ConfigOptionInt>("extruder", true)->value = int(volume_id + 1); } } @@ -855,8 +875,9 @@ void Print::_make_skirt() // prepended to the first 'n' layers (with 'n' = skirt_height). // $skirt_height_z in this case is the highest possible skirt height for safety. coordf_t skirt_height_z = 0.; - for (const PrintObject *object : this->objects) { - size_t skirt_layers = this->has_infinite_skirt() ? + PrintObjectPtrs printable_objects = get_printable_objects(); + for (const PrintObject *object : printable_objects) { + size_t skirt_layers = this->has_infinite_skirt() ? object->layer_count() : std::min(size_t(this->config.skirt_height.value), object->layer_count()); skirt_height_z = std::max(skirt_height_z, object->layers[skirt_layers-1]->print_z); @@ -864,7 +885,7 @@ void Print::_make_skirt() // Collect points from all layers contained in skirt height. Points points; - for (const PrintObject *object : this->objects) { + for (const PrintObject *object : printable_objects) { Points object_points; // Get object layers up to skirt_height_z. for (const Layer *layer : object->layers) { @@ -977,7 +998,8 @@ void Print::_make_brim() // Brim is only printed on first layer and uses perimeter extruder. Flow flow = this->brim_flow(); Polygons islands; - for (PrintObject *object : this->objects) { + PrintObjectPtrs printable_objects = get_printable_objects(); + for (PrintObject *object : printable_objects) { Polygons object_islands; for (ExPolygon &expoly : object->layers.front()->slices.expolygons) object_islands.push_back(expoly.contour); @@ -1033,6 +1055,16 @@ void Print::_make_wipe_tower() if (! this->has_wipe_tower()) return; + m_wipe_tower_depth = 0.f; + + // Get wiping matrix to get number of extruders and convert vector<double> to vector<float>: + std::vector<float> wiping_matrix((this->config.wiping_volumes_matrix.values).begin(),(this->config.wiping_volumes_matrix.values).end()); + // Extract purging volumes for each extruder pair: + std::vector<std::vector<float>> wipe_volumes; + const unsigned int number_of_extruders = (unsigned int)(sqrt(wiping_matrix.size())+EPSILON); + for (unsigned int i = 0; i<number_of_extruders; ++i) + wipe_volumes.push_back(std::vector<float>(wiping_matrix.begin()+i*number_of_extruders, wiping_matrix.begin()+(i+1)*number_of_extruders)); + // Let the ToolOrdering class know there will be initial priming extrusions at the start of the print. m_tool_ordering = ToolOrdering(*this, (unsigned int)-1, true); if (! m_tool_ordering.has_wipe_tower()) @@ -1048,7 +1080,7 @@ void Print::_make_wipe_tower() size_t idx_end = m_tool_ordering.layer_tools().size(); // Find the first wipe tower layer, which does not have a counterpart in an object or a support layer. for (size_t i = 0; i < idx_end; ++ i) { - const ToolOrdering::LayerTools < = m_tool_ordering.layer_tools()[i]; + const LayerTools < = m_tool_ordering.layer_tools()[i]; if (lt.has_wipe_tower && ! lt.has_object && ! lt.has_support) { idx_begin = i; break; @@ -1062,7 +1094,7 @@ void Print::_make_wipe_tower() for (; it_layer != it_end && (*it_layer)->print_z - EPSILON < wipe_tower_new_layer_print_z_first; ++ it_layer); // Find the stopper of the sequence of wipe tower layers, which do not have a counterpart in an object or a support layer. for (size_t i = idx_begin; i < idx_end; ++ i) { - ToolOrdering::LayerTools < = const_cast<ToolOrdering::LayerTools&>(m_tool_ordering.layer_tools()[i]); + LayerTools < = const_cast<LayerTools&>(m_tool_ordering.layer_tools()[i]); if (! (lt.has_wipe_tower && ! lt.has_object && ! lt.has_support)) break; lt.has_support = true; @@ -1077,115 +1109,76 @@ void Print::_make_wipe_tower() } } - // Get wiping matrix to get number of extruders and convert vector<double> to vector<float>: - std::vector<float> wiping_volumes((this->config.wiping_volumes_matrix.values).begin(),(this->config.wiping_volumes_matrix.values).end()); - // Initialize the wipe tower. WipeTowerPrusaMM wipe_tower( float(this->config.wipe_tower_x.value), float(this->config.wipe_tower_y.value), float(this->config.wipe_tower_width.value), float(this->config.wipe_tower_rotation_angle.value), float(this->config.cooling_tube_retraction.value), float(this->config.cooling_tube_length.value), float(this->config.parking_pos_retraction.value), - float(this->config.wipe_tower_bridging), wiping_volumes, m_tool_ordering.first_extruder()); + float(this->config.extra_loading_move.value), float(this->config.wipe_tower_bridging), wipe_volumes, + m_tool_ordering.first_extruder()); //wipe_tower.set_retract(); //wipe_tower.set_zhop(); // Set the extruder & material properties at the wipe tower object. - for (size_t i = 0; i < (int)(sqrt(wiping_volumes.size())+EPSILON); ++ i) + for (size_t i = 0; i < number_of_extruders; ++ i) wipe_tower.set_extruder( i, WipeTowerPrusaMM::parse_material(this->config.filament_type.get_at(i).c_str()), this->config.temperature.get_at(i), this->config.first_layer_temperature.get_at(i), this->config.filament_loading_speed.get_at(i), + this->config.filament_loading_speed_start.get_at(i), this->config.filament_unloading_speed.get_at(i), + this->config.filament_unloading_speed_start.get_at(i), this->config.filament_toolchange_delay.get_at(i), + this->config.filament_cooling_moves.get_at(i), + this->config.filament_cooling_initial_speed.get_at(i), + this->config.filament_cooling_final_speed.get_at(i), this->config.filament_ramming_parameters.get_at(i), this->config.nozzle_diameter.get_at(i)); - // When printing the first layer's wipe tower, the first extruder is expected to be active and primed. - // Therefore the number of wipe sections at the wipe tower will be (m_tool_ordering.front().extruders-1) at the 1st layer. - // The following variable is true if the last priming section cannot be squeezed inside the wipe tower. - bool last_priming_wipe_full = m_tool_ordering.front().extruders.size() > m_tool_ordering.front().wipe_tower_partitions; - m_wipe_tower_priming = Slic3r::make_unique<WipeTower::ToolChangeResult>( - wipe_tower.prime(this->skirt_first_layer_height(), m_tool_ordering.all_extruders(), ! last_priming_wipe_full)); - + wipe_tower.prime(this->skirt_first_layer_height(), m_tool_ordering.all_extruders(), false)); // Lets go through the wipe tower layers and determine pairs of extruder changes for each // to pass to wipe_tower (so that it can use it for planning the layout of the tower) { unsigned int current_extruder_id = m_tool_ordering.all_extruders().back(); - for (const auto &layer_tools : m_tool_ordering.layer_tools()) { // for all layers + for (auto &layer_tools : m_tool_ordering.layer_tools()) { // for all layers if (!layer_tools.has_wipe_tower) continue; bool first_layer = &layer_tools == &m_tool_ordering.front(); wipe_tower.plan_toolchange(layer_tools.print_z, layer_tools.wipe_tower_layer_height, current_extruder_id, current_extruder_id,false); for (const auto extruder_id : layer_tools.extruders) { if ((first_layer && extruder_id == m_tool_ordering.all_extruders().back()) || extruder_id != current_extruder_id) { - wipe_tower.plan_toolchange(layer_tools.print_z, layer_tools.wipe_tower_layer_height, current_extruder_id, extruder_id, first_layer && extruder_id == m_tool_ordering.all_extruders().back()); + float volume_to_wipe = wipe_volumes[current_extruder_id][extruder_id]; // total volume to wipe after this toolchange + // Not all of that can be used for infill purging: + volume_to_wipe -= config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id); + + // try to assign some infills/objects for the wiping: + volume_to_wipe = layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_extruder_id, extruder_id, volume_to_wipe); + + // add back the minimal amount toforce on the wipe tower: + volume_to_wipe += config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id); + + // request a toolchange at the wipe tower with at least volume_to_wipe purging amount + wipe_tower.plan_toolchange(layer_tools.print_z, layer_tools.wipe_tower_layer_height, current_extruder_id, extruder_id, + first_layer && extruder_id == m_tool_ordering.all_extruders().back(), volume_to_wipe); current_extruder_id = extruder_id; } } + layer_tools.wiping_extrusions().ensure_perimeters_infills_order(*this); if (&layer_tools == &m_tool_ordering.back() || (&layer_tools + 1)->wipe_tower_partitions == 0) break; } } - - // Generate the wipe tower layers. m_wipe_tower_tool_changes.reserve(m_tool_ordering.layer_tools().size()); wipe_tower.generate(m_wipe_tower_tool_changes); - - // Set current_extruder_id to the last extruder primed. - /*unsigned int current_extruder_id = m_tool_ordering.all_extruders().back(); + m_wipe_tower_depth = wipe_tower.get_depth(); - for (const ToolOrdering::LayerTools &layer_tools : m_tool_ordering.layer_tools()) { - if (! layer_tools.has_wipe_tower) - // This is a support only layer, or the wipe tower does not reach to this height. - continue; - bool first_layer = &layer_tools == &m_tool_ordering.front(); - bool last_layer = &layer_tools == &m_tool_ordering.back() || (&layer_tools + 1)->wipe_tower_partitions == 0; - wipe_tower.set_layer( - float(layer_tools.print_z), - float(layer_tools.wipe_tower_layer_height), - layer_tools.wipe_tower_partitions, - first_layer, - last_layer); - std::vector<WipeTower::ToolChangeResult> tool_changes; - for (unsigned int extruder_id : layer_tools.extruders) - // Call the wipe_tower.tool_change() at the first layer for the initial extruder - // to extrude the wipe tower brim, - if ((first_layer && extruder_id == m_tool_ordering.all_extruders().back()) || - // or when an extruder shall be switched. - extruder_id != current_extruder_id) { - tool_changes.emplace_back(wipe_tower.tool_change(extruder_id, extruder_id == layer_tools.extruders.back(), WipeTower::PURPOSE_EXTRUDE)); - current_extruder_id = extruder_id; - } - if (! wipe_tower.layer_finished()) { - tool_changes.emplace_back(wipe_tower.finish_layer(WipeTower::PURPOSE_EXTRUDE)); - if (tool_changes.size() > 1) { - // Merge the two last tool changes into one. - WipeTower::ToolChangeResult &tc1 = tool_changes[tool_changes.size() - 2]; - WipeTower::ToolChangeResult &tc2 = tool_changes.back(); - if (tc1.end_pos != tc2.start_pos) { - // Add a travel move from tc1.end_pos to tc2.start_pos. - char buf[2048]; - sprintf(buf, "G1 X%.3f Y%.3f F7200\n", tc2.start_pos.x, tc2.start_pos.y); - tc1.gcode += buf; - } - tc1.gcode += tc2.gcode; - append(tc1.extrusions, tc2.extrusions); - tc1.end_pos = tc2.end_pos; - tool_changes.pop_back(); - } - } - m_wipe_tower_tool_changes.emplace_back(std::move(tool_changes)); - if (last_layer) - break; - }*/ - // Unload the current filament over the purge tower. coordf_t layer_height = this->objects.front()->config.layer_height.value; if (m_tool_ordering.back().wipe_tower_partitions > 0) { @@ -1204,6 +1197,9 @@ void Print::_make_wipe_tower() } m_wipe_tower_final_purge = Slic3r::make_unique<WipeTower::ToolChangeResult>( wipe_tower.tool_change((unsigned int)-1, false)); + + m_wipe_tower_used_filament = wipe_tower.get_used_filament(); + m_wipe_tower_number_of_toolchanges = wipe_tower.get_number_of_toolchanges(); } std::string Print::output_filename() @@ -1212,7 +1208,7 @@ std::string Print::output_filename() try { return this->placeholder_parser.process(this->config.output_filename_format.value, 0); } catch (std::runtime_error &err) { - throw std::runtime_error(std::string("Failed processing of the output_filename_format template.\n") + err.what()); + throw std::runtime_error(L("Failed processing of the output_filename_format template.") + "\n" + err.what()); } } @@ -1244,4 +1240,11 @@ void Print::set_status(int percent, const std::string &message) printf("Print::status %d => %s\n", percent, message.c_str()); } +// Returns extruder this eec should be printed with, according to PrintRegion config +int Print::get_extruder(const ExtrusionEntityCollection& fill, const PrintRegion ®ion) +{ + return is_infill(fill.role()) ? std::max<int>(0, (is_solid_infill(fill.entities.front()->role()) ? region.config.solid_infill_extruder : region.config.infill_extruder) - 1) : + std::max<int>(region.config.perimeter_extruder.value - 1, 0); +} + } |