mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-09-27 01:03:19 +08:00
Merge branch 'master' of https://github.com/Prusa-Development/PrusaSlicerPrivate into et_sequential
This commit is contained in:
commit
1e8441b057
@ -1,4 +1,5 @@
|
|||||||
min_slic3r_version = 2.6.0-alpha5
|
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%.
|
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
|
min_slic3r_version = 2.6.0-alpha1
|
||||||
1.7.0-alpha0 Added profiles for Print With Smile filaments.
|
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-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.
|
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
|
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.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.
|
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
|
min_slic3r_version = 2.5.0-alpha0
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
name = Prusa Research
|
name = Prusa Research
|
||||||
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
# 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.
|
# 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?
|
# Where to get the updates from?
|
||||||
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaResearch/
|
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%
|
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*
|
inherits = Filatech FilaCarbon; *ABSPG*; *04PLUSPG*
|
||||||
first_layer_bed_temperature = 100
|
first_layer_bed_temperature = 100
|
||||||
|
|
||||||
[filament:Filatech FilaCarbonc 0.6]
|
[filament:Filatech FilaCarbon @PG 0.6]
|
||||||
inherits = Filatech FilaCarbon @PG; *ABS06PG*
|
inherits = Filatech FilaCarbon @PG; *ABS06PG*
|
||||||
|
|
||||||
[filament:Filatech FilaCarbon @PG 0.8]
|
[filament:Filatech FilaCarbon @PG 0.8]
|
||||||
@ -6428,7 +6428,7 @@ extrusion_multiplier = 1.03
|
|||||||
filament_cost = 54.99
|
filament_cost = 54.99
|
||||||
filament_density = 1.27
|
filament_density = 1.27
|
||||||
filament_colour = #BBBBBB
|
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]
|
[filament:Prusament PETG Carbon Fiber @PG]
|
||||||
inherits = Prusament PETG; *PETPG*; *04PLUSPG*
|
inherits = Prusament PETG; *PETPG*; *04PLUSPG*
|
||||||
@ -7969,7 +7969,7 @@ temperature = 285
|
|||||||
first_layer_bed_temperature = 90
|
first_layer_bed_temperature = 90
|
||||||
bed_temperature = 90
|
bed_temperature = 90
|
||||||
fan_below_layer_time = 10
|
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
|
max_fan_speed = 15
|
||||||
min_fan_speed = 15
|
min_fan_speed = 15
|
||||||
filament_type = PA
|
filament_type = PA
|
||||||
|
@ -957,7 +957,7 @@ namespace Slic3r {
|
|||||||
|
|
||||||
try
|
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;
|
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()) {
|
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];
|
char error_buf[1024];
|
||||||
@ -991,7 +991,7 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
if (stat.m_uncomp_size > 0) {
|
if (stat.m_uncomp_size > 0) {
|
||||||
std::string buffer((size_t)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) {
|
if (res == 0) {
|
||||||
add_error("Error while reading cut information data to buffer");
|
add_error("Error while reading cut information data to buffer");
|
||||||
return;
|
return;
|
||||||
@ -1053,7 +1053,7 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
if (stat.m_uncomp_size > 0) {
|
if (stat.m_uncomp_size > 0) {
|
||||||
std::string buffer((size_t)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) {
|
if (res == 0) {
|
||||||
add_error("Error while reading config data to buffer");
|
add_error("Error while reading config data to buffer");
|
||||||
return;
|
return;
|
||||||
@ -1073,7 +1073,7 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
if (stat.m_uncomp_size > 0) {
|
if (stat.m_uncomp_size > 0) {
|
||||||
std::string buffer((size_t)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) {
|
if (res == 0) {
|
||||||
add_error("Error while reading layer heights profile data to buffer");
|
add_error("Error while reading layer heights profile data to buffer");
|
||||||
return;
|
return;
|
||||||
@ -1135,7 +1135,7 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
if (stat.m_uncomp_size > 0) {
|
if (stat.m_uncomp_size > 0) {
|
||||||
std::string buffer((size_t)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) {
|
if (res == 0) {
|
||||||
add_error("Error while reading layer config ranges data to buffer");
|
add_error("Error while reading layer config ranges data to buffer");
|
||||||
return;
|
return;
|
||||||
@ -1192,7 +1192,7 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
if (stat.m_uncomp_size > 0) {
|
if (stat.m_uncomp_size > 0) {
|
||||||
std::string buffer((size_t)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) {
|
if (res == 0) {
|
||||||
add_error("Error while reading sla support points data to buffer");
|
add_error("Error while reading sla support points data to buffer");
|
||||||
return;
|
return;
|
||||||
@ -1274,7 +1274,7 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
if (stat.m_uncomp_size > 0) {
|
if (stat.m_uncomp_size > 0) {
|
||||||
std::string buffer(size_t(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) {
|
if (res == 0) {
|
||||||
add_error("Error while reading sla support points data to buffer");
|
add_error("Error while reading sla support points data to buffer");
|
||||||
return;
|
return;
|
||||||
@ -1379,7 +1379,7 @@ namespace Slic3r {
|
|||||||
return false;
|
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) {
|
if (res == 0) {
|
||||||
add_error("Error while reading config data to buffer");
|
add_error("Error while reading config data to buffer");
|
||||||
return false;
|
return false;
|
||||||
@ -1399,7 +1399,7 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
if (stat.m_uncomp_size > 0) {
|
if (stat.m_uncomp_size > 0) {
|
||||||
std::string buffer((size_t)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) {
|
if (res == 0) {
|
||||||
add_error("Error while reading custom Gcodes per height data to buffer");
|
add_error("Error while reading custom Gcodes per height data to buffer");
|
||||||
return;
|
return;
|
||||||
|
@ -965,7 +965,7 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi
|
|||||||
|
|
||||||
try
|
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;
|
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())
|
if (!XML_Parse(data->parser, (const char*)pBuf, (int)n, (file_ofs + n == data->stat.m_uncomp_size) ? 1 : 0) || data->ctx.error())
|
||||||
{
|
{
|
||||||
|
@ -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');
|
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))
|
buf.data(), buf.size(), 0))
|
||||||
throw Slic3r::FileIOError(zip.get_errorstr());
|
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);
|
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))
|
buf.data(), buf.size(), 0))
|
||||||
throw Slic3r::FileIOError(zip.get_errorstr());
|
throw Slic3r::FileIOError(zip.get_errorstr());
|
||||||
|
|
||||||
|
@ -789,10 +789,11 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||||||
}
|
}
|
||||||
#undef EXTRUDER_CONFIG
|
#undef EXTRUDER_CONFIG
|
||||||
bridge_fan_control = bridge_fan_speed > fan_speed_new;
|
bridge_fan_control = bridge_fan_speed > fan_speed_new;
|
||||||
} else {
|
} else { // fan disabled
|
||||||
bridge_fan_control = false;
|
bridge_fan_control = false;
|
||||||
bridge_fan_speed = 0;
|
bridge_fan_speed = 0;
|
||||||
fan_speed_new = 0;
|
fan_speed_new = 0;
|
||||||
|
custom_fan_speed_limits.second = 0;
|
||||||
}
|
}
|
||||||
if (fan_speed_new != m_fan_speed) {
|
if (fan_speed_new != m_fan_speed) {
|
||||||
m_fan_speed = fan_speed_new;
|
m_fan_speed = fan_speed_new;
|
||||||
|
@ -1627,7 +1627,7 @@ void PrintObject::bridge_over_infill()
|
|||||||
contains_only_lightning = false;
|
contains_only_lightning = false;
|
||||||
}
|
}
|
||||||
Polygons fill_polys = to_polygons(region->fill_expolygons());
|
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()) {
|
for (const Surface &surface : region->fill_surfaces()) {
|
||||||
if (surface.surface_type != stInternal || region->region().config().fill_density.value == 100) {
|
if (surface.surface_type != stInternal || region->region().config().fill_density.value == 100) {
|
||||||
Polygons p = to_polygons(surface.expolygon);
|
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);
|
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);
|
unsupported_area = diff(unsupported_area, lower_layer_solids);
|
||||||
|
|
||||||
for (const LayerRegion *region : layer->regions()) {
|
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;
|
bool partially_supported = area(unsupported) < area(to_polygons(s->expolygon)) - EPSILON;
|
||||||
if (!unsupported.empty() && (!partially_supported || area(unsupported) > 5 * 5 * spacing * spacing)) {
|
if (!unsupported.empty() && (!partially_supported || area(unsupported) > 5 * 5 * spacing * spacing)) {
|
||||||
Polygons worth_bridging = intersection(to_polygons(s->expolygon), expand(unsupported, 5 * spacing));
|
Polygons worth_bridging = intersection(to_polygons(s->expolygon), expand(unsupported, 5 * spacing));
|
||||||
for (Polygon p : diff(to_polygons(s->expolygon), worth_bridging)) {
|
for (const Polygon& p : diff(to_polygons(s->expolygon), expand(worth_bridging, spacing))) {
|
||||||
if (p.area() < region->flow(frSolidInfill, true).scaled_spacing() * scale_(12.0)) {
|
auto area = p.area();
|
||||||
|
if (area < spacing * scale_(12.0) && area > spacing * spacing) {
|
||||||
worth_bridging.push_back(p);
|
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));
|
candidate_surfaces.push_back(CandidateSurface(s, lidx, worth_bridging, region, 0, contains_only_lightning));
|
||||||
|
|
||||||
#ifdef DEBUG_BRIDGE_OVER_INFILL
|
#ifdef DEBUG_BRIDGE_OVER_INFILL
|
||||||
debug_draw(std::to_string(lidx) + "_candidate_surface_" + std::to_string(area(s->expolygon)),
|
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(region->layer()->lslices), to_lines(s->expolygon), to_lines(worth_bridging),
|
||||||
to_lines(unsupported_area));
|
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
|
#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.
|
// 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) {
|
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
|
// Gather layers sparse infill areas, to depth defined by used bridge flow
|
||||||
Polygons lower_layers_sparse_infill{};
|
ExPolygons layers_sparse_infill{};
|
||||||
Polygons not_sparse_infill{};
|
ExPolygons not_sparse_infill{};
|
||||||
double bottom_z = po->get_layer(lidx)->print_z - target_flow_height * target_flow_height_factor - EPSILON;
|
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) {
|
for (int i = int(lidx) - 1; i >= 0; --i) {
|
||||||
// Stop iterating if layer is lower than bottom_z.
|
// Stop iterating if layer is lower than bottom_z.
|
||||||
@ -1778,19 +1786,19 @@ void PrintObject::bridge_over_infill()
|
|||||||
for (const LayerRegion *region : layer->regions()) {
|
for (const LayerRegion *region : layer->regions()) {
|
||||||
bool has_low_density = region->region().config().fill_density.value < 100;
|
bool has_low_density = region->region().config().fill_density.value < 100;
|
||||||
for (const Surface &surface : region->fill_surfaces()) {
|
for (const Surface &surface : region->fill_surfaces()) {
|
||||||
if (surface.surface_type == stInternal && has_low_density) {
|
if ((surface.surface_type == stInternal && has_low_density) || surface.surface_type == stInternalVoid ) {
|
||||||
Polygons p = to_polygons(surface.expolygon);
|
layers_sparse_infill.push_back(surface.expolygon);
|
||||||
lower_layers_sparse_infill.insert(lower_layers_sparse_infill.end(), p.begin(), p.end());
|
|
||||||
} else {
|
} else {
|
||||||
Polygons p = to_polygons(surface.expolygon);
|
not_sparse_infill.push_back(surface.expolygon);
|
||||||
not_sparse_infill.insert(not_sparse_infill.end(), p.begin(), p.end());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lower_layers_sparse_infill = union_(lower_layers_sparse_infill);
|
|
||||||
}
|
}
|
||||||
lower_layers_sparse_infill = closing(lower_layers_sparse_infill, SCALED_EPSILON);
|
layers_sparse_infill = union_ex(layers_sparse_infill);
|
||||||
return diff(lower_layers_sparse_infill, not_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
|
// LAMBDA do determine optimal bridging angle
|
||||||
@ -1927,7 +1935,7 @@ void PrintObject::bridge_over_infill()
|
|||||||
});
|
});
|
||||||
if (maybe_below_anchor != anchors_intersections.rend()) {
|
if (maybe_below_anchor != anchors_intersections.rend()) {
|
||||||
section.a = maybe_below_anchor->first;
|
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,
|
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()) {
|
if (maybe_upper_anchor != anchors_intersections.end()) {
|
||||||
section.b = maybe_upper_anchor->first;
|
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
|
// 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;
|
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);
|
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
|
// Now gather expansion polygons - internal infill on current layer, from which we can cut off anchors
|
||||||
Polygons expansion_area;
|
Polygons expansion_area;
|
||||||
Polygons total_fill_area;
|
Polygons total_fill_area;
|
||||||
@ -2088,30 +2099,42 @@ void PrintObject::bridge_over_infill()
|
|||||||
Polygons fill_polys = to_polygons(region->fill_expolygons());
|
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.insert(total_fill_area.end(), fill_polys.begin(), fill_polys.end());
|
||||||
}
|
}
|
||||||
total_fill_area = closing(total_fill_area, SCALED_EPSILON);
|
total_fill_area = closing(total_fill_area, SCALED_EPSILON);
|
||||||
expansion_area = closing(expansion_area, SCALED_EPSILON);
|
expansion_area = closing(expansion_area, SCALED_EPSILON);
|
||||||
expansion_area = intersection(expansion_area, deep_infill_area);
|
expansion_area = intersection(expansion_area, deep_infill_area);
|
||||||
Polylines anchors = intersection_pl(infill_lines[lidx - 1], expansion_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;
|
std::vector<CandidateSurface> expanded_surfaces;
|
||||||
expanded_surfaces.reserve(surfaces_by_layer[lidx].size());
|
expanded_surfaces.reserve(surfaces_by_layer[lidx].size());
|
||||||
for (const CandidateSurface &candidate : surfaces_by_layer[lidx]) {
|
for (const CandidateSurface &candidate : surfaces_by_layer[lidx]) {
|
||||||
const Flow &flow = candidate.region->bridging_flow(frSolidInfill, true);
|
const Flow &flow = candidate.region->bridging_flow(frSolidInfill, true);
|
||||||
Polygons area_to_be_bridge = intersection(candidate.new_polys, deep_infill_area);
|
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())
|
if (area_to_be_bridge.empty())
|
||||||
continue;
|
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 boundary_plines = to_polylines(expand(total_fill_area, 1.3 * flow.scaled_spacing()));
|
||||||
{
|
{
|
||||||
Polylines expansion_plines = to_polylines(expansion_area);
|
Polylines limiting_plines = to_polylines(expand(limiting_area, 0.3*flow.spacing()));
|
||||||
boundary_plines.insert(boundary_plines.end(), expansion_plines.begin(), expansion_plines.end());
|
boundary_plines.insert(boundary_plines.end(), limiting_plines.begin(), limiting_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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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;
|
double bridging_angle = 0;
|
||||||
if (!anchors.empty()) {
|
if (!anchors.empty()) {
|
||||||
bridging_angle = determine_bridging_angle(area_to_be_bridge, to_lines(anchors),
|
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 = opening(bridging_area, flow.scaled_spacing());
|
||||||
|
bridging_area = intersection(bridging_area, limiting_area);
|
||||||
bridging_area = intersection(bridging_area, total_fill_area);
|
bridging_area = intersection(bridging_area, total_fill_area);
|
||||||
expansion_area = diff(expansion_area, bridging_area);
|
expansion_area = diff(expansion_area, bridging_area);
|
||||||
|
|
||||||
#ifdef DEBUG_BRIDGE_OVER_INFILL
|
#ifdef DEBUG_BRIDGE_OVER_INFILL
|
||||||
debug_draw(std::to_string(lidx) + "_" + std::to_string(cluster_idx) + "_" + std::to_string(job_idx) +
|
debug_draw(std::to_string(lidx) + "_" + std::to_string(cluster_idx) + "_" + std::to_string(job_idx) + "_" + "_expanded_bridging" + std::to_string(r),
|
||||||
"_expanded_bridging",
|
to_lines(layer->lslices), to_lines(boundary_plines), to_lines(candidate.new_polys), to_lines(bridging_area));
|
||||||
to_lines(layer->lslices), to_lines(boundary_plines), to_lines(candidate.new_polys),
|
|
||||||
to_lines(bridging_area));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
expanded_surfaces.push_back(CandidateSurface(candidate.original_surface, candidate.layer_index, bridging_area,
|
expanded_surfaces.push_back(CandidateSurface(candidate.original_surface, candidate.layer_index, bridging_area,
|
||||||
|
@ -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,
|
: DPIDialog(parent_window, wxID_ANY, _(L("Archive preview")), wxDefaultPosition,
|
||||||
wxSize(45 * wxGetApp().em_unit(), 40 * wxGetApp().em_unit()),
|
wxSize(45 * wxGetApp().em_unit(), 40 * wxGetApp().em_unit()),
|
||||||
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX)
|
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX)
|
||||||
, m_selected_paths (selected_paths)
|
, m_selected_paths_w_size (selected_paths_w_size)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
wxGetApp().UpdateDarkUI(this);
|
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);
|
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_uint num_entries = mz_zip_reader_get_num_files(archive);
|
||||||
mz_zip_archive_file_stat stat;
|
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) {
|
for (mz_uint i = 0; i < num_entries; ++i) {
|
||||||
if (mz_zip_reader_file_stat(archive, i, &stat)) {
|
if (mz_zip_reader_file_stat(archive, i, &stat)) {
|
||||||
std::string extra(1024, 0);
|
std::string extra(1024, 0);
|
||||||
@ -232,22 +232,25 @@ FileArchiveDialog::FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* ar
|
|||||||
// filter out MACOS specific hidden files
|
// filter out MACOS specific hidden files
|
||||||
if (boost::algorithm::starts_with(path.string(), "__MACOSX"))
|
if (boost::algorithm::starts_with(path.string(), "__MACOSX"))
|
||||||
continue;
|
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
|
// 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 entry_count = 0;
|
||||||
size_t depth = 1;
|
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);
|
std::shared_ptr<ArchiveViewNode> parent(nullptr);
|
||||||
|
|
||||||
depth = std::max(depth, adjust_stack(path, stack));
|
depth = std::max(depth, adjust_stack(path, stack));
|
||||||
if (!stack.empty())
|
if (!stack.empty())
|
||||||
parent = stack.back();
|
parent = stack.back();
|
||||||
if (std::regex_match(path.extension().string(), pattern_drop)) { // this leaves out non-compatible files
|
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++;
|
entry_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -305,12 +308,12 @@ void FileArchiveDialog::on_open_button()
|
|||||||
wxDataViewItemArray top_items;
|
wxDataViewItemArray top_items;
|
||||||
m_avc->get_model()->GetChildren(wxDataViewItem(nullptr), 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)
|
if (node == nullptr)
|
||||||
return;
|
return;
|
||||||
if (node->get_children().empty()) {
|
if (node->get_children().empty()) {
|
||||||
if (node->get_toggle())
|
if (node->get_toggle())
|
||||||
paths.emplace_back(node->get_fullpath());
|
paths.emplace_back(node->get_fullpath(), node->get_size());
|
||||||
} else {
|
} else {
|
||||||
for (std::shared_ptr<ArchiveViewNode> child : node->get_children())
|
for (std::shared_ptr<ArchiveViewNode> child : node->get_children())
|
||||||
deep_fill(child.get());
|
deep_fill(child.get());
|
||||||
|
@ -33,6 +33,8 @@ public:
|
|||||||
void set_is_folder(bool is_folder) { m_folder = is_folder; }
|
void set_is_folder(bool is_folder) { m_folder = is_folder; }
|
||||||
void set_fullpath(boost::filesystem::path path) { m_fullpath = path; }
|
void set_fullpath(boost::filesystem::path path) { m_fullpath = path; }
|
||||||
boost::filesystem::path get_fullpath() const { return m_fullpath; }
|
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:
|
private:
|
||||||
wxString m_name;
|
wxString m_name;
|
||||||
@ -43,6 +45,7 @@ private:
|
|||||||
bool m_folder { false };
|
bool m_folder { false };
|
||||||
boost::filesystem::path m_fullpath;
|
boost::filesystem::path m_fullpath;
|
||||||
bool m_container { false };
|
bool m_container { false };
|
||||||
|
size_t m_size { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArchiveViewModel : public wxDataViewModel
|
class ArchiveViewModel : public wxDataViewModel
|
||||||
@ -100,7 +103,7 @@ protected:
|
|||||||
class FileArchiveDialog : public DPIDialog
|
class FileArchiveDialog : public DPIDialog
|
||||||
{
|
{
|
||||||
public:
|
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:
|
protected:
|
||||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||||
@ -109,7 +112,9 @@ protected:
|
|||||||
void on_all_button();
|
void on_all_button();
|
||||||
void on_none_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;
|
ArchiveViewCtrl* m_avc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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());
|
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);
|
throw Slic3r::FileIOError(err_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
|
mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
|
||||||
|
|
||||||
mz_zip_archive_file_stat stat;
|
mz_zip_archive_file_stat stat;
|
||||||
|
// selected_paths contains paths and its uncompressed size. The size is used to distinguish between files with same path.
|
||||||
std::vector<fs::path> selected_paths;
|
std::vector<std::pair<fs::path, size_t>> selected_paths;
|
||||||
|
|
||||||
FileArchiveDialog dlg(static_cast<wxWindow*>(wxGetApp().mainframe), &archive, selected_paths);
|
FileArchiveDialog dlg(static_cast<wxWindow*>(wxGetApp().mainframe), &archive, selected_paths);
|
||||||
if (dlg.ShowModal() == wxID_OK)
|
if (dlg.ShowModal() == wxID_OK)
|
||||||
{
|
{
|
||||||
std::string archive_path_string = archive_path.string();
|
std::string archive_path_string = archive_path.string();
|
||||||
archive_path_string = archive_path_string.substr(0, archive_path_string.size() - 4);
|
archive_path_string = archive_path_string.substr(0, archive_path_string.size() - 4);
|
||||||
|
|
||||||
fs::path archive_dir(wxStandardPaths::Get().GetTempDir().utf8_str().data());
|
fs::path archive_dir(wxStandardPaths::Get().GetTempDir().utf8_str().data());
|
||||||
|
|
||||||
for (mz_uint i = 0; i < num_entries; ++i) {
|
for (auto& path_w_size : selected_paths) {
|
||||||
if (mz_zip_reader_file_stat(&archive, i, &stat)) {
|
const fs::path& path = path_w_size.first;
|
||||||
wxString wname = boost::nowide::widen(stat.m_filename);
|
size_t size = path_w_size.second;
|
||||||
std::string name = boost::nowide::narrow(wname);
|
// find path in zip archive
|
||||||
fs::path archive_path(name);
|
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);
|
||||||
|
|
||||||
std::string extra(1024, 0);
|
std::string extra(1024, 0);
|
||||||
size_t extra_size = mz_zip_reader_get_filename_from_extra(&archive, i, extra.data(), extra.size());
|
size_t extra_size = mz_zip_reader_get_filename_from_extra(&archive, i, extra.data(), extra.size());
|
||||||
if (extra_size > 0) {
|
if (extra_size > 0) {
|
||||||
archive_path = fs::path(extra.substr(0, extra_size));
|
archive_path = fs::path(extra.substr(0, extra_size));
|
||||||
name = archive_path.string();
|
name = archive_path.string();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archive_path.empty())
|
if (archive_path.empty())
|
||||||
continue;
|
continue;
|
||||||
for (const auto& path : selected_paths) {
|
if (path != archive_path)
|
||||||
if (path == archive_path) {
|
continue;
|
||||||
try
|
// 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;
|
||||||
|
|
||||||
|
size_t version = 0;
|
||||||
|
while (fs::exists(archive_dir / (final_filename + extension)))
|
||||||
{
|
{
|
||||||
std::replace(name.begin(), name.end(), '\\', '/');
|
++version;
|
||||||
// rename if file exists
|
final_filename = just_filename + "(" + std::to_string(version) + ")";
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
filename = final_filename + extension;
|
||||||
{
|
fs::path final_path = archive_dir / filename;
|
||||||
// ensure the zip archive is closed and rethrow the exception
|
std::string buffer((size_t)stat.m_uncomp_size, 0);
|
||||||
close_zip_reader(&archive);
|
// Decompress action. We already has correct file index in stat structure.
|
||||||
throw Slic3r::FileIOError(e.what());
|
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;
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -130,8 +130,11 @@ class PrusaConnect : public PrusaLink
|
|||||||
public:
|
public:
|
||||||
PrusaConnect(DynamicPrintConfig* config);
|
PrusaConnect(DynamicPrintConfig* config);
|
||||||
~PrusaConnect() override = default;
|
~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; }
|
PrintHostPostUploadActions get_post_upload_actions() const override { return PrintHostPostUploadAction::StartPrint | PrintHostPostUploadAction::QueuePrint; }
|
||||||
const char* get_name() const override { return "PrusaConnect"; }
|
const char* get_name() const override { return "PrusaConnect"; }
|
||||||
|
bool get_storage(wxArrayString& storage_path, wxArrayString& storage_name) const override { return false; }
|
||||||
protected:
|
protected:
|
||||||
void set_http_post_header_args(Http& http, PrintHostPostUploadAction post_action) const override;
|
void set_http_post_header_args(Http& http, PrintHostPostUploadAction post_action) const override;
|
||||||
};
|
};
|
||||||
|
@ -399,7 +399,7 @@ void PresetUpdater::priv::sync_config(const VendorMap vendors, const std::string
|
|||||||
std::string name(stat.m_filename);
|
std::string name(stat.m_filename);
|
||||||
if (stat.m_uncomp_size > 0) {
|
if (stat.m_uncomp_size > 0) {
|
||||||
std::string buffer((size_t)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) {
|
if (res == 0) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "Failed to unzip " << stat.m_filename;
|
BOOST_LOG_TRIVIAL(error) << "Failed to unzip " << stat.m_filename;
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user