This commit is contained in:
enricoturri1966 2023-03-17 11:39:36 +01:00
commit 1e8441b057
13 changed files with 188 additions and 138 deletions

View File

@ -1,4 +1,5 @@
min_slic3r_version = 2.6.0-alpha5
1.7.0-alpha2 Updated compatibility condition in some filament profiles (Prusa XL).
1.7.0-alpha1 Added profiles for Original Prusa XL. Added filament profile for Prusament PETG Tungsten 75%.
min_slic3r_version = 2.6.0-alpha1
1.7.0-alpha0 Added profiles for Print With Smile filaments.
@ -6,6 +7,7 @@ min_slic3r_version = 2.6.0-alpha1
1.6.0-alpha1 Updated FW version notification. Decreased min layer time for PLA.
1.6.0-alpha0 Default top fill set to monotonic lines. Updated infill/perimeter overlap values. Updated output filename format. Enabled dynamic overhang speeds.
min_slic3r_version = 2.5.1-rc0
1.6.2 Updated compatibility condition in some filament profiles (Prusa XL).
1.6.1 Added filament profile for Prusament PETG Tungsten 75%. Updated Prusa XL profiles.
1.6.0 Added Original Prusa XL profiles. Updated acceleration settings for Prusa MINI. Updated infill/perimeter overlap values.
min_slic3r_version = 2.5.0-alpha0

View File

@ -5,7 +5,7 @@
name = Prusa Research
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded.
config_version = 1.7.0-alpha1
config_version = 1.7.0-alpha2
# Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaResearch/
changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
@ -5178,7 +5178,7 @@ compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI
inherits = Filatech FilaCarbon; *ABSPG*; *04PLUSPG*
first_layer_bed_temperature = 100
[filament:Filatech FilaCarbonc 0.6]
[filament:Filatech FilaCarbon @PG 0.6]
inherits = Filatech FilaCarbon @PG; *ABS06PG*
[filament:Filatech FilaCarbon @PG 0.8]
@ -6428,7 +6428,7 @@ extrusion_multiplier = 1.03
filament_cost = 54.99
filament_density = 1.27
filament_colour = #BBBBBB
compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
[filament:Prusament PETG Carbon Fiber @PG]
inherits = Prusament PETG; *PETPG*; *04PLUSPG*
@ -7969,7 +7969,7 @@ temperature = 285
first_layer_bed_temperature = 90
bed_temperature = 90
fan_below_layer_time = 10
compatible_printers_condition = printer_model!="MINI" and ! single_extruder_multi_material
compatible_printers_condition = printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material
max_fan_speed = 15
min_fan_speed = 15
filament_type = PA

View File

@ -957,7 +957,7 @@ namespace Slic3r {
try
{
res = mz_zip_reader_extract_file_to_callback(&archive, stat.m_filename, [](void* pOpaque, mz_uint64 file_ofs, const void* pBuf, size_t n)->size_t {
res = mz_zip_reader_extract_to_callback(&archive, stat.m_file_index, [](void* pOpaque, mz_uint64 file_ofs, const void* pBuf, size_t n)->size_t {
CallbackData* data = (CallbackData*)pOpaque;
if (!XML_Parse(data->parser, (const char*)pBuf, (int)n, (file_ofs + n == data->stat.m_uncomp_size) ? 1 : 0) || data->importer.parse_error()) {
char error_buf[1024];
@ -991,7 +991,7 @@ namespace Slic3r {
{
if (stat.m_uncomp_size > 0) {
std::string buffer((size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0) {
add_error("Error while reading cut information data to buffer");
return;
@ -1053,7 +1053,7 @@ namespace Slic3r {
{
if (stat.m_uncomp_size > 0) {
std::string buffer((size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0) {
add_error("Error while reading config data to buffer");
return;
@ -1073,7 +1073,7 @@ namespace Slic3r {
{
if (stat.m_uncomp_size > 0) {
std::string buffer((size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0) {
add_error("Error while reading layer heights profile data to buffer");
return;
@ -1135,7 +1135,7 @@ namespace Slic3r {
{
if (stat.m_uncomp_size > 0) {
std::string buffer((size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0) {
add_error("Error while reading layer config ranges data to buffer");
return;
@ -1192,7 +1192,7 @@ namespace Slic3r {
{
if (stat.m_uncomp_size > 0) {
std::string buffer((size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0) {
add_error("Error while reading sla support points data to buffer");
return;
@ -1274,7 +1274,7 @@ namespace Slic3r {
{
if (stat.m_uncomp_size > 0) {
std::string buffer(size_t(stat.m_uncomp_size), 0);
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0) {
add_error("Error while reading sla support points data to buffer");
return;
@ -1379,7 +1379,7 @@ namespace Slic3r {
return false;
}
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, (size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, parser_buffer, (size_t)stat.m_uncomp_size, 0);
if (res == 0) {
add_error("Error while reading config data to buffer");
return false;
@ -1399,7 +1399,7 @@ namespace Slic3r {
{
if (stat.m_uncomp_size > 0) {
std::string buffer((size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0) {
add_error("Error while reading custom Gcodes per height data to buffer");
return;

View File

@ -965,7 +965,7 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi
try
{
res = mz_zip_reader_extract_file_to_callback(&archive, stat.m_filename, [](void* pOpaque, mz_uint64 file_ofs, const void* pBuf, size_t n)->size_t {
res = mz_zip_reader_extract_to_callback(&archive, stat.m_file_index, [](void* pOpaque, mz_uint64 file_ofs, const void* pBuf, size_t n)->size_t {
CallbackData* data = (CallbackData*)pOpaque;
if (!XML_Parse(data->parser, (const char*)pBuf, (int)n, (file_ofs + n == data->stat.m_uncomp_size) ? 1 : 0) || data->ctx.error())
{

View File

@ -18,7 +18,7 @@ boost::property_tree::ptree read_ini(const mz_zip_archive_file_stat &entry,
{
std::string buf(size_t(entry.m_uncomp_size), '\0');
if (!mz_zip_reader_extract_file_to_mem(&zip.arch, entry.m_filename,
if (!mz_zip_reader_extract_to_mem(&zip.arch, entry.m_file_index,
buf.data(), buf.size(), 0))
throw Slic3r::FileIOError(zip.get_errorstr());
@ -35,7 +35,7 @@ EntryBuffer read_entry(const mz_zip_archive_file_stat &entry,
{
std::vector<uint8_t> buf(entry.m_uncomp_size);
if (!mz_zip_reader_extract_file_to_mem(&zip.arch, entry.m_filename,
if (!mz_zip_reader_extract_to_mem(&zip.arch, entry.m_file_index,
buf.data(), buf.size(), 0))
throw Slic3r::FileIOError(zip.get_errorstr());

View File

@ -789,10 +789,11 @@ std::string CoolingBuffer::apply_layer_cooldown(
}
#undef EXTRUDER_CONFIG
bridge_fan_control = bridge_fan_speed > fan_speed_new;
} else {
} else { // fan disabled
bridge_fan_control = false;
bridge_fan_speed = 0;
fan_speed_new = 0;
custom_fan_speed_limits.second = 0;
}
if (fan_speed_new != m_fan_speed) {
m_fan_speed = fan_speed_new;

View File

@ -1627,7 +1627,7 @@ void PrintObject::bridge_over_infill()
contains_only_lightning = false;
}
Polygons fill_polys = to_polygons(region->fill_expolygons());
unsupported_area = union_(unsupported_area, expand(fill_polys, spacing));
unsupported_area.insert(unsupported_area.end(), fill_polys.begin(), fill_polys.end());
for (const Surface &surface : region->fill_surfaces()) {
if (surface.surface_type != stInternal || region->region().config().fill_density.value == 100) {
Polygons p = to_polygons(surface.expolygon);
@ -1635,9 +1635,10 @@ void PrintObject::bridge_over_infill()
}
}
}
unsupported_area = closing(unsupported_area, SCALED_EPSILON);
lower_layer_solids = expand(lower_layer_solids, 4 * spacing);
unsupported_area = shrink(unsupported_area, 5 * spacing);
unsupported_area = shrink(unsupported_area, 4 * spacing);
unsupported_area = diff(unsupported_area, lower_layer_solids);
for (const LayerRegion *region : layer->regions()) {
@ -1647,18 +1648,25 @@ void PrintObject::bridge_over_infill()
bool partially_supported = area(unsupported) < area(to_polygons(s->expolygon)) - EPSILON;
if (!unsupported.empty() && (!partially_supported || area(unsupported) > 5 * 5 * spacing * spacing)) {
Polygons worth_bridging = intersection(to_polygons(s->expolygon), expand(unsupported, 5 * spacing));
for (Polygon p : diff(to_polygons(s->expolygon), worth_bridging)) {
if (p.area() < region->flow(frSolidInfill, true).scaled_spacing() * scale_(12.0)) {
for (const Polygon& p : diff(to_polygons(s->expolygon), expand(worth_bridging, spacing))) {
auto area = p.area();
if (area < spacing * scale_(12.0) && area > spacing * spacing) {
worth_bridging.push_back(p);
}
}
worth_bridging = intersection(closing(worth_bridging, 3 * region->flow(frSolidInfill, true).scaled_spacing()), s->expolygon);
worth_bridging = intersection(closing(worth_bridging, 2 * spacing), s->expolygon);
candidate_surfaces.push_back(CandidateSurface(s, lidx, worth_bridging, region, 0, contains_only_lightning));
#ifdef DEBUG_BRIDGE_OVER_INFILL
debug_draw(std::to_string(lidx) + "_candidate_surface_" + std::to_string(area(s->expolygon)),
to_lines(region->layer()->lslices), to_lines(s->expolygon), to_lines(worth_bridging),
to_lines(unsupported_area));
#endif
#ifdef DEBUG_BRIDGE_OVER_INFILL
debug_draw(std::to_string(lidx) + "_candidate_processing_" + std::to_string(area(s->expolygon)),
to_lines(unsupported), to_lines(intersection(to_polygons(s->expolygon), expand(unsupported, 5 * spacing))),
to_lines(diff(to_polygons(s->expolygon), expand(worth_bridging, spacing))),
to_lines(unsupported_area));
#endif
}
}
@ -1765,9 +1773,9 @@ void PrintObject::bridge_over_infill()
// LAMBDA to gather areas with sparse infill deep enough that we can fit thick bridges there.
auto gather_areas_w_depth = [target_flow_height_factor](const PrintObject *po, int lidx, float target_flow_height) {
// Gather lower layers sparse infill areas, to depth defined by used bridge flow
Polygons lower_layers_sparse_infill{};
Polygons not_sparse_infill{};
// Gather layers sparse infill areas, to depth defined by used bridge flow
ExPolygons layers_sparse_infill{};
ExPolygons not_sparse_infill{};
double bottom_z = po->get_layer(lidx)->print_z - target_flow_height * target_flow_height_factor - EPSILON;
for (int i = int(lidx) - 1; i >= 0; --i) {
// Stop iterating if layer is lower than bottom_z.
@ -1778,19 +1786,19 @@ void PrintObject::bridge_over_infill()
for (const LayerRegion *region : layer->regions()) {
bool has_low_density = region->region().config().fill_density.value < 100;
for (const Surface &surface : region->fill_surfaces()) {
if (surface.surface_type == stInternal && has_low_density) {
Polygons p = to_polygons(surface.expolygon);
lower_layers_sparse_infill.insert(lower_layers_sparse_infill.end(), p.begin(), p.end());
if ((surface.surface_type == stInternal && has_low_density) || surface.surface_type == stInternalVoid ) {
layers_sparse_infill.push_back(surface.expolygon);
} else {
Polygons p = to_polygons(surface.expolygon);
not_sparse_infill.insert(not_sparse_infill.end(), p.begin(), p.end());
not_sparse_infill.push_back(surface.expolygon);
}
}
}
lower_layers_sparse_infill = union_(lower_layers_sparse_infill);
}
lower_layers_sparse_infill = closing(lower_layers_sparse_infill, SCALED_EPSILON);
return diff(lower_layers_sparse_infill, not_sparse_infill);
layers_sparse_infill = union_ex(layers_sparse_infill);
layers_sparse_infill = closing_ex(layers_sparse_infill, SCALED_EPSILON);
not_sparse_infill = union_ex(not_sparse_infill);
not_sparse_infill = closing_ex(not_sparse_infill, SCALED_EPSILON);
return diff(layers_sparse_infill, not_sparse_infill);
};
// LAMBDA do determine optimal bridging angle
@ -1927,7 +1935,7 @@ void PrintObject::bridge_over_infill()
});
if (maybe_below_anchor != anchors_intersections.rend()) {
section.a = maybe_below_anchor->first;
section.a.y() -= bridging_flow.scaled_width() * (0.5 + 1.0);
section.a.y() -= bridging_flow.scaled_width() * (0.5 + 0.5);
}
auto maybe_upper_anchor = std::upper_bound(anchors_intersections.begin(), anchors_intersections.end(), section.b,
@ -1936,7 +1944,7 @@ void PrintObject::bridge_over_infill()
});
if (maybe_upper_anchor != anchors_intersections.end()) {
section.b = maybe_upper_anchor->first;
section.b.y() += bridging_flow.scaled_width() * (0.5 + 1.0);
section.b.y() += bridging_flow.scaled_width() * (0.5 + 0.5);
}
}
@ -2059,6 +2067,7 @@ void PrintObject::bridge_over_infill()
});
// Gather deep infill areas, where thick bridges fit
coordf_t spacing = surfaces_by_layer[lidx].front().region->flow(frSolidInfill, true).scaled_spacing();
coordf_t target_flow_height = surfaces_by_layer[lidx].front().region->flow(frSolidInfill, true).height() * target_flow_height_factor;
Polygons deep_infill_area = gather_areas_w_depth(po, lidx, target_flow_height);
@ -2079,6 +2088,8 @@ void PrintObject::bridge_over_infill()
}
}
deep_infill_area = expand(deep_infill_area, spacing);
// Now gather expansion polygons - internal infill on current layer, from which we can cut off anchors
Polygons expansion_area;
Polygons total_fill_area;
@ -2088,30 +2099,42 @@ void PrintObject::bridge_over_infill()
Polygons fill_polys = to_polygons(region->fill_expolygons());
total_fill_area.insert(total_fill_area.end(), fill_polys.begin(), fill_polys.end());
}
total_fill_area = closing(total_fill_area, SCALED_EPSILON);
expansion_area = closing(expansion_area, SCALED_EPSILON);
expansion_area = intersection(expansion_area, deep_infill_area);
Polylines anchors = intersection_pl(infill_lines[lidx - 1], expansion_area);
total_fill_area = closing(total_fill_area, SCALED_EPSILON);
expansion_area = closing(expansion_area, SCALED_EPSILON);
expansion_area = intersection(expansion_area, deep_infill_area);
Polylines anchors = intersection_pl(infill_lines[lidx - 1], expansion_area);
#ifdef DEBUG_BRIDGE_OVER_INFILL
debug_draw(std::to_string(lidx) + "_" + std::to_string(cluster_idx) + "_" + std::to_string(job_idx) + "_" +
"_total_area",
to_lines(total_fill_area), to_lines(expansion_area), to_lines(deep_infill_area), to_lines(anchors));
#endif
std::vector<CandidateSurface> expanded_surfaces;
expanded_surfaces.reserve(surfaces_by_layer[lidx].size());
for (const CandidateSurface &candidate : surfaces_by_layer[lidx]) {
const Flow &flow = candidate.region->bridging_flow(frSolidInfill, true);
Polygons area_to_be_bridge = intersection(candidate.new_polys, deep_infill_area);
const Flow &flow = candidate.region->bridging_flow(frSolidInfill, true);
Polygons area_to_be_bridge = expand(candidate.new_polys, flow.scaled_spacing());
area_to_be_bridge = intersection(area_to_be_bridge, deep_infill_area);
Polygons limiting_area = union_(area_to_be_bridge, expansion_area);
if (area_to_be_bridge.empty())
continue;
area_to_be_bridge = expand(area_to_be_bridge, flow.scaled_spacing());
Polylines boundary_plines = to_polylines(expand(total_fill_area, 1.3 * flow.scaled_spacing()));
{
Polylines expansion_plines = to_polylines(expansion_area);
boundary_plines.insert(boundary_plines.end(), expansion_plines.begin(), expansion_plines.end());
Polylines expanded_expansion_plines = to_polylines(expand(expansion_area, 1.3 * flow.scaled_spacing()));
boundary_plines.insert(boundary_plines.end(), expanded_expansion_plines.begin(), expanded_expansion_plines.end());
Polylines limiting_plines = to_polylines(expand(limiting_area, 0.3*flow.spacing()));
boundary_plines.insert(boundary_plines.end(), limiting_plines.begin(), limiting_plines.end());
}
#ifdef DEBUG_BRIDGE_OVER_INFILL
int r = rand();
debug_draw(std::to_string(lidx) + "_" + std::to_string(cluster_idx) + "_" + std::to_string(job_idx) + "_" +
"_anchors_" + std::to_string(r),
to_lines(area_to_be_bridge), to_lines(boundary_plines), to_lines(anchors), to_lines(expansion_area));
#endif
double bridging_angle = 0;
if (!anchors.empty()) {
bridging_angle = determine_bridging_angle(area_to_be_bridge, to_lines(anchors),
@ -2145,14 +2168,13 @@ void PrintObject::bridge_over_infill()
}
bridging_area = opening(bridging_area, flow.scaled_spacing());
bridging_area = intersection(bridging_area, limiting_area);
bridging_area = intersection(bridging_area, total_fill_area);
expansion_area = diff(expansion_area, bridging_area);
#ifdef DEBUG_BRIDGE_OVER_INFILL
debug_draw(std::to_string(lidx) + "_" + std::to_string(cluster_idx) + "_" + std::to_string(job_idx) +
"_expanded_bridging",
to_lines(layer->lslices), to_lines(boundary_plines), to_lines(candidate.new_polys),
to_lines(bridging_area));
debug_draw(std::to_string(lidx) + "_" + std::to_string(cluster_idx) + "_" + std::to_string(job_idx) + "_" + "_expanded_bridging" + std::to_string(r),
to_lines(layer->lslices), to_lines(boundary_plines), to_lines(candidate.new_polys), to_lines(bridging_area));
#endif
expanded_surfaces.push_back(CandidateSurface(candidate.original_surface, candidate.layer_index, bridging_area,

View File

@ -166,11 +166,11 @@ ArchiveViewCtrl::~ArchiveViewCtrl()
}
}
FileArchiveDialog::FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* archive, std::vector<boost::filesystem::path>& selected_paths)
FileArchiveDialog::FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* archive, std::vector<std::pair<boost::filesystem::path, size_t>>& selected_paths_w_size)
: DPIDialog(parent_window, wxID_ANY, _(L("Archive preview")), wxDefaultPosition,
wxSize(45 * wxGetApp().em_unit(), 40 * wxGetApp().em_unit()),
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX)
, m_selected_paths (selected_paths)
, m_selected_paths_w_size (selected_paths_w_size)
{
#ifdef _WIN32
wxGetApp().UpdateDarkUI(this);
@ -213,7 +213,7 @@ FileArchiveDialog::FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* ar
const std::regex pattern_drop(".*[.](stl|obj|amf|3mf|prusa|step|stp)", std::regex::icase);
mz_uint num_entries = mz_zip_reader_get_num_files(archive);
mz_zip_archive_file_stat stat;
std::vector<boost::filesystem::path> filtered_entries;
std::vector<std::pair<boost::filesystem::path, size_t>> filtered_entries; // second is unzipped size
for (mz_uint i = 0; i < num_entries; ++i) {
if (mz_zip_reader_file_stat(archive, i, &stat)) {
std::string extra(1024, 0);
@ -232,22 +232,25 @@ FileArchiveDialog::FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* ar
// filter out MACOS specific hidden files
if (boost::algorithm::starts_with(path.string(), "__MACOSX"))
continue;
filtered_entries.emplace_back(std::move(path));
filtered_entries.emplace_back(std::move(path), stat.m_uncomp_size);
}
}
// sorting files will help adjust_stack function to not create multiple same folders
std::sort(filtered_entries.begin(), filtered_entries.end(), [](const boost::filesystem::path& p1, const boost::filesystem::path& p2){ return p1.string() > p2.string(); });
std::sort(filtered_entries.begin(), filtered_entries.end(), [](const std::pair<boost::filesystem::path, size_t>& p1, const std::pair<boost::filesystem::path, size_t>& p2){ return p1.first.string() < p2.first.string(); });
size_t entry_count = 0;
size_t depth = 1;
for (const boost::filesystem::path& path : filtered_entries)
for (const auto& entry : filtered_entries)
{
const boost::filesystem::path& path = entry.first;
std::shared_ptr<ArchiveViewNode> parent(nullptr);
depth = std::max(depth, adjust_stack(path, stack));
if (!stack.empty())
parent = stack.back();
if (std::regex_match(path.extension().string(), pattern_drop)) { // this leaves out non-compatible files
m_avc->get_model()->AddFile(parent, boost::nowide::widen(path.filename().string()), false)->set_fullpath(/*std::move(path)*/path); // filename string to wstring?
std::shared_ptr<ArchiveViewNode> new_node = m_avc->get_model()->AddFile(parent, boost::nowide::widen(path.filename().string()), false);
new_node->set_fullpath(/*std::move(path)*/path); // filename string to wstring?
new_node->set_size(entry.second);
entry_count++;
}
}
@ -305,12 +308,12 @@ void FileArchiveDialog::on_open_button()
wxDataViewItemArray top_items;
m_avc->get_model()->GetChildren(wxDataViewItem(nullptr), top_items);
std::function<void(ArchiveViewNode*)> deep_fill = [&paths = m_selected_paths, &deep_fill](ArchiveViewNode* node){
std::function<void(ArchiveViewNode*)> deep_fill = [&paths = m_selected_paths_w_size, &deep_fill](ArchiveViewNode* node){
if (node == nullptr)
return;
if (node->get_children().empty()) {
if (node->get_toggle())
paths.emplace_back(node->get_fullpath());
paths.emplace_back(node->get_fullpath(), node->get_size());
} else {
for (std::shared_ptr<ArchiveViewNode> child : node->get_children())
deep_fill(child.get());

View File

@ -33,6 +33,8 @@ public:
void set_is_folder(bool is_folder) { m_folder = is_folder; }
void set_fullpath(boost::filesystem::path path) { m_fullpath = path; }
boost::filesystem::path get_fullpath() const { return m_fullpath; }
void set_size(size_t size) { m_size = size; }
size_t get_size() const { return m_size; }
private:
wxString m_name;
@ -43,6 +45,7 @@ private:
bool m_folder { false };
boost::filesystem::path m_fullpath;
bool m_container { false };
size_t m_size { 0 };
};
class ArchiveViewModel : public wxDataViewModel
@ -100,7 +103,7 @@ protected:
class FileArchiveDialog : public DPIDialog
{
public:
FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* archive, std::vector<boost::filesystem::path>& selected_paths);
FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* archive, std::vector<std::pair<boost::filesystem::path, size_t>>& selected_paths_w_size);
protected:
void on_dpi_changed(const wxRect& suggested_rect) override;
@ -109,7 +112,9 @@ protected:
void on_all_button();
void on_none_button();
std::vector<boost::filesystem::path>& m_selected_paths;
// chosen files are written into this vector and returned to caller via reference.
// path in archive and decompressed size. The size can be used to distinguish between files with same path.
std::vector<std::pair<boost::filesystem::path,size_t>>& m_selected_paths_w_size;
ArchiveViewCtrl* m_avc;
};

View File

@ -5546,96 +5546,98 @@ bool Plater::preview_zip_archive(const boost::filesystem::path& archive_path)
std::string err_msg = GUI::format(_utf8("Loading of a zip archive on path %1% has failed."), archive_path.string());
throw Slic3r::FileIOError(err_msg);
}
mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
mz_zip_archive_file_stat stat;
std::vector<fs::path> selected_paths;
// selected_paths contains paths and its uncompressed size. The size is used to distinguish between files with same path.
std::vector<std::pair<fs::path, size_t>> selected_paths;
FileArchiveDialog dlg(static_cast<wxWindow*>(wxGetApp().mainframe), &archive, selected_paths);
if (dlg.ShowModal() == wxID_OK)
{
{
std::string archive_path_string = archive_path.string();
archive_path_string = archive_path_string.substr(0, archive_path_string.size() - 4);
fs::path archive_dir(wxStandardPaths::Get().GetTempDir().utf8_str().data());
for (auto& path_w_size : selected_paths) {
const fs::path& path = path_w_size.first;
size_t size = path_w_size.second;
// find path in zip archive
for (mz_uint i = 0; i < num_entries; ++i) {
if (mz_zip_reader_file_stat(&archive, i, &stat)) {
if (size != stat.m_uncomp_size) // size must fit
continue;
wxString wname = boost::nowide::widen(stat.m_filename);
std::string name = boost::nowide::narrow(wname);
fs::path archive_path(name);
for (mz_uint i = 0; i < num_entries; ++i) {
if (mz_zip_reader_file_stat(&archive, i, &stat)) {
wxString wname = boost::nowide::widen(stat.m_filename);
std::string name = boost::nowide::narrow(wname);
fs::path archive_path(name);
std::string extra(1024, 0);
size_t extra_size = mz_zip_reader_get_filename_from_extra(&archive, i, extra.data(), extra.size());
if (extra_size > 0) {
archive_path = fs::path(extra.substr(0, extra_size));
name = archive_path.string();
}
std::string extra(1024, 0);
size_t extra_size = mz_zip_reader_get_filename_from_extra(&archive, i, extra.data(), extra.size());
if (extra_size > 0) {
archive_path = fs::path(extra.substr(0, extra_size));
name = archive_path.string();
}
if (archive_path.empty())
continue;
if (path != archive_path)
continue;
// decompressing
try
{
std::replace(name.begin(), name.end(), '\\', '/');
// rename if file exists
std::string filename = path.filename().string();
std::string extension = boost::filesystem::extension(path);
std::string just_filename = filename.substr(0, filename.size() - extension.size());
std::string final_filename = just_filename;
if (archive_path.empty())
continue;
for (const auto& path : selected_paths) {
if (path == archive_path) {
try
size_t version = 0;
while (fs::exists(archive_dir / (final_filename + extension)))
{
std::replace(name.begin(), name.end(), '\\', '/');
// rename if file exists
std::string filename = path.filename().string();
std::string extension = boost::filesystem::extension(path);
std::string just_filename = filename.substr(0, filename.size() - extension.size());
std::string final_filename = just_filename;
size_t version = 0;
while (fs::exists(archive_dir / (final_filename + extension)))
{
++version;
final_filename = just_filename + "(" + std::to_string(version) + ")";
}
filename = final_filename + extension;
fs::path final_path = archive_dir / filename;
std::string buffer((size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0) {
wxString error_log = GUI::format_wxstr(_L("Failed to unzip file to %1%: %2% "), final_path.string(), mz_zip_get_error_string(mz_zip_get_last_error(&archive)));
BOOST_LOG_TRIVIAL(error) << error_log;
show_error(nullptr, error_log);
continue;
}
fs::fstream file(final_path, std::ios::out | std::ios::binary | std::ios::trunc);
file.write(buffer.c_str(), buffer.size());
file.close();
if (!fs::exists(final_path)) {
wxString error_log = GUI::format_wxstr(_L("Failed to find unzipped file at %1%. Unzipping of file has failed."), final_path.string());
BOOST_LOG_TRIVIAL(error) << error_log;
show_error(nullptr, error_log);
continue;
}
BOOST_LOG_TRIVIAL(info) << "Unzipped " << final_path;
if (!boost::algorithm::iends_with(filename, ".3mf") && !boost::algorithm::iends_with(filename, ".amf")) {
non_project_paths.emplace_back(final_path);
continue;
}
// if 3mf - read archive headers to find project file
if ((boost::algorithm::iends_with(filename, ".3mf") && !is_project_3mf(final_path.string())) ||
(boost::algorithm::iends_with(filename, ".amf") && !boost::algorithm::iends_with(filename, ".zip.amf"))) {
non_project_paths.emplace_back(final_path);
continue;
}
project_paths.emplace_back(final_path);
++version;
final_filename = just_filename + "(" + std::to_string(version) + ")";
}
catch (const std::exception& e)
{
// ensure the zip archive is closed and rethrow the exception
close_zip_reader(&archive);
throw Slic3r::FileIOError(e.what());
filename = final_filename + extension;
fs::path final_path = archive_dir / filename;
std::string buffer((size_t)stat.m_uncomp_size, 0);
// Decompress action. We already has correct file index in stat structure.
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0) {
wxString error_log = GUI::format_wxstr(_L("Failed to unzip file to %1%: %2% "), final_path.string(), mz_zip_get_error_string(mz_zip_get_last_error(&archive)));
BOOST_LOG_TRIVIAL(error) << error_log;
show_error(nullptr, error_log);
break;
}
// write buffer to file
fs::fstream file(final_path, std::ios::out | std::ios::binary | std::ios::trunc);
file.write(buffer.c_str(), buffer.size());
file.close();
if (!fs::exists(final_path)) {
wxString error_log = GUI::format_wxstr(_L("Failed to find unzipped file at %1%. Unzipping of file has failed."), final_path.string());
BOOST_LOG_TRIVIAL(error) << error_log;
show_error(nullptr, error_log);
break;
}
BOOST_LOG_TRIVIAL(info) << "Unzipped " << final_path;
if (!boost::algorithm::iends_with(filename, ".3mf") && !boost::algorithm::iends_with(filename, ".amf")) {
non_project_paths.emplace_back(final_path);
break;
}
// if 3mf - read archive headers to find project file
if ((boost::algorithm::iends_with(filename, ".3mf") && !is_project_3mf(final_path.string())) ||
(boost::algorithm::iends_with(filename, ".amf") && !boost::algorithm::iends_with(filename, ".zip.amf"))) {
non_project_paths.emplace_back(final_path);
break;
}
project_paths.emplace_back(final_path);
break;
}
catch (const std::exception& e)
{
// ensure the zip archive is closed and rethrow the exception
close_zip_reader(&archive);
throw Slic3r::FileIOError(e.what());
}
}
}
}

View File

@ -1135,4 +1135,16 @@ void PrusaConnect::set_http_post_header_args(Http& http, PrintHostPostUploadActi
}
wxString PrusaConnect::get_test_ok_msg() const
{
return _(L("Connection to PrusaConnect works correctly."));
}
wxString PrusaConnect::get_test_failed_msg(wxString& msg) const
{
return GUI::from_u8((boost::format("%s: %s")
% _utf8(L("Could not connect to PrusaConnect"))
% std::string(msg.ToUTF8())).str());
}
}

View File

@ -130,8 +130,11 @@ class PrusaConnect : public PrusaLink
public:
PrusaConnect(DynamicPrintConfig* config);
~PrusaConnect() override = default;
wxString get_test_ok_msg() const override;
wxString get_test_failed_msg(wxString& msg) const override;
PrintHostPostUploadActions get_post_upload_actions() const override { return PrintHostPostUploadAction::StartPrint | PrintHostPostUploadAction::QueuePrint; }
const char* get_name() const override { return "PrusaConnect"; }
bool get_storage(wxArrayString& storage_path, wxArrayString& storage_name) const override { return false; }
protected:
void set_http_post_header_args(Http& http, PrintHostPostUploadAction post_action) const override;
};

View File

@ -399,7 +399,7 @@ void PresetUpdater::priv::sync_config(const VendorMap vendors, const std::string
std::string name(stat.m_filename);
if (stat.m_uncomp_size > 0) {
std::string buffer((size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0) {
BOOST_LOG_TRIVIAL(error) << "Failed to unzip " << stat.m_filename;
continue;