mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-16 17:25:51 +08:00
Fixed conflicts after merge with branch et_opengl_3
This commit is contained in:
commit
73fed3e119
@ -414,6 +414,7 @@ if(SLIC3R_STATIC)
|
||||
endif()
|
||||
set(TBB_DEBUG 1)
|
||||
find_package(TBB REQUIRED)
|
||||
slic3r_remap_configs(TBB::tbb RelWithDebInfo Release)
|
||||
# include_directories(${TBB_INCLUDE_DIRS})
|
||||
# add_definitions(${TBB_DEFINITIONS})
|
||||
# if(MSVC)
|
||||
|
@ -581,11 +581,6 @@ static void process_arrangeable(const ArrangePolygon &arrpoly,
|
||||
const Vec2crd &offs = arrpoly.translation;
|
||||
double rotation = arrpoly.rotation;
|
||||
|
||||
// This fixes:
|
||||
// https://github.com/prusa3d/PrusaSlicer/issues/2209
|
||||
if (p.points.size() < 3)
|
||||
return;
|
||||
|
||||
outp.emplace_back(std::move(p));
|
||||
outp.back().rotation(rotation);
|
||||
outp.back().translation({offs.x(), offs.y()});
|
||||
|
@ -503,13 +503,11 @@ static void write_thumbnail(Zipper &zipper, const ThumbnailData &data)
|
||||
}
|
||||
}
|
||||
|
||||
void SL1Archive::export_print(const std::string fname,
|
||||
void SL1Archive::export_print(Zipper &zipper,
|
||||
const SLAPrint &print,
|
||||
const ThumbnailsList &thumbnails,
|
||||
const std::string &prjname)
|
||||
{
|
||||
Zipper zipper{fname};
|
||||
|
||||
std::string project =
|
||||
prjname.empty() ?
|
||||
boost::filesystem::path(zipper.get_filename()).stem().string() :
|
||||
@ -549,4 +547,14 @@ void SL1Archive::export_print(const std::string fname,
|
||||
}
|
||||
}
|
||||
|
||||
void SL1Archive::export_print(const std::string fname,
|
||||
const SLAPrint &print,
|
||||
const ThumbnailsList &thumbnails,
|
||||
const std::string &prjname)
|
||||
{
|
||||
Zipper zipper{fname, Zipper::FAST_COMPRESSION};
|
||||
|
||||
export_print(zipper, print, thumbnails, prjname);
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -22,6 +22,11 @@ protected:
|
||||
SLAPrinterConfig & cfg() { return m_cfg; }
|
||||
const SLAPrinterConfig & cfg() const { return m_cfg; }
|
||||
|
||||
void export_print(Zipper &,
|
||||
const SLAPrint &print,
|
||||
const ThumbnailsList &thumbnails,
|
||||
const std::string &projectname);
|
||||
|
||||
public:
|
||||
|
||||
SL1Archive() = default;
|
||||
|
@ -224,4 +224,14 @@ sla::RasterEncoder SL1_SVGArchive::get_encoder() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SL1_SVGArchive::export_print(const std::string fname,
|
||||
const SLAPrint &print,
|
||||
const ThumbnailsList &thumbnails,
|
||||
const std::string &projectname)
|
||||
{
|
||||
Zipper zipper{fname, Zipper::TIGHT_COMPRESSION};
|
||||
|
||||
SL1Archive::export_print(zipper, print, thumbnails, projectname);
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -14,6 +14,11 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
void export_print(const std::string fname,
|
||||
const SLAPrint &print,
|
||||
const ThumbnailsList &thumbnails,
|
||||
const std::string &projectname = "") override;
|
||||
|
||||
using SL1Archive::SL1Archive;
|
||||
};
|
||||
|
||||
|
@ -34,6 +34,9 @@ static const float DEFAULT_TRAVEL_ACCELERATION = 1250.0f;
|
||||
static const size_t MIN_EXTRUDERS_COUNT = 5;
|
||||
static const float DEFAULT_FILAMENT_DIAMETER = 1.75f;
|
||||
static const float DEFAULT_FILAMENT_DENSITY = 1.245f;
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
static const float DEFAULT_FILAMENT_COST = 0.0f;
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
static const Slic3r::Vec3f DEFAULT_EXTRUDER_OFFSET = Slic3r::Vec3f::Zero();
|
||||
|
||||
#if ENABLE_PROCESS_G2_G3_LINES
|
||||
@ -358,6 +361,7 @@ void GCodeProcessor::TimeProcessor::reset()
|
||||
machines[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].enabled = true;
|
||||
}
|
||||
|
||||
#if !ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, std::vector<GCodeProcessorResult::MoveVertex>& moves, std::vector<size_t>& lines_ends)
|
||||
{
|
||||
FilePtr in{ boost::nowide::fopen(filename.c_str(), "rb") };
|
||||
@ -663,16 +667,17 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st
|
||||
throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + out_path + " to " + filename + '\n' +
|
||||
"Is " + out_path + " locked?" + '\n');
|
||||
}
|
||||
#endif // !ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
|
||||
void GCodeProcessor::UsedFilaments::reset()
|
||||
{
|
||||
color_change_cache = 0.0f;
|
||||
color_change_cache = 0.0;
|
||||
volumes_per_color_change = std::vector<double>();
|
||||
|
||||
tool_change_cache = 0.0f;
|
||||
tool_change_cache = 0.0;
|
||||
volumes_per_extruder.clear();
|
||||
|
||||
role_cache = 0.0f;
|
||||
role_cache = 0.0;
|
||||
filaments_per_role.clear();
|
||||
}
|
||||
|
||||
@ -694,21 +699,21 @@ void GCodeProcessor::UsedFilaments::process_color_change_cache()
|
||||
void GCodeProcessor::UsedFilaments::process_extruder_cache(GCodeProcessor* processor)
|
||||
{
|
||||
size_t active_extruder_id = processor->m_extruder_id;
|
||||
if (tool_change_cache != 0.0f) {
|
||||
if (tool_change_cache != 0.0) {
|
||||
if (volumes_per_extruder.find(active_extruder_id) != volumes_per_extruder.end())
|
||||
volumes_per_extruder[active_extruder_id] += tool_change_cache;
|
||||
else
|
||||
volumes_per_extruder[active_extruder_id] = tool_change_cache;
|
||||
tool_change_cache = 0.0f;
|
||||
tool_change_cache = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void GCodeProcessor::UsedFilaments::process_role_cache(GCodeProcessor* processor)
|
||||
{
|
||||
if (role_cache != 0.0f) {
|
||||
if (role_cache != 0.0) {
|
||||
std::pair<double, double> filament = { 0.0f, 0.0f };
|
||||
|
||||
double s = PI * sqr(0.5 * processor->m_result.filament_diameters[processor->m_extruder_id]);
|
||||
const double s = PI * sqr(0.5 * processor->m_result.filament_diameters[processor->m_extruder_id]);
|
||||
filament.first = role_cache / s * 0.001;
|
||||
filament.second = role_cache * processor->m_result.filament_densities[processor->m_extruder_id] * 0.001;
|
||||
|
||||
@ -719,7 +724,7 @@ void GCodeProcessor::UsedFilaments::process_role_cache(GCodeProcessor* processor
|
||||
}
|
||||
else
|
||||
filaments_per_role[active_role] = filament;
|
||||
role_cache = 0.0f;
|
||||
role_cache = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -740,6 +745,9 @@ void GCodeProcessorResult::reset() {
|
||||
extruder_colors = std::vector<std::string>();
|
||||
filament_diameters = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER);
|
||||
filament_densities = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY);
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
filament_cost = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_COST);
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
|
||||
spiral_vase_layers = std::vector<std::pair<float, std::pair<size_t, size_t>>>();
|
||||
time = 0;
|
||||
@ -756,6 +764,9 @@ void GCodeProcessorResult::reset() {
|
||||
extruder_colors = std::vector<std::string>();
|
||||
filament_diameters = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER);
|
||||
filament_densities = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY);
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
filament_cost = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_COST);
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
|
||||
spiral_vase_layers = std::vector<std::pair<float, std::pair<size_t, size_t>>>();
|
||||
}
|
||||
@ -850,6 +861,9 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
|
||||
m_extruder_colors.resize(extruders_count);
|
||||
m_result.filament_diameters.resize(extruders_count);
|
||||
m_result.filament_densities.resize(extruders_count);
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
m_result.filament_cost.resize(extruders_count);
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
m_extruder_temps.resize(extruders_count);
|
||||
|
||||
for (size_t i = 0; i < extruders_count; ++ i) {
|
||||
@ -857,6 +871,9 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
|
||||
m_extruder_colors[i] = static_cast<unsigned char>(i);
|
||||
m_result.filament_diameters[i] = static_cast<float>(config.filament_diameter.get_at(i));
|
||||
m_result.filament_densities[i] = static_cast<float>(config.filament_density.get_at(i));
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
m_result.filament_cost[i] = static_cast<float>(config.filament_cost.get_at(i));
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
}
|
||||
|
||||
if ((m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware || m_flavor == gcfRepRapFirmware) && config.machine_limits_usage.value != MachineLimitsUsage::Ignore) {
|
||||
@ -970,6 +987,23 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
const ConfigOptionFloats* filament_cost = config.option<ConfigOptionFloats>("filament_cost");
|
||||
if (filament_cost != nullptr) {
|
||||
m_result.filament_cost.clear();
|
||||
m_result.filament_cost.resize(filament_cost->values.size());
|
||||
for (size_t i = 0; i < filament_cost->values.size(); ++i) {
|
||||
m_result.filament_cost[i] = static_cast<float>(filament_cost->values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_result.filament_cost.size() < m_result.extruders_count) {
|
||||
for (size_t i = m_result.filament_cost.size(); i < m_result.extruders_count; ++i) {
|
||||
m_result.filament_cost.emplace_back(DEFAULT_FILAMENT_COST);
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
|
||||
const ConfigOptionPoints* extruder_offset = config.option<ConfigOptionPoints>("extruder_offset");
|
||||
if (extruder_offset != nullptr) {
|
||||
m_extruder_offsets.resize(extruder_offset->values.size());
|
||||
@ -1331,7 +1365,7 @@ void GCodeProcessor::process_buffer(const std::string &buffer)
|
||||
});
|
||||
}
|
||||
|
||||
void GCodeProcessor::finalize(bool post_process)
|
||||
void GCodeProcessor::finalize(bool perform_post_process)
|
||||
{
|
||||
// update width/height of wipe moves
|
||||
for (GCodeProcessorResult::MoveVertex& move : m_result.moves) {
|
||||
@ -1361,8 +1395,12 @@ void GCodeProcessor::finalize(bool post_process)
|
||||
m_width_compare.output();
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
|
||||
if (post_process)
|
||||
if (perform_post_process)
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
post_process();
|
||||
#else
|
||||
m_time_processor.post_process(m_result.filename, m_result.moves, m_result.lines_ends);
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
m_result.time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - m_start_time).count();
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
@ -1534,6 +1572,12 @@ void GCodeProcessor::apply_config_simplify3d(const std::string& filename)
|
||||
} else if (comment.find("filamentDensities") != comment.npos) {
|
||||
m_result.filament_densities.clear();
|
||||
extract_floats(comment, "filamentDensities", m_result.filament_densities);
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
}
|
||||
else if (comment.find("filamentPricesPerKg") != comment.npos) {
|
||||
m_result.filament_cost.clear();
|
||||
extract_floats(comment, "filamentPricesPerKg", m_result.filament_cost);
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
} else if (comment.find("extruderDiameter") != comment.npos) {
|
||||
std::vector<float> extruder_diameters;
|
||||
extract_floats(comment, "extruderDiameter", extruder_diameters);
|
||||
@ -1549,8 +1593,14 @@ void GCodeProcessor::apply_config_simplify3d(const std::string& filename)
|
||||
}
|
||||
});
|
||||
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
if (m_result.extruders_count == 0)
|
||||
m_result.extruders_count = std::max<size_t>(1, std::min(m_result.filament_diameters.size(),
|
||||
std::min(m_result.filament_densities.size(), m_result.filament_cost.size())));
|
||||
#else
|
||||
if (m_result.extruders_count == 0)
|
||||
m_result.extruders_count = std::max<size_t>(1, std::min(m_result.filament_diameters.size(), m_result.filament_densities.size()));
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
|
||||
if (bed_size.is_defined()) {
|
||||
m_result.bed_shape = {
|
||||
@ -3493,6 +3543,354 @@ void GCodeProcessor::process_T(const std::string_view command)
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
void GCodeProcessor::post_process()
|
||||
{
|
||||
FilePtr in{ boost::nowide::fopen(m_result.filename.c_str(), "rb") };
|
||||
if (in.f == nullptr)
|
||||
throw Slic3r::RuntimeError(std::string("GCode processor post process export failed.\nCannot open file for reading.\n"));
|
||||
|
||||
// temporary file to contain modified gcode
|
||||
std::string out_path = m_result.filename + ".postprocess";
|
||||
FilePtr out{ boost::nowide::fopen(out_path.c_str(), "wb") };
|
||||
if (out.f == nullptr) {
|
||||
throw Slic3r::RuntimeError(std::string("GCode processor post process export failed.\nCannot open file for writing.\n"));
|
||||
}
|
||||
|
||||
auto time_in_minutes = [](float time_in_seconds) {
|
||||
assert(time_in_seconds >= 0.f);
|
||||
return int((time_in_seconds + 0.5f) / 60.0f);
|
||||
};
|
||||
|
||||
auto time_in_last_minute = [](float time_in_seconds) {
|
||||
assert(time_in_seconds <= 60.0f);
|
||||
return time_in_seconds / 60.0f;
|
||||
};
|
||||
|
||||
auto format_line_M73_main = [](const std::string& mask, int percent, int time) {
|
||||
char line_M73[64];
|
||||
sprintf(line_M73, mask.c_str(),
|
||||
std::to_string(percent).c_str(),
|
||||
std::to_string(time).c_str());
|
||||
return std::string(line_M73);
|
||||
};
|
||||
|
||||
auto format_line_M73_stop_int = [](const std::string& mask, int time) {
|
||||
char line_M73[64];
|
||||
sprintf(line_M73, mask.c_str(), std::to_string(time).c_str());
|
||||
return std::string(line_M73);
|
||||
};
|
||||
|
||||
auto format_time_float = [](float time) {
|
||||
return Slic3r::float_to_string_decimal_point(time, 2);
|
||||
};
|
||||
|
||||
auto format_line_M73_stop_float = [format_time_float](const std::string& mask, float time) {
|
||||
char line_M73[64];
|
||||
sprintf(line_M73, mask.c_str(), format_time_float(time).c_str());
|
||||
return std::string(line_M73);
|
||||
};
|
||||
|
||||
std::string gcode_line;
|
||||
size_t g1_lines_counter = 0;
|
||||
// keeps track of last exported pair <percent, remaining time>
|
||||
std::array<std::pair<int, int>, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> last_exported_main;
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
last_exported_main[i] = { 0, time_in_minutes(m_time_processor.machines[i].time) };
|
||||
}
|
||||
|
||||
// keeps track of last exported remaining time to next printer stop
|
||||
std::array<int, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> last_exported_stop;
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
last_exported_stop[i] = time_in_minutes(m_time_processor.machines[i].time);
|
||||
}
|
||||
|
||||
// buffer line to export only when greater than 64K to reduce writing calls
|
||||
std::string export_line;
|
||||
|
||||
// replace placeholder lines with the proper final value
|
||||
// gcode_line is in/out parameter, to reduce expensive memory allocation
|
||||
auto process_placeholders = [&](std::string& gcode_line) {
|
||||
unsigned int extra_lines_count = 0;
|
||||
|
||||
// remove trailing '\n'
|
||||
auto line = std::string_view(gcode_line).substr(0, gcode_line.length() - 1);
|
||||
|
||||
std::string ret;
|
||||
if (line.length() > 1) {
|
||||
line = line.substr(1);
|
||||
if (m_time_processor.export_remaining_time_enabled &&
|
||||
(line == reserved_tag(ETags::First_Line_M73_Placeholder) || line == reserved_tag(ETags::Last_Line_M73_Placeholder))) {
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
const TimeMachine& machine = m_time_processor.machines[i];
|
||||
if (machine.enabled) {
|
||||
// export pair <percent, remaining time>
|
||||
ret += format_line_M73_main(machine.line_m73_main_mask.c_str(),
|
||||
(line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? 0 : 100,
|
||||
(line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? time_in_minutes(machine.time) : 0);
|
||||
++extra_lines_count;
|
||||
|
||||
// export remaining time to next printer stop
|
||||
if (line == reserved_tag(ETags::First_Line_M73_Placeholder) && !machine.stop_times.empty()) {
|
||||
int to_export_stop = time_in_minutes(machine.stop_times.front().elapsed_time);
|
||||
ret += format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop);
|
||||
last_exported_stop[i] = to_export_stop;
|
||||
++extra_lines_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line == reserved_tag(ETags::Estimated_Printing_Time_Placeholder)) {
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
const TimeMachine& machine = m_time_processor.machines[i];
|
||||
PrintEstimatedStatistics::ETimeMode mode = static_cast<PrintEstimatedStatistics::ETimeMode>(i);
|
||||
if (mode == PrintEstimatedStatistics::ETimeMode::Normal || machine.enabled) {
|
||||
char buf[128];
|
||||
sprintf(buf, "; estimated printing time (%s mode) = %s\n",
|
||||
(mode == PrintEstimatedStatistics::ETimeMode::Normal) ? "normal" : "silent",
|
||||
get_time_dhms(machine.time).c_str());
|
||||
ret += buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret.empty())
|
||||
// Not moving the move operator on purpose, so that the gcode_line allocation will grow and it will not be reallocated after handful of lines are processed.
|
||||
gcode_line = ret;
|
||||
return std::tuple(!ret.empty(), (extra_lines_count == 0) ? extra_lines_count : extra_lines_count - 1);
|
||||
};
|
||||
|
||||
struct FilamentData
|
||||
{
|
||||
double mm{ 0.0 };
|
||||
double cm3{ 0.0 };
|
||||
double g{ 0.0 };
|
||||
double cost{ 0.0 };
|
||||
};
|
||||
|
||||
FilamentData filament_data;
|
||||
for (const auto& [role, used] : m_result.print_statistics.used_filaments_per_role) {
|
||||
filament_data.mm += used.first;
|
||||
filament_data.g += used.second;
|
||||
}
|
||||
for (const auto& [id, volume] : m_result.print_statistics.volumes_per_extruder) {
|
||||
filament_data.cm3 += volume;
|
||||
filament_data.cost += volume * double(m_result.filament_densities[id]) * double(m_result.filament_cost[id]) * 0.000001;
|
||||
}
|
||||
|
||||
auto process_used_filament = [&filament_data](std::string& gcode_line) {
|
||||
auto process_tag = [](std::string& gcode_line, const std::string& tag, double value) {
|
||||
if (boost::algorithm::istarts_with(gcode_line, tag)) {
|
||||
char buf[128];
|
||||
sprintf(buf, "%s %.2lf\n", tag.c_str(), value);
|
||||
gcode_line = buf;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool ret = false;
|
||||
ret |= process_tag(gcode_line, "; filament used [mm] =", filament_data.mm * 1000.0);
|
||||
ret |= process_tag(gcode_line, "; filament used [g] =", filament_data.g);
|
||||
ret |= process_tag(gcode_line, "; total filament used [g] =", filament_data.g);
|
||||
ret |= process_tag(gcode_line, "; filament used [cm3] =", filament_data.cm3 / 1000.0);
|
||||
ret |= process_tag(gcode_line, "; filament cost =", filament_data.cost);
|
||||
ret |= process_tag(gcode_line, "; total filament cost =", filament_data.cost);
|
||||
return ret;
|
||||
};
|
||||
|
||||
// check for temporary lines
|
||||
auto is_temporary_decoration = [](const std::string_view gcode_line) {
|
||||
// remove trailing '\n'
|
||||
assert(!gcode_line.empty());
|
||||
assert(gcode_line.back() == '\n');
|
||||
|
||||
// return true for decorations which are used in processing the gcode but that should not be exported into the final gcode
|
||||
// i.e.:
|
||||
// bool ret = gcode_line.substr(0, gcode_line.length() - 1) == ";" + Layer_Change_Tag;
|
||||
// ...
|
||||
// return ret;
|
||||
return false;
|
||||
};
|
||||
|
||||
// Iterators for the normal and silent cached time estimate entry recently processed, used by process_line_G1.
|
||||
auto g1_times_cache_it = Slic3r::reserve_vector<std::vector<TimeMachine::G1LinesCacheItem>::const_iterator>(m_time_processor.machines.size());
|
||||
for (const auto& machine : m_time_processor.machines)
|
||||
g1_times_cache_it.emplace_back(machine.g1_times_cache.begin());
|
||||
|
||||
// add lines M73 to exported gcode
|
||||
auto process_line_G1 = [this,
|
||||
// Lambdas, mostly for string formatting, all with an empty capture block.
|
||||
time_in_minutes, format_time_float, format_line_M73_main, format_line_M73_stop_int, format_line_M73_stop_float, time_in_last_minute,
|
||||
// Caches, to be modified
|
||||
&g1_times_cache_it, &last_exported_main, &last_exported_stop,
|
||||
// String output
|
||||
&export_line]
|
||||
(const size_t g1_lines_counter) {
|
||||
unsigned int exported_lines_count = 0;
|
||||
if (m_time_processor.export_remaining_time_enabled) {
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
const TimeMachine& machine = m_time_processor.machines[i];
|
||||
if (machine.enabled) {
|
||||
// export pair <percent, remaining time>
|
||||
// Skip all machine.g1_times_cache below g1_lines_counter.
|
||||
auto& it = g1_times_cache_it[i];
|
||||
while (it != machine.g1_times_cache.end() && it->id < g1_lines_counter)
|
||||
++it;
|
||||
if (it != machine.g1_times_cache.end() && it->id == g1_lines_counter) {
|
||||
std::pair<int, int> to_export_main = { int(100.0f * it->elapsed_time / machine.time),
|
||||
time_in_minutes(machine.time - it->elapsed_time) };
|
||||
if (last_exported_main[i] != to_export_main) {
|
||||
export_line += format_line_M73_main(machine.line_m73_main_mask.c_str(),
|
||||
to_export_main.first, to_export_main.second);
|
||||
last_exported_main[i] = to_export_main;
|
||||
++exported_lines_count;
|
||||
}
|
||||
// export remaining time to next printer stop
|
||||
auto it_stop = std::upper_bound(machine.stop_times.begin(), machine.stop_times.end(), it->elapsed_time,
|
||||
[](float value, const TimeMachine::StopTime& t) { return value < t.elapsed_time; });
|
||||
if (it_stop != machine.stop_times.end()) {
|
||||
int to_export_stop = time_in_minutes(it_stop->elapsed_time - it->elapsed_time);
|
||||
if (last_exported_stop[i] != to_export_stop) {
|
||||
if (to_export_stop > 0) {
|
||||
if (last_exported_stop[i] != to_export_stop) {
|
||||
export_line += format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop);
|
||||
last_exported_stop[i] = to_export_stop;
|
||||
++exported_lines_count;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bool is_last = false;
|
||||
auto next_it = it + 1;
|
||||
is_last |= (next_it == machine.g1_times_cache.end());
|
||||
|
||||
if (next_it != machine.g1_times_cache.end()) {
|
||||
auto next_it_stop = std::upper_bound(machine.stop_times.begin(), machine.stop_times.end(), next_it->elapsed_time,
|
||||
[](float value, const TimeMachine::StopTime& t) { return value < t.elapsed_time; });
|
||||
is_last |= (next_it_stop != it_stop);
|
||||
|
||||
std::string time_float_str = format_time_float(time_in_last_minute(it_stop->elapsed_time - it->elapsed_time));
|
||||
std::string next_time_float_str = format_time_float(time_in_last_minute(it_stop->elapsed_time - next_it->elapsed_time));
|
||||
is_last |= (string_to_double_decimal_point(time_float_str) > 0. && string_to_double_decimal_point(next_time_float_str) == 0.);
|
||||
}
|
||||
|
||||
if (is_last) {
|
||||
if (std::distance(machine.stop_times.begin(), it_stop) == static_cast<ptrdiff_t>(machine.stop_times.size() - 1))
|
||||
export_line += format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop);
|
||||
else
|
||||
export_line += format_line_M73_stop_float(machine.line_m73_stop_mask.c_str(), time_in_last_minute(it_stop->elapsed_time - it->elapsed_time));
|
||||
|
||||
last_exported_stop[i] = to_export_stop;
|
||||
++exported_lines_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return exported_lines_count;
|
||||
};
|
||||
|
||||
// helper function to write to disk
|
||||
size_t out_file_pos = 0;
|
||||
m_result.lines_ends.clear();
|
||||
auto write_string = [this, &export_line, &out, &out_path, &out_file_pos](const std::string& str) {
|
||||
fwrite((const void*)export_line.c_str(), 1, export_line.length(), out.f);
|
||||
if (ferror(out.f)) {
|
||||
out.close();
|
||||
boost::nowide::remove(out_path.c_str());
|
||||
throw Slic3r::RuntimeError(std::string("GCode processor post process export failed.\nIs the disk full?\n"));
|
||||
}
|
||||
for (size_t i = 0; i < export_line.size(); ++i)
|
||||
if (export_line[i] == '\n')
|
||||
m_result.lines_ends.emplace_back(out_file_pos + i + 1);
|
||||
out_file_pos += export_line.size();
|
||||
export_line.clear();
|
||||
};
|
||||
|
||||
unsigned int line_id = 0;
|
||||
std::vector<std::pair<unsigned int, unsigned int>> offsets;
|
||||
|
||||
{
|
||||
// Read the input stream 64kB at a time, extract lines and process them.
|
||||
std::vector<char> buffer(65536 * 10, 0);
|
||||
// Line buffer.
|
||||
assert(gcode_line.empty());
|
||||
for (;;) {
|
||||
size_t cnt_read = ::fread(buffer.data(), 1, buffer.size(), in.f);
|
||||
if (::ferror(in.f))
|
||||
throw Slic3r::RuntimeError(std::string("GCode processor post process export failed.\nError while reading from file.\n"));
|
||||
bool eof = cnt_read == 0;
|
||||
auto it = buffer.begin();
|
||||
auto it_bufend = buffer.begin() + cnt_read;
|
||||
while (it != it_bufend || (eof && !gcode_line.empty())) {
|
||||
// Find end of line.
|
||||
bool eol = false;
|
||||
auto it_end = it;
|
||||
for (; it_end != it_bufend && !(eol = *it_end == '\r' || *it_end == '\n'); ++it_end);
|
||||
// End of line is indicated also if end of file was reached.
|
||||
eol |= eof && it_end == it_bufend;
|
||||
gcode_line.insert(gcode_line.end(), it, it_end);
|
||||
if (eol) {
|
||||
++line_id;
|
||||
|
||||
gcode_line += "\n";
|
||||
// replace placeholder lines
|
||||
auto [processed, lines_added_count] = process_placeholders(gcode_line);
|
||||
if (processed && lines_added_count > 0)
|
||||
offsets.push_back({ line_id, lines_added_count });
|
||||
if (!processed)
|
||||
processed = process_used_filament(gcode_line);
|
||||
if (!processed && !is_temporary_decoration(gcode_line) && GCodeReader::GCodeLine::cmd_is(gcode_line, "G1")) {
|
||||
// remove temporary lines, add lines M73 where needed
|
||||
unsigned int extra_lines_count = process_line_G1(g1_lines_counter++);
|
||||
if (extra_lines_count > 0)
|
||||
offsets.push_back({ line_id, extra_lines_count });
|
||||
}
|
||||
|
||||
export_line += gcode_line;
|
||||
if (export_line.length() > 65535)
|
||||
write_string(export_line);
|
||||
gcode_line.clear();
|
||||
}
|
||||
// Skip EOL.
|
||||
it = it_end;
|
||||
if (it != it_bufend && *it == '\r')
|
||||
++it;
|
||||
if (it != it_bufend && *it == '\n')
|
||||
++it;
|
||||
}
|
||||
if (eof)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!export_line.empty())
|
||||
write_string(export_line);
|
||||
|
||||
out.close();
|
||||
in.close();
|
||||
|
||||
// updates moves' gcode ids which have been modified by the insertion of the M73 lines
|
||||
unsigned int curr_offset_id = 0;
|
||||
unsigned int total_offset = 0;
|
||||
for (GCodeProcessorResult::MoveVertex& move : m_result.moves) {
|
||||
while (curr_offset_id < static_cast<unsigned int>(offsets.size()) && offsets[curr_offset_id].first <= move.gcode_id) {
|
||||
total_offset += offsets[curr_offset_id].second;
|
||||
++curr_offset_id;
|
||||
}
|
||||
move.gcode_id += total_offset;
|
||||
}
|
||||
|
||||
if (rename_file(out_path, m_result.filename))
|
||||
throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + out_path + " to " + m_result.filename + '\n' +
|
||||
"Is " + out_path + " locked?" + '\n');
|
||||
}
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
|
||||
#if ENABLE_PROCESS_G2_G3_LINES
|
||||
void GCodeProcessor::store_move_vertex(EMoveType type, bool internal_only)
|
||||
#else
|
||||
|
@ -67,6 +67,9 @@ namespace Slic3r {
|
||||
std::vector<double> volumes_per_color_change;
|
||||
std::map<size_t, double> volumes_per_extruder;
|
||||
std::map<ExtrusionRole, std::pair<double, double>> used_filaments_per_role;
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
std::map<size_t, double> cost_per_extruder;
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
|
||||
std::array<Mode, static_cast<size_t>(ETimeMode::Count)> modes;
|
||||
|
||||
@ -79,6 +82,9 @@ namespace Slic3r {
|
||||
volumes_per_color_change.clear();
|
||||
volumes_per_extruder.clear();
|
||||
used_filaments_per_role.clear();
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
cost_per_extruder.clear();
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
}
|
||||
};
|
||||
|
||||
@ -132,6 +138,10 @@ namespace Slic3r {
|
||||
std::vector<std::string> extruder_colors;
|
||||
std::vector<float> filament_diameters;
|
||||
std::vector<float> filament_densities;
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
std::vector<float> filament_cost;
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
|
||||
PrintEstimatedStatistics print_statistics;
|
||||
std::vector<CustomGCode::Item> custom_gcode_per_print_z;
|
||||
std::vector<std::pair<float, std::pair<size_t, size_t>>> spiral_vase_layers;
|
||||
@ -352,9 +362,13 @@ namespace Slic3r {
|
||||
|
||||
void reset();
|
||||
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
friend class GCodeProcessor;
|
||||
#else
|
||||
// post process the file with the given filename to add remaining time lines M73
|
||||
// and updates moves' gcode ids accordingly
|
||||
void post_process(const std::string& filename, std::vector<GCodeProcessorResult::MoveVertex>& moves, std::vector<size_t>& lines_ends);
|
||||
#endif // !ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
};
|
||||
|
||||
struct UsedFilaments // filaments per ColorChange
|
||||
@ -753,6 +767,13 @@ namespace Slic3r {
|
||||
void process_T(const GCodeReader::GCodeLine& line);
|
||||
void process_T(const std::string_view command);
|
||||
|
||||
#if ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
// post process the file with the given filename to:
|
||||
// 1) add remaining time lines M73 and update moves' gcode ids accordingly
|
||||
// 2) update used filament data
|
||||
void post_process();
|
||||
#endif // ENABLE_USED_FILAMENT_POST_PROCESS
|
||||
|
||||
#if ENABLE_PROCESS_G2_G3_LINES
|
||||
void store_move_vertex(EMoveType type, bool internal_only = false);
|
||||
#else
|
||||
|
@ -818,7 +818,7 @@ private:
|
||||
}
|
||||
// Providing a new mesh, therefore this volume will get a new unique ID assigned.
|
||||
ModelVolume(ModelObject *object, const ModelVolume &other, TriangleMesh &&mesh) :
|
||||
name(other.name), source(other.source), m_mesh(new TriangleMesh(std::move(mesh))), config(other.config), m_type(other.m_type), object(object), m_transformation(other.m_transformation)
|
||||
name(other.name), source(other.source), config(other.config), object(object), m_mesh(new TriangleMesh(std::move(mesh))), m_type(other.m_type), m_transformation(other.m_transformation)
|
||||
{
|
||||
assert(this->id().valid());
|
||||
assert(this->config.id().valid());
|
||||
@ -833,7 +833,7 @@ private:
|
||||
assert(this->config.id() == other.config.id());
|
||||
this->set_material_id(other.material_id());
|
||||
this->config.set_new_unique_id();
|
||||
if (mesh.facets_count() > 1)
|
||||
if (m_mesh->facets_count() > 1)
|
||||
calculate_convex_hull();
|
||||
assert(this->config.id().valid());
|
||||
assert(this->config.id() != other.config.id());
|
||||
|
@ -77,6 +77,10 @@
|
||||
#define ENABLE_ALTERNATIVE_FILE_WILDCARDS_GENERATOR (1 && ENABLE_2_5_0_ALPHA1)
|
||||
// Enable processing of gcode G2 and G3 lines
|
||||
#define ENABLE_PROCESS_G2_G3_LINES (1 && ENABLE_2_5_0_ALPHA1)
|
||||
// Enable fix of used filament data exported to gcode file
|
||||
#define ENABLE_USED_FILAMENT_POST_PROCESS (1 && ENABLE_2_5_0_ALPHA1)
|
||||
// Enable gizmo grabbers to share common models
|
||||
#define ENABLE_GIZMO_GRABBER_REFACTOR (1 && ENABLE_2_5_0_ALPHA1)
|
||||
|
||||
|
||||
#endif // _prusaslicer_technologies_h_
|
||||
|
@ -18,10 +18,19 @@ const float GLGizmoBase::Grabber::SizeFactor = 0.05f;
|
||||
const float GLGizmoBase::Grabber::MinHalfSize = 1.5f;
|
||||
const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f;
|
||||
|
||||
void GLGizmoBase::Grabber::render(bool hover, float size)
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
GLModel GLGizmoBase::Grabber::s_cube;
|
||||
GLModel GLGizmoBase::Grabber::s_cone;
|
||||
|
||||
GLGizmoBase::Grabber::~Grabber()
|
||||
{
|
||||
render(size, hover ? complementary(color) : color, false);
|
||||
if (s_cube.is_initialized())
|
||||
s_cube.reset();
|
||||
|
||||
if (s_cone.is_initialized())
|
||||
s_cone.reset();
|
||||
}
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
float GLGizmoBase::Grabber::get_half_size(float size) const
|
||||
{
|
||||
@ -41,39 +50,151 @@ void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, boo
|
||||
return;
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
if (!s_cube.is_initialized()) {
|
||||
#else
|
||||
if (!m_cube.is_initialized()) {
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
// This cannot be done in constructor, OpenGL is not yet
|
||||
// initialized at that point (on Linux at least).
|
||||
indexed_triangle_set its = its_make_cube(1., 1., 1.);
|
||||
indexed_triangle_set its = its_make_cube(1.0, 1.0, 1.0);
|
||||
its_translate(its, -0.5f * Vec3f::Ones());
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
s_cube.init_from(its);
|
||||
#else
|
||||
m_cube.init_from(its);
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
#else
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
s_cube.init_from(its, BoundingBoxf3{ { -0.5, -0.5, -0.5 }, { 0.5, 0.5, 0.5 } });
|
||||
#else
|
||||
m_cube.init_from(its, BoundingBoxf3{ { -0.5, -0.5, -0.5 }, { 0.5, 0.5, 0.5 } });
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
}
|
||||
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
if (!s_cone.is_initialized())
|
||||
s_cone.init_from(its_make_cone(0.375, 1.5, double(PI) / 18.0));
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
const float half_size = dragging ? get_dragging_half_size(size) : get_half_size(size);
|
||||
#else
|
||||
const float fullsize = 2.0f * (dragging ? get_dragging_half_size(size) : get_half_size(size));
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
s_cube.set_color(render_color);
|
||||
s_cone.set_color(render_color);
|
||||
#else
|
||||
m_cube.set_color(render_color);
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() * matrix * Geometry::assemble_transform(center, angles, 2.0 * half_size * Vec3d::Ones());
|
||||
#else
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() * matrix * Geometry::assemble_transform(center, angles, fullsize * Vec3d::Ones());
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
const Transform3d& projection_matrix = camera.get_projection_matrix();
|
||||
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
#else
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
s_cube.set_color(-1, render_color);
|
||||
s_cone.set_color(-1, render_color);
|
||||
#else
|
||||
m_cube.set_color(-1, render_color);
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
||||
glsafe(::glRotated(Geometry::rad2deg(angles.z()), 0.0, 0.0, 1.0));
|
||||
glsafe(::glRotated(Geometry::rad2deg(angles.y()), 0.0, 1.0, 0.0));
|
||||
glsafe(::glRotated(Geometry::rad2deg(angles.x()), 1.0, 0.0, 0.0));
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
glsafe(::glScaled(2.0 * half_size, 2.0 * half_size, 2.0 * half_size));
|
||||
#else
|
||||
glsafe(::glScaled(fullsize, fullsize, fullsize));
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
s_cube.render();
|
||||
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosX)) != 0) {
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix * Geometry::assemble_transform(Vec3d::UnitX(), Vec3d(0.0, 0.5 * double(PI), 0.0)));
|
||||
s_cone.render();
|
||||
}
|
||||
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegX)) != 0) {
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix * Geometry::assemble_transform(-Vec3d::UnitX(), Vec3d(0.0, -0.5 * double(PI), 0.0)));
|
||||
s_cone.render();
|
||||
}
|
||||
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosY)) != 0) {
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix * Geometry::assemble_transform(Vec3d::UnitY(), Vec3d(-0.5 * double(PI), 0.0, 0.0)));
|
||||
s_cone.render();
|
||||
}
|
||||
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegY)) != 0) {
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix * Geometry::assemble_transform(-Vec3d::UnitY(), Vec3d(0.5 * double(PI), 0.0, 0.0)));
|
||||
s_cone.render();
|
||||
}
|
||||
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosZ)) != 0) {
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix * Geometry::assemble_transform(Vec3d::UnitZ()));
|
||||
s_cone.render();
|
||||
}
|
||||
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegZ)) != 0) {
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix * Geometry::assemble_transform(-Vec3d::UnitZ(), Vec3d(double(PI), 0.0, 0.0)));
|
||||
s_cone.render();
|
||||
}
|
||||
#else
|
||||
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosX)) != 0) {
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(1.0, 0.0, 0.0));
|
||||
glsafe(::glRotated(0.5 * Geometry::rad2deg(double(PI)), 0.0, 1.0, 0.0));
|
||||
s_cone.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegX)) != 0) {
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(-1.0, 0.0, 0.0));
|
||||
glsafe(::glRotated(-0.5 * Geometry::rad2deg(double(PI)), 0.0, 1.0, 0.0));
|
||||
s_cone.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosY)) != 0) {
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(0.0, 1.0, 0.0));
|
||||
glsafe(::glRotated(-0.5 * Geometry::rad2deg(double(PI)), 1.0, 0.0, 0.0));
|
||||
s_cone.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegY)) != 0) {
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(0.0, -1.0, 0.0));
|
||||
glsafe(::glRotated(0.5 * Geometry::rad2deg(double(PI)), 1.0, 0.0, 0.0));
|
||||
s_cone.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::PosZ)) != 0) {
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(0.0, 0.0, 1.0));
|
||||
s_cone.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
if ((int(extensions) & int(GLGizmoBase::EGrabberExtension::NegZ)) != 0) {
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(0.0, 0.0, -1.0));
|
||||
glsafe(::glRotated(Geometry::rad2deg(double(PI)), 1.0, 0.0, 0.0));
|
||||
s_cone.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
#else
|
||||
m_cube.render();
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
#if !ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
glsafe(::glPopMatrix());
|
||||
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
@ -38,6 +38,19 @@ public:
|
||||
// (254 is choosen to leave some space for forward compatibility)
|
||||
static const unsigned int BASE_ID = 255 * 255 * 254;
|
||||
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
enum class EGrabberExtension
|
||||
{
|
||||
None = 0,
|
||||
PosX = 1 << 0,
|
||||
NegX = 1 << 1,
|
||||
PosY = 1 << 2,
|
||||
NegY = 1 << 3,
|
||||
PosZ = 1 << 4,
|
||||
NegZ = 1 << 5,
|
||||
};
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
protected:
|
||||
struct Grabber
|
||||
{
|
||||
@ -53,10 +66,16 @@ protected:
|
||||
Transform3d matrix{ Transform3d::Identity() };
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
ColorRGBA color{ ColorRGBA::WHITE() };
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
EGrabberExtension extensions{ EGrabberExtension::None };
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
Grabber() = default;
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
~Grabber();
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
void render(bool hover, float size);
|
||||
void render(bool hover, float size) { render(size, hover ? complementary(color) : color, false); }
|
||||
void render_for_picking(float size) { render(size, color, true); }
|
||||
|
||||
float get_half_size(float size) const;
|
||||
@ -65,7 +84,12 @@ protected:
|
||||
private:
|
||||
void render(float size, const ColorRGBA& render_color, bool picking);
|
||||
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
static GLModel s_cube;
|
||||
static GLModel s_cone;
|
||||
#else
|
||||
GLModel m_cube;
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -49,8 +49,16 @@ bool GLGizmoMove3D::on_init()
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
m_grabbers.push_back(Grabber());
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
m_grabbers.back().extensions = GLGizmoBase::EGrabberExtension::PosZ;
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
}
|
||||
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
m_grabbers[0].angles = { 0.0, 0.5 * double(PI), 0.0 };
|
||||
m_grabbers[1].angles = { -0.5 * double(PI), 0.0, 0.0 };
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
m_shortcut_key = WXK_CONTROL_M;
|
||||
|
||||
return true;
|
||||
@ -99,8 +107,10 @@ void GLGizmoMove3D::on_dragging(const UpdateData& data)
|
||||
|
||||
void GLGizmoMove3D::on_render()
|
||||
{
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
if (!m_cone.is_initialized())
|
||||
m_cone.init_from(its_make_cone(1.0, 1.0, double(PI) / 18.0));
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
|
||||
@ -196,10 +206,12 @@ void GLGizmoMove3D::on_render()
|
||||
|
||||
// draw grabbers
|
||||
render_grabbers(box);
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
if (m_grabbers[i].enabled)
|
||||
render_grabber_extension((Axis)i, box, false);
|
||||
}
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
}
|
||||
else {
|
||||
// draw axis
|
||||
@ -244,7 +256,9 @@ void GLGizmoMove3D::on_render()
|
||||
m_grabbers[m_hover_id].render(true, mean_size);
|
||||
shader->stop_using();
|
||||
}
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
render_grabber_extension((Axis)m_hover_id, box, false);
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,9 +268,11 @@ void GLGizmoMove3D::on_render_for_picking()
|
||||
|
||||
const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box();
|
||||
render_grabbers_for_picking(box);
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
render_grabber_extension(X, box, true);
|
||||
render_grabber_extension(Y, box, true);
|
||||
render_grabber_extension(Z, box, true);
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
}
|
||||
|
||||
double GLGizmoMove3D::calc_projection(const UpdateData& data) const
|
||||
@ -285,6 +301,7 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const
|
||||
return projection;
|
||||
}
|
||||
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box, bool picking)
|
||||
{
|
||||
const float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0);
|
||||
@ -339,6 +356,7 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box
|
||||
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
shader->stop_using();
|
||||
}
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
@ -17,7 +17,9 @@ class GLGizmoMove3D : public GLGizmoBase
|
||||
Vec3d m_starting_box_center{ Vec3d::Zero() };
|
||||
Vec3d m_starting_box_bottom_center{ Vec3d::Zero() };
|
||||
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
GLModel m_cone;
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
struct GrabberConnection
|
||||
{
|
||||
@ -47,6 +49,7 @@ public:
|
||||
/// Detect reduction of move for wipetover on selection change
|
||||
/// </summary>
|
||||
void data_changed() override;
|
||||
|
||||
protected:
|
||||
bool on_init() override;
|
||||
std::string on_get_name() const override;
|
||||
@ -59,11 +62,11 @@ protected:
|
||||
|
||||
private:
|
||||
double calc_projection(const UpdateData& data) const;
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
void render_grabber_extension(Axis axis, const BoundingBoxf3& box, bool picking);
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
|
@ -91,6 +91,9 @@ void GLGizmoRotate::disable_grabber() { m_grabbers[0].enabled = false; }
|
||||
bool GLGizmoRotate::on_init()
|
||||
{
|
||||
m_grabbers.push_back(Grabber());
|
||||
#if ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
m_grabbers.back().extensions = (GLGizmoBase::EGrabberExtension)(int(GLGizmoBase::EGrabberExtension::PosY) | int(GLGizmoBase::EGrabberExtension::NegY));
|
||||
#endif // ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -142,8 +145,10 @@ void GLGizmoRotate::on_render()
|
||||
if (!m_grabbers.front().enabled)
|
||||
return;
|
||||
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
if (!m_cone.is_initialized())
|
||||
m_cone.init_from(its_make_cone(1.0, 1.0, double(PI) / 12.0));
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const BoundingBoxf3& box = selection.get_bounding_box();
|
||||
@ -229,7 +234,9 @@ void GLGizmoRotate::on_render()
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
||||
render_grabber(box);
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
render_grabber_extension(box, false);
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
#if !ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
glsafe(::glPopMatrix());
|
||||
@ -251,7 +258,9 @@ void GLGizmoRotate::on_render_for_picking()
|
||||
|
||||
const BoundingBoxf3& box = selection.get_bounding_box();
|
||||
render_grabbers_for_picking(box);
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
render_grabber_extension(box, true);
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
#if !ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
glsafe(::glPopMatrix());
|
||||
@ -576,7 +585,8 @@ void GLGizmoRotate::render_grabber(const BoundingBoxf3& box)
|
||||
render_grabbers(box);
|
||||
}
|
||||
|
||||
void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool picking)
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
\void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool picking)
|
||||
{
|
||||
const float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0);
|
||||
const double size = m_dragging ? double(m_grabbers.front().get_dragging_half_size(mean_size)) : double(m_grabbers.front().get_half_size(mean_size));
|
||||
@ -648,6 +658,7 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick
|
||||
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
shader->stop_using();
|
||||
}
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
Transform3d GLGizmoRotate::local_transform(const Selection& selection) const
|
||||
|
@ -35,7 +35,9 @@ private:
|
||||
float m_snap_fine_in_radius{ 0.0f };
|
||||
float m_snap_fine_out_radius{ 0.0f };
|
||||
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
GLModel m_cone;
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
GLModel m_circle;
|
||||
GLModel m_scale;
|
||||
@ -55,6 +57,7 @@ private:
|
||||
|
||||
ColorRGBA m_drag_color;
|
||||
ColorRGBA m_highlight_color;
|
||||
|
||||
public:
|
||||
GLGizmoRotate(GLCanvas3D& parent, Axis axis);
|
||||
virtual ~GLGizmoRotate() = default;
|
||||
@ -104,7 +107,9 @@ private:
|
||||
void render_angle() const;
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
void render_grabber(const BoundingBoxf3& box);
|
||||
#if !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
void render_grabber_extension(const BoundingBoxf3& box, bool picking);
|
||||
#endif // !ENABLE_GIZMO_GRABBER_REFACTOR
|
||||
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
Transform3d local_transform(const Selection& selection) const;
|
||||
|
@ -54,6 +54,7 @@ public:
|
||||
inp_choices.size(), inp_choices.data(), wxCB_READONLY | wxCB_DROPDOWN);
|
||||
|
||||
szchoices->Add(m_import_dropdown);
|
||||
szchoices->AddStretchSpacer(1);
|
||||
szchoices->Add(new wxStaticText(this, wxID_ANY, _L("Quality") + ": "), 0, wxALIGN_CENTER | wxALL, 5);
|
||||
|
||||
static const std::vector<wxString> qual_choices = {
|
||||
@ -65,7 +66,7 @@ public:
|
||||
m_quality_dropdown = new wxComboBox(
|
||||
this, wxID_ANY, qual_choices[0], wxDefaultPosition, wxDefaultSize,
|
||||
qual_choices.size(), qual_choices.data(), wxCB_READONLY | wxCB_DROPDOWN);
|
||||
szchoices->Add(m_quality_dropdown);
|
||||
szchoices->Add(m_quality_dropdown, 1);
|
||||
|
||||
m_import_dropdown->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &) {
|
||||
if (get_selection() == Sel::profileOnly)
|
||||
@ -73,14 +74,20 @@ public:
|
||||
else m_quality_dropdown->Enable();
|
||||
});
|
||||
|
||||
szvert->Add(szchoices, 0, wxALL, 5);
|
||||
szvert->AddStretchSpacer(1);
|
||||
szvert->Add(szchoices, 1, wxEXPAND | wxALL, 5);
|
||||
auto szbtn = new wxBoxSizer(wxHORIZONTAL);
|
||||
szbtn->Add(new wxButton{this, wxID_CANCEL});
|
||||
szbtn->Add(new wxButton{this, wxID_CANCEL}, 0, wxRIGHT, 5);
|
||||
szbtn->Add(new wxButton{this, wxID_OK});
|
||||
szvert->Add(szbtn, 0, wxALIGN_RIGHT | wxALL, 5);
|
||||
|
||||
SetSizerAndFit(szvert);
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
}
|
||||
|
||||
int ShowModal() override
|
||||
{
|
||||
CenterOnParent();
|
||||
return wxDialog::ShowModal();
|
||||
}
|
||||
|
||||
Sel get_selection() const override
|
||||
|
@ -139,6 +139,7 @@ void SLAImportJob::finalize(bool canceled, std::exception_ptr &eptr)
|
||||
config += std::move(p->profile);
|
||||
|
||||
wxGetApp().preset_bundle->load_config_model(name, std::move(config));
|
||||
p->plater->check_selected_presets_visibility(ptSLA);
|
||||
wxGetApp().load_current_presets();
|
||||
}
|
||||
|
||||
|
@ -1821,6 +1821,8 @@ bool MainFrame::load_config_file(const std::string &path)
|
||||
show_error(this, ex.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_plater->check_selected_presets_visibility(ptFFF);
|
||||
wxGetApp().load_current_presets();
|
||||
return true;
|
||||
}
|
||||
|
@ -2336,6 +2336,52 @@ std::string Plater::priv::get_config(const std::string &key) const
|
||||
return wxGetApp().app_config->get(key);
|
||||
}
|
||||
|
||||
// After loading of the presets from project, check if they are visible.
|
||||
// Set them to visible if they are not.
|
||||
void Plater::check_selected_presets_visibility(PrinterTechnology loaded_printer_technology)
|
||||
{
|
||||
auto update_selected_preset_visibility = [](PresetCollection& presets, std::vector<std::string>& names) {
|
||||
if (!presets.get_selected_preset().is_visible) {
|
||||
assert(presets.get_selected_preset().name == presets.get_edited_preset().name);
|
||||
presets.get_selected_preset().is_visible = true;
|
||||
presets.get_edited_preset().is_visible = true;
|
||||
names.emplace_back(presets.get_selected_preset().name);
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<std::string> names;
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
if (loaded_printer_technology == ptFFF) {
|
||||
update_selected_preset_visibility(preset_bundle->prints, names);
|
||||
for (const std::string& filament : preset_bundle->filament_presets) {
|
||||
Preset* preset = preset_bundle->filaments.find_preset(filament);
|
||||
if (preset && !preset->is_visible) {
|
||||
preset->is_visible = true;
|
||||
names.emplace_back(preset->name);
|
||||
if (preset->name == preset_bundle->filaments.get_edited_preset().name)
|
||||
preset_bundle->filaments.get_selected_preset().is_visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
update_selected_preset_visibility(preset_bundle->sla_prints, names);
|
||||
update_selected_preset_visibility(preset_bundle->sla_materials, names);
|
||||
}
|
||||
update_selected_preset_visibility(preset_bundle->printers, names);
|
||||
|
||||
preset_bundle->update_compatible(PresetSelectCompatibleType::Never);
|
||||
|
||||
// show notification about temporarily installed presets
|
||||
if (!names.empty()) {
|
||||
std::string notif_text = into_u8(_L_PLURAL("The preset below was temporarily installed on the active instance of PrusaSlicer",
|
||||
"The presets below were temporarily installed on the active instance of PrusaSlicer", names.size())) + ":";
|
||||
for (std::string& name : names)
|
||||
notif_text += "\n - " + name;
|
||||
get_notification_manager()->push_notification(NotificationType::CustomNotification,
|
||||
NotificationManager::NotificationLevel::PrintInfoNotificationLevel, notif_text);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_files, bool load_model, bool load_config, bool imperial_units/* = false*/)
|
||||
{
|
||||
if (input_files.empty()) { return std::vector<size_t>(); }
|
||||
@ -2435,50 +2481,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
Preset::normalize(config);
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
preset_bundle->load_config_model(filename.string(), std::move(config));
|
||||
{
|
||||
// After loading of the presets from project, check if they are visible.
|
||||
// Set them to visible if they are not.
|
||||
|
||||
auto update_selected_preset_visibility = [](PresetCollection& presets, std::vector<std::string>& names) {
|
||||
if (!presets.get_selected_preset().is_visible) {
|
||||
assert(presets.get_selected_preset().name == presets.get_edited_preset().name);
|
||||
presets.get_selected_preset().is_visible = true;
|
||||
presets.get_edited_preset().is_visible = true;
|
||||
names.emplace_back(presets.get_selected_preset().name);
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<std::string> names;
|
||||
if (loaded_printer_technology == ptFFF) {
|
||||
update_selected_preset_visibility(preset_bundle->prints, names);
|
||||
for (const std::string& filament : preset_bundle->filament_presets) {
|
||||
Preset* preset = preset_bundle->filaments.find_preset(filament);
|
||||
if (preset && !preset->is_visible) {
|
||||
preset->is_visible = true;
|
||||
names.emplace_back(preset->name);
|
||||
if (preset->name == preset_bundle->filaments.get_edited_preset().name)
|
||||
preset_bundle->filaments.get_selected_preset().is_visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
update_selected_preset_visibility(preset_bundle->sla_prints, names);
|
||||
update_selected_preset_visibility(preset_bundle->sla_materials, names);
|
||||
}
|
||||
update_selected_preset_visibility(preset_bundle->printers, names);
|
||||
|
||||
preset_bundle->update_compatible(PresetSelectCompatibleType::Never);
|
||||
|
||||
// show notification about temporarily installed presets
|
||||
if (!names.empty()) {
|
||||
std::string notif_text = into_u8(_L_PLURAL("The preset below was temporarily installed on the active instance of PrusaSlicer",
|
||||
"The presets below were temporarily installed on the active instance of PrusaSlicer", names.size())) + ":";
|
||||
for (std::string& name : names)
|
||||
notif_text += "\n - " + name;
|
||||
notification_manager->push_notification(NotificationType::CustomNotification,
|
||||
NotificationManager::NotificationLevel::PrintInfoNotificationLevel, notif_text);
|
||||
}
|
||||
}
|
||||
q->check_selected_presets_visibility(loaded_printer_technology);
|
||||
|
||||
if (loaded_printer_technology == ptFFF)
|
||||
CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, &preset_bundle->project_config);
|
||||
|
@ -175,6 +175,7 @@ public:
|
||||
std::vector<size_t> load_files(const std::vector<std::string>& input_files, bool load_model = true, bool load_config = true, bool imperial_units = false);
|
||||
// to be called on drag and drop
|
||||
bool load_files(const wxArrayString& filenames);
|
||||
void check_selected_presets_visibility(PrinterTechnology loaded_printer_technology);
|
||||
|
||||
const wxString& get_last_loaded_gcode() const { return m_last_loaded_gcode; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user