fix manual remap, send nozzle diam

This commit is contained in:
Rad
2026-04-19 21:34:15 +02:00
parent d370edb5b2
commit 38a79b24a1
3 changed files with 48 additions and 99 deletions

View File

@@ -30,75 +30,6 @@ namespace Slic3r {
using namespace Slic3r::Feature::FuzzySkin;
static bool is_gap_fill_allowed_for_surface(const PrintObjectConfig* config, const SurfaceType surface_type)
{
if (config == nullptr || config->gap_fill_target.value == gftNowhere)
return false;
return surface_type != stInternalSolid || config->gap_fill_target.value == gftEverywhere;
}
static void append_collapsed_infill_gap_fill(const ExPolygons &areas,
const Flow &flow,
const double simplify_resolution,
const float filter_out_gap_fill,
ExtrusionEntityCollection *gap_fill)
{
if (gap_fill == nullptr || areas.empty())
return;
const double min = 0.2 * flow.scaled_spacing() * (1 - INSET_OVERLAP_TOLERANCE);
const double max = 2.0 * flow.scaled_spacing();
ExPolygons gaps_ex = diff_ex(
opening_ex(areas, float(min / 2.0)),
offset2_ex(areas, -float(max / 2.0), float(max / 2.0 + ClipperSafetyOffset)));
if (gaps_ex.empty())
gaps_ex = union_ex(areas);
ThickPolylines polylines;
for (ExPolygon &ex : gaps_ex) {
ex.douglas_peucker(simplify_resolution);
try {
ex.medial_axis(min, max, &polylines);
} catch (...) {
}
}
auto filter_short_polylines = [&](ThickPolylines &src) {
src.erase(std::remove_if(src.begin(),
src.end(),
[&](const ThickPolyline &p) { return p.length() < scale_(filter_out_gap_fill); }),
src.end());
};
filter_short_polylines(polylines);
if (polylines.empty()) {
for (const double inset_factor : {0.25, 0.125}) {
ExPolygons inset_loops = offset_ex(areas, -float(flow.scaled_width() * inset_factor));
if (inset_loops.empty())
continue;
ThickPolylines inset_polylines = to_thick_polylines(to_polylines(std::move(inset_loops)), flow.scaled_width());
filter_short_polylines(inset_polylines);
if (inset_polylines.empty())
continue;
ExtrusionEntityCollection gap_fill_entities;
variable_width(inset_polylines, erGapFill, flow, gap_fill_entities.entities);
gap_fill->append(std::move(gap_fill_entities.entities));
return;
}
}
if (polylines.empty())
return;
ExtrusionEntityCollection gap_fill_entities;
variable_width(polylines, erGapFill, flow, gap_fill_entities.entities);
gap_fill->append(std::move(gap_fill_entities.entities));
}
// Hierarchy of perimeters.
class PerimeterGeneratorLoop {
public:
@@ -1284,7 +1215,6 @@ void PerimeterGenerator::process_classic()
ExPolygons gaps;
ExPolygons top_fills;
ExPolygons fill_clip;
ExPolygons collapsed_gap_fill_source;
if (loop_number >= 0) {
// In case no perimeters are to be generated, loop_number will equal to -1.
std::vector<PerimeterGeneratorLoops> contours(loop_number+1); // depth => loops
@@ -1613,10 +1543,6 @@ void PerimeterGenerator::process_classic()
}
}
}
collapsed_gap_fill_source = entities.empty() ?
ExPolygons() :
diff_ex(ExPolygons { surface.expolygon }, entities.polygons_covered_by_width(10.f));
// append perimeters for this slice as a collection
if (! entities.empty())
this->loops->append(entities);
@@ -1714,17 +1640,6 @@ void PerimeterGenerator::process_classic()
not_filled_exp,
float(-inset - min_perimeter_infill_spacing / 2.),
float(min_perimeter_infill_spacing / 2.));
if (infill_exp.empty() && has_gap_fill && is_gap_fill_allowed_for_surface(object_config, surface.surface_type)) {
ExPolygons gap_fill_source = not_filled_exp.empty() ? collapsed_gap_fill_source : not_filled_exp;
if (gap_fill_source.empty())
gap_fill_source = ExPolygons { surface.expolygon };
append_collapsed_infill_gap_fill(gap_fill_source,
this->solid_infill_flow,
surface_simplify_resolution,
config->filter_out_gap_fill.value,
this->gap_fill);
}
// append infill areas to fill_surfaces
//if any top_fills, grow them by ext_perimeter_spacing/2 to have the real un-anchored fill
ExPolygons top_infill_exp = intersection_ex(fill_clip, offset_ex(top_fills, double(ext_perimeter_spacing / 2)));
@@ -2541,7 +2456,6 @@ void PerimeterGenerator::process_arachne()
steep_overhang_contour = true;
steep_overhang_hole = true;
}
ExPolygons collapsed_gap_fill_source;
if (ExtrusionEntityCollection extrusion_coll = traverse_extrusions(*this, ordered_extrusions, steep_overhang_contour, steep_overhang_hole); !extrusion_coll.empty()) {
// All walls are counter-clockwise initially, so we don't need to reorient it if that's what we want
if (wall_direction != WallDirection::CounterClockwise) {
@@ -2549,7 +2463,6 @@ void PerimeterGenerator::process_arachne()
// Reverse internal only if the wall direction is auto
this->config->overhang_reverse_internal_only && wall_direction == WallDirection::Auto);
}
collapsed_gap_fill_source = diff_ex(ExPolygons { surface.expolygon }, extrusion_coll.polygons_covered_by_width(10.f));
this->loops->append(extrusion_coll);
}
@@ -2589,18 +2502,6 @@ void PerimeterGenerator::process_arachne()
not_filled_exp,
float(-min_perimeter_infill_spacing / 2.),
float(inset + min_perimeter_infill_spacing / 2.));
if (infill_exp.empty() && this->config->gap_infill_speed.value > 0 &&
is_gap_fill_allowed_for_surface(object_config, surface.surface_type)) {
ExPolygons gap_fill_source = not_filled_exp.empty() ? collapsed_gap_fill_source : not_filled_exp;
if (gap_fill_source.empty())
gap_fill_source = ExPolygons { surface.expolygon };
append_collapsed_infill_gap_fill(gap_fill_source,
this->solid_infill_flow,
surface_simplify_resolution,
config->filter_out_gap_fill.value,
this->gap_fill);
}
// append infill areas to fill_surfaces
if (!top_expolygons.empty()) {
infill_exp = union_ex(infill_exp, offset_ex(top_expolygons, double(top_inset)));

View File

@@ -6397,6 +6397,38 @@ void GUI_App::load_current_presets(bool active_preset_combox/*= false*/, bool ch
if (tab->supports_printer_technology(printer_technology)) {
tab->rebuild_page_tree();
}
if (printer_technology == ptFFF && preset_bundle != nullptr) {
static const t_config_option_keys mixed_project_option_keys = {
"mixed_filament_gradient_mode",
"mixed_filament_height_lower_bound",
"mixed_filament_height_upper_bound",
"mixed_filament_advanced_dithering",
"mixed_filament_component_bias_enabled",
"mixed_filament_surface_indentation",
"mixed_filament_region_collapse",
"mixed_color_layer_height_a",
"mixed_color_layer_height_b",
"dithering_z_step_size",
"dithering_local_z_mode",
"dithering_step_painted_zones_only",
"mixed_filament_pointillism_pixel_size",
"mixed_filament_pointillism_line_gap",
"mixed_filament_definitions"
};
// Keep the Mixed Filaments sidebar state in sync when presets are reloaded
// programmatically (for example after New Project). These options are also
// mirrored on manual edits in Tab::on_value_change(), but that path does
// not run when the current preset is simply reloaded.
preset_bundle->project_config.apply_only(
preset_bundle->prints.get_edited_preset().config,
mixed_project_option_keys,
true);
if (plater_ != nullptr)
sidebar().update_mixed_filament_panel(false);
}
}
static std::mutex mutex_delete_cache_presets;

View File

@@ -10,6 +10,7 @@
#include <iterator>
#include <exception>
#include <cstdlib>
#include <iomanip>
#include <regex>
#include <thread>
#include <string_view>
@@ -3110,6 +3111,21 @@ void SSWCP_MachineOption_Instance::sw_GetFileFilamentMapping()
}
response["filament_type"] = filament_types;
}
// file nozzle diameters
if (full_config.has("nozzle_diameter")) {
const auto *opt_nozzle_diameters = full_config.option<ConfigOptionFloats>("nozzle_diameter");
if (opt_nozzle_diameters != nullptr) {
std::vector<std::string> nozzle_diameters;
nozzle_diameters.reserve(opt_nozzle_diameters->values.size());
for (double diameter : opt_nozzle_diameters->values) {
std::ostringstream stream;
stream << std::fixed << std::setprecision(1) << diameter;
nozzle_diameters.emplace_back(stream.str());
}
response["nozzle_diameters"] = nozzle_diameters;
}
}
// filament used