mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-06 00:16:17 +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
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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())
|
||||
{
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user