This commit is contained in:
enricoturri1966 2023-01-26 15:58:10 +01:00
commit 0adb8ce209
11 changed files with 89 additions and 59 deletions

View File

@ -2308,7 +2308,8 @@ void GCode::process_layer_single_object(
ExtrusionEntitiesPtr temp_fill_extrusions; ExtrusionEntitiesPtr temp_fill_extrusions;
if (const Layer *layer = layer_to_print.object_layer; layer) if (const Layer *layer = layer_to_print.object_layer; layer)
for (const LayerSlice &lslice : layer->lslices_ex) { for (size_t idx : layer->lslice_indices_sorted_by_print_order) {
const LayerSlice &lslice = layer->lslices_ex[idx];
auto extrude_infill_range = [&]( auto extrude_infill_range = [&](
const LayerRegion &layerm, const ExtrusionEntityCollection &fills, const LayerRegion &layerm, const ExtrusionEntityCollection &fills,
LayerExtrusionRanges::const_iterator it_fill_ranges_begin, LayerExtrusionRanges::const_iterator it_fill_ranges_end, bool ironing) { LayerExtrusionRanges::const_iterator it_fill_ranges_begin, LayerExtrusionRanges::const_iterator it_fill_ranges_end, bool ironing) {

View File

@ -38,32 +38,37 @@ LayerRegion* Layer::add_region(const PrintRegion *print_region)
// merge all regions' slices to get islands // merge all regions' slices to get islands
void Layer::make_slices() void Layer::make_slices()
{ {
ExPolygons slices; {
if (m_regions.size() == 1) { ExPolygons slices;
// optimization: if we only have one region, take its slices if (m_regions.size() == 1) {
slices = to_expolygons(m_regions.front()->slices().surfaces); // optimization: if we only have one region, take its slices
} else { slices = to_expolygons(m_regions.front()->slices().surfaces);
Polygons slices_p; } else {
for (LayerRegion *layerm : m_regions) Polygons slices_p;
polygons_append(slices_p, to_polygons(layerm->slices().surfaces)); for (LayerRegion *layerm : m_regions)
slices = union_safety_offset_ex(slices_p); polygons_append(slices_p, to_polygons(layerm->slices().surfaces));
slices = union_safety_offset_ex(slices_p);
}
// lslices are sorted by topological order from outside to inside from the clipper union used above
this->lslices = slices;
} }
this->lslices.clear(); // prepare lslices ordered by print order
this->lslices.reserve(slices.size()); this->lslice_indices_sorted_by_print_order.clear();
this->lslice_indices_sorted_by_print_order.reserve(lslices.size());
// prepare ordering points // prepare ordering points
Points ordering_points; Points ordering_points;
ordering_points.reserve(slices.size()); ordering_points.reserve( this->lslices.size());
for (const ExPolygon &ex : slices) for (const ExPolygon &ex : this->lslices)
ordering_points.push_back(ex.contour.first_point()); ordering_points.push_back(ex.contour.first_point());
// sort slices // sort slices
std::vector<Points::size_type> order = chain_points(ordering_points); std::vector<Points::size_type> order = chain_points(ordering_points);
// populate slices vector // populate slices vector
for (size_t i : order) for (size_t i : order) {
this->lslices.emplace_back(std::move(slices[i])); this->lslice_indices_sorted_by_print_order.emplace_back(i);
}
} }
// used by Layer::build_up_down_graph() // used by Layer::build_up_down_graph()

View File

@ -336,6 +336,7 @@ public:
// These lslices are also used to detect overhangs and overlaps between successive layers, therefore it is important // These lslices are also used to detect overhangs and overlaps between successive layers, therefore it is important
// that the 1st lslice is not compensated by the Elephant foot compensation algorithm. // that the 1st lslice is not compensated by the Elephant foot compensation algorithm.
ExPolygons lslices; ExPolygons lslices;
std::vector<size_t> lslice_indices_sorted_by_print_order;
LayerSlices lslices_ex; LayerSlices lslices_ex;
size_t region_count() const { return m_regions.size(); } size_t region_count() const { return m_regions.size(); }

View File

@ -444,7 +444,7 @@ static std::vector<std::string> s_Preset_print_options {
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed", "top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
"bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "first_layer_speed_over_raft", "perimeter_acceleration", "infill_acceleration", "bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "first_layer_speed_over_raft", "perimeter_acceleration", "infill_acceleration",
"bridge_acceleration", "first_layer_acceleration", "first_layer_acceleration_over_raft", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield", "bridge_acceleration", "first_layer_acceleration", "first_layer_acceleration_over_raft", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
"min_skirt_length", "brim_width", "brim_separation", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers", "min_skirt_length", "brim_width", "brim_separation", "brim_type", "check_for_issues_mode", "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", "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_closing_radius", "support_material_style", "support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_closing_radius", "support_material_style",
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_bottom_interface_layers", "support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_bottom_interface_layers",

View File

@ -537,7 +537,7 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionFloat(60)); def->set_default_value(new ConfigOptionFloat(60));
def = this->add("enable_dynamic_overhang_speeds", coBool); def = this->add("enable_dynamic_overhang_speeds", coBool);
def->label = L("Enable dynamic overhang speeds (Experimental)"); def->label = L("Enable dynamic overhang speeds");
def->category = L("Speed"); def->category = L("Speed");
def->tooltip = L("This setting enables dynamic speed control on overhangs."); def->tooltip = L("This setting enables dynamic speed control on overhangs.");
def->mode = comAdvanced; def->mode = comAdvanced;
@ -2589,6 +2589,14 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced; def->mode = comAdvanced;
def->set_default_value(new ConfigOptionEnum<SlicingMode>(SlicingMode::Regular)); def->set_default_value(new ConfigOptionEnum<SlicingMode>(SlicingMode::Regular));
def = this->add("check_for_issues_mode", coBool);
def->label = L("Check for issues: ");
def->category = L("Support material");
def->tooltip = L("Check for supportable issues that may appear during printing. "
"If enabled, slicer will make alerts when it detects "
"issues that may be resolved with supports and/or brim.");
def->set_default_value(new ConfigOptionBool(true));
def = this->add("support_material", coBool); def = this->add("support_material", coBool);
def->label = L("Generate support material"); def->label = L("Generate support material");
def->category = L("Support material"); def->category = L("Support material");

View File

@ -516,6 +516,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionInt, wall_distribution_count)) ((ConfigOptionInt, wall_distribution_count))
((ConfigOptionFloatOrPercent, min_feature_size)) ((ConfigOptionFloatOrPercent, min_feature_size))
((ConfigOptionFloatOrPercent, min_bead_width)) ((ConfigOptionFloatOrPercent, min_bead_width))
((ConfigOptionBool, check_for_issues_mode))
((ConfigOptionBool, support_material)) ((ConfigOptionBool, support_material))
// Automatic supports (generated based fdm support point generator). // Automatic supports (generated based fdm support point generator).
((ConfigOptionBool, support_material_auto)) ((ConfigOptionBool, support_material_auto))

View File

@ -462,7 +462,7 @@ void PrintObject::generate_support_spots()
} }
}; };
if (!this->has_support()) { if (!this->has_support() && this->config().check_for_issues_mode.getBool()) {
SupportSpotsGenerator::raise_alerts_for_issues(supp_points, partial_objects, alert_fn); SupportSpotsGenerator::raise_alerts_for_issues(supp_points, partial_objects, alert_fn);
} }
} }
@ -619,6 +619,8 @@ bool PrintObject::invalidate_state_by_config_options(
steps.emplace_back(posSupportSpotsSearch); steps.emplace_back(posSupportSpotsSearch);
// Brim is printed below supports, support invalidates brim and skirt. // Brim is printed below supports, support invalidates brim and skirt.
steps.emplace_back(posSupportMaterial); steps.emplace_back(posSupportMaterial);
}else if (opt_key == "check_for_issues_mode") {
steps.emplace_back(posSupportSpotsSearch);
} else if ( } else if (
opt_key == "perimeters" opt_key == "perimeters"
|| opt_key == "extra_perimeters" || opt_key == "extra_perimeters"

View File

@ -799,7 +799,7 @@ void PrintObject::slice_volumes()
layer->m_regions[region_id]->trim_surfaces(trimming); layer->m_regions[region_id]->trim_surfaces(trimming);
} }
} }
// Merge all regions' slices to get islands, chain them by a shortest path. // Merge all regions' slices to get islands sorted topologically, chain them by a shortest path in separate index list
layer->make_slices(); layer->make_slices();
} }
}); });

View File

@ -260,8 +260,8 @@ std::vector<ExtrusionLine> check_extrusion_entity_stability(const ExtrusionEntit
SupportPointCause potential_cause = std::abs(curr_point.curvature) > 0.1 ? SupportPointCause::FloatingBridgeAnchor : SupportPointCause potential_cause = std::abs(curr_point.curvature) > 0.1 ? SupportPointCause::FloatingBridgeAnchor :
SupportPointCause::LongBridge; SupportPointCause::LongBridge;
float line_len = i > 0 ? ((annotated_points[i - 1].position - curr_point.position).norm()) : 0.0f; float line_len = i > 0 ? ((annotated_points[i - 1].position - curr_point.position).norm()) : 0.0f;
Vec2d line_dir = (curr_point.position - prev_point.position).normalized(); Vec2d line_dir = line_len > EPSILON ? Vec2d((curr_point.position - prev_point.position) / double(line_len)) : Vec2d::Zero();
ExtrusionLine line_out{i > 0 ? annotated_points[i - 1].position.cast<float>() : curr_point.position.cast<float>(), ExtrusionLine line_out{i > 0 ? annotated_points[i - 1].position.cast<float>() : curr_point.position.cast<float>(),
curr_point.position.cast<float>(), line_len, entity}; curr_point.position.cast<float>(), line_len, entity};
@ -335,14 +335,6 @@ std::vector<ExtrusionLine> check_extrusion_entity_stability(const ExtrusionEntit
line_out.form_quality = 0.8f; line_out.form_quality = 0.8f;
bridged_distance += line_len; bridged_distance += line_len;
if (bridged_distance > max_bridge_len) { if (bridged_distance > max_bridge_len) {
std::cout << "Problem found A: " << std::endl;
std::cout << "bridged_distance: " << bridged_distance << std::endl;
std::cout << "max_bridge_len: " << max_bridge_len << std::endl;
std::cout << "line_out.form_quality: " << line_out.form_quality << std::endl;
std::cout << "curr_point.distance: " << curr_point.distance << std::endl;
std::cout << "curr_point.curvature: " << curr_point.curvature << std::endl;
std::cout << "flow_width: " << flow_width << std::endl;
line_out.support_point_generated = potential_cause; line_out.support_point_generated = potential_cause;
bridged_distance = 0.0f; bridged_distance = 0.0f;
} }
@ -350,14 +342,6 @@ std::vector<ExtrusionLine> check_extrusion_entity_stability(const ExtrusionEntit
bridged_distance += line_len; bridged_distance += line_len;
line_out.form_quality = nearest_prev_layer_line.form_quality - 0.3f; line_out.form_quality = nearest_prev_layer_line.form_quality - 0.3f;
if (line_out.form_quality < 0 && bridged_distance > max_bridge_len) { if (line_out.form_quality < 0 && bridged_distance > max_bridge_len) {
std::cout << "Problem found B: " << std::endl;
std::cout << "bridged_distance: " << bridged_distance << std::endl;
std::cout << "max_bridge_len: " << max_bridge_len << std::endl;
std::cout << "line_out.form_quality: " << line_out.form_quality << std::endl;
std::cout << "curr_point.distance: " << curr_point.distance << std::endl;
std::cout << "curr_point.curvature: " << curr_point.curvature << std::endl;
std::cout << "flow_width: " << flow_width << std::endl;
line_out.support_point_generated = potential_cause; line_out.support_point_generated = potential_cause;
line_out.form_quality = 0.5f; line_out.form_quality = 0.5f;
bridged_distance = 0.0f; bridged_distance = 0.0f;
@ -662,7 +646,8 @@ std::tuple<ObjectPart, float> build_object_part_from_slice(const size_t &slice_i
} }
// BRIM HANDLING // BRIM HANDLING
if (layer->id() == params.raft_layers_count && params.raft_layers_count == 0 && params.brim_type != BrimType::btNoBrim) { if (layer->id() == params.raft_layers_count && params.raft_layers_count == 0 && params.brim_type != BrimType::btNoBrim &&
params.brim_width > 0.0) {
// TODO: The algorithm here should take into account that multiple slices may have coliding Brim areas and the final brim area is // TODO: The algorithm here should take into account that multiple slices may have coliding Brim areas and the final brim area is
// smaller, // smaller,
// thus has lower adhesion. For now this effect will be neglected. // thus has lower adhesion. For now this effect will be neglected.
@ -921,7 +906,8 @@ std::tuple<SupportPoints, PartialObjects> check_stability(const PrintObject *po,
for (const auto &perimeter_idx : island.perimeters) { for (const auto &perimeter_idx : island.perimeters) {
const ExtrusionEntity *entity = perimeter_region->perimeters().entities[perimeter_idx]; const ExtrusionEntity *entity = perimeter_region->perimeters().entities[perimeter_idx];
std::vector<ExtrusionLine> perims = check_extrusion_entity_stability(entity, perimeter_region, std::vector<ExtrusionLine> perims = check_extrusion_entity_stability(entity, perimeter_region,
prev_layer_ext_perim_lines,prev_layer_boundary, params); prev_layer_ext_perim_lines, prev_layer_boundary,
params);
for (const ExtrusionLine &perim : perims) { for (const ExtrusionLine &perim : perims) {
if (perim.support_point_generated.has_value()) { if (perim.support_point_generated.has_value()) {
reckon_new_support_point(*perim.support_point_generated, create_support_point_position(perim.b), -EPSILON, reckon_new_support_point(*perim.support_point_generated, create_support_point_position(perim.b), -EPSILON,
@ -932,6 +918,30 @@ std::tuple<SupportPoints, PartialObjects> check_stability(const PrintObject *po,
} }
} }
} }
// DEBUG EXPORT, NOT USED NOW
// if (BR_bridge) {
// Lines scaledl;
// for (const auto &l : prev_layer_boundary.get_lines()) {
// scaledl.emplace_back(Point::new_scale(l.a), Point::new_scale(l.b));
// }
// Lines perimsl;
// for (const auto &l : current_slice_ext_perims_lines) {
// perimsl.emplace_back(Point::new_scale(l.a), Point::new_scale(l.b));
// }
// BoundingBox bb = get_extents(scaledl);
// bb.merge(get_extents(perimsl));
// ::Slic3r::SVG svg(debug_out_path(
// ("slice" + std::to_string(slice_idx) + "_" + std::to_string(layer_idx).c_str()).c_str()),
// get_extents(scaledl));
// svg.draw(scaledl, "red", scale_(0.4));
// svg.draw(perimsl, "blue", scale_(0.25));
// svg.Close();
// }
} }
LD current_slice_lines_distancer(current_slice_ext_perims_lines); LD current_slice_lines_distancer(current_slice_ext_perims_lines);
@ -1165,13 +1175,6 @@ void raise_alerts_for_issues(const SupportPoints
PartialObjects &partial_objects, PartialObjects &partial_objects,
std::function<void(PrintStateBase::WarningLevel, SupportPointCause)> alert_fn) std::function<void(PrintStateBase::WarningLevel, SupportPointCause)> alert_fn)
{ {
for (const SupportPoint &sp : support_points) {
if (sp.cause == SupportPointCause::SeparationFromBed) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::SeparationFromBed);
break;
}
}
std::reverse(partial_objects.begin(), partial_objects.end()); std::reverse(partial_objects.begin(), partial_objects.end());
std::sort(partial_objects.begin(), partial_objects.end(), std::sort(partial_objects.begin(), partial_objects.end(),
[](const PartialObject &left, const PartialObject &right) { return left.volume > right.volume; }); [](const PartialObject &left, const PartialObject &right) { return left.volume > right.volume; });
@ -1221,21 +1224,29 @@ void raise_alerts_for_issues(const SupportPoints
} }
} }
if (ext_supp_points.size() > 5) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::FloatingExtrusion);
}
for (const SupportPoint &sp : support_points) { for (const SupportPoint &sp : support_points) {
if (sp.cause == SupportPointCause::LongBridge) { if (sp.cause == SupportPointCause::SeparationFromBed) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::LongBridge); alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::SeparationFromBed);
break; return;
} }
} }
for (const SupportPoint &sp : support_points) { for (const SupportPoint &sp : support_points) {
if (sp.cause == SupportPointCause::WeakObjectPart) { if (sp.cause == SupportPointCause::WeakObjectPart) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::WeakObjectPart); alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::WeakObjectPart);
break; return;
}
}
if (ext_supp_points.size() > 5) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::FloatingExtrusion);
return;
}
for (const SupportPoint &sp : support_points) {
if (sp.cause == SupportPointCause::LongBridge) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::LongBridge);
return;
} }
} }
} }

View File

@ -53,7 +53,7 @@ static SettingsFactory::Bundle FREQ_SETTINGS_BUNDLE_FFF =
{ {
{ L("Layers and Perimeters"), { "layer_height" , "perimeters", "top_solid_layers", "bottom_solid_layers" } }, { L("Layers and Perimeters"), { "layer_height" , "perimeters", "top_solid_layers", "bottom_solid_layers" } },
{ L("Infill") , { "fill_density", "fill_pattern" } }, { L("Infill") , { "fill_density", "fill_pattern" } },
{ L("Support material") , { "support_material", "support_material_auto", "support_material_threshold", { L("Support material") , { "check_for_issues_mode", "support_material", "support_material_auto", "support_material_threshold",
"support_material_pattern", "support_material_interface_pattern", "support_material_buildplate_only", "support_material_pattern", "support_material_interface_pattern", "support_material_buildplate_only",
"support_material_spacing" } }, "support_material_spacing" } },
{ L("Wipe options") , { "wipe_into_infill", "wipe_into_objects" } } { L("Wipe options") , { "wipe_into_infill", "wipe_into_objects" } }

View File

@ -1495,6 +1495,7 @@ void TabPrint::build()
page = add_options_page(L("Support material"), "support"); page = add_options_page(L("Support material"), "support");
category_path = "support-material_1698#"; category_path = "support-material_1698#";
optgroup = page->new_optgroup(L("Support material")); optgroup = page->new_optgroup(L("Support material"));
optgroup->append_single_option_line("check_for_issues_mode", category_path + "check-for-issues-mode");
optgroup->append_single_option_line("support_material", category_path + "generate-support-material"); optgroup->append_single_option_line("support_material", category_path + "generate-support-material");
optgroup->append_single_option_line("support_material_auto", category_path + "auto-generated-supports"); optgroup->append_single_option_line("support_material_auto", category_path + "auto-generated-supports");
optgroup->append_single_option_line("support_material_threshold", category_path + "overhang-threshold"); optgroup->append_single_option_line("support_material_threshold", category_path + "overhang-threshold");