mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 00:37:51 -06:00
Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_toolpaths_export
This commit is contained in:
commit
a99a89a831
13 changed files with 225 additions and 214 deletions
|
@ -60,8 +60,21 @@ PrinterTechnology get_printer_technology(const DynamicConfig &config)
|
||||||
|
|
||||||
int CLI::run(int argc, char **argv)
|
int CLI::run(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
// Switch boost::filesystem to utf8.
|
// Switch boost::filesystem to utf8.
|
||||||
boost::nowide::nowide_filesystem();
|
try {
|
||||||
|
boost::nowide::nowide_filesystem();
|
||||||
|
} catch (const std::runtime_error& ex) {
|
||||||
|
std::string caption = std::string(SLIC3R_APP_NAME) + " Error";
|
||||||
|
std::string text = std::string("An error occured while setting up locale.\n") + SLIC3R_APP_NAME + " will now terminate.\n\n" + ex.what();
|
||||||
|
#ifdef SLIC3R_GUI
|
||||||
|
if (m_actions.empty())
|
||||||
|
MessageBoxA(NULL, text.c_str(), caption.c_str(), MB_OK | MB_ICONERROR);
|
||||||
|
#endif
|
||||||
|
boost::nowide::cerr << text.c_str() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (! this->setup(argc, argv))
|
if (! this->setup(argc, argv))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -197,9 +197,6 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
|
||||||
|
|
||||||
std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation);
|
std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation);
|
||||||
|
|
||||||
// Disable linear advance for the wipe tower operations.
|
|
||||||
gcode += (gcodegen.config().gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n"));
|
|
||||||
|
|
||||||
if (!tcr.priming) {
|
if (!tcr.priming) {
|
||||||
// Move over the wipe tower.
|
// Move over the wipe tower.
|
||||||
// Retract for a tool change, using the toolchange retract value and setting the priming extra length.
|
// Retract for a tool change, using the toolchange retract value and setting the priming extra length.
|
||||||
|
|
|
@ -22,6 +22,7 @@ TODO LIST
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
#include "Analyzer.hpp"
|
#include "Analyzer.hpp"
|
||||||
|
#include "BoundingBox.hpp"
|
||||||
|
|
||||||
#if defined(__linux) || defined(__GNUC__ )
|
#if defined(__linux) || defined(__GNUC__ )
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
@ -113,6 +114,11 @@ public:
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WipeTowerWriter& disable_linear_advance() {
|
||||||
|
m_gcode += (m_gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n"));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// Suppress / resume G-code preview in Slic3r. Slic3r will have difficulty to differentiate the various
|
// Suppress / resume G-code preview in Slic3r. Slic3r will have difficulty to differentiate the various
|
||||||
// filament loading and cooling moves from normal extrusion moves. Therefore the writer
|
// filament loading and cooling moves from normal extrusion moves. Therefore the writer
|
||||||
// is asked to suppres output of some lines, which look like extrusions.
|
// is asked to suppres output of some lines, which look like extrusions.
|
||||||
|
@ -470,6 +476,83 @@ private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WipeTower::WipeTower(const PrintConfig& config, const std::vector<std::vector<float>>& wiping_matrix, size_t initial_tool) :
|
||||||
|
m_semm(config.single_extruder_multi_material.value),
|
||||||
|
m_wipe_tower_pos(config.wipe_tower_x, config.wipe_tower_y),
|
||||||
|
m_wipe_tower_width(config.wipe_tower_width),
|
||||||
|
m_wipe_tower_rotation_angle(config.wipe_tower_rotation_angle),
|
||||||
|
m_y_shift(0.f),
|
||||||
|
m_z_pos(0.f),
|
||||||
|
m_is_first_layer(false),
|
||||||
|
m_bridging(config.wipe_tower_bridging),
|
||||||
|
m_gcode_flavor(config.gcode_flavor),
|
||||||
|
m_current_tool(initial_tool),
|
||||||
|
wipe_volumes(wiping_matrix)
|
||||||
|
{
|
||||||
|
// If this is a single extruder MM printer, we will use all the SE-specific config values.
|
||||||
|
// Otherwise, the defaults will be used to turn off the SE stuff.
|
||||||
|
if (m_semm) {
|
||||||
|
m_cooling_tube_retraction = config.cooling_tube_retraction;
|
||||||
|
m_cooling_tube_length = config.cooling_tube_length;
|
||||||
|
m_parking_pos_retraction = config.parking_pos_retraction;
|
||||||
|
m_extra_loading_move = config.extra_loading_move;
|
||||||
|
m_set_extruder_trimpot = config.high_current_on_filament_swap;
|
||||||
|
}
|
||||||
|
// Calculate where the priming lines should be - very naive test not detecting parallelograms or custom shapes
|
||||||
|
const std::vector<Vec2d>& bed_points = config.bed_shape.values;
|
||||||
|
m_bed_shape = (bed_points.size() == 4 ? RectangularBed : CircularBed);
|
||||||
|
m_bed_width = BoundingBoxf(bed_points).size().x();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void WipeTower::set_extruder(size_t idx, const PrintConfig& config)
|
||||||
|
{
|
||||||
|
//while (m_filpar.size() < idx+1) // makes sure the required element is in the vector
|
||||||
|
m_filpar.push_back(FilamentParameters());
|
||||||
|
|
||||||
|
m_filpar[idx].material = config.filament_type.get_at(idx);
|
||||||
|
m_filpar[idx].temperature = config.temperature.get_at(idx);
|
||||||
|
m_filpar[idx].first_layer_temperature = config.first_layer_temperature.get_at(idx);
|
||||||
|
|
||||||
|
// If this is a single extruder MM printer, we will use all the SE-specific config values.
|
||||||
|
// Otherwise, the defaults will be used to turn off the SE stuff.
|
||||||
|
if (m_semm) {
|
||||||
|
m_filpar[idx].loading_speed = config.filament_loading_speed.get_at(idx);
|
||||||
|
m_filpar[idx].loading_speed_start = config.filament_loading_speed_start.get_at(idx);
|
||||||
|
m_filpar[idx].unloading_speed = config.filament_unloading_speed.get_at(idx);
|
||||||
|
m_filpar[idx].unloading_speed_start = config.filament_unloading_speed_start.get_at(idx);
|
||||||
|
m_filpar[idx].delay = config.filament_toolchange_delay.get_at(idx);
|
||||||
|
m_filpar[idx].cooling_moves = config.filament_cooling_moves.get_at(idx);
|
||||||
|
m_filpar[idx].cooling_initial_speed = config.filament_cooling_initial_speed.get_at(idx);
|
||||||
|
m_filpar[idx].cooling_final_speed = config.filament_cooling_final_speed.get_at(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_filpar[idx].filament_area = float((M_PI/4.f) * pow(config.filament_diameter.get_at(idx), 2)); // all extruders are assumed to have the same filament diameter at this point
|
||||||
|
float nozzle_diameter = config.nozzle_diameter.get_at(idx);
|
||||||
|
m_filpar[idx].nozzle_diameter = nozzle_diameter; // to be used in future with (non-single) multiextruder MM
|
||||||
|
|
||||||
|
float max_vol_speed = config.filament_max_volumetric_speed.get_at(idx);
|
||||||
|
if (max_vol_speed!= 0.f)
|
||||||
|
m_filpar[idx].max_e_speed = (max_vol_speed / filament_area());
|
||||||
|
|
||||||
|
m_perimeter_width = nozzle_diameter * Width_To_Nozzle_Ratio; // all extruders are now assumed to have the same diameter
|
||||||
|
|
||||||
|
if (m_semm) {
|
||||||
|
std::istringstream stream{config.filament_ramming_parameters.get_at(idx)};
|
||||||
|
float speed = 0.f;
|
||||||
|
stream >> m_filpar[idx].ramming_line_width_multiplicator >> m_filpar[idx].ramming_step_multiplicator;
|
||||||
|
m_filpar[idx].ramming_line_width_multiplicator /= 100;
|
||||||
|
m_filpar[idx].ramming_step_multiplicator /= 100;
|
||||||
|
while (stream >> speed)
|
||||||
|
m_filpar[idx].ramming_speed.push_back(speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_used_filament_length.resize(std::max(m_used_filament_length.size(), idx + 1)); // makes sure that the vector is big enough so we don't have to check later
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Returns gcode to prime the nozzles at the front edge of the print bed.
|
// Returns gcode to prime the nozzles at the front edge of the print bed.
|
||||||
std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
|
std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
|
||||||
// print_z of the first layer.
|
// print_z of the first layer.
|
||||||
|
@ -488,9 +571,11 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
|
||||||
// therefore the homing position is shifted inside the bed by 0.2 in the firmware to [0.2, -2.0].
|
// therefore the homing position is shifted inside the bed by 0.2 in the firmware to [0.2, -2.0].
|
||||||
// box_coordinates cleaning_box(xy(0.5f, - 1.5f), m_wipe_tower_width, wipe_area);
|
// box_coordinates cleaning_box(xy(0.5f, - 1.5f), m_wipe_tower_width, wipe_area);
|
||||||
|
|
||||||
const float prime_section_width = std::min(240.f / tools.size(), 60.f);
|
float prime_section_width = std::min(0.9f * m_bed_width / tools.size(), 60.f);
|
||||||
box_coordinates cleaning_box(Vec2f(5.f, 0.01f + m_perimeter_width/2.f), prime_section_width, 100.f);
|
box_coordinates cleaning_box(Vec2f(0.02f * m_bed_width, 0.01f + m_perimeter_width/2.f), prime_section_width, 100.f);
|
||||||
|
// In case of a circular bed, place it so it goes across the diameter and hope it will fit
|
||||||
|
if (m_bed_shape == CircularBed)
|
||||||
|
cleaning_box.translate(-m_bed_width/2 + m_bed_width * 0.03f, -m_bed_width * 0.12f);
|
||||||
|
|
||||||
std::vector<ToolChangeResult> results;
|
std::vector<ToolChangeResult> results;
|
||||||
|
|
||||||
|
@ -818,6 +903,8 @@ void WipeTower::toolchange_Unload(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writer.disable_linear_advance();
|
||||||
|
|
||||||
// now the ramming itself:
|
// now the ramming itself:
|
||||||
while (i < m_filpar[m_current_tool].ramming_speed.size())
|
while (i < m_filpar[m_current_tool].ramming_speed.size())
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,83 +78,12 @@ public:
|
||||||
// y -- y coordinates of wipe tower in mm ( left bottom corner )
|
// y -- y coordinates of wipe tower in mm ( left bottom corner )
|
||||||
// width -- width of wipe tower in mm ( default 60 mm - leave as it is )
|
// width -- width of wipe tower in mm ( default 60 mm - leave as it is )
|
||||||
// wipe_area -- space available for one toolchange in mm
|
// wipe_area -- space available for one toolchange in mm
|
||||||
WipeTower(bool semm, float x, float y, float width, float rotation_angle, float cooling_tube_retraction,
|
WipeTower(const PrintConfig& config, const std::vector<std::vector<float>>& wiping_matrix, size_t initial_tool);
|
||||||
float cooling_tube_length, float parking_pos_retraction, float extra_loading_move,
|
|
||||||
float bridging, bool set_extruder_trimpot, GCodeFlavor flavor,
|
|
||||||
const std::vector<std::vector<float>>& wiping_matrix, unsigned int initial_tool) :
|
|
||||||
m_semm(semm),
|
|
||||||
m_wipe_tower_pos(x, y),
|
|
||||||
m_wipe_tower_width(width),
|
|
||||||
m_wipe_tower_rotation_angle(rotation_angle),
|
|
||||||
m_y_shift(0.f),
|
|
||||||
m_z_pos(0.f),
|
|
||||||
m_is_first_layer(false),
|
|
||||||
m_gcode_flavor(flavor),
|
|
||||||
m_bridging(bridging),
|
|
||||||
m_current_tool(initial_tool),
|
|
||||||
wipe_volumes(wiping_matrix)
|
|
||||||
{
|
|
||||||
// If this is a single extruder MM printer, we will use all the SE-specific config values.
|
|
||||||
// Otherwise, the defaults will be used to turn off the SE stuff.
|
|
||||||
if (m_semm) {
|
|
||||||
m_cooling_tube_retraction = cooling_tube_retraction;
|
|
||||||
m_cooling_tube_length = cooling_tube_length;
|
|
||||||
m_parking_pos_retraction = parking_pos_retraction;
|
|
||||||
m_extra_loading_move = extra_loading_move;
|
|
||||||
m_set_extruder_trimpot = set_extruder_trimpot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~WipeTower() {}
|
virtual ~WipeTower() {}
|
||||||
|
|
||||||
|
|
||||||
// Set the extruder properties.
|
// Set the extruder properties.
|
||||||
void set_extruder(size_t idx, std::string material, int temp, int first_layer_temp, float loading_speed, float loading_speed_start,
|
void set_extruder(size_t idx, const PrintConfig& config);
|
||||||
float unloading_speed, float unloading_speed_start, float delay, int cooling_moves,
|
|
||||||
float cooling_initial_speed, float cooling_final_speed, std::string ramming_parameters, float max_volumetric_speed,
|
|
||||||
float nozzle_diameter, float filament_diameter)
|
|
||||||
{
|
|
||||||
//while (m_filpar.size() < idx+1) // makes sure the required element is in the vector
|
|
||||||
m_filpar.push_back(FilamentParameters());
|
|
||||||
|
|
||||||
m_filpar[idx].material = material;
|
|
||||||
m_filpar[idx].temperature = temp;
|
|
||||||
m_filpar[idx].first_layer_temperature = first_layer_temp;
|
|
||||||
|
|
||||||
// If this is a single extruder MM printer, we will use all the SE-specific config values.
|
|
||||||
// Otherwise, the defaults will be used to turn off the SE stuff.
|
|
||||||
if (m_semm) {
|
|
||||||
m_filpar[idx].loading_speed = loading_speed;
|
|
||||||
m_filpar[idx].loading_speed_start = loading_speed_start;
|
|
||||||
m_filpar[idx].unloading_speed = unloading_speed;
|
|
||||||
m_filpar[idx].unloading_speed_start = unloading_speed_start;
|
|
||||||
m_filpar[idx].delay = delay;
|
|
||||||
m_filpar[idx].cooling_moves = cooling_moves;
|
|
||||||
m_filpar[idx].cooling_initial_speed = cooling_initial_speed;
|
|
||||||
m_filpar[idx].cooling_final_speed = cooling_final_speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_filpar[idx].filament_area = float((M_PI/4.f) * pow(filament_diameter, 2)); // all extruders are assumed to have the same filament diameter at this point
|
|
||||||
m_filpar[idx].nozzle_diameter = nozzle_diameter; // to be used in future with (non-single) multiextruder MM
|
|
||||||
|
|
||||||
if (max_volumetric_speed != 0.f)
|
|
||||||
m_filpar[idx].max_e_speed = (max_volumetric_speed / filament_area());
|
|
||||||
|
|
||||||
m_perimeter_width = nozzle_diameter * Width_To_Nozzle_Ratio; // all extruders are now assumed to have the same diameter
|
|
||||||
|
|
||||||
if (m_semm) {
|
|
||||||
std::stringstream stream{ramming_parameters};
|
|
||||||
float speed = 0.f;
|
|
||||||
stream >> m_filpar[idx].ramming_line_width_multiplicator >> m_filpar[idx].ramming_step_multiplicator;
|
|
||||||
m_filpar[idx].ramming_line_width_multiplicator /= 100;
|
|
||||||
m_filpar[idx].ramming_step_multiplicator /= 100;
|
|
||||||
while (stream >> speed)
|
|
||||||
m_filpar[idx].ramming_speed.push_back(speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_used_filament_length.resize(std::max(m_used_filament_length.size(), idx + 1)); // makes sure that the vector is big enough so we don't have to check later
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Appends into internal structure m_plan containing info about the future wipe tower
|
// Appends into internal structure m_plan containing info about the future wipe tower
|
||||||
// to be used before building begins. The entries must be added ordered in z.
|
// to be used before building begins. The entries must be added ordered in z.
|
||||||
|
@ -263,7 +192,6 @@ private:
|
||||||
SHAPE_REVERSED = -1
|
SHAPE_REVERSED = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const bool m_peters_wipe_tower = false; // sparse wipe tower inspired by Peter's post processor - not finished yet
|
const bool m_peters_wipe_tower = false; // sparse wipe tower inspired by Peter's post processor - not finished yet
|
||||||
const float Width_To_Nozzle_Ratio = 1.25f; // desired line width (oval) in multiples of nozzle diameter - may not be actually neccessary to adjust
|
const float Width_To_Nozzle_Ratio = 1.25f; // desired line width (oval) in multiples of nozzle diameter - may not be actually neccessary to adjust
|
||||||
const float WT_EPSILON = 1e-3f;
|
const float WT_EPSILON = 1e-3f;
|
||||||
|
@ -295,6 +223,13 @@ private:
|
||||||
bool m_adhesion = true;
|
bool m_adhesion = true;
|
||||||
GCodeFlavor m_gcode_flavor;
|
GCodeFlavor m_gcode_flavor;
|
||||||
|
|
||||||
|
// Bed properties
|
||||||
|
enum {
|
||||||
|
RectangularBed,
|
||||||
|
CircularBed
|
||||||
|
} m_bed_shape;
|
||||||
|
float m_bed_width; // width of the bed bounding box
|
||||||
|
|
||||||
float m_perimeter_width = 0.4f * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill.
|
float m_perimeter_width = 0.4f * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill.
|
||||||
float m_extrusion_flow = 0.038f; //0.029f;// Extrusion flow is derived from m_perimeter_width, layer height and filament diameter.
|
float m_extrusion_flow = 0.038f; //0.029f;// Extrusion flow is derived from m_perimeter_width, layer height and filament diameter.
|
||||||
|
|
||||||
|
|
|
@ -1762,15 +1762,7 @@ void Print::_make_wipe_tower()
|
||||||
this->throw_if_canceled();
|
this->throw_if_canceled();
|
||||||
|
|
||||||
// Initialize the wipe tower.
|
// Initialize the wipe tower.
|
||||||
WipeTower wipe_tower(
|
WipeTower wipe_tower(m_config, wipe_volumes, m_wipe_tower_data.tool_ordering.first_extruder());
|
||||||
m_config.single_extruder_multi_material.value,
|
|
||||||
float(m_config.wipe_tower_x.value), float(m_config.wipe_tower_y.value),
|
|
||||||
float(m_config.wipe_tower_width.value),
|
|
||||||
float(m_config.wipe_tower_rotation_angle.value), float(m_config.cooling_tube_retraction.value),
|
|
||||||
float(m_config.cooling_tube_length.value), float(m_config.parking_pos_retraction.value),
|
|
||||||
float(m_config.extra_loading_move.value), float(m_config.wipe_tower_bridging),
|
|
||||||
m_config.high_current_on_filament_swap.value, m_config.gcode_flavor, wipe_volumes,
|
|
||||||
m_wipe_tower_data.tool_ordering.first_extruder());
|
|
||||||
|
|
||||||
//wipe_tower.set_retract();
|
//wipe_tower.set_retract();
|
||||||
//wipe_tower.set_zhop();
|
//wipe_tower.set_zhop();
|
||||||
|
@ -1779,22 +1771,7 @@ void Print::_make_wipe_tower()
|
||||||
for (size_t i = 0; i < number_of_extruders; ++ i)
|
for (size_t i = 0; i < number_of_extruders; ++ i)
|
||||||
|
|
||||||
wipe_tower.set_extruder(
|
wipe_tower.set_extruder(
|
||||||
i,
|
i, m_config);
|
||||||
m_config.filament_type.get_at(i),
|
|
||||||
m_config.temperature.get_at(i),
|
|
||||||
m_config.first_layer_temperature.get_at(i),
|
|
||||||
(float)m_config.filament_loading_speed.get_at(i),
|
|
||||||
(float)m_config.filament_loading_speed_start.get_at(i),
|
|
||||||
(float)m_config.filament_unloading_speed.get_at(i),
|
|
||||||
(float)m_config.filament_unloading_speed_start.get_at(i),
|
|
||||||
(float)m_config.filament_toolchange_delay.get_at(i),
|
|
||||||
m_config.filament_cooling_moves.get_at(i),
|
|
||||||
(float)m_config.filament_cooling_initial_speed.get_at(i),
|
|
||||||
(float)m_config.filament_cooling_final_speed.get_at(i),
|
|
||||||
m_config.filament_ramming_parameters.get_at(i),
|
|
||||||
(float)m_config.filament_max_volumetric_speed.get_at(i),
|
|
||||||
(float)m_config.nozzle_diameter.get_at(i),
|
|
||||||
(float)m_config.filament_diameter.get_at(i));
|
|
||||||
|
|
||||||
m_wipe_tower_data.priming = Slic3r::make_unique<std::vector<WipeTower::ToolChangeResult>>(
|
m_wipe_tower_data.priming = Slic3r::make_unique<std::vector<WipeTower::ToolChangeResult>>(
|
||||||
wipe_tower.prime((float)this->skirt_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), false));
|
wipe_tower.prime((float)this->skirt_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), false));
|
||||||
|
|
|
@ -2379,7 +2379,7 @@ void PrintObject::discover_horizontal_shells()
|
||||||
if (new_internal_solid.empty()) {
|
if (new_internal_solid.empty()) {
|
||||||
// No internal solid needed on this layer. In order to decide whether to continue
|
// No internal solid needed on this layer. In order to decide whether to continue
|
||||||
// searching on the next neighbor (thus enforcing the configured number of solid
|
// searching on the next neighbor (thus enforcing the configured number of solid
|
||||||
// layers, use different strategies according to configured infill density:
|
// layers, use different strategies according to configured infill density:
|
||||||
if (region_config.fill_density.value == 0) {
|
if (region_config.fill_density.value == 0) {
|
||||||
// If user expects the object to be void (for example a hollow sloping vase),
|
// If user expects the object to be void (for example a hollow sloping vase),
|
||||||
// don't continue the search. In this case, we only generate the external solid
|
// don't continue the search. In this case, we only generate the external solid
|
||||||
|
|
|
@ -15,9 +15,13 @@
|
||||||
#include <boost/nowide/fstream.hpp>
|
#include <boost/nowide/fstream.hpp>
|
||||||
#include <boost/property_tree/ini_parser.hpp>
|
#include <boost/property_tree/ini_parser.hpp>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
#include <boost/property_tree/exceptions.hpp>
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
|
#include <wx/string.h>
|
||||||
|
#include "I18N.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
static const std::string VENDOR_PREFIX = "vendor:";
|
static const std::string VENDOR_PREFIX = "vendor:";
|
||||||
|
@ -58,7 +62,7 @@ void AppConfig::set_defaults()
|
||||||
if (!get("use_legacy_opengl").empty())
|
if (!get("use_legacy_opengl").empty())
|
||||||
erase("", "use_legacy_opengl");
|
erase("", "use_legacy_opengl");
|
||||||
|
|
||||||
#if __APPLE__
|
#ifdef __APPLE__
|
||||||
if (get("use_retina_opengl").empty())
|
if (get("use_retina_opengl").empty())
|
||||||
set("use_retina_opengl", "1");
|
set("use_retina_opengl", "1");
|
||||||
#endif
|
#endif
|
||||||
|
@ -90,7 +94,14 @@ void AppConfig::load()
|
||||||
namespace pt = boost::property_tree;
|
namespace pt = boost::property_tree;
|
||||||
pt::ptree tree;
|
pt::ptree tree;
|
||||||
boost::nowide::ifstream ifs(AppConfig::config_path());
|
boost::nowide::ifstream ifs(AppConfig::config_path());
|
||||||
pt::read_ini(ifs, tree);
|
try {
|
||||||
|
pt::read_ini(ifs, tree);
|
||||||
|
} catch (pt::ptree_error& ex) {
|
||||||
|
// Error while parsing config file. We'll customize the error message and rethrow to be displayed.
|
||||||
|
throw std::runtime_error(wxString::Format(_(L("Error parsing config file, it is probably corrupted. "
|
||||||
|
"Try to manualy delete the file. Your user profiles will not be affected.\n\n%s\n\n%s")),
|
||||||
|
AppConfig::config_path(), ex.what()).ToStdString());
|
||||||
|
}
|
||||||
|
|
||||||
// 2) Parse the property_tree, extract the sections and key / value pairs.
|
// 2) Parse the property_tree, extract the sections and key / value pairs.
|
||||||
for (const auto §ion : tree) {
|
for (const auto §ion : tree) {
|
||||||
|
|
|
@ -151,7 +151,12 @@ void BackgroundSlicingProcess::thread_proc()
|
||||||
} catch (CanceledException & /* ex */) {
|
} catch (CanceledException & /* ex */) {
|
||||||
// Canceled, this is all right.
|
// Canceled, this is all right.
|
||||||
assert(m_print->canceled());
|
assert(m_print->canceled());
|
||||||
} catch (std::exception &ex) {
|
} catch (const std::bad_alloc& ex) {
|
||||||
|
wxString errmsg = wxString::Format(_(L("%s has encountered an error. It was likely caused by running out of memory. "
|
||||||
|
"If you are sure you have enough RAM on your system, this may also be a bug and we would "
|
||||||
|
"be glad if you reported it.")), SLIC3R_APP_NAME);
|
||||||
|
error = errmsg.ToStdString() + "\n\n" + std::string(ex.what());
|
||||||
|
} catch (std::exception &ex) {
|
||||||
error = ex.what();
|
error = ex.what();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
error = "Unknown C++ exception.";
|
error = "Unknown C++ exception.";
|
||||||
|
|
|
@ -206,8 +206,8 @@ void Field::get_value_by_opt_type(wxString& str)
|
||||||
const wxString msg_text = wxString::Format(_(L("Do you mean %s%% instead of %s %s?\n"
|
const wxString msg_text = wxString::Format(_(L("Do you mean %s%% instead of %s %s?\n"
|
||||||
"Select YES if you want to change this value to %s%%, \n"
|
"Select YES if you want to change this value to %s%%, \n"
|
||||||
"or NO if you are sure that %s %s is a correct value.")), stVal, stVal, sidetext, stVal, stVal, sidetext);
|
"or NO if you are sure that %s %s is a correct value.")), stVal, stVal, sidetext, stVal, stVal, sidetext);
|
||||||
auto dialog = new wxMessageDialog(m_parent, msg_text, _(L("Parameter validation")), wxICON_WARNING | wxYES | wxNO);
|
wxMessageDialog dialog(m_parent, msg_text, _(L("Parameter validation")), wxICON_WARNING | wxYES | wxNO);
|
||||||
if (dialog->ShowModal() == wxID_YES) {
|
if (dialog.ShowModal() == wxID_YES) {
|
||||||
set_value(wxString::Format("%s%%", stVal), false/*true*/);
|
set_value(wxString::Format("%s%%", stVal), false/*true*/);
|
||||||
str += "%%";
|
str += "%%";
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,16 @@ static void generic_exception_handle()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
throw;
|
throw;
|
||||||
} catch (const std::exception &ex) {
|
} catch (const std::bad_alloc& ex) {
|
||||||
|
// bad_alloc in main thread is most likely fatal. Report immediately to the user (wxLogError would be delayed)
|
||||||
|
// and terminate the app so it is at least certain to happen now.
|
||||||
|
wxString errmsg = wxString::Format(_(L("%s has encountered an error. It was likely caused by running out of memory. "
|
||||||
|
"If you are sure you have enough RAM on your system, this may also be a bug and we would "
|
||||||
|
"be glad if you reported it.\n\nThe application will now terminate.")), SLIC3R_APP_NAME);
|
||||||
|
wxMessageBox(errmsg + "\n\n" + wxString(ex.what()), _(L("Fatal error")), wxOK | wxICON_ERROR);
|
||||||
|
BOOST_LOG_TRIVIAL(error) << boost::format("std::bad_alloc exception: %1%") % ex.what();
|
||||||
|
std::terminate();
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
wxLogError("Internal error: %s", ex.what());
|
wxLogError("Internal error: %s", ex.what());
|
||||||
BOOST_LOG_TRIVIAL(error) << boost::format("Uncaught exception: %1%") % ex.what();
|
BOOST_LOG_TRIVIAL(error) << boost::format("Uncaught exception: %1%") % ex.what();
|
||||||
throw;
|
throw;
|
||||||
|
|
|
@ -738,29 +738,26 @@ void MainFrame::quick_slice(const int qs)
|
||||||
|
|
||||||
// select input file
|
// select input file
|
||||||
if (!(qs & qsReslice)) {
|
if (!(qs & qsReslice)) {
|
||||||
auto dlg = new wxFileDialog(this, _(L("Choose a file to slice (STL/OBJ/AMF/3MF/PRUSA):")),
|
wxFileDialog dlg(this, _(L("Choose a file to slice (STL/OBJ/AMF/3MF/PRUSA):")),
|
||||||
wxGetApp().app_config->get_last_dir(), "",
|
wxGetApp().app_config->get_last_dir(), "",
|
||||||
file_wildcards(FT_MODEL), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
file_wildcards(FT_MODEL), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||||
if (dlg->ShowModal() != wxID_OK) {
|
if (dlg.ShowModal() != wxID_OK)
|
||||||
dlg->Destroy();
|
|
||||||
return;
|
return;
|
||||||
}
|
input_file = dlg.GetPath();
|
||||||
input_file = dlg->GetPath();
|
|
||||||
dlg->Destroy();
|
|
||||||
if (!(qs & qsExportSVG))
|
if (!(qs & qsExportSVG))
|
||||||
m_qs_last_input_file = input_file;
|
m_qs_last_input_file = input_file;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (m_qs_last_input_file.IsEmpty()) {
|
if (m_qs_last_input_file.IsEmpty()) {
|
||||||
auto dlg = new wxMessageDialog(this, _(L("No previously sliced file.")),
|
wxMessageDialog dlg(this, _(L("No previously sliced file.")),
|
||||||
_(L("Error")), wxICON_ERROR | wxOK);
|
_(L("Error")), wxICON_ERROR | wxOK);
|
||||||
dlg->ShowModal();
|
dlg.ShowModal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (std::ifstream(m_qs_last_input_file.ToUTF8().data())) {
|
if (std::ifstream(m_qs_last_input_file.ToUTF8().data())) {
|
||||||
auto dlg = new wxMessageDialog(this, _(L("Previously sliced file ("))+m_qs_last_input_file+_(L(") not found.")),
|
wxMessageDialog dlg(this, _(L("Previously sliced file ("))+m_qs_last_input_file+_(L(") not found.")),
|
||||||
_(L("File Not Found")), wxICON_ERROR | wxOK);
|
_(L("File Not Found")), wxICON_ERROR | wxOK);
|
||||||
dlg->ShowModal();
|
dlg.ShowModal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
input_file = m_qs_last_input_file;
|
input_file = m_qs_last_input_file;
|
||||||
|
@ -794,30 +791,24 @@ void MainFrame::quick_slice(const int qs)
|
||||||
}
|
}
|
||||||
else if (qs & qsSaveAs) {
|
else if (qs & qsSaveAs) {
|
||||||
// The following line may die if the output_filename_format template substitution fails.
|
// The following line may die if the output_filename_format template substitution fails.
|
||||||
auto dlg = new wxFileDialog(this, wxString::Format(_(L("Save %s file as:")) , qs & qsExportSVG ? _(L("SVG")) : _(L("G-code")) ),
|
wxFileDialog dlg(this, wxString::Format(_(L("Save %s file as:")) , qs & qsExportSVG ? _(L("SVG")) : _(L("G-code")) ),
|
||||||
wxGetApp().app_config->get_last_output_dir(get_dir_name(output_file)), get_base_name(input_file),
|
wxGetApp().app_config->get_last_output_dir(get_dir_name(output_file)), get_base_name(input_file),
|
||||||
qs & qsExportSVG ? file_wildcards(FT_SVG) : file_wildcards(FT_GCODE),
|
qs & qsExportSVG ? file_wildcards(FT_SVG) : file_wildcards(FT_GCODE),
|
||||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
||||||
if (dlg->ShowModal() != wxID_OK) {
|
if (dlg.ShowModal() != wxID_OK)
|
||||||
dlg->Destroy();
|
|
||||||
return;
|
return;
|
||||||
}
|
output_file = dlg.GetPath();
|
||||||
output_file = dlg->GetPath();
|
|
||||||
dlg->Destroy();
|
|
||||||
if (!(qs & qsExportSVG))
|
if (!(qs & qsExportSVG))
|
||||||
m_qs_last_output_file = output_file;
|
m_qs_last_output_file = output_file;
|
||||||
wxGetApp().app_config->update_last_output_dir(get_dir_name(output_file));
|
wxGetApp().app_config->update_last_output_dir(get_dir_name(output_file));
|
||||||
}
|
}
|
||||||
else if (qs & qsExportPNG) {
|
else if (qs & qsExportPNG) {
|
||||||
auto dlg = new wxFileDialog(this, _(L("Save zip file as:")),
|
wxFileDialog dlg(this, _(L("Save zip file as:")),
|
||||||
wxGetApp().app_config->get_last_output_dir(get_dir_name(output_file)),
|
wxGetApp().app_config->get_last_output_dir(get_dir_name(output_file)),
|
||||||
get_base_name(output_file), "*.sl1", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
get_base_name(output_file), "*.sl1", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
||||||
if (dlg->ShowModal() != wxID_OK) {
|
if (dlg.ShowModal() != wxID_OK)
|
||||||
dlg->Destroy();
|
|
||||||
return;
|
return;
|
||||||
}
|
output_file = dlg.GetPath();
|
||||||
output_file = dlg->GetPath();
|
|
||||||
dlg->Destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// show processbar dialog
|
// show processbar dialog
|
||||||
|
@ -863,28 +854,22 @@ void MainFrame::repair_stl()
|
||||||
{
|
{
|
||||||
wxString input_file;
|
wxString input_file;
|
||||||
{
|
{
|
||||||
auto dlg = new wxFileDialog(this, _(L("Select the STL file to repair:")),
|
wxFileDialog dlg(this, _(L("Select the STL file to repair:")),
|
||||||
wxGetApp().app_config->get_last_dir(), "",
|
wxGetApp().app_config->get_last_dir(), "",
|
||||||
file_wildcards(FT_STL), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
file_wildcards(FT_STL), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||||
if (dlg->ShowModal() != wxID_OK) {
|
if (dlg.ShowModal() != wxID_OK)
|
||||||
dlg->Destroy();
|
|
||||||
return;
|
return;
|
||||||
}
|
input_file = dlg.GetPath();
|
||||||
input_file = dlg->GetPath();
|
|
||||||
dlg->Destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString output_file = input_file;
|
wxString output_file = input_file;
|
||||||
{
|
{
|
||||||
auto dlg = new wxFileDialog( this, L("Save OBJ file (less prone to coordinate errors than STL) as:"),
|
wxFileDialog dlg( this, L("Save OBJ file (less prone to coordinate errors than STL) as:"),
|
||||||
get_dir_name(output_file), get_base_name(output_file, ".obj"),
|
get_dir_name(output_file), get_base_name(output_file, ".obj"),
|
||||||
file_wildcards(FT_OBJ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
file_wildcards(FT_OBJ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
||||||
if (dlg->ShowModal() != wxID_OK) {
|
if (dlg.ShowModal() != wxID_OK)
|
||||||
dlg->Destroy();
|
|
||||||
return;
|
return;
|
||||||
}
|
output_file = dlg.GetPath();
|
||||||
output_file = dlg->GetPath();
|
|
||||||
dlg->Destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tmesh = new Slic3r::TriangleMesh();
|
auto tmesh = new Slic3r::TriangleMesh();
|
||||||
|
@ -905,14 +890,13 @@ void MainFrame::export_config()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Ask user for the file name for the config file.
|
// Ask user for the file name for the config file.
|
||||||
auto dlg = new wxFileDialog(this, _(L("Save configuration as:")),
|
wxFileDialog dlg(this, _(L("Save configuration as:")),
|
||||||
!m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
|
!m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
|
||||||
!m_last_config.IsEmpty() ? get_base_name(m_last_config) : "config.ini",
|
!m_last_config.IsEmpty() ? get_base_name(m_last_config) : "config.ini",
|
||||||
file_wildcards(FT_INI), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
file_wildcards(FT_INI), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
||||||
wxString file;
|
wxString file;
|
||||||
if (dlg->ShowModal() == wxID_OK)
|
if (dlg.ShowModal() == wxID_OK)
|
||||||
file = dlg->GetPath();
|
file = dlg.GetPath();
|
||||||
dlg->Destroy();
|
|
||||||
if (!file.IsEmpty()) {
|
if (!file.IsEmpty()) {
|
||||||
wxGetApp().app_config->update_config_dir(get_dir_name(file));
|
wxGetApp().app_config->update_config_dir(get_dir_name(file));
|
||||||
m_last_config = file;
|
m_last_config = file;
|
||||||
|
@ -925,13 +909,12 @@ void MainFrame::load_config_file()
|
||||||
{
|
{
|
||||||
if (!wxGetApp().check_unsaved_changes())
|
if (!wxGetApp().check_unsaved_changes())
|
||||||
return;
|
return;
|
||||||
auto dlg = new wxFileDialog(this, _(L("Select configuration to load:")),
|
wxFileDialog dlg(this, _(L("Select configuration to load:")),
|
||||||
!m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
|
!m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
|
||||||
"config.ini", "INI files (*.ini, *.gcode)|*.ini;*.INI;*.gcode;*.g", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
"config.ini", "INI files (*.ini, *.gcode)|*.ini;*.INI;*.gcode;*.g", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||||
wxString file;
|
wxString file;
|
||||||
if (dlg->ShowModal() == wxID_OK)
|
if (dlg.ShowModal() == wxID_OK)
|
||||||
file = dlg->GetPath();
|
file = dlg.GetPath();
|
||||||
dlg->Destroy();
|
|
||||||
if (! file.IsEmpty() && this->load_config_file(file.ToUTF8().data())) {
|
if (! file.IsEmpty() && this->load_config_file(file.ToUTF8().data())) {
|
||||||
wxGetApp().app_config->update_config_dir(get_dir_name(file));
|
wxGetApp().app_config->update_config_dir(get_dir_name(file));
|
||||||
m_last_config = file;
|
m_last_config = file;
|
||||||
|
@ -962,14 +945,13 @@ void MainFrame::export_configbundle()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Ask user for a file name.
|
// Ask user for a file name.
|
||||||
auto dlg = new wxFileDialog(this, _(L("Save presets bundle as:")),
|
wxFileDialog dlg(this, _(L("Save presets bundle as:")),
|
||||||
!m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
|
!m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
|
||||||
SLIC3R_APP_KEY "_config_bundle.ini",
|
SLIC3R_APP_KEY "_config_bundle.ini",
|
||||||
file_wildcards(FT_INI), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
file_wildcards(FT_INI), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
||||||
wxString file;
|
wxString file;
|
||||||
if (dlg->ShowModal() == wxID_OK)
|
if (dlg.ShowModal() == wxID_OK)
|
||||||
file = dlg->GetPath();
|
file = dlg.GetPath();
|
||||||
dlg->Destroy();
|
|
||||||
if (!file.IsEmpty()) {
|
if (!file.IsEmpty()) {
|
||||||
// Export the config bundle.
|
// Export the config bundle.
|
||||||
wxGetApp().app_config->update_config_dir(get_dir_name(file));
|
wxGetApp().app_config->update_config_dir(get_dir_name(file));
|
||||||
|
@ -989,15 +971,12 @@ void MainFrame::load_configbundle(wxString file/* = wxEmptyString, const bool re
|
||||||
if (!wxGetApp().check_unsaved_changes())
|
if (!wxGetApp().check_unsaved_changes())
|
||||||
return;
|
return;
|
||||||
if (file.IsEmpty()) {
|
if (file.IsEmpty()) {
|
||||||
auto dlg = new wxFileDialog(this, _(L("Select configuration to load:")),
|
wxFileDialog dlg(this, _(L("Select configuration to load:")),
|
||||||
!m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
|
!m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(),
|
||||||
"config.ini", file_wildcards(FT_INI), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
"config.ini", file_wildcards(FT_INI), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||||
if (dlg->ShowModal() != wxID_OK) {
|
if (dlg.ShowModal() != wxID_OK)
|
||||||
dlg->Destroy();
|
return;
|
||||||
return;
|
file = dlg.GetPath();
|
||||||
}
|
|
||||||
file = dlg->GetPath();
|
|
||||||
dlg->Destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxGetApp().app_config->update_config_dir(get_dir_name(file));
|
wxGetApp().app_config->update_config_dir(get_dir_name(file));
|
||||||
|
|
|
@ -296,11 +296,11 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 *
|
||||||
data->SetChooseFull(1);
|
data->SetChooseFull(1);
|
||||||
data->SetColour(clr);
|
data->SetColour(clr);
|
||||||
|
|
||||||
auto dialog = new wxColourDialog(this, data);
|
wxColourDialog dialog(this, data);
|
||||||
dialog->CenterOnParent();
|
dialog.CenterOnParent();
|
||||||
if (dialog->ShowModal() == wxID_OK)
|
if (dialog.ShowModal() == wxID_OK)
|
||||||
{
|
{
|
||||||
colors->values[extruder_idx] = dialog->GetColourData().GetColour().GetAsString(wxC2S_HTML_SYNTAX);
|
colors->values[extruder_idx] = dialog.GetColourData().GetColour().GetAsString(wxC2S_HTML_SYNTAX);
|
||||||
|
|
||||||
DynamicPrintConfig cfg_new = *cfg;
|
DynamicPrintConfig cfg_new = *cfg;
|
||||||
cfg_new.set_key_value("extruder_colour", colors);
|
cfg_new.set_key_value("extruder_colour", colors);
|
||||||
|
@ -309,7 +309,6 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 *
|
||||||
wxGetApp().preset_bundle->update_platter_filament_ui(extruder_idx, this);
|
wxGetApp().preset_bundle->update_platter_filament_ui(extruder_idx, this);
|
||||||
wxGetApp().plater()->on_config_change(cfg_new);
|
wxGetApp().plater()->on_config_change(cfg_new);
|
||||||
}
|
}
|
||||||
dialog->Destroy();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2523,15 +2522,14 @@ wxString Plater::priv::get_export_file(GUI::FileType file_type)
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxFileDialog* dlg = new wxFileDialog(q, dlg_title,
|
wxFileDialog dlg(q, dlg_title,
|
||||||
from_path(output_file.parent_path()), from_path(output_file.filename()),
|
from_path(output_file.parent_path()), from_path(output_file.filename()),
|
||||||
wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
||||||
|
|
||||||
if (dlg->ShowModal() != wxID_OK) {
|
if (dlg.ShowModal() != wxID_OK)
|
||||||
return wxEmptyString;
|
return wxEmptyString;
|
||||||
}
|
|
||||||
|
|
||||||
wxString out_path = dlg->GetPath();
|
wxString out_path = dlg.GetPath();
|
||||||
fs::path path(into_path(out_path));
|
fs::path path(into_path(out_path));
|
||||||
wxGetApp().app_config->update_last_output_dir(path.parent_path().string());
|
wxGetApp().app_config->update_last_output_dir(path.parent_path().string());
|
||||||
|
|
||||||
|
|
|
@ -159,8 +159,8 @@ void Tab::create_preset_tab()
|
||||||
m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(true); }));
|
m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_roll_back_value(true); }));
|
||||||
m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent)
|
m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent)
|
||||||
{
|
{
|
||||||
auto dlg = new ButtonsDescription(this, m_icon_descriptions);
|
ButtonsDescription dlg(this, m_icon_descriptions);
|
||||||
if (dlg->ShowModal() == wxID_OK) {
|
if (dlg.ShowModal() == wxID_OK) {
|
||||||
// Colors for ui "decoration"
|
// Colors for ui "decoration"
|
||||||
for (Tab *tab : wxGetApp().tabs_list) {
|
for (Tab *tab : wxGetApp().tabs_list) {
|
||||||
tab->m_sys_label_clr = wxGetApp().get_label_clr_sys();
|
tab->m_sys_label_clr = wxGetApp().get_label_clr_sys();
|
||||||
|
@ -1266,10 +1266,10 @@ void TabPrint::update()
|
||||||
if (m_config->opt_float("layer_height") < EPSILON)
|
if (m_config->opt_float("layer_height") < EPSILON)
|
||||||
{
|
{
|
||||||
const wxString msg_text = _(L("Zero layer height is not valid.\n\nThe layer height will be reset to 0.01."));
|
const wxString msg_text = _(L("Zero layer height is not valid.\n\nThe layer height will be reset to 0.01."));
|
||||||
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Layer height")), wxICON_WARNING | wxOK);
|
wxMessageDialog dialog(parent(), msg_text, _(L("Layer height")), wxICON_WARNING | wxOK);
|
||||||
DynamicPrintConfig new_conf = *m_config;
|
DynamicPrintConfig new_conf = *m_config;
|
||||||
is_msg_dlg_already_exist = true;
|
is_msg_dlg_already_exist = true;
|
||||||
dialog->ShowModal();
|
dialog.ShowModal();
|
||||||
new_conf.set_key_value("layer_height", new ConfigOptionFloat(0.01));
|
new_conf.set_key_value("layer_height", new ConfigOptionFloat(0.01));
|
||||||
load_config(new_conf);
|
load_config(new_conf);
|
||||||
is_msg_dlg_already_exist = false;
|
is_msg_dlg_already_exist = false;
|
||||||
|
@ -1278,10 +1278,10 @@ void TabPrint::update()
|
||||||
if (fabs(m_config->option<ConfigOptionFloatOrPercent>("first_layer_height")->value - 0) < EPSILON)
|
if (fabs(m_config->option<ConfigOptionFloatOrPercent>("first_layer_height")->value - 0) < EPSILON)
|
||||||
{
|
{
|
||||||
const wxString msg_text = _(L("Zero first layer height is not valid.\n\nThe first layer height will be reset to 0.01."));
|
const wxString msg_text = _(L("Zero first layer height is not valid.\n\nThe first layer height will be reset to 0.01."));
|
||||||
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("First layer height")), wxICON_WARNING | wxOK);
|
wxMessageDialog dialog(parent(), msg_text, _(L("First layer height")), wxICON_WARNING | wxOK);
|
||||||
DynamicPrintConfig new_conf = *m_config;
|
DynamicPrintConfig new_conf = *m_config;
|
||||||
is_msg_dlg_already_exist = true;
|
is_msg_dlg_already_exist = true;
|
||||||
dialog->ShowModal();
|
dialog.ShowModal();
|
||||||
new_conf.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(0.01, false));
|
new_conf.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(0.01, false));
|
||||||
load_config(new_conf);
|
load_config(new_conf);
|
||||||
is_msg_dlg_already_exist = false;
|
is_msg_dlg_already_exist = false;
|
||||||
|
@ -1299,9 +1299,9 @@ void TabPrint::update()
|
||||||
"- no support material\n"
|
"- no support material\n"
|
||||||
"- no ensure_vertical_shell_thickness\n"
|
"- no ensure_vertical_shell_thickness\n"
|
||||||
"\nShall I adjust those settings in order to enable Spiral Vase?"));
|
"\nShall I adjust those settings in order to enable Spiral Vase?"));
|
||||||
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Spiral Vase")), wxICON_WARNING | wxYES | wxNO);
|
wxMessageDialog dialog(parent(), msg_text, _(L("Spiral Vase")), wxICON_WARNING | wxYES | wxNO);
|
||||||
DynamicPrintConfig new_conf = *m_config;
|
DynamicPrintConfig new_conf = *m_config;
|
||||||
if (dialog->ShowModal() == wxID_YES) {
|
if (dialog.ShowModal() == wxID_YES) {
|
||||||
new_conf.set_key_value("perimeters", new ConfigOptionInt(1));
|
new_conf.set_key_value("perimeters", new ConfigOptionInt(1));
|
||||||
new_conf.set_key_value("top_solid_layers", new ConfigOptionInt(0));
|
new_conf.set_key_value("top_solid_layers", new ConfigOptionInt(0));
|
||||||
new_conf.set_key_value("fill_density", new ConfigOptionPercent(0));
|
new_conf.set_key_value("fill_density", new ConfigOptionPercent(0));
|
||||||
|
@ -1324,9 +1324,9 @@ void TabPrint::update()
|
||||||
"if they are printed with the current extruder without triggering a tool change.\n"
|
"if they are printed with the current extruder without triggering a tool change.\n"
|
||||||
"(both support_material_extruder and support_material_interface_extruder need to be set to 0).\n"
|
"(both support_material_extruder and support_material_interface_extruder need to be set to 0).\n"
|
||||||
"\nShall I adjust those settings in order to enable the Wipe Tower?"));
|
"\nShall I adjust those settings in order to enable the Wipe Tower?"));
|
||||||
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Wipe Tower")), wxICON_WARNING | wxYES | wxNO);
|
wxMessageDialog dialog(parent(), msg_text, _(L("Wipe Tower")), wxICON_WARNING | wxYES | wxNO);
|
||||||
DynamicPrintConfig new_conf = *m_config;
|
DynamicPrintConfig new_conf = *m_config;
|
||||||
if (dialog->ShowModal() == wxID_YES) {
|
if (dialog.ShowModal() == wxID_YES) {
|
||||||
new_conf.set_key_value("support_material_extruder", new ConfigOptionInt(0));
|
new_conf.set_key_value("support_material_extruder", new ConfigOptionInt(0));
|
||||||
new_conf.set_key_value("support_material_interface_extruder", new ConfigOptionInt(0));
|
new_conf.set_key_value("support_material_interface_extruder", new ConfigOptionInt(0));
|
||||||
}
|
}
|
||||||
|
@ -1341,9 +1341,9 @@ void TabPrint::update()
|
||||||
wxString msg_text = _(L("For the Wipe Tower to work with the soluble supports, the support layers\n"
|
wxString msg_text = _(L("For the Wipe Tower to work with the soluble supports, the support layers\n"
|
||||||
"need to be synchronized with the object layers.\n"
|
"need to be synchronized with the object layers.\n"
|
||||||
"\nShall I synchronize support layers in order to enable the Wipe Tower?"));
|
"\nShall I synchronize support layers in order to enable the Wipe Tower?"));
|
||||||
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Wipe Tower")), wxICON_WARNING | wxYES | wxNO);
|
wxMessageDialog dialog(parent(), msg_text, _(L("Wipe Tower")), wxICON_WARNING | wxYES | wxNO);
|
||||||
DynamicPrintConfig new_conf = *m_config;
|
DynamicPrintConfig new_conf = *m_config;
|
||||||
if (dialog->ShowModal() == wxID_YES) {
|
if (dialog.ShowModal() == wxID_YES) {
|
||||||
new_conf.set_key_value("support_material_synchronize_layers", new ConfigOptionBool(true));
|
new_conf.set_key_value("support_material_synchronize_layers", new ConfigOptionBool(true));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1359,9 +1359,9 @@ void TabPrint::update()
|
||||||
wxString msg_text = _(L("Supports work better, if the following feature is enabled:\n"
|
wxString msg_text = _(L("Supports work better, if the following feature is enabled:\n"
|
||||||
"- Detect bridging perimeters\n"
|
"- Detect bridging perimeters\n"
|
||||||
"\nShall I adjust those settings for supports?"));
|
"\nShall I adjust those settings for supports?"));
|
||||||
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Support Generator")), wxICON_WARNING | wxYES | wxNO | wxCANCEL);
|
wxMessageDialog dialog(parent(), msg_text, _(L("Support Generator")), wxICON_WARNING | wxYES | wxNO | wxCANCEL);
|
||||||
DynamicPrintConfig new_conf = *m_config;
|
DynamicPrintConfig new_conf = *m_config;
|
||||||
auto answer = dialog->ShowModal();
|
auto answer = dialog.ShowModal();
|
||||||
if (answer == wxID_YES) {
|
if (answer == wxID_YES) {
|
||||||
// Enable "detect bridging perimeters".
|
// Enable "detect bridging perimeters".
|
||||||
new_conf.set_key_value("overhangs", new ConfigOptionBool(true));
|
new_conf.set_key_value("overhangs", new ConfigOptionBool(true));
|
||||||
|
@ -1403,9 +1403,9 @@ void TabPrint::update()
|
||||||
if (!correct_100p_fill) {
|
if (!correct_100p_fill) {
|
||||||
wxString msg_text = GUI::from_u8((boost::format(_utf8(L("The %1% infill pattern is not supposed to work at 100%% density.\n\n"
|
wxString msg_text = GUI::from_u8((boost::format(_utf8(L("The %1% infill pattern is not supposed to work at 100%% density.\n\n"
|
||||||
"Shall I switch to rectilinear fill pattern?"))) % str_fill_pattern).str());
|
"Shall I switch to rectilinear fill pattern?"))) % str_fill_pattern).str());
|
||||||
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Infill")), wxICON_WARNING | wxYES | wxNO);
|
wxMessageDialog dialog(parent(), msg_text, _(L("Infill")), wxICON_WARNING | wxYES | wxNO);
|
||||||
DynamicPrintConfig new_conf = *m_config;
|
DynamicPrintConfig new_conf = *m_config;
|
||||||
if (dialog->ShowModal() == wxID_YES) {
|
if (dialog.ShowModal() == wxID_YES) {
|
||||||
new_conf.set_key_value("fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
|
new_conf.set_key_value("fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
|
||||||
fill_density = 100;
|
fill_density = 100;
|
||||||
}
|
}
|
||||||
|
@ -2045,10 +2045,10 @@ void TabPrinter::build_fff()
|
||||||
const wxString msg_text = _(L("Single Extruder Multi Material is selected, \n"
|
const wxString msg_text = _(L("Single Extruder Multi Material is selected, \n"
|
||||||
"and all extruders must have the same diameter.\n"
|
"and all extruders must have the same diameter.\n"
|
||||||
"Do you want to change the diameter for all extruders to first extruder nozzle diameter value?"));
|
"Do you want to change the diameter for all extruders to first extruder nozzle diameter value?"));
|
||||||
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO);
|
wxMessageDialog dialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO);
|
||||||
|
|
||||||
DynamicPrintConfig new_conf = *m_config;
|
DynamicPrintConfig new_conf = *m_config;
|
||||||
if (dialog->ShowModal() == wxID_YES) {
|
if (dialog.ShowModal() == wxID_YES) {
|
||||||
for (size_t i = 1; i < nozzle_diameters.size(); i++)
|
for (size_t i = 1; i < nozzle_diameters.size(); i++)
|
||||||
nozzle_diameters[i] = frst_diam;
|
nozzle_diameters[i] = frst_diam;
|
||||||
|
|
||||||
|
@ -2507,10 +2507,10 @@ void TabPrinter::build_unregular_pages()
|
||||||
{
|
{
|
||||||
const wxString msg_text = _(L("This is a single extruder multimaterial printer, diameters of all extruders "
|
const wxString msg_text = _(L("This is a single extruder multimaterial printer, diameters of all extruders "
|
||||||
"will be set to the new value. Do you want to proceed?"));
|
"will be set to the new value. Do you want to proceed?"));
|
||||||
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO);
|
wxMessageDialog dialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO);
|
||||||
|
|
||||||
DynamicPrintConfig new_conf = *m_config;
|
DynamicPrintConfig new_conf = *m_config;
|
||||||
if (dialog->ShowModal() == wxID_YES) {
|
if (dialog.ShowModal() == wxID_YES) {
|
||||||
for (size_t i = 0; i < nozzle_diameters.size(); i++) {
|
for (size_t i = 0; i < nozzle_diameters.size(); i++) {
|
||||||
if (i==extruder_idx)
|
if (i==extruder_idx)
|
||||||
continue;
|
continue;
|
||||||
|
@ -2715,13 +2715,13 @@ void TabPrinter::update_fff()
|
||||||
get_field("retract_before_wipe", i)->toggle(wipe);
|
get_field("retract_before_wipe", i)->toggle(wipe);
|
||||||
|
|
||||||
if (use_firmware_retraction && wipe) {
|
if (use_firmware_retraction && wipe) {
|
||||||
auto dialog = new wxMessageDialog(parent(),
|
wxMessageDialog dialog(parent(),
|
||||||
_(L("The Wipe option is not available when using the Firmware Retraction mode.\n"
|
_(L("The Wipe option is not available when using the Firmware Retraction mode.\n"
|
||||||
"\nShall I disable it in order to enable Firmware Retraction?")),
|
"\nShall I disable it in order to enable Firmware Retraction?")),
|
||||||
_(L("Firmware Retraction")), wxICON_WARNING | wxYES | wxNO);
|
_(L("Firmware Retraction")), wxICON_WARNING | wxYES | wxNO);
|
||||||
|
|
||||||
DynamicPrintConfig new_conf = *m_config;
|
DynamicPrintConfig new_conf = *m_config;
|
||||||
if (dialog->ShowModal() == wxID_YES) {
|
if (dialog.ShowModal() == wxID_YES) {
|
||||||
auto wipe = static_cast<ConfigOptionBools*>(m_config->option("wipe")->clone());
|
auto wipe = static_cast<ConfigOptionBools*>(m_config->option("wipe")->clone());
|
||||||
for (int w = 0; w < wipe->values.size(); w++)
|
for (int w = 0; w < wipe->values.size(); w++)
|
||||||
wipe->values[w] = false;
|
wipe->values[w] = false;
|
||||||
|
@ -3073,10 +3073,10 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr
|
||||||
message += wxString("\n") + tab + from_u8(new_printer_name) + "\n\n";
|
message += wxString("\n") + tab + from_u8(new_printer_name) + "\n\n";
|
||||||
message += _(L("and it has the following unsaved changes:"));
|
message += _(L("and it has the following unsaved changes:"));
|
||||||
}
|
}
|
||||||
auto confirm = new wxMessageDialog(parent(),
|
wxMessageDialog confirm(parent(),
|
||||||
message + "\n" + changes + "\n\n" + _(L("Discard changes and continue anyway?")),
|
message + "\n" + changes + "\n\n" + _(L("Discard changes and continue anyway?")),
|
||||||
_(L("Unsaved Changes")), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
|
_(L("Unsaved Changes")), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
|
||||||
return confirm->ShowModal() == wxID_YES;
|
return confirm.ShowModal() == wxID_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are switching from the FFF-preset to the SLA, we should to control the printed objects if they have a part(s).
|
// If we are switching from the FFF-preset to the SLA, we should to control the printed objects if they have a part(s).
|
||||||
|
@ -3183,11 +3183,11 @@ void Tab::save_preset(std::string name /*= ""*/)
|
||||||
values.push_back(preset.name);
|
values.push_back(preset.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dlg = new SavePresetWindow(parent());
|
SavePresetWindow dlg(parent());
|
||||||
dlg->build(title(), default_name, values);
|
dlg.build(title(), default_name, values);
|
||||||
if (dlg->ShowModal() != wxID_OK)
|
if (dlg.ShowModal() != wxID_OK)
|
||||||
return;
|
return;
|
||||||
name = dlg->get_name();
|
name = dlg.get_name();
|
||||||
if (name == "") {
|
if (name == "") {
|
||||||
show_error(this, _(L("The supplied name is empty. It can't be saved.")));
|
show_error(this, _(L("The supplied name is empty. It can't be saved.")));
|
||||||
return;
|
return;
|
||||||
|
@ -3799,13 +3799,13 @@ void TabSLAPrint::update()
|
||||||
wxString msg_text = _(
|
wxString msg_text = _(
|
||||||
L("Head penetration should not be greater than the head width."));
|
L("Head penetration should not be greater than the head width."));
|
||||||
|
|
||||||
auto dialog = new wxMessageDialog(parent(),
|
wxMessageDialog dialog(parent(),
|
||||||
msg_text,
|
msg_text,
|
||||||
_(L("Invalid Head penetration")),
|
_(L("Invalid Head penetration")),
|
||||||
wxICON_WARNING | wxOK);
|
wxICON_WARNING | wxOK);
|
||||||
|
|
||||||
DynamicPrintConfig new_conf = *m_config;
|
DynamicPrintConfig new_conf = *m_config;
|
||||||
if (dialog->ShowModal() == wxID_OK) {
|
if (dialog.ShowModal() == wxID_OK) {
|
||||||
new_conf.set_key_value("support_head_penetration",
|
new_conf.set_key_value("support_head_penetration",
|
||||||
new ConfigOptionFloat(head_width));
|
new ConfigOptionFloat(head_width));
|
||||||
}
|
}
|
||||||
|
@ -3819,13 +3819,13 @@ void TabSLAPrint::update()
|
||||||
wxString msg_text = _(L(
|
wxString msg_text = _(L(
|
||||||
"Pinhead diameter should be smaller than the pillar diameter."));
|
"Pinhead diameter should be smaller than the pillar diameter."));
|
||||||
|
|
||||||
auto dialog = new wxMessageDialog(parent(),
|
wxMessageDialog dialog (parent(),
|
||||||
msg_text,
|
msg_text,
|
||||||
_(L("Invalid pinhead diameter")),
|
_(L("Invalid pinhead diameter")),
|
||||||
wxICON_WARNING | wxOK);
|
wxICON_WARNING | wxOK);
|
||||||
|
|
||||||
DynamicPrintConfig new_conf = *m_config;
|
DynamicPrintConfig new_conf = *m_config;
|
||||||
if (dialog->ShowModal() == wxID_OK) {
|
if (dialog.ShowModal() == wxID_OK) {
|
||||||
new_conf.set_key_value("support_head_front_diameter",
|
new_conf.set_key_value("support_head_front_diameter",
|
||||||
new ConfigOptionFloat(pillar_d / 2.0));
|
new ConfigOptionFloat(pillar_d / 2.0));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue