diff --git a/src/libslic3r/Support/TreeSupport.cpp b/src/libslic3r/Support/TreeSupport.cpp index 47e7422b3c..a8cfa9cbfe 100644 --- a/src/libslic3r/Support/TreeSupport.cpp +++ b/src/libslic3r/Support/TreeSupport.cpp @@ -1143,6 +1143,17 @@ void TreeSupport::create_tree_support_layers() raft_slice_z = raft_print_z - height / 2; m_object->add_tree_support_layer(layer_id++, height, raft_print_z, raft_slice_z); } + + // Layers between the raft contacts and bottom of the object. + double dist_to_go = m_slicing_params.object_print_z_min - raft_print_z; + auto nsteps = int(ceil(dist_to_go / m_slicing_params.max_suport_layer_height)); + double height = dist_to_go / nsteps; + for (int i = 0; i < nsteps; ++i) { + raft_print_z += height; + raft_slice_z = raft_print_z - height / 2; + m_object->add_tree_support_layer(layer_id++, height, raft_print_z, raft_slice_z); + } + m_raft_layers = layer_id; } for (Layer *layer : m_object->layers()) { @@ -1242,7 +1253,7 @@ static void make_perimeter_and_inner_brim(ExtrusionEntitiesPtr &dst, const ExPol _make_loops(dst, support_area_new, role, wall_count, flow); } -static void make_perimeter_and_infill(ExtrusionEntitiesPtr& dst, const Print& print, const ExPolygon& support_area, size_t wall_count, const Flow& flow, ExtrusionRole role, Fill* filler_support, double support_density, bool infill_first=true) +static void make_perimeter_and_infill(ExtrusionEntitiesPtr& dst, const ExPolygon& support_area, size_t wall_count, const Flow& flow, ExtrusionRole role, Fill* filler_support, double support_density, bool infill_first=true) { Polygons loops; ExPolygons support_area_new = offset_ex(support_area, -0.5f * float(flow.scaled_spacing()), jtSquare); @@ -1349,7 +1360,8 @@ void TreeSupport::generate_toolpaths() raft_areas = std::move(offset_ex(raft_areas, scale_(object_config.raft_first_layer_expansion))); - for (size_t layer_nr = 0; layer_nr < m_slicing_params.base_raft_layers; layer_nr++) { + size_t layer_nr = 0; + for (; layer_nr < m_slicing_params.base_raft_layers; layer_nr++) { SupportLayer *ts_layer = m_object->get_support_layer(layer_nr); coordf_t expand_offset = (layer_nr == 0 ? m_object_config->raft_first_layer_expansion.value : 0.); auto raft_areas1 = offset_ex(raft_areas, scale_(expand_offset)); @@ -1384,10 +1396,13 @@ void TreeSupport::generate_toolpaths() first_non_raft_base.emplace_back(*area_group.area); } } + first_non_raft_base = offset_ex(first_non_raft_base, support_extrusion_width); ExPolygons raft_base_areas = intersection_ex(raft_areas, first_non_raft_base); ExPolygons raft_interface_areas = diff_ex(raft_areas, raft_base_areas); - for (size_t layer_nr = m_slicing_params.base_raft_layers; + + // raft interfaces + for (layer_nr = m_slicing_params.base_raft_layers; layer_nr < m_slicing_params.base_raft_layers + m_slicing_params.interface_raft_layers; layer_nr++) { @@ -1410,6 +1425,17 @@ void TreeSupport::generate_toolpaths() filler_interface, fill_params, erSupportMaterial, support_flow); } + // layers between raft and object + for (; layer_nr < m_raft_layers; layer_nr++) { + SupportLayer *ts_layer = m_object->get_support_layer(layer_nr); + Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter); + Fill* filler_raft = Fill::new_from_type(ipRectilinear); + filler_raft->angle = PI / 2; + filler_raft->spacing = support_flow.spacing(); + for (auto& poly : first_non_raft_base) + make_perimeter_and_infill(ts_layer->support_fills.entities, poly, std::min(size_t(1), wall_count), support_flow, erSupportMaterial, filler_raft, interface_density, false); + } + if (m_object->support_layer_count() <= m_raft_layers) return; @@ -1435,7 +1461,7 @@ void TreeSupport::generate_toolpaths() SupportLayer* ts_layer = m_object->get_support_layer(layer_id); Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter); - m_support_material_interface_flow = support_material_interface_flow(m_object, ts_layer->height); // update flow using real support layer height + Flow interface_flow = support_material_interface_flow(m_object, ts_layer->height); // update flow using real support layer height coordf_t support_spacing = object_config.support_base_pattern_spacing.value + support_flow.spacing(); coordf_t support_density = std::min(1., support_flow.spacing() / support_spacing); ts_layer->support_fills.no_sort = false; @@ -1464,10 +1490,10 @@ void TreeSupport::generate_toolpaths() // roof_1st_layer fill_params.density = interface_density; // Note: spacing means the separation between two lines as if they are tightly extruded - filler_Roof1stLayer->spacing = m_support_material_interface_flow.spacing(); + filler_Roof1stLayer->spacing = interface_flow.spacing(); // generate a perimeter first to support interface better ExtrusionEntityCollection* temp_support_fills = new ExtrusionEntityCollection(); - make_perimeter_and_infill(temp_support_fills->entities, *m_object->print(), poly, 1, m_support_material_interface_flow, erSupportMaterial, + make_perimeter_and_infill(temp_support_fills->entities, poly, 1, interface_flow, erSupportMaterial, filler_Roof1stLayer.get(), interface_density, false); temp_support_fills->no_sort = true; // make sure loops are first if (!temp_support_fills->entities.empty()) @@ -1477,13 +1503,13 @@ void TreeSupport::generate_toolpaths() } else if (area_group.type == SupportLayer::FloorType) { // floor_areas fill_params.density = bottom_interface_density; - filler_interface->spacing = m_support_material_interface_flow.spacing(); + filler_interface->spacing = interface_flow.spacing(); fill_expolygons_generate_paths(ts_layer->support_fills.entities, polys, - filler_interface.get(), fill_params, erSupportMaterialInterface, m_support_material_interface_flow); + filler_interface.get(), fill_params, erSupportMaterialInterface, interface_flow); } else if (area_group.type == SupportLayer::RoofType) { // roof_areas fill_params.density = interface_density; - filler_interface->spacing = m_support_material_interface_flow.spacing(); + filler_interface->spacing = interface_flow.spacing(); if (m_object_config->support_interface_pattern == smipGrid) { filler_interface->angle = Geometry::deg2rad(object_config.support_angle.value); fill_params.dont_sort = true; @@ -1492,7 +1518,7 @@ void TreeSupport::generate_toolpaths() filler_interface->layer_id = area_group.interface_id; fill_expolygons_generate_paths(ts_layer->support_fills.entities, polys, filler_interface.get(), fill_params, erSupportMaterialInterface, - m_support_material_interface_flow); + interface_flow); } else { // base_areas @@ -1517,7 +1543,7 @@ void TreeSupport::generate_toolpaths() // otherwise must draw 1 wall // Don't need extra walls if we have infill. Extra walls may overlap with the infills. size_t min_wall_count = offset(poly, -scale_(support_spacing * 1.5)).empty() ? 1 : 0; - make_perimeter_and_infill(ts_layer->support_fills.entities, *m_object->print(), poly, std::max(min_wall_count, wall_count), flow, + make_perimeter_and_infill(ts_layer->support_fills.entities, poly, std::max(min_wall_count, wall_count), flow, erSupportMaterial, filler_support.get(), support_density); } else { diff --git a/src/libslic3r/Support/TreeSupport.hpp b/src/libslic3r/Support/TreeSupport.hpp index dc641669da..b8d4bdbbba 100644 --- a/src/libslic3r/Support/TreeSupport.hpp +++ b/src/libslic3r/Support/TreeSupport.hpp @@ -413,7 +413,7 @@ private: SlicingParameters m_slicing_params; // Various precomputed support parameters to be shared with external functions. SupportParameters m_support_params; - size_t m_raft_layers = 0; + size_t m_raft_layers = 0; // number of raft layers, including raft base, raft interface, raft gap size_t m_highest_overhang_layer = 0; std::vector> m_spanning_trees; std::vector< std::unordered_map> m_mst_line_x_layer_contour_caches;