diff --git a/src/libslic3r/Support/TreeSupport.cpp b/src/libslic3r/Support/TreeSupport.cpp index 2209afbd7b..aaf3ba4443 100644 --- a/src/libslic3r/Support/TreeSupport.cpp +++ b/src/libslic3r/Support/TreeSupport.cpp @@ -1593,13 +1593,20 @@ void TreeSupport::generate_toolpaths() } else { // base_areas - Flow flow = (layer_id == 0 && m_raft_layers == 0) ? m_object->print()->brim_flow() : support_flow; + bool support_base_on_bed = (layer_id == 0 && m_raft_layers == 0); + Flow flow = support_base_on_bed ? m_support_params.first_layer_flow : support_flow; bool need_infill = with_infill; if(m_object_config->support_base_pattern==smpDefault) need_infill &= area_group.need_infill; - std::shared_ptr filler_support = std::shared_ptr(Fill::new_from_type(layer_id == 0 ? ipConcentric : m_support_params.base_fill_pattern)); + // Orca: Use rectilinear for support base on the bed + const InfillPattern base_fill_pattern = support_base_on_bed ? ipRectilinear : m_support_params.base_fill_pattern; + std::shared_ptr filler_support = std::shared_ptr(Fill::new_from_type(base_fill_pattern)); filler_support->set_bounding_box(bbox_object); - filler_support->spacing = support_spacing * support_density; // constant spacing to align support infill lines + + filler_support->spacing = + support_base_on_bed ? + flow.spacing() : // Orca: On the bed-contacting support base layer, use first-layer flow spacing directly. + support_spacing * support_density; // constant spacing to align support infill lines filler_support->angle = Geometry::deg2rad(object_config.support_angle.value); Polygons loops = to_polygons(poly); @@ -1639,7 +1646,7 @@ void TreeSupport::generate_toolpaths() // strengthen lightnings while it may make support harder. decide to enable it or not. if yes, proper values for params are remained to be tested auto& lightning_layer = generator->getTreesForLayer(printZ_to_lightninglayer[print_z]); - Flow flow = (layer_id == 0 && m_raft_layers == 0) ? m_object->print()->brim_flow() :support_flow; + Flow flow = (layer_id == 0 && m_raft_layers == 0) ? m_support_params.first_layer_flow : support_flow; ExPolygons areas = offset_ex(ts_layer->base_areas, -flow.scaled_spacing()); for (auto& area : areas) @@ -2342,6 +2349,31 @@ void TreeSupport::draw_circles() floor_areas = std::move(new_floor_areas); } + // Orca: Hybrid tree first-layer expansion belongs only to the normal-support + // part. area_poly is collected from ePolygon nodes above, which are the normal + // support nodes in Hybrid mode. Apply the expansion before area_groups and + // lslices are built so toolpaths and brim avoidance use the same footprint. + if (layer_nr == 0 && m_raft_layers == 0 && m_support_params.support_style == smsTreeHybrid && + m_object_config->raft_first_layer_expansion.value > 0.f) { + ExPolygons expanded_base_areas; + const float inflate_factor_1st_layer = float(scale_(m_object_config->raft_first_layer_expansion.value)); + Polygons trimming = offset(m_object->layers().front()->lslices, float(scale_(m_support_params.gap_xy_first_layer)), + SUPPORT_SURFACES_OFFSET_PARAMETERS); + // Orca: Match normal support expansion: grow in steps and re-trim against the object each time. + const int nsteps = std::max(5, int(ceil(inflate_factor_1st_layer / m_support_params.first_layer_flow.scaled_width()))); + const float step = inflate_factor_1st_layer / nsteps; + for (const ExPolygon &expoly : ts_layer->base_areas) { + if (overlaps({ expoly }, area_poly)) { // normal support in Hybrid mode + Polygons expanded = to_polygons(expoly); + for (int i = 0; i < nsteps; ++i) + expanded = diff(expand(expanded, step), trimming); + append(expanded_base_areas, union_ex(expanded)); + } else + expanded_base_areas.emplace_back(expoly); + } + ts_layer->base_areas = std::move(expanded_base_areas); + } + auto &area_groups = ts_layer->area_groups; for (auto& expoly : ts_layer->base_areas) { diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index f3a359f560..65a475d817 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -788,9 +788,12 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co toggle_line("raft_contact_distance", have_raft && !have_support_soluble); - // Orca: Raft, grid, snug and organic supports use these two parameters to control the size & density of the "brim"/flange - for (auto el : { "raft_first_layer_expansion", "raft_first_layer_density"}) - toggle_field(el, have_support_material && !(support_is_normal_tree && !have_raft)); + // Orca: First-layer density is available for supports broadly. + toggle_field("raft_first_layer_density", have_support_material); + // Orca: For regular tree (Slim/Strong) without raft, hide first-layer expansion. + // Keep it enabled for non-tree supports, organic tree, hybrid tree, and any raft case. + toggle_field("raft_first_layer_expansion", + have_support_material && ((!support_is_normal_tree || support_style == smsTreeHybrid) || have_raft)); bool has_ironing = (config->opt_enum("ironing_type") != IroningType::NoIroning); for (auto el : { "ironing_pattern", "ironing_flow", "ironing_spacing", "ironing_angle", "ironing_inset", "ironing_angle_fixed" })