mirror of
https://github.com/QIDITECH/QIDISlicer.git
synced 2026-01-30 23:48:44 +03:00
Prusa 2.7.1
This commit is contained in:
@@ -130,6 +130,8 @@ void AppConfig::set_defaults()
|
||||
if (get("auto_toolbar_size").empty())
|
||||
set("auto_toolbar_size", "100");
|
||||
|
||||
if (get("use_binary_gcode_when_supported").empty())
|
||||
set("use_binary_gcode_when_supported", "1");
|
||||
if (get("notify_release").empty())
|
||||
set("notify_release", "all"); // or "none" or "release"
|
||||
|
||||
@@ -746,25 +748,7 @@ bool AppConfig::update_skein_dir(const std::string &dir)
|
||||
return false; // do not save "shapes gallery" directory
|
||||
return this->set("recent", "skein_directory", dir);
|
||||
}
|
||||
/*
|
||||
std::string AppConfig::get_last_output_dir(const std::string &alt) const
|
||||
{
|
||||
|
||||
const auto it = m_storage.find("");
|
||||
if (it != m_storage.end()) {
|
||||
const auto it2 = it->second.find("last_output_path");
|
||||
const auto it3 = it->second.find("remember_output_path");
|
||||
if (it2 != it->second.end() && it3 != it->second.end() && ! it2->second.empty() && it3->second == "1")
|
||||
return it2->second;
|
||||
}
|
||||
return alt;
|
||||
}
|
||||
|
||||
void AppConfig::update_last_output_dir(const std::string &dir)
|
||||
{
|
||||
this->set("", "last_output_path", dir);
|
||||
}
|
||||
*/
|
||||
std::string AppConfig::get_last_output_dir(const std::string& alt, const bool removable) const
|
||||
{
|
||||
std::string s1 = (removable ? "last_output_path_removable" : "last_output_path");
|
||||
|
||||
@@ -753,6 +753,7 @@ namespace DoExport {
|
||||
print_statistics.total_used_filament += used_filament;
|
||||
print_statistics.total_extruded_volume += extruded_volume;
|
||||
print_statistics.total_wipe_tower_filament += has_wipe_tower ? used_filament - extruder.used_filament() : 0.;
|
||||
print_statistics.total_wipe_tower_filament_weight += has_wipe_tower ? (extruded_volume - extruder.extruded_volume()) * extruder.filament_density() * 0.001 : 0.;
|
||||
print_statistics.total_wipe_tower_cost += has_wipe_tower ? (extruded_volume - extruder.extruded_volume())* extruder.filament_density() * 0.001 * extruder.filament_cost() * 0.001 : 0.;
|
||||
}
|
||||
if (!export_binary_data) {
|
||||
@@ -843,7 +844,7 @@ static inline GCode::SmoothPathCache smooth_path_interpolate_global(const Print&
|
||||
|
||||
void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGeneratorCallback thumbnail_cb)
|
||||
{
|
||||
const bool export_to_binary_gcode = print.full_print_config().option<ConfigOptionBool>("gcode_binary")->value;
|
||||
const bool export_to_binary_gcode = print.full_print_config().option<ConfigOptionBool>("binary_gcode")->value;
|
||||
// if exporting gcode in binary format:
|
||||
// we generate here the data to be passed to the post-processor, who is responsible to export them to file
|
||||
// 1) generate the thumbnails
|
||||
@@ -1404,6 +1405,7 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
|
||||
file.write("\n");
|
||||
file.write_format(PrintStatistics::TotalFilamentUsedGValueMask.c_str(), print.m_print_statistics.total_weight);
|
||||
file.write_format(PrintStatistics::TotalFilamentCostValueMask.c_str(), print.m_print_statistics.total_cost);
|
||||
file.write_format(PrintStatistics::TotalFilamentUsedWipeTowerValueMask.c_str(), print.m_print_statistics.total_wipe_tower_filament_weight);
|
||||
if (print.m_print_statistics.total_toolchanges > 0)
|
||||
file.write_format("; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges);
|
||||
file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder).c_str());
|
||||
@@ -2192,7 +2194,7 @@ LayerResult GCodeGenerator::process_layer(
|
||||
print.config().before_layer_gcode.value, m_writer.extruder()->id(), &config)
|
||||
+ "\n";
|
||||
}
|
||||
gcode += this->change_layer(previous_layer_z, print_z); // this will increase m_layer_index
|
||||
gcode += this->change_layer(previous_layer_z, print_z, result.spiral_vase_enable); // this will increase m_layer_index
|
||||
m_layer = &layer;
|
||||
if (this->line_distancer_is_required(layer_tools.extruders) && this->m_layer != nullptr && this->m_layer->lower_layer != nullptr) {
|
||||
this->m_previous_layer_distancer = GCode::Impl::get_expolygons_distancer(m_layer->lower_layer->lslices);
|
||||
@@ -2704,7 +2706,11 @@ Polygon Bed::get_inner_offset(const std::vector<Vec2d>& shape, const double padd
|
||||
transform(begin(shape), end(shape), back_inserter(shape_scaled), [](const Vec2d& point){
|
||||
return scaled(point);
|
||||
});
|
||||
return shrink({Polygon{shape_scaled}}, scaled(padding)).front();
|
||||
Polygons inner_offset{shrink({Polygon{shape_scaled}}, scaled(padding))};
|
||||
if (inner_offset.empty()) {
|
||||
return Polygon{};
|
||||
}
|
||||
return inner_offset.front();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2724,21 +2730,18 @@ std::optional<std::string> GCodeGenerator::get_helical_layer_change_gcode(
|
||||
|
||||
const Point n_gon_start_point{this->last_pos()};
|
||||
|
||||
static GCode::Impl::Bed bed{
|
||||
GCode::Impl::Bed bed{
|
||||
this->m_config.bed_shape.values,
|
||||
circle_radius
|
||||
circle_radius * 2
|
||||
};
|
||||
if (!bed.contains_within_padding(this->point_to_gcode(n_gon_start_point))) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const Point n_gon_centeroid{
|
||||
n_gon_start_point
|
||||
+ scaled(Vec2d{
|
||||
(bed.centroid - unscaled(n_gon_start_point)).normalized()
|
||||
* circle_radius
|
||||
})
|
||||
};
|
||||
const Vec2crd n_gon_vector{scaled(Vec2d{
|
||||
(bed.centroid - this->point_to_gcode(n_gon_start_point)).normalized() * circle_radius
|
||||
})};
|
||||
const Point n_gon_centeroid{n_gon_start_point + n_gon_vector};
|
||||
|
||||
const Polygon n_gon{GCode::Impl::generate_regular_polygon(
|
||||
n_gon_centeroid,
|
||||
@@ -2763,8 +2766,11 @@ std::optional<std::string> GCodeGenerator::get_helical_layer_change_gcode(
|
||||
}
|
||||
|
||||
// called by GCodeGenerator::process_layer()
|
||||
std::string GCodeGenerator::change_layer(coordf_t previous_layer_z, coordf_t print_z)
|
||||
{
|
||||
std::string GCodeGenerator::change_layer(
|
||||
coordf_t previous_layer_z,
|
||||
coordf_t print_z,
|
||||
const bool spiral_vase_enabled
|
||||
) {
|
||||
std::string gcode;
|
||||
if (m_layer_count > 0)
|
||||
// Increment a progress bar indicator.
|
||||
@@ -2775,14 +2781,16 @@ std::string GCodeGenerator::change_layer(coordf_t previous_layer_z, coordf_t pri
|
||||
|
||||
const std::string comment{"move to next layer (" + std::to_string(m_layer_index) + ")"};
|
||||
|
||||
bool helical_layer_change{
|
||||
(!this->m_spiral_vase || !this->m_spiral_vase->is_enabled())
|
||||
bool do_helical_layer_change{
|
||||
!spiral_vase_enabled
|
||||
&& print_z > previous_layer_z
|
||||
&& EXTRUDER_CONFIG(retract_layer_change)
|
||||
&& EXTRUDER_CONFIG(retract_length) > 0
|
||||
&& EXTRUDER_CONFIG(travel_ramping_lift)
|
||||
&& EXTRUDER_CONFIG(travel_slope) > 0 && EXTRUDER_CONFIG(travel_slope) < 90
|
||||
};
|
||||
const std::optional<std::string> helix_gcode{
|
||||
helical_layer_change ?
|
||||
do_helical_layer_change ?
|
||||
this->get_helical_layer_change_gcode(
|
||||
m_config.z_offset.value + previous_layer_z,
|
||||
m_config.z_offset.value + print_z,
|
||||
|
||||
@@ -351,7 +351,11 @@ private:
|
||||
const coordf_t print_z,
|
||||
const std::string& comment
|
||||
);
|
||||
std::string change_layer(coordf_t previous_layer_z, coordf_t print_z);
|
||||
std::string change_layer(
|
||||
coordf_t previous_layer_z,
|
||||
coordf_t print_z,
|
||||
const bool spiral_vase_enabled
|
||||
);
|
||||
std::string extrude_entity(const ExtrusionEntityReference &entity, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
|
||||
std::string extrude_loop(const ExtrusionLoop &loop, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
|
||||
std::string extrude_skirt(const ExtrusionLoop &loop_src, const ExtrusionFlow &extrusion_flow_override,
|
||||
|
||||
@@ -568,8 +568,8 @@ GCodeProcessor::GCodeProcessor()
|
||||
void GCodeProcessor::apply_config(const PrintConfig& config)
|
||||
{
|
||||
m_parser.apply_config(config);
|
||||
m_binarizer.set_enabled(config.gcode_binary);
|
||||
m_result.is_binary_file = config.gcode_binary;
|
||||
m_binarizer.set_enabled(config.binary_gcode);
|
||||
m_result.is_binary_file = config.binary_gcode;
|
||||
|
||||
m_producer = EProducer::QIDISlicer;
|
||||
m_flavor = config.gcode_flavor;
|
||||
@@ -3687,6 +3687,7 @@ void GCodeProcessor::post_process()
|
||||
filament_total_cost += filament_cost[id];
|
||||
}
|
||||
|
||||
double total_g_wipe_tower = m_print->print_statistics().total_wipe_tower_filament_weight;
|
||||
if (m_binarizer.is_enabled()) {
|
||||
// update print metadata
|
||||
auto stringify = [](const std::vector<double>& values) {
|
||||
@@ -3707,11 +3708,13 @@ void GCodeProcessor::post_process()
|
||||
binary_data.print_metadata.raw_data.emplace_back(PrintStatistics::FilamentCost, stringify(filament_cost));
|
||||
binary_data.print_metadata.raw_data.emplace_back(PrintStatistics::TotalFilamentUsedG, stringify({ filament_total_g }));
|
||||
binary_data.print_metadata.raw_data.emplace_back(PrintStatistics::TotalFilamentCost, stringify({ filament_total_cost }));
|
||||
binary_data.print_metadata.raw_data.emplace_back(PrintStatistics::TotalFilamentUsedWipeTower, stringify({ total_g_wipe_tower }));
|
||||
|
||||
binary_data.printer_metadata.raw_data.emplace_back(PrintStatistics::FilamentUsedMm, stringify(filament_mm)); // duplicated into print metadata
|
||||
binary_data.printer_metadata.raw_data.emplace_back(PrintStatistics::FilamentUsedG, stringify(filament_g)); // duplicated into print metadata
|
||||
binary_data.printer_metadata.raw_data.emplace_back(PrintStatistics::FilamentCost, stringify(filament_cost)); // duplicated into print metadata
|
||||
binary_data.printer_metadata.raw_data.emplace_back(PrintStatistics::FilamentUsedCm3, stringify(filament_cm3)); // duplicated into print metadata
|
||||
binary_data.printer_metadata.raw_data.emplace_back(PrintStatistics::TotalFilamentUsedWipeTower, stringify({ total_g_wipe_tower })); // duplicated into print metadata
|
||||
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
const TimeMachine& machine = m_time_processor.machines[i];
|
||||
|
||||
@@ -19,9 +19,6 @@ public:
|
||||
m_enabled = en;
|
||||
}
|
||||
|
||||
bool is_enabled() const {
|
||||
return m_enabled;
|
||||
}
|
||||
std::string process_layer(const std::string &gcode);
|
||||
|
||||
private:
|
||||
|
||||
@@ -454,7 +454,7 @@ static std::vector<std::string> s_Preset_print_options {
|
||||
"support_tree_angle", "support_tree_angle_slow", "support_tree_branch_diameter", "support_tree_branch_diameter_angle", "support_tree_branch_diameter_double_wall",
|
||||
"support_tree_top_rate", "support_tree_branch_distance", "support_tree_tip_diameter",
|
||||
"dont_support_bridges", "thick_bridges", "notes", "complete_objects", "extruder_clearance_radius",
|
||||
"extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "gcode_substitutions", "gcode_binary","perimeter_extruder",
|
||||
"extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "gcode_substitutions", "perimeter_extruder",
|
||||
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
|
||||
"ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
|
||||
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
|
||||
@@ -517,7 +517,7 @@ static std::vector<std::string> s_Preset_machine_limits_options {
|
||||
|
||||
static std::vector<std::string> s_Preset_printer_options {
|
||||
"printer_technology", "autoemit_temperature_commands",
|
||||
"bed_shape", "bed_custom_texture", "bed_custom_model", "z_offset", "gcode_flavor", "use_relative_e_distances",
|
||||
"bed_shape", "bed_custom_texture", "bed_custom_model", "binary_gcode", "z_offset", "gcode_flavor", "use_relative_e_distances",
|
||||
"use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
|
||||
//FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset.
|
||||
"host_type", "print_host", "printhost_apikey", "printhost_cafile",
|
||||
|
||||
@@ -64,6 +64,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||
"bed_temperature",
|
||||
"before_layer_gcode",
|
||||
"between_objects_gcode",
|
||||
"binary_gcode",
|
||||
"bridge_acceleration",
|
||||
"bridge_fan_speed",
|
||||
//B15
|
||||
@@ -121,7 +122,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||
"perimeter_acceleration",
|
||||
"post_process",
|
||||
"gcode_substitutions",
|
||||
"gcode_binary",
|
||||
"printer_notes",
|
||||
"travel_ramping_lift",
|
||||
"travel_initial_part_length",
|
||||
@@ -1588,7 +1588,14 @@ std::string Print::output_filename(const std::string &filename_base) const
|
||||
DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders();
|
||||
config.set_key_value("num_extruders", new ConfigOptionInt((int)m_config.nozzle_diameter.size()));
|
||||
config.set_key_value("default_output_extension", new ConfigOptionString(".gcode"));
|
||||
return this->PrintBase::output_filename(m_config.output_filename_format.value, ".gcode", filename_base, &config);
|
||||
// Handle output_filename_format. There is a hack related to binary G-codes: gcode / bgcode substitution.
|
||||
std::string output_filename_format = m_config.output_filename_format.value;
|
||||
if (m_config.binary_gcode && boost::iends_with(output_filename_format, ".gcode"))
|
||||
output_filename_format.insert(output_filename_format.end()-5, 'b');
|
||||
if (! m_config.binary_gcode && boost::iends_with(output_filename_format, ".bgcode"))
|
||||
output_filename_format.erase(output_filename_format.end()-6);
|
||||
|
||||
return this->PrintBase::output_filename(output_filename_format, ".gcode", filename_base, &config);
|
||||
}
|
||||
|
||||
const std::string PrintStatistics::FilamentUsedG = "filament used [g]";
|
||||
@@ -1610,6 +1617,8 @@ const std::string PrintStatistics::FilamentCostMask = "; filament cost =";
|
||||
const std::string PrintStatistics::TotalFilamentCost = "total filament cost";
|
||||
const std::string PrintStatistics::TotalFilamentCostMask = "; total filament cost =";
|
||||
const std::string PrintStatistics::TotalFilamentCostValueMask = "; total filament cost = %.2lf\n";
|
||||
const std::string PrintStatistics::TotalFilamentUsedWipeTower = "total filament used for wipe tower [g]";
|
||||
const std::string PrintStatistics::TotalFilamentUsedWipeTowerValueMask = "; total filament used for wipe tower [g] = %.2lf\n";
|
||||
DynamicConfig PrintStatistics::config() const
|
||||
{
|
||||
DynamicConfig config;
|
||||
|
||||
@@ -486,6 +486,7 @@ struct PrintStatistics
|
||||
double total_weight;
|
||||
double total_wipe_tower_cost;
|
||||
double total_wipe_tower_filament;
|
||||
double total_wipe_tower_filament_weight;
|
||||
std::vector<unsigned int> printing_extruders;
|
||||
unsigned int initial_extruder_id;
|
||||
std::string initial_filament_type;
|
||||
@@ -507,6 +508,7 @@ struct PrintStatistics
|
||||
total_weight = 0.;
|
||||
total_wipe_tower_cost = 0.;
|
||||
total_wipe_tower_filament = 0.;
|
||||
total_wipe_tower_filament_weight = 0.;
|
||||
initial_extruder_id = 0;
|
||||
initial_filament_type.clear();
|
||||
printing_filament_types.clear();
|
||||
@@ -527,6 +529,8 @@ struct PrintStatistics
|
||||
static const std::string TotalFilamentCost;
|
||||
static const std::string TotalFilamentCostMask;
|
||||
static const std::string TotalFilamentCostValueMask;
|
||||
static const std::string TotalFilamentUsedWipeTower;
|
||||
static const std::string TotalFilamentUsedWipeTowerValueMask;
|
||||
};
|
||||
|
||||
using PrintObjectPtrs = std::vector<PrintObject*>;
|
||||
|
||||
@@ -1546,11 +1546,6 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionStrings());
|
||||
|
||||
def = this->add("gcode_binary", coBool);
|
||||
def->label = L("Export as binary G-code");
|
||||
def->tooltip = L("Export G-code in binary format.");
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionBool(0));
|
||||
def = this->add("high_current_on_filament_swap", coBool);
|
||||
def->label = L("High extruder current on filament swap");
|
||||
def->tooltip = L("It may be beneficial to increase the extruder motor current during the filament exchange"
|
||||
@@ -1826,6 +1821,12 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionBool(true));
|
||||
|
||||
def = this->add("binary_gcode", coBool);
|
||||
def->label = L("Supports binary G-code");
|
||||
def->tooltip = L("Enable, if the firmware supports binary G-code format (bgcode). "
|
||||
"To generate .bgcode files, make sure you have binary G-code enabled in Configuration->Preferences->Other.");
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
def = this->add("machine_limits_usage", coEnum);
|
||||
def->label = L("How to apply limits");
|
||||
def->full_label = L("Purpose of Machine Limits");
|
||||
@@ -4452,6 +4453,7 @@ static std::set<std::string> PrintConfigDef_ignore = {
|
||||
"ensure_vertical_shell_thickness",
|
||||
// Disabled in 2.6.0-alpha6, this option is problematic
|
||||
"infill_only_where_needed",
|
||||
"gcode_binary" // Introduced in 2.7.0-alpha1, removed in 2.7.1 (replaced by binary_gcode).
|
||||
};
|
||||
|
||||
void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value)
|
||||
|
||||
@@ -688,6 +688,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionBool, autoemit_temperature_commands))
|
||||
((ConfigOptionString, before_layer_gcode))
|
||||
((ConfigOptionString, between_objects_gcode))
|
||||
((ConfigOptionBool, binary_gcode))
|
||||
((ConfigOptionFloats, deretract_speed))
|
||||
((ConfigOptionString, end_gcode))
|
||||
((ConfigOptionStrings, end_filament_gcode))
|
||||
@@ -724,7 +725,6 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
// i - case insensitive
|
||||
// w - whole word
|
||||
((ConfigOptionStrings, gcode_substitutions))
|
||||
((ConfigOptionBool, gcode_binary))
|
||||
((ConfigOptionString, layer_gcode))
|
||||
((ConfigOptionFloat, max_print_speed))
|
||||
((ConfigOptionFloat, max_volumetric_speed))
|
||||
|
||||
@@ -198,9 +198,10 @@ wxString Field::get_tooltip_text(const wxString& default_string)
|
||||
opt_id += "]";
|
||||
}
|
||||
|
||||
bool newline_after_name = boost::iends_with(opt_id, "_gcode") && opt_id != "binary_gcode";
|
||||
return from_u8(m_opt.tooltip) + "\n" + _L("default value") + "\t: " +
|
||||
(boost::iends_with(opt_id, "_gcode") ? "\n" : "") + default_string +
|
||||
(boost::iends_with(opt_id, "_gcode") ? "" : "\n") +
|
||||
(newline_after_name ? "\n" : "") + default_string +
|
||||
(newline_after_name ? "" : "\n") +
|
||||
_L("parameter name") + "\t: " + opt_id;
|
||||
}
|
||||
|
||||
|
||||
@@ -2023,7 +2023,7 @@ void GLCanvas3D::render()
|
||||
}
|
||||
|
||||
#if ENABLE_BINARIZED_GCODE_DEBUG_WINDOW
|
||||
if (wxGetApp().plater()->is_view3D_shown() && current_printer_technology() != ptSLA && fff_print()->config().gcode_binary)
|
||||
if (wxGetApp().plater()->is_view3D_shown() && current_printer_technology() != ptSLA && fff_print()->config().binary_gcode)
|
||||
show_binary_gcode_debug_window();
|
||||
#endif // ENABLE_BINARIZED_GCODE_DEBUG_WINDOW
|
||||
std::string tooltip;
|
||||
|
||||
@@ -220,7 +220,7 @@ bool GLGizmoSVG::create_volume(std::string_view svg_file, const Vec2d &mouse_pos
|
||||
}
|
||||
|
||||
bool GLGizmoSVG::is_svg(const ModelVolume &volume) {
|
||||
return volume.emboss_shape.has_value();
|
||||
return volume.emboss_shape.has_value() && volume.emboss_shape->svg_file.has_value();
|
||||
}
|
||||
|
||||
bool GLGizmoSVG::is_svg_object(const ModelVolume &volume) {
|
||||
@@ -1174,6 +1174,7 @@ void GLGizmoSVG::set_volume_by_selection()
|
||||
// calculate scale for height and depth inside of scaled object instance
|
||||
calculate_scale(); // must be before calculation of tesselation
|
||||
|
||||
// checking that exist is inside of function "is_svg"
|
||||
EmbossShape &es = *volume->emboss_shape;
|
||||
EmbossShape::SvgFile &svg_file = *es.svg_file;
|
||||
if (svg_file.image == nullptr) {
|
||||
|
||||
@@ -264,6 +264,13 @@ ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg, const std::funct
|
||||
{
|
||||
create(m_content, 84);
|
||||
}
|
||||
HtmlCapableRichMessageDialog::HtmlCapableRichMessageDialog(wxWindow *parent,
|
||||
const wxString &msg,
|
||||
const wxString &caption,
|
||||
long style,
|
||||
const std::function<void(const std::string &)> &on_link_clicked)
|
||||
: RichMessageDialogBase(parent, HtmlContent{msg, false, true, on_link_clicked}, caption, style)
|
||||
{}
|
||||
// WarningDialog
|
||||
|
||||
WarningDialog::WarningDialog(wxWindow *parent,
|
||||
@@ -289,19 +296,29 @@ MessageDialog::MessageDialog(wxWindow* parent,
|
||||
add_msg_content(this, content_sizer, HtmlContent{ get_wraped_wxString(message) });
|
||||
finalize();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// RichMessageDialog
|
||||
// RichMessageDialogBase
|
||||
|
||||
RichMessageDialog::RichMessageDialog(wxWindow* parent,
|
||||
RichMessageDialogBase::RichMessageDialogBase(wxWindow* parent,
|
||||
const wxString& message,
|
||||
const wxString& caption/* = wxEmptyString*/,
|
||||
long style/* = wxOK*/)
|
||||
: RichMessageDialogBase(parent, HtmlContent{get_wraped_wxString(message)}, caption, style)
|
||||
{}
|
||||
|
||||
RichMessageDialogBase::RichMessageDialogBase(wxWindow* parent, const HtmlContent& content, const wxString& caption, long style)
|
||||
: MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s info"), SLIC3R_APP_NAME) : caption, wxEmptyString, style)
|
||||
{
|
||||
add_msg_content(this, content_sizer, HtmlContent{ get_wraped_wxString(message) });
|
||||
m_content = content; // We need a copy for the on_link_clicked lambda.
|
||||
add_msg_content(this, content_sizer, m_content);
|
||||
|
||||
#ifdef _WIN32 // See comment in the header where m_checkBox is defined.
|
||||
m_checkBox = new ::CheckBox(this, m_checkBoxText);
|
||||
#else
|
||||
m_checkBox = new wxCheckBox(this, wxID_ANY, m_checkBoxText);
|
||||
#endif
|
||||
wxGetApp().UpdateDarkUI(m_checkBox);
|
||||
m_checkBox->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) { m_checkBoxValue = m_checkBox->GetValue(); });
|
||||
|
||||
@@ -310,7 +327,7 @@ RichMessageDialog::RichMessageDialog(wxWindow* parent,
|
||||
finalize();
|
||||
}
|
||||
|
||||
int RichMessageDialog::ShowModal()
|
||||
int RichMessageDialogBase::ShowModal()
|
||||
{
|
||||
if (m_checkBoxText.IsEmpty())
|
||||
m_checkBox->Hide();
|
||||
@@ -322,7 +339,6 @@ int RichMessageDialog::ShowModal()
|
||||
|
||||
return wxDialog::ShowModal();
|
||||
}
|
||||
#endif
|
||||
|
||||
// InfoDialog
|
||||
|
||||
|
||||
@@ -101,58 +101,31 @@ public:
|
||||
|
||||
wxString get_wraped_wxString(const wxString& text_in, size_t line_len = 80);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Generic static line, used intead of wxStaticLine
|
||||
class StaticLine: public wxTextCtrl
|
||||
{
|
||||
public:
|
||||
StaticLine( wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxLI_HORIZONTAL,
|
||||
const wxString& name = wxString::FromAscii(wxTextCtrlNameStr))
|
||||
: wxTextCtrl(parent, id, wxEmptyString, pos, size!=wxDefaultSize ? size : (style == wxLI_HORIZONTAL ? wxSize(10, 1) : wxSize(1, 10)), wxSIMPLE_BORDER, wxDefaultValidator, name)
|
||||
{
|
||||
this->Enable(false);
|
||||
}
|
||||
~StaticLine() {}
|
||||
};
|
||||
|
||||
// Generic message dialog, used intead of wxMessageDialog
|
||||
class MessageDialog : public MsgDialog
|
||||
{
|
||||
public:
|
||||
// NOTE! Don't change a signature of contsrucor. It have to be tha same as for wxMessageDialog
|
||||
MessageDialog( wxWindow *parent,
|
||||
const wxString& message,
|
||||
const wxString& caption = wxEmptyString,
|
||||
long style = wxOK);
|
||||
MessageDialog(MessageDialog&&) = delete;
|
||||
MessageDialog(const MessageDialog&) = delete;
|
||||
MessageDialog &operator=(MessageDialog&&) = delete;
|
||||
MessageDialog &operator=(const MessageDialog&) = delete;
|
||||
virtual ~MessageDialog() = default;
|
||||
};
|
||||
|
||||
// Generic rich message dialog, used intead of wxRichMessageDialog
|
||||
class RichMessageDialog : public MsgDialog
|
||||
class RichMessageDialogBase : public MsgDialog
|
||||
{
|
||||
// Using CheckBox causes some weird sizer-related issues on Linux and macOS. To get around the problem before
|
||||
// we find a better fix, we will fallback to wxCheckBox in this dialog. This makes little difference for most dialogs,
|
||||
// We currently only use this class as a base for HtmlCapableRichMessageDialog on Linux and macOS. The normal
|
||||
// RichMessageDialog is just an alias for wxRichMessageDialog on these platforms.
|
||||
#ifdef _WIN32
|
||||
CheckBox* m_checkBox{ nullptr };
|
||||
#else
|
||||
wxCheckBox* m_checkBox{ nullptr };
|
||||
#endif
|
||||
wxString m_checkBoxText;
|
||||
bool m_checkBoxValue{ false };
|
||||
|
||||
public:
|
||||
// NOTE! Don't change a signature of contsrucor. It have to be tha same as for wxRichMessageDialog
|
||||
RichMessageDialog( wxWindow *parent,
|
||||
const wxString& message,
|
||||
const wxString& caption = wxEmptyString,
|
||||
long style = wxOK);
|
||||
RichMessageDialog(RichMessageDialog&&) = delete;
|
||||
RichMessageDialog(const RichMessageDialog&) = delete;
|
||||
RichMessageDialog &operator=(RichMessageDialog&&) = delete;
|
||||
RichMessageDialog &operator=(const RichMessageDialog&) = delete;
|
||||
virtual ~RichMessageDialog() = default;
|
||||
RichMessageDialogBase(wxWindow* parent, const wxString& message, const wxString& caption = wxEmptyString, long style = wxOK);
|
||||
RichMessageDialogBase(wxWindow* parent, const HtmlContent& content, const wxString& caption = wxEmptyString, long style = wxOK);
|
||||
RichMessageDialogBase(RichMessageDialogBase&&) = delete;
|
||||
RichMessageDialogBase(const RichMessageDialogBase&) = delete;
|
||||
RichMessageDialogBase &operator=(RichMessageDialogBase&&) = delete;
|
||||
RichMessageDialogBase &operator=(const RichMessageDialogBase&) = delete;
|
||||
virtual ~RichMessageDialogBase() = default;
|
||||
|
||||
int ShowModal() override;
|
||||
|
||||
@@ -273,7 +246,44 @@ private:
|
||||
m_ok,
|
||||
m_cancel,
|
||||
m_help;
|
||||
HtmlContent m_content;
|
||||
};
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
// Generic static line, used intead of wxStaticLine
|
||||
class StaticLine: public wxTextCtrl
|
||||
{
|
||||
public:
|
||||
StaticLine( wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxLI_HORIZONTAL,
|
||||
const wxString& name = wxString::FromAscii(wxTextCtrlNameStr))
|
||||
: wxTextCtrl(parent, id, wxEmptyString, pos, size!=wxDefaultSize ? size : (style == wxLI_HORIZONTAL ? wxSize(10, 1) : wxSize(1, 10)), wxSIMPLE_BORDER, wxDefaultValidator, name)
|
||||
{
|
||||
this->Enable(false);
|
||||
}
|
||||
~StaticLine() {}
|
||||
};
|
||||
|
||||
// Generic message dialog, used intead of wxMessageDialog
|
||||
class MessageDialog : public MsgDialog
|
||||
{
|
||||
public:
|
||||
// NOTE! Don't change a signature of contsrucor. It have to be tha same as for wxMessageDialog
|
||||
MessageDialog(wxWindow *parent,
|
||||
const wxString& message,
|
||||
const wxString& caption = wxEmptyString,
|
||||
long style = wxOK);
|
||||
MessageDialog(MessageDialog &&) = delete;
|
||||
MessageDialog(const MessageDialog &) = delete;
|
||||
MessageDialog &operator=(MessageDialog &&) = delete;
|
||||
MessageDialog &operator=(const MessageDialog &) = delete;
|
||||
virtual ~MessageDialog() = default;
|
||||
};
|
||||
using RichMessageDialog = RichMessageDialogBase;
|
||||
#else
|
||||
// just a wrapper for wxStaticLine to use the same code on all platforms
|
||||
class StaticLine : public wxStaticLine
|
||||
@@ -315,6 +325,15 @@ public:
|
||||
};
|
||||
#endif
|
||||
|
||||
class HtmlCapableRichMessageDialog : public RichMessageDialogBase
|
||||
{
|
||||
public:
|
||||
HtmlCapableRichMessageDialog(wxWindow *parent, const wxString &msg, const wxString& caption, long style, const std::function<void(const std::string &)> &on_link_clicked);
|
||||
~HtmlCapableRichMessageDialog() {}
|
||||
|
||||
private:
|
||||
HtmlContent m_content;
|
||||
};
|
||||
// Generic info dialog, used for displaying exceptions
|
||||
class InfoDialog : public MsgDialog
|
||||
{
|
||||
|
||||
@@ -964,7 +964,7 @@ Sidebar::Sidebar(Plater *parent)
|
||||
|
||||
enable_buttons(false);
|
||||
|
||||
auto *btns_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
auto *btns_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
auto* complect_btns_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
complect_btns_sizer->Add(p->btn_export_gcode, 1, wxEXPAND);
|
||||
@@ -973,8 +973,8 @@ Sidebar::Sidebar(Plater *parent)
|
||||
// complect_btns_sizer->Add(p->btn_eject_device);
|
||||
|
||||
|
||||
btns_sizer->Add(p->btn_reslice, 0, wxEXPAND | wxTOP, margin_5);
|
||||
btns_sizer->Add(complect_btns_sizer, 0, wxEXPAND | wxTOP, margin_5);
|
||||
btns_sizer->Add(p->btn_reslice, 1, wxEXPAND | wxTOP | wxBOTTOM, margin_5);
|
||||
btns_sizer->Add(complect_btns_sizer, 1, wxEXPAND | wxTOP | wxBOTTOM, margin_5);
|
||||
|
||||
auto *sizer = new wxBoxSizer(wxVERTICAL);
|
||||
sizer->Add(p->scrolled, 1, wxEXPAND);
|
||||
@@ -3333,6 +3333,10 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
|
||||
// bitmap of enum UpdateBackgroundProcessReturnState
|
||||
unsigned int return_state = 0;
|
||||
|
||||
// Get the config ready. The binary gcode flag depends on Preferences, which the backend has no access to.
|
||||
DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config();
|
||||
if (full_config.has("binary_gcode")) // needed for SLA
|
||||
full_config.set("binary_gcode", bool(full_config.opt_bool("binary_gcode") & wxGetApp().app_config->get_bool("use_binary_gcode_when_supported")));
|
||||
// If the update_background_process() was not called by the timer, kill the timer,
|
||||
// so the update_restart_background_process() will not be called again in vain.
|
||||
background_process_timer.Stop();
|
||||
@@ -3340,7 +3344,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
|
||||
update_print_volume_state();
|
||||
// Apply new config to the possibly running background task.
|
||||
bool was_running = background_process.running();
|
||||
Print::ApplyStatus invalidated = background_process.apply(q->model(), wxGetApp().preset_bundle->full_config());
|
||||
Print::ApplyStatus invalidated = background_process.apply(q->model(), full_config);
|
||||
|
||||
// Just redraw the 3D canvas without reloading the scene to consume the update of the layer height profile.
|
||||
if (view3D->is_layers_editing_enabled())
|
||||
@@ -6642,7 +6646,7 @@ ProjectDropDialog::ProjectDropDialog(const std::string& filename)
|
||||
main_sizer->Add(stb_sizer, 1, wxEXPAND | wxRIGHT | wxLEFT, 10);
|
||||
|
||||
wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxCheckBox* check = new wxCheckBox(this, wxID_ANY, _L("Don't show again"));
|
||||
::CheckBox* check = new ::CheckBox(this, _L("Don't show again"));
|
||||
check->Bind(wxEVT_CHECKBOX, [](wxCommandEvent& evt) {
|
||||
wxGetApp().app_config->set("show_drop_project_dialog", evt.IsChecked() ? "0" : "1");
|
||||
});
|
||||
@@ -7126,14 +7130,14 @@ static wxString check_binary_vs_ascii_gcode_extension(PrinterTechnology pt, cons
|
||||
if (binary_output && ascii_extension) {
|
||||
// TRN The placeholder %1% is the file extension the user has selected.
|
||||
err_out = format_wxstr(_L("Cannot save binary G-code with %1% extension.\n\n"
|
||||
"Use <a href=%2%>a different extension</a> or disable <a href=%3%>binary G-code export</a> "
|
||||
"in Print Settings."), ext, "output_filename_format;print", "gcode_binary;print");
|
||||
"Use a different extension or disable <a href=%2%>binary G-code export</a> "
|
||||
"in Printer Settings."), ext, "binary_gcode;printer");
|
||||
}
|
||||
if (!binary_output && binary_extension) {
|
||||
// TRN The placeholder %1% is the file extension the user has selected.
|
||||
err_out = format_wxstr(_L("Cannot save ASCII G-code with %1% extension.\n\n"
|
||||
"Use <a href=%2%>a different extension</a> or enable <a href=%3%>binary G-code export</a> "
|
||||
"in Print Settings."), ext, "output_filename_format;print", "gcode_binary;print");
|
||||
"Use a different extension or enable <a href=%2%>binary G-code export</a> "
|
||||
"in Printer Settings."), ext, "binary_gcode;printer");
|
||||
}
|
||||
}
|
||||
return err_out;
|
||||
@@ -7157,9 +7161,15 @@ static void alert_when_exporting_binary_gcode(bool binary_output, const std::str
|
||||
const std::string option_key = "dont_warn_about_firmware_version_when_exporting_binary_gcode";
|
||||
|
||||
if (app_config->get(option_key) != "1") {
|
||||
RichMessageDialog dialog(parent, _L("You are exporting binary G-code for a Prusa printer. Please, make sure that your printer "
|
||||
"is running firmware version 5.1.0-alpha2 or later. Older firmwares are not able to handle binary G-codes."),
|
||||
_L("Exporting binary G-code"), wxICON_WARNING | wxOK);
|
||||
const wxString url = "https://qidi.io/binary-gcode";
|
||||
HtmlCapableRichMessageDialog dialog(parent,
|
||||
format_wxstr(_L("You are exporting binary G-code for a QIDI printer. "
|
||||
"Binary G-code enables significantly faster uploads. "
|
||||
"Ensure that your printer is running firmware version 5.1.0 or newer, as older versions do not support binary G-codes.\n\n"
|
||||
"To learn more about binary G-code, visit <a href=%1%>%1%</a>."),
|
||||
url),
|
||||
_L("Warning"), wxOK,
|
||||
[&url](const std::string&) { wxGetApp().open_browser_with_warning_dialog(url); });
|
||||
dialog.ShowCheckBox(_L("Don't show again"));
|
||||
if (dialog.ShowModal() == wxID_OK && dialog.IsCheckBoxChecked())
|
||||
app_config->set(option_key, "1");
|
||||
@@ -7229,7 +7239,11 @@ void Plater::export_gcode(bool prefer_removable)
|
||||
_L("The following characters are not allowed by a FAT file system:") + " <>:/\\|?*\"";
|
||||
return true;
|
||||
}
|
||||
err_out = check_binary_vs_ascii_gcode_extension(printer_technology(), ext, wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("gcode_binary"));
|
||||
if (this->printer_technology() == ptFFF) {
|
||||
bool supports_binary = wxGetApp().preset_bundle->printers.get_edited_preset().config.opt_bool("binary_gcode");
|
||||
bool uses_binary = wxGetApp().app_config->get_bool("use_binary_gcode_when_supported");
|
||||
err_out = check_binary_vs_ascii_gcode_extension(printer_technology(), ext, supports_binary && uses_binary);
|
||||
}
|
||||
return !err_out.IsEmpty();
|
||||
};
|
||||
|
||||
@@ -7237,8 +7251,10 @@ void Plater::export_gcode(bool prefer_removable)
|
||||
if (check_for_error(output_path, error_str)) {
|
||||
ErrorDialog(this, error_str, [this](const std::string& key) -> void { sidebar().jump_to_option(key); }).ShowModal();
|
||||
output_path.clear();
|
||||
} else {
|
||||
alert_when_exporting_binary_gcode(wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("gcode_binary"),
|
||||
} else if (printer_technology() == ptFFF) {
|
||||
bool supports_binary = wxGetApp().preset_bundle->printers.get_edited_preset().config.opt_bool("binary_gcode");
|
||||
bool uses_binary = wxGetApp().app_config->get_bool("use_binary_gcode_when_supported");
|
||||
alert_when_exporting_binary_gcode(supports_binary && uses_binary,
|
||||
wxGetApp().preset_bundle->printers.get_edited_preset().config.opt_string("printer_notes"));
|
||||
}
|
||||
}
|
||||
@@ -7785,18 +7801,21 @@ void Plater::send_gcode()
|
||||
|
||||
PrintHostSendDialog dlg(default_output_file, upload_job.printhost->get_post_upload_actions(), groups, storage_paths, storage_names);
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
{
|
||||
if (printer_technology() == ptFFF) {
|
||||
const std::string ext = boost::algorithm::to_lower_copy(dlg.filename().extension().string());
|
||||
const bool binary_output = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("gcode_binary");
|
||||
const bool binary_output = wxGetApp().preset_bundle->printers.get_edited_preset().config.opt_bool("binary_gcode") &&
|
||||
wxGetApp().app_config->get_bool("use_binary_gcode_when_supported");
|
||||
const wxString error_str = check_binary_vs_ascii_gcode_extension(printer_technology(), ext, binary_output);
|
||||
if (! error_str.IsEmpty()) {
|
||||
ErrorDialog(this, error_str, t_kill_focus([](const std::string& key) -> void { wxGetApp().sidebar().jump_to_option(key); })).ShowModal();
|
||||
return;
|
||||
}
|
||||
bool supports_binary = wxGetApp().preset_bundle->printers.get_edited_preset().config.opt_bool("binary_gcode");
|
||||
bool uses_binary = wxGetApp().app_config->get_bool("use_binary_gcode_when_supported");
|
||||
alert_when_exporting_binary_gcode(supports_binary && uses_binary,
|
||||
wxGetApp().preset_bundle->printers.get_edited_preset().config.opt_string("printer_notes"));
|
||||
}
|
||||
|
||||
alert_when_exporting_binary_gcode(wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("gcode_binary"),
|
||||
wxGetApp().preset_bundle->printers.get_edited_preset().config.opt_string("printer_notes"));
|
||||
upload_job.upload_data.upload_path = dlg.filename();
|
||||
upload_job.upload_data.post_action = dlg.post_action();
|
||||
upload_job.upload_data.group = dlg.group();
|
||||
|
||||
@@ -616,6 +616,10 @@ void PreferencesDialog::build()
|
||||
};
|
||||
|
||||
|
||||
append_bool_option(m_optgroup_other, "use_binary_gcode_when_supported", L("Use binary G-code when the printer supports it"),
|
||||
L("If the 'Supports binary G-code' option is enabled in Printer Settings, "
|
||||
"checking this option will result in the export of G-code in binary format."),
|
||||
app_config->get_bool("use_binary_gcode_when_supported"));
|
||||
append_bool_option(m_optgroup_other, "suppress_hyperlinks",
|
||||
L("Suppress to open hyperlink in browser"),
|
||||
L("If enabled, QIDISlicer will not open a hyperlinks in your browser."),
|
||||
|
||||
@@ -1698,34 +1698,8 @@ void TabPrint::build()
|
||||
Option option = optgroup->get_option("output_filename_format");
|
||||
option.opt.full_width = true;
|
||||
optgroup->append_single_option_line(option);
|
||||
optgroup->append_single_option_line("gcode_binary");
|
||||
|
||||
optgroup->m_on_change = [this](const t_config_option_key& opt_key, boost::any value)
|
||||
{
|
||||
if (opt_key == "gcode_binary") {
|
||||
const bool is_binary = m_config->opt_bool("gcode_binary");
|
||||
std::string output_filename_format = m_config->opt_string("output_filename_format");
|
||||
bool modified = false;
|
||||
if (is_binary && boost::iends_with(output_filename_format, ".gcode")) {
|
||||
output_filename_format = output_filename_format.substr(0, output_filename_format.length() - 5) + "bgcode";
|
||||
modified = true;
|
||||
}
|
||||
else if (!is_binary && boost::iends_with(output_filename_format, ".bgcode")) {
|
||||
output_filename_format = output_filename_format.substr(0, output_filename_format.length() - 6) + "gcode";
|
||||
modified = true;
|
||||
}
|
||||
if (modified) {
|
||||
DynamicPrintConfig new_conf = *m_config;
|
||||
auto off_option = static_cast<ConfigOptionString*>(m_config->option("output_filename_format")->clone());
|
||||
off_option->value = output_filename_format;
|
||||
new_conf.set_key_value("output_filename_format", off_option);
|
||||
load_config(new_conf);
|
||||
}
|
||||
}
|
||||
|
||||
update_dirty();
|
||||
update();
|
||||
};
|
||||
|
||||
optgroup = page->new_optgroup(L("Other"));
|
||||
|
||||
@@ -2752,6 +2726,7 @@ void TabPrinter::build_fff()
|
||||
|
||||
optgroup->append_single_option_line("silent_mode");
|
||||
optgroup->append_single_option_line("remaining_times");
|
||||
optgroup->append_single_option_line("binary_gcode");
|
||||
|
||||
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
|
||||
wxTheApp->CallAfter([this, opt_key, value]() {
|
||||
|
||||
Reference in New Issue
Block a user