From f2cb4f747c4e147ef059d1acede0fb6e5d20c5af Mon Sep 17 00:00:00 2001 From: "jiaxi.chen" Date: Wed, 12 Feb 2025 16:21:23 +0800 Subject: [PATCH] ENH: improve quality of interface 1. change type of transition layers below interface to erSupportTransition, 2. fix the number of transition layer above tree branches, 3. change the default setting of support_interface_pattern to smipRectilinearInterlaced, 4. change the default support_style to HybridTree when interface is soluble 5. FIX: conflict between xy_expansion && split_hole jira: STUDIO-10239, STUDIO-10314, STUDIO-10319 Change-Id: I3eb392ccd005acedb001aa862d5bf3eb104c5293 --- .../BBL/process/fdm_process_common.json | 2 +- src/libslic3r/GCode.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 2 +- src/libslic3r/Support/SupportParameters.hpp | 2 +- src/libslic3r/Support/TreeSupport.cpp | 52 +++++++++---------- 5 files changed, 28 insertions(+), 32 deletions(-) diff --git a/resources/profiles/BBL/process/fdm_process_common.json b/resources/profiles/BBL/process/fdm_process_common.json index 4a1725535..808caaa1f 100644 --- a/resources/profiles/BBL/process/fdm_process_common.json +++ b/resources/profiles/BBL/process/fdm_process_common.json @@ -125,7 +125,7 @@ ], "tree_support_branch_angle": "45", "tree_support_branch_diameter": "2", - "tree_support_wall_count": "0", + "tree_support_wall_count": "1", "wall_generator": "classic", "wall_infill_order": "inner wall/outer wall/infill", "wall_loops": "2", diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index fd1d45df0..798a04c7e 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3849,7 +3849,7 @@ GCode::LayerResult GCode::process_layer( // Assign an extruder to the base. ObjectByExtruder &obj = object_by_extruder(by_extruder, has_support ? support_extruder : interface_extruder, &layer_to_print - layers.data(), layers.size()); obj.support = &support_layer.support_fills; - obj.support_extrusion_role = single_extruder ? erMixed : erSupportMaterial; + obj.support_extrusion_role = single_extruder ? erMixed : role; if (! single_extruder && has_interface) { ObjectByExtruder &obj_interface = object_by_extruder(by_extruder, interface_extruder, &layer_to_print - layers.data(), layers.size()); obj_interface.support = &support_layer.support_fills; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 79e8f8520..ffaf975e2 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -4036,7 +4036,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 2; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionInt(0)); + def->set_default_value(new ConfigOptionInt(1)); def = this->add("chamber_temperatures", coInts); def->label = L("Chamber temperature"); diff --git a/src/libslic3r/Support/SupportParameters.hpp b/src/libslic3r/Support/SupportParameters.hpp index 2bd95fc10..def096efb 100644 --- a/src/libslic3r/Support/SupportParameters.hpp +++ b/src/libslic3r/Support/SupportParameters.hpp @@ -195,7 +195,7 @@ struct SupportParameters { if (support_style == smsDefault) { if (is_tree(object_config.support_type)) { // organic support doesn't work with variable layer heights (including adaptive layer height and height range modifier, see #4313) - if (!object.has_variable_layer_heights) { + if (!object.has_variable_layer_heights && !slicing_params.soluble_interface) { BOOST_LOG_TRIVIAL(warning) << "tree support default to organic support"; support_style = smsTreeOrganic; } else { diff --git a/src/libslic3r/Support/TreeSupport.cpp b/src/libslic3r/Support/TreeSupport.cpp index 452a4d62c..7134dd664 100644 --- a/src/libslic3r/Support/TreeSupport.cpp +++ b/src/libslic3r/Support/TreeSupport.cpp @@ -1081,26 +1081,9 @@ void TreeSupport::detect_overhangs(bool check_support_necessity/* = false*/) if (!cluster.is_type(Small)) { cluster.check_polygon_node(m_support_params.thresh_big_overhang, m_ts_data->m_layer_outlines_below[cluster.min_layer - 1]); for (auto it = cluster.layer_overhangs.begin(); it != cluster.layer_overhangs.end(); it++) { - int layer_nr = it->first; - ExPolygons overhangs{*it->second}; - coordf_t xy_expansion = scale_(config.support_expansion.value); - if (m_support_params.soluble_interface && xy_expansion < EPSILON) xy_expansion = scale_(2); - coord_t gap_width = scale_(extrusion_width / 2.) + xy_expansion + scale_(m_ts_data->m_xy_distance); - for (auto &overhang : overhangs) { - if (cluster.type & OverhangType::BigFlat) { - ExPolygons sub_overhangs = overhang.split_expoly_with_holes(gap_width, get_collision(0, layer_nr)); - if (sub_overhangs.size() > 0) { - for (auto &sub : sub_overhangs) { - if (sub.area() < SQ(scale_(1.))) - add_overhang(m_object->get_layer(layer_nr), sub, OverhangType::Normal); - else - add_overhang(m_object->get_layer(layer_nr), sub, OverhangType::BigFlat); - } - } else - add_overhang(m_object->get_layer(layer_nr), overhang, cluster.type); - } else - add_overhang(m_object->get_layer(layer_nr), overhang, cluster.type); - } + int layer_nr = it->first; + ExPolygon overhang = *it->second; + add_overhang(m_object->get_layer(layer_nr), overhang, cluster.type); } } } @@ -1531,6 +1514,7 @@ void TreeSupport::generate_toolpaths() BoundingBox bbox_object(Point(-scale_(1.), -scale_(1.0)), Point(scale_(1.), scale_(1.))); + if (m_support_params.support_style == smsTreeHybrid && object_config.support_interface_pattern == smipAuto) m_support_params.contact_fill_pattern = ipRectilinear; std::shared_ptr filler_interface = std::shared_ptr(Fill::new_from_type(m_support_params.contact_fill_pattern)); std::shared_ptr filler_Roof1stLayer = std::shared_ptr(Fill::new_from_type(ipRectilinear)); filler_interface->set_bounding_box(bbox_object); @@ -1577,13 +1561,14 @@ void TreeSupport::generate_toolpaths() fill_params.dont_adjust = true; } if (area_group.type == SupportLayer::Roof1stLayer) { - // roof_1st_layer - fill_params.density = interface_density; + // use higher flow for roof_1st_layer ? + Flow roof_1st_layer_flow = support_material_interface_flow(m_object, ts_layer->height)/*.with_flow_ratio(1.5)*/; + // Note: spacing means the separation between two lines as if they are tightly extruded - filler_Roof1stLayer->spacing = interface_flow.spacing(); + filler_Roof1stLayer->spacing = roof_1st_layer_flow.spacing(); // generate a perimeter first to support interface better ExtrusionEntityCollection* temp_support_fills = new ExtrusionEntityCollection(); - make_perimeter_and_infill(temp_support_fills->entities, poly, 1, interface_flow, erSupportMaterial, + make_perimeter_and_infill(temp_support_fills->entities, poly, 1, roof_1st_layer_flow, erSupportTransition, filler_Roof1stLayer.get(), interface_density, false); temp_support_fills->no_sort = true; // make sure loops are first if (!temp_support_fills->entities.empty()) @@ -1604,8 +1589,9 @@ void TreeSupport::generate_toolpaths() filler_interface->angle = Geometry::deg2rad(object_config.support_angle.value); fill_params.dont_sort = true; } - if (m_object_config->support_interface_pattern == smipRectilinearInterlaced) + if (m_object_config->support_interface_pattern == smipRectilinearInterlaced || m_object_config->support_interface_pattern == smipAuto) { filler_interface->layer_id = area_group.interface_id; + } fill_expolygons_generate_paths(ts_layer->support_fills.entities, polys, filler_interface.get(), fill_params, erSupportMaterialInterface, interface_flow); @@ -2220,7 +2206,7 @@ void TreeSupport::draw_circles() // merge overhang to get a smoother interface surface // Do not merge when buildplate_only is on, because some underneath nodes may have been deleted. - if (top_interface_layers > 0 && node.support_roof_layers_below > 0 && !on_buildplate_only && !node.is_sharp_tail) { + if (top_interface_layers > 0 && node.support_roof_layers_below >=0 && !on_buildplate_only && !node.is_sharp_tail) { ExPolygons overhang_expanded; if (node.overhang.contour.size() > 100 || node.overhang.holes.size()>1) overhang_expanded.emplace_back(node.overhang); @@ -3629,6 +3615,7 @@ void TreeSupport::generate_contact_points() bool on_buildplate_only = m_object_config->support_on_build_plate_only.value; const bool roof_enabled = config.support_interface_top_layers.value > 0; const bool force_tip_to_roof = roof_enabled && m_support_params.soluble_interface; + const coordf_t extrusion_width = config.line_width.value; //First generate grid points to cover the entire area of the print. BoundingBox bounding_box = m_object->bounding_box(); @@ -3753,11 +3740,20 @@ void TreeSupport::generate_contact_points() if (m_support_params.support_style == smsTreeHybrid && (overhang_type & (BigFlat | ThinPlate))) { overhangs_regular = offset_ex(intersection_ex(overhangs, m_ts_data->m_layer_outlines_below[layer_nr - 1]), radius_scaled); - ExPolygons overhangs_normal = diff_ex(overhangs, overhangs_regular); + ExPolygons overhangs_normal = offset2_ex(diff_ex(overhangs, overhangs_regular),scale_(extrusion_width),-scale_(extrusion_width)); overhangs_regular = intersection_ex(overhangs_regular, overhangs_no_extra_expand); // if the outside area is still big, we can need normal nodes + coord_t gap_width = scale_(extrusion_width / 2.) + scale_(m_ts_data->m_xy_distance); + ExPolygons overhangs_normal_split; for (auto &overhang : overhangs_normal) { - if (!is_stable(layer->bottom_z(), overhang, 0)) { + ExPolygons sub_overhangs = overhang.split_expoly_with_holes(gap_width, get_collision(0, layer_nr)); + if (sub_overhangs.size() > 0) + for (auto &sub : sub_overhangs) overhangs_normal_split.emplace_back(sub); + else + overhangs_normal_split.emplace_back(overhang); + } + for (auto &overhang : overhangs_normal_split) { + if (!is_stable(layer->bottom_z(), overhang, 0) || overhang.area() < SQ(scale_(2.))) { ExPolygons unstable_overhangs = intersection_ex({overhang}, overhangs_no_extra_expand); overhangs_regular.insert(overhangs_regular.end(), unstable_overhangs.begin(), unstable_overhangs.end()); continue;