Implementing a new switch for the shape of support towers:
expanded to a grid (the old way) vs. snug (like the upstream Slic3r, Cura or Ideamaker). Snug supports suffered from the degeneracies when merging overhang islands over a large number of layers when projecting the support towers down. We borrowed the idea & a bit of code from Cura by simplifying the support polygons by closing the concave cracks, see the smooth_outward() function and the MutablePolygon class. Fixes Support problems with models with hole in the walls. #555 Fixes Support in the Air #740 Fixes [Bug] Supports generated beyond bed edges (X<0 and X>250) and where none are needed. #902 Fixes Unable to remove support material/can't change support "inflation distance" #2708 Fixes FR: support inflation and support conform to boundary #4783 Fixes Support blocker not working on this model #1346 Fixes Unnecessary support material #1993 Fixes support blocker enforcer issue #6240
This commit is contained in:
parent
00295919bf
commit
af9c7c967f
@ -427,7 +427,7 @@ const std::vector<std::string>& Preset::print_options()
|
||||
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
|
||||
"min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
|
||||
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
|
||||
"support_material_pattern", "support_material_with_sheath", "support_material_spacing",
|
||||
"support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_style",
|
||||
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_bottom_interface_layers",
|
||||
"support_material_interface_pattern", "support_material_interface_spacing", "support_material_interface_contact_loops",
|
||||
"support_material_contact_distance", "support_material_bottom_contact_distance",
|
||||
|
@ -2419,6 +2419,20 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(60));
|
||||
|
||||
def = this->add("support_material_style", coEnum);
|
||||
def->label = L("Style");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("Style and shape of the support towers. Projecting the supports into a regular grid "
|
||||
"will create more stable supports, while snug support towers will save material and reduce "
|
||||
"object scarring.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<SupportMaterialStyle>::get_enum_values();
|
||||
def->enum_values.push_back("grid");
|
||||
def->enum_values.push_back("snug");
|
||||
def->enum_labels.push_back(L("Grid"));
|
||||
def->enum_labels.push_back(L("Snug"));
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<SupportMaterialStyle>(smsGrid));
|
||||
|
||||
def = this->add("support_material_synchronize_layers", coBool);
|
||||
def->label = L("Synchronize with object layers");
|
||||
def->category = L("Support material");
|
||||
|
@ -65,6 +65,10 @@ enum SupportMaterialPattern {
|
||||
smpRectilinear, smpRectilinearGrid, smpHoneycomb,
|
||||
};
|
||||
|
||||
enum SupportMaterialStyle {
|
||||
smsGrid, smsSnug,
|
||||
};
|
||||
|
||||
enum SupportMaterialInterfacePattern {
|
||||
smipAuto, smipRectilinear, smipConcentric,
|
||||
};
|
||||
@ -211,6 +215,15 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<SupportMaterialPa
|
||||
return keys_map;
|
||||
}
|
||||
|
||||
template<> inline const t_config_enum_values& ConfigOptionEnum<SupportMaterialStyle>::get_enum_values() {
|
||||
static t_config_enum_values keys_map;
|
||||
if (keys_map.empty()) {
|
||||
keys_map["grid"] = smsGrid;
|
||||
keys_map["snug"] = smsSnug;
|
||||
}
|
||||
return keys_map;
|
||||
}
|
||||
|
||||
template<> inline const t_config_enum_values& ConfigOptionEnum<SupportMaterialInterfacePattern>::get_enum_values() {
|
||||
static t_config_enum_values keys_map;
|
||||
if (keys_map.empty()) {
|
||||
@ -519,6 +532,7 @@ public:
|
||||
// Spacing between support material lines (the hatching distance).
|
||||
ConfigOptionFloat support_material_spacing;
|
||||
ConfigOptionFloat support_material_speed;
|
||||
ConfigOptionEnum<SupportMaterialStyle> support_material_style;
|
||||
ConfigOptionBool support_material_synchronize_layers;
|
||||
// Overhang angle threshold.
|
||||
ConfigOptionInt support_material_threshold;
|
||||
@ -570,6 +584,7 @@ protected:
|
||||
OPT_PTR(support_material_interface_pattern);
|
||||
OPT_PTR(support_material_spacing);
|
||||
OPT_PTR(support_material_speed);
|
||||
OPT_PTR(support_material_style);
|
||||
OPT_PTR(support_material_synchronize_layers);
|
||||
OPT_PTR(support_material_xy_spacing);
|
||||
OPT_PTR(support_material_threshold);
|
||||
|
@ -588,6 +588,7 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
|| opt_key == "support_material_interface_extruder"
|
||||
|| opt_key == "support_material_interface_spacing"
|
||||
|| opt_key == "support_material_pattern"
|
||||
|| opt_key == "support_material_style"
|
||||
|| opt_key == "support_material_xy_spacing"
|
||||
|| opt_key == "support_material_spacing"
|
||||
|| opt_key == "support_material_synchronize_layers"
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "Fill/FillBase.hpp"
|
||||
#include "Geometry.hpp"
|
||||
#include "Point.hpp"
|
||||
#include "MutablePolygon.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
@ -667,12 +668,14 @@ Polygons collect_slices_outer(const Layer &layer)
|
||||
|
||||
struct SupportGridParams {
|
||||
SupportGridParams(const PrintObjectConfig &object_config, const Flow &support_material_flow) :
|
||||
style(object_config.support_material_style.value),
|
||||
grid_resolution(object_config.support_material_spacing.value + support_material_flow.spacing()),
|
||||
support_angle(Geometry::deg2rad(object_config.support_material_angle.value)),
|
||||
extrusion_width(support_material_flow.spacing()),
|
||||
expansion_to_slice(coord_t(support_material_flow.scaled_spacing() / 2 + 5)),
|
||||
expansion_to_propagate(-3) {}
|
||||
|
||||
SupportMaterialStyle style;
|
||||
double grid_resolution;
|
||||
double support_angle;
|
||||
double extrusion_width;
|
||||
@ -689,9 +692,14 @@ public:
|
||||
// Trimming polygons, to trim the stretched support islands. support_polygons were already trimmed with trimming_polygons.
|
||||
const Polygons *trimming_polygons,
|
||||
const SupportGridParams ¶ms) :
|
||||
m_style(params.style),
|
||||
m_support_polygons(support_polygons), m_trimming_polygons(trimming_polygons),
|
||||
m_support_spacing(params.grid_resolution), m_support_angle(params.support_angle)
|
||||
{
|
||||
switch (m_style) {
|
||||
case smsGrid:
|
||||
{
|
||||
// Prepare the grid data, it will be reused when extracting support structures.
|
||||
if (m_support_angle != 0.) {
|
||||
// Create a copy of the rotated contours.
|
||||
m_support_polygons_rotated = *support_polygons;
|
||||
@ -758,6 +766,14 @@ public:
|
||||
#endif
|
||||
m_grid.calculate_sdf();
|
||||
#endif // SUPPORT_USE_AGG_RASTERIZER
|
||||
break;
|
||||
}
|
||||
|
||||
case smsSnug:
|
||||
default:
|
||||
// nothing to prepare
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract polygons from the grid, offsetted by offset_in_grid,
|
||||
@ -770,6 +786,9 @@ public:
|
||||
#endif
|
||||
)
|
||||
{
|
||||
switch (m_style) {
|
||||
case smsGrid:
|
||||
{
|
||||
#ifdef SUPPORT_USE_AGG_RASTERIZER
|
||||
Polygons support_polygons_simplified = contours_simplified(m_grid_size, m_pixel_size, m_bbox.min, m_grid2, offset_in_grid, fill_holes);
|
||||
#else // SUPPORT_USE_AGG_RASTERIZER
|
||||
@ -782,9 +801,6 @@ public:
|
||||
|
||||
// Extract polygons, which contain some of the island_samples.
|
||||
Polygons out;
|
||||
#if 0
|
||||
out = to_polygons(std::move(islands));
|
||||
#else
|
||||
|
||||
// Sample a single point per input support polygon, keep it as a reference to maintain corresponding
|
||||
// polygons if ever these polygons get split into parts by the trimming polygons.
|
||||
@ -835,7 +851,6 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SLIC3R_DEBUG
|
||||
BoundingBox bbox = get_extents(*m_trimming_polygons);
|
||||
@ -862,6 +877,12 @@ public:
|
||||
polygons_rotate(out, m_support_angle);
|
||||
return out;
|
||||
}
|
||||
case smsSnug:
|
||||
// Just close the gaps.
|
||||
float thr = scaled<float>(0.5);
|
||||
return smooth_outward(offset(offset_ex(*m_support_polygons, thr), - thr), thr);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SLIC3R_DEBUG) && ! defined(SUPPORT_USE_AGG_RASTERIZER)
|
||||
void serialize(const std::string &path)
|
||||
@ -1096,6 +1117,7 @@ private:
|
||||
return pts;
|
||||
}
|
||||
|
||||
SupportMaterialStyle m_style;
|
||||
const Polygons *m_support_polygons;
|
||||
const Polygons *m_trimming_polygons;
|
||||
Polygons m_support_polygons_rotated;
|
||||
@ -1525,7 +1547,7 @@ static inline std::tuple<Polygons, Polygons, Polygons, float> detect_overhangs(
|
||||
ClipperLib::jtRound,
|
||||
// round mitter limit
|
||||
scale_(0.05)),
|
||||
slices_margin_cached);
|
||||
slices_margin.polygons);
|
||||
}
|
||||
#else
|
||||
diff_polygons = diff(diff_polygons, slices_margin.polygons);
|
||||
|
@ -278,7 +278,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
||||
bool have_support_material_auto = have_support_material && config->opt_bool("support_material_auto");
|
||||
bool have_support_interface = config->opt_int("support_material_interface_layers") > 0;
|
||||
bool have_support_soluble = have_support_material && config->opt_float("support_material_contact_distance") == 0;
|
||||
for (auto el : { "support_material_pattern", "support_material_with_sheath",
|
||||
for (auto el : { "support_material_style", "support_material_pattern", "support_material_with_sheath",
|
||||
"support_material_spacing", "support_material_angle",
|
||||
"support_material_interface_pattern", "support_material_interface_layers",
|
||||
"dont_support_bridges", "support_material_extrusion_width", "support_material_contact_distance",
|
||||
|
@ -1224,6 +1224,8 @@ boost::any& Choice::get_value()
|
||||
m_value = static_cast<SupportMaterialPattern>(ret_enum);
|
||||
else if (m_opt_id.compare("support_material_interface_pattern") == 0)
|
||||
m_value = static_cast<SupportMaterialInterfacePattern>(ret_enum);
|
||||
else if (m_opt_id.compare("support_material_style") == 0)
|
||||
m_value = static_cast<SupportMaterialStyle>(ret_enum);
|
||||
else if (m_opt_id.compare("seam_position") == 0)
|
||||
m_value = static_cast<SeamPosition>(ret_enum);
|
||||
else if (m_opt_id.compare("host_type") == 0)
|
||||
|
@ -198,6 +198,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<SupportMaterialPattern>(boost::any_cast<SupportMaterialPattern>(value)));
|
||||
else if (opt_key.compare("support_material_interface_pattern") == 0)
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<SupportMaterialInterfacePattern>(boost::any_cast<SupportMaterialInterfacePattern>(value)));
|
||||
else if (opt_key.compare("support_material_style") == 0)
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<SupportMaterialStyle>(boost::any_cast<SupportMaterialStyle>(value)));
|
||||
else if (opt_key.compare("seam_position") == 0)
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<SeamPosition>(boost::any_cast<SeamPosition>(value)));
|
||||
else if (opt_key.compare("host_type") == 0)
|
||||
|
@ -50,7 +50,7 @@ static SettingsFactory::Bundle FREQ_SETTINGS_BUNDLE_FFF =
|
||||
{ L("Layers and Perimeters"), { "layer_height" , "perimeters", "top_solid_layers", "bottom_solid_layers" } },
|
||||
{ L("Infill") , { "fill_density", "fill_pattern" } },
|
||||
{ L("Support material") , { "support_material", "support_material_auto", "support_material_threshold",
|
||||
"support_material_pattern", "support_material_interface_pattern", "support_material_buildplate_only",
|
||||
"support_material_pattern", "support_material_pattern", "support_material_interface_pattern", "support_material_buildplate_only",
|
||||
"support_material_spacing" } },
|
||||
{ L("Wipe options") , { "wipe_into_infill", "wipe_into_objects" } }
|
||||
};
|
||||
|
@ -1506,6 +1506,7 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("raft_expansion");
|
||||
|
||||
optgroup = page->new_optgroup(L("Options for support material and raft"));
|
||||
optgroup->append_single_option_line("support_material_style", category_path + "style");
|
||||
optgroup->append_single_option_line("support_material_contact_distance", category_path + "contact-z-distance");
|
||||
optgroup->append_single_option_line("support_material_bottom_contact_distance", category_path + "contact-z-distance");
|
||||
optgroup->append_single_option_line("support_material_pattern", category_path + "pattern");
|
||||
|
Loading…
Reference in New Issue
Block a user