mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-30 13:26:58 +00:00
fix manual remap, send nozzle diam
This commit is contained in:
@@ -30,75 +30,6 @@ namespace Slic3r {
|
|||||||
|
|
||||||
using namespace Slic3r::Feature::FuzzySkin;
|
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.
|
// Hierarchy of perimeters.
|
||||||
class PerimeterGeneratorLoop {
|
class PerimeterGeneratorLoop {
|
||||||
public:
|
public:
|
||||||
@@ -1284,7 +1215,6 @@ void PerimeterGenerator::process_classic()
|
|||||||
ExPolygons gaps;
|
ExPolygons gaps;
|
||||||
ExPolygons top_fills;
|
ExPolygons top_fills;
|
||||||
ExPolygons fill_clip;
|
ExPolygons fill_clip;
|
||||||
ExPolygons collapsed_gap_fill_source;
|
|
||||||
if (loop_number >= 0) {
|
if (loop_number >= 0) {
|
||||||
// In case no perimeters are to be generated, loop_number will equal to -1.
|
// In case no perimeters are to be generated, loop_number will equal to -1.
|
||||||
std::vector<PerimeterGeneratorLoops> contours(loop_number+1); // depth => loops
|
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
|
// append perimeters for this slice as a collection
|
||||||
if (! entities.empty())
|
if (! entities.empty())
|
||||||
this->loops->append(entities);
|
this->loops->append(entities);
|
||||||
@@ -1714,17 +1640,6 @@ void PerimeterGenerator::process_classic()
|
|||||||
not_filled_exp,
|
not_filled_exp,
|
||||||
float(-inset - min_perimeter_infill_spacing / 2.),
|
float(-inset - min_perimeter_infill_spacing / 2.),
|
||||||
float(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
|
// append infill areas to fill_surfaces
|
||||||
//if any top_fills, grow them by ext_perimeter_spacing/2 to have the real un-anchored fill
|
//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)));
|
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_contour = true;
|
||||||
steep_overhang_hole = 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()) {
|
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
|
// 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) {
|
if (wall_direction != WallDirection::CounterClockwise) {
|
||||||
@@ -2549,7 +2463,6 @@ void PerimeterGenerator::process_arachne()
|
|||||||
// Reverse internal only if the wall direction is auto
|
// Reverse internal only if the wall direction is auto
|
||||||
this->config->overhang_reverse_internal_only && wall_direction == WallDirection::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);
|
this->loops->append(extrusion_coll);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2589,18 +2502,6 @@ void PerimeterGenerator::process_arachne()
|
|||||||
not_filled_exp,
|
not_filled_exp,
|
||||||
float(-min_perimeter_infill_spacing / 2.),
|
float(-min_perimeter_infill_spacing / 2.),
|
||||||
float(inset + 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
|
// append infill areas to fill_surfaces
|
||||||
if (!top_expolygons.empty()) {
|
if (!top_expolygons.empty()) {
|
||||||
infill_exp = union_ex(infill_exp, offset_ex(top_expolygons, double(top_inset)));
|
infill_exp = union_ex(infill_exp, offset_ex(top_expolygons, double(top_inset)));
|
||||||
|
|||||||
@@ -6397,6 +6397,38 @@ void GUI_App::load_current_presets(bool active_preset_combox/*= false*/, bool ch
|
|||||||
if (tab->supports_printer_technology(printer_technology)) {
|
if (tab->supports_printer_technology(printer_technology)) {
|
||||||
tab->rebuild_page_tree();
|
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;
|
static std::mutex mutex_delete_cache_presets;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <iomanip>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@@ -3110,6 +3111,21 @@ void SSWCP_MachineOption_Instance::sw_GetFileFilamentMapping()
|
|||||||
}
|
}
|
||||||
response["filament_type"] = filament_types;
|
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
|
// filament used
|
||||||
|
|||||||
Reference in New Issue
Block a user