NEW: add support_critical_regions_only for tree support
When this option enabled, only generate supports for sharp tail, cantilever, thin pillar (not well supported). So holes are safe from unnessary supports. Currently only works for tree supports, will need to copied to normal supports if it works fine. Change-Id: I5eb86484a5b503149e3bfdee8ce73f76a0a849e4
This commit is contained in:
parent
5152a90545
commit
abddb1edc3
|
@ -125,6 +125,7 @@ public:
|
|||
|
||||
// BBS
|
||||
mutable ExPolygons sharp_tails;
|
||||
mutable ExPolygons cantilevers;
|
||||
mutable std::map<const ExPolygon*, float> sharp_tails_height;
|
||||
|
||||
// Collection of expolygons generated by slicing the possibly multiple meshes of the source geometry
|
||||
|
|
|
@ -666,7 +666,7 @@ static std::vector<std::string> s_Preset_print_options {
|
|||
//"independent_support_layer_height",
|
||||
"support_angle", "support_interface_top_layers", "support_interface_bottom_layers",
|
||||
"support_interface_pattern", "support_interface_spacing", "support_interface_loop_pattern",
|
||||
"support_top_z_distance", "support_on_build_plate_only", "bridge_no_support", "thick_bridges", "max_bridge_length", "print_sequence",
|
||||
"support_top_z_distance", "support_on_build_plate_only","support_critical_regions_only", "bridge_no_support", "thick_bridges", "max_bridge_length", "print_sequence",
|
||||
"filename_format", "wall_filament",
|
||||
"sparse_infill_filament", "solid_infill_filament", "support_filament", "support_interface_filament",
|
||||
"ooze_prevention", "standby_temperature_delta", "interface_shells", "line_width", "initial_layer_line_width",
|
||||
|
|
|
@ -2168,6 +2168,14 @@ void PrintConfigDef::init_fff_params()
|
|||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
// BBS
|
||||
def = this->add("support_critical_regions_only", coBool);
|
||||
def->label = L("Support critical regions only");
|
||||
def->category = L("Support");
|
||||
def->tooltip = L("Only create support for critical regions including sharp tail, cantilever, etc.");
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
// BBS: change type to common float.
|
||||
// It may be rounded to mulitple layer height when independent_support_layer_height is false.
|
||||
def = this->add("support_top_z_distance", coFloat);
|
||||
|
|
|
@ -594,6 +594,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
// Direction of the support pattern (in XY plane).`
|
||||
((ConfigOptionFloat, support_angle))
|
||||
((ConfigOptionBool, support_on_build_plate_only))
|
||||
((ConfigOptionBool, support_critical_regions_only))
|
||||
((ConfigOptionFloat, support_top_z_distance))
|
||||
((ConfigOptionInt, enforce_support_layers))
|
||||
((ConfigOptionInt, support_filament))
|
||||
|
|
|
@ -701,6 +701,7 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||
opt_key == "support_type"
|
||||
|| opt_key == "support_angle"
|
||||
|| opt_key == "support_on_build_plate_only"
|
||||
|| opt_key == "support_critical_regions_only"
|
||||
|| opt_key == "enforce_support_layers"
|
||||
|| opt_key == "support_filament"
|
||||
|| opt_key == "support_line_width"
|
||||
|
|
|
@ -673,6 +673,7 @@ void TreeSupport::detect_object_overhangs()
|
|||
const coordf_t extrusion_width_scaled = scale_(extrusion_width);
|
||||
const coordf_t max_bridge_length = scale_(config.max_bridge_length.value);
|
||||
const bool bridge_no_support = max_bridge_length > 0;// config.bridge_no_support.value;
|
||||
const bool support_critical_regions_only = config.support_critical_regions_only.value;
|
||||
const int enforce_support_layers = config.enforce_support_layers.value;
|
||||
const double area_thresh_well_supported = SQ(scale_(6)); // min: 6x6=36mm^2
|
||||
const double length_thresh_well_supported = scale_(6); // min: 6mm
|
||||
|
@ -694,6 +695,7 @@ void TreeSupport::detect_object_overhangs()
|
|||
int min_layer = 1e7;
|
||||
int max_layer = 0;
|
||||
coordf_t offset = 0;
|
||||
bool is_cantilever = false;
|
||||
OverhangCluster(const ExPolygon* expoly, int layer_nr) {
|
||||
push_back(expoly, layer_nr);
|
||||
}
|
||||
|
@ -823,7 +825,10 @@ void TreeSupport::detect_object_overhangs()
|
|||
ExPolygons lower_layer_offseted = offset_ex(lower_polys, support_offset_scaled, SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
||||
ExPolygons overhang_areas = std::move(diff_ex(curr_polys, lower_layer_offseted));
|
||||
// overhang_areas = std::move(offset2_ex(overhang_areas, -0.1 * extrusion_width_scaled, 0.1 * extrusion_width_scaled));
|
||||
overhang_areas.erase(std::remove_if(overhang_areas.begin(), overhang_areas.end(), [extrusion_width_scaled](ExPolygon& area) {return offset_ex(area, -0.1 * extrusion_width_scaled).empty(); }), overhang_areas.end());
|
||||
overhang_areas.erase(std::remove_if(overhang_areas.begin(), overhang_areas.end(),
|
||||
[extrusion_width_scaled](ExPolygon &area) { return offset_ex(area, -0.1 * extrusion_width_scaled).empty(); }),
|
||||
overhang_areas.end());
|
||||
|
||||
|
||||
ExPolygons overhangs_sharp_tail;
|
||||
if (is_auto && g_config_support_sharp_tails)
|
||||
|
@ -854,7 +859,7 @@ void TreeSupport::detect_object_overhangs()
|
|||
overhang_areas = union_ex(overhang_areas, overhangs_sharp_tail);
|
||||
}
|
||||
#else
|
||||
// BBS
|
||||
// BBS detect sharp tail
|
||||
const ExPolygons& lower_layer_sharptails = lower_layer->sharp_tails;
|
||||
auto& lower_layer_sharptails_height = lower_layer->sharp_tails_height;
|
||||
for (ExPolygon& expoly : layer->lslices) {
|
||||
|
@ -939,19 +944,8 @@ void TreeSupport::detect_object_overhangs()
|
|||
|
||||
TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers);
|
||||
for (ExPolygon& poly : overhang_areas) {
|
||||
// NOTE: must push something into ts_layer->overhang_areas, can't be empty for any layer,
|
||||
// otherwise remove_small_overhangs can't correctly cluster overhangs
|
||||
#if 0
|
||||
ExPolygons poly_simp = poly.simplify(scale_(radius_sample_resolution));
|
||||
// simplify method may delete the entire polygon which is unwanted
|
||||
if(!poly_simp.empty())
|
||||
append(ts_layer->overhang_areas, poly_simp);
|
||||
else
|
||||
ts_layer->overhang_areas.emplace_back(poly);
|
||||
#else
|
||||
if (!offset_ex(poly, -0.1 * extrusion_width_scaled).empty())
|
||||
ts_layer->overhang_areas.emplace_back(poly);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (is_auto && g_config_remove_small_overhangs) {
|
||||
|
@ -1004,6 +998,34 @@ void TreeSupport::detect_object_overhangs()
|
|||
m_object->project_and_append_custom_facets(false, EnforcerBlockerType::ENFORCER, enforcers);
|
||||
m_object->project_and_append_custom_facets(false, EnforcerBlockerType::BLOCKER, blockers);
|
||||
|
||||
// check whether the overhang cluster is cantilever (far awary from main body)
|
||||
for (auto& cluster : overhangClusters) {
|
||||
Layer* layer = m_object->get_layer(cluster.min_layer);
|
||||
if (layer->lower_layer == NULL) continue;
|
||||
Layer* lower_layer = layer->lower_layer;
|
||||
auto cluster_boundary = intersection(cluster.merged_poly, offset(lower_layer->lslices, scale_(0.5)));
|
||||
double dist_max = 0;
|
||||
Points cluster_pts;
|
||||
for (auto& poly : cluster.merged_poly)
|
||||
append(cluster_pts, poly.contour.points);
|
||||
for (auto& pt : cluster_pts) {
|
||||
double dist_pt = std::numeric_limits<double>::max();
|
||||
for (auto& poly : cluster_boundary) {
|
||||
double d = poly.distance_to(pt);
|
||||
dist_pt = std::min(dist_pt, d);
|
||||
}
|
||||
dist_max = std::max(dist_max, dist_pt);
|
||||
}
|
||||
if (dist_max > scale_(5)) { // this cluster is cantilever, add all expolygons to sharp tail
|
||||
for (auto it = cluster.layer_overhangs.begin(); it != cluster.layer_overhangs.end(); it++) {
|
||||
int layer_nr = it->first;
|
||||
auto p_overhang = it->second;
|
||||
m_object->get_layer(layer_nr)->cantilevers.emplace_back(*p_overhang);
|
||||
}
|
||||
cluster.is_cantilever = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_auto && g_config_remove_small_overhangs) {
|
||||
if (blockers.size() < m_object->layer_count())
|
||||
blockers.resize(m_object->layer_count());
|
||||
|
@ -1045,25 +1067,8 @@ void TreeSupport::detect_object_overhangs()
|
|||
}
|
||||
if (is_sharp_tail) continue;
|
||||
|
||||
// 4. check whether the overhang cluster is cantilever (far awary from main body)
|
||||
Layer* layer = m_object->get_layer(cluster.min_layer);
|
||||
if (layer->lower_layer == NULL) continue;
|
||||
Layer* lower_layer = layer->lower_layer;
|
||||
auto cluster_boundary = intersection(cluster.merged_poly, offset(lower_layer->lslices, scale_(0.5)));
|
||||
double dist_max = 0;
|
||||
Points cluster_pts;
|
||||
for (auto& poly : cluster.merged_poly)
|
||||
append(cluster_pts, poly.contour.points);
|
||||
for (auto& pt : cluster_pts) {
|
||||
double dist_pt = std::numeric_limits<double>::max();
|
||||
for (auto& poly : cluster_boundary) {
|
||||
double d = poly.distance_to(pt);
|
||||
dist_pt = std::min(dist_pt, d);
|
||||
}
|
||||
dist_max = std::max(dist_max, dist_pt);
|
||||
}
|
||||
if (dist_max > scale_(5))
|
||||
continue;
|
||||
// 4. check whether the overhang cluster is cantilever
|
||||
if (cluster.is_cantilever) continue;
|
||||
|
||||
for (auto it = cluster.layer_overhangs.begin(); it != cluster.layer_overhangs.end(); it++) {
|
||||
int layer_nr = it->first;
|
||||
|
@ -1088,6 +1093,11 @@ void TreeSupport::detect_object_overhangs()
|
|||
break;
|
||||
|
||||
TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers);
|
||||
if (support_critical_regions_only) {
|
||||
auto layer = m_object->get_layer(layer_nr);
|
||||
ts_layer->overhang_areas = layer->sharp_tails;
|
||||
append(ts_layer->overhang_areas, layer->cantilevers);
|
||||
}
|
||||
|
||||
if (layer_nr < blockers.size()) {
|
||||
Polygons& blocker = blockers[layer_nr];
|
||||
|
|
|
@ -510,7 +510,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
"support_interface_pattern", "support_interface_top_layers", "support_interface_bottom_layers",
|
||||
"bridge_no_support", "thick_bridges", "max_bridge_length", "support_top_z_distance",
|
||||
//BBS: add more support params to dependent of enable_support
|
||||
"support_type","support_on_build_plate_only",
|
||||
"support_type", "support_on_build_plate_only", "support_critical_regions_only",
|
||||
"support_object_xy_distance", "independent_support_layer_height"})
|
||||
toggle_field(el, have_support_material);
|
||||
toggle_field("support_threshold_angle", have_support_material && (support_type == stNormalAuto || support_type == stTreeAuto || support_type==stHybridAuto));
|
||||
|
|
|
@ -55,7 +55,7 @@ static SettingsFactory::Bundle FREQ_SETTINGS_BUNDLE_FFF =
|
|||
{ L("Infill") , { "sparse_infill_density", "sparse_infill_pattern" } },
|
||||
// BBS
|
||||
{ L("Support") , { "enable_support", "support_type", "support_threshold_angle",
|
||||
"support_base_pattern", "support_on_build_plate_only",
|
||||
"support_base_pattern", "support_on_build_plate_only","support_critical_regions_only",
|
||||
"support_base_pattern_spacing" } }
|
||||
//BBS
|
||||
//{ L("Wipe options") , { "flush_into_infill", "flush_into_objects" } }
|
||||
|
@ -81,7 +81,7 @@ std::map<std::string, std::vector<SimpleSettingData>> SettingsFactory::OBJECT_C
|
|||
{"tree_support_branch_angle", "",10}, {"tree_support_wall_count", "",11},{"tree_support_with_infill", "",12},//tree support
|
||||
{"support_top_z_distance", "",13},{"support_base_pattern", "",14},{"support_base_pattern_spacing", "",15},
|
||||
{"support_interface_top_layers", "",16},{"support_interface_bottom_layers", "",17},{"support_interface_spacing", "",18},{"support_bottom_interface_spacing", "",19},
|
||||
{"support_object_xy_distance", "",20}, {"bridge_no_support", "",21},{"max_bridge_length", "",22}
|
||||
{"support_object_xy_distance", "",20}, {"bridge_no_support", "",21},{"max_bridge_length", "",22},{"support_critical_regions_only", "",23}
|
||||
}},
|
||||
{ L("Speed"), {{"support_speed", "",12}, {"support_interface_speed", "",13}
|
||||
}}
|
||||
|
@ -138,7 +138,7 @@ std::vector<SimpleSettingData> SettingsFactory::get_visible_options(const std::s
|
|||
//Quality
|
||||
"layer_height", "initial_layer_print_height", "adaptive_layer_height", "seam_position", "xy_hole_compensation", "xy_contour_compensation", "elefant_foot_compensation", "support_line_width",
|
||||
//Support
|
||||
"enable_support", "support_type", "support_threshold_angle", "support_on_build_plate_only", "enforce_support_layers",
|
||||
"enable_support", "support_type", "support_threshold_angle", "support_on_build_plate_only", "support_critical_regions_only", "enforce_support_layers",
|
||||
//tree support
|
||||
"tree_support_wall_count", "tree_support_with_infill",
|
||||
//support
|
||||
|
|
|
@ -1853,6 +1853,7 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("support_type", "support#support-types");
|
||||
optgroup->append_single_option_line("support_threshold_angle", "support#threshold-angle");
|
||||
optgroup->append_single_option_line("support_on_build_plate_only");
|
||||
optgroup->append_single_option_line("support_critical_regions_only");
|
||||
//optgroup->append_single_option_line("enforce_support_layers");
|
||||
|
||||
optgroup = page->new_optgroup(L("Support filament"));
|
||||
|
|
Loading…
Reference in New Issue