void FffPolygonGenerator::processSkins(SliceDataStorage& storage, unsigned int layer_nr) { for(SliceMeshStorage& mesh : storage.meshes) { if (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") == ESurfaceMode::SURFACE) { continue; } int skin_extrusion_width = mesh.getSettingInMicrons("skin_line_width"); int innermost_wall_extrusion_width = mesh.getSettingInMicrons("wall_line_width_x"); int extrusionWidth_infill = mesh.getSettingInMicrons("infill_line_width"); generateSkins(layer_nr, mesh, skin_extrusion_width, mesh.getSettingAsCount("bottom_layers"), mesh.getSettingAsCount("top_layers"), innermost_wall_extrusion_width, mesh.getSettingAsCount("skin_outline_count"), mesh.getSettingBoolean("skin_no_small_gaps_heuristic"), mesh.getSettingBoolean("remove_overlapping_walls_0_enabled"), mesh.getSettingBoolean("remove_overlapping_walls_x_enabled")); if (mesh.getSettingInMicrons("infill_line_distance") > 0) { int infill_skin_overlap = 0; if (mesh.getSettingInMicrons("infill_line_distance") > mesh.getSettingInMicrons("infill_line_width") + 10) { infill_skin_overlap = skin_extrusion_width / 2; } generateInfill(layer_nr, mesh, extrusionWidth_infill, infill_skin_overlap); if (mesh.getSettingAsFillPerimeterGapMode("fill_perimeter_gaps") == FillPerimeterGapMode::SKIN) { generatePerimeterGaps(layer_nr, mesh, skin_extrusion_width, mesh.getSettingAsCount("bottom_layers"), mesh.getSettingAsCount("top_layers")); } else if (mesh.getSettingAsFillPerimeterGapMode("fill_perimeter_gaps") == FillPerimeterGapMode::EVERYWHERE) { generatePerimeterGaps(layer_nr, mesh, skin_extrusion_width, 0, 0); } } bool frontend_can_show_polygon_as_filled_polygon = false; if (frontend_can_show_polygon_as_filled_polygon) { SliceLayer& layer = mesh.layers[layer_nr]; for(SliceLayerPart& part : layer.parts) { // sendPolygons(InfillType, layer_nr, part.infill_area[0], extrusionWidth_infill); // sends the outline, not the actual infill for (SkinPart& skin_part : part.skin_parts) { sendPolygons(SkinType, layer_nr, skin_part.outline, innermost_wall_extrusion_width); } } } } }
/* * This function is executed in a parallel region based on layer_nr. * When modifying make sure any changes does not introduce data races. * * generateSkinAreas reads data from mesh.layers[*].parts[*].insets and writes to mesh.layers[n].parts[*].skin_parts */ void SkinInfillAreaComputation::generateSkinAndInfillAreas(SliceLayerPart& part) { int min_infill_area = mesh.getSettingInMillimeters("min_infill_area"); Polygons original_outline = part.insets.back().offset(-innermost_wall_line_width / 2); // make a copy of the outline which we later intersect and union with the resized skins to ensure the resized skin isn't too large or removed completely. Polygons upskin; if (top_layer_count > 0) { upskin = Polygons(original_outline); } Polygons downskin; if (bottom_layer_count > 0) { downskin = Polygons(original_outline); } calculateBottomSkin(part, min_infill_area, downskin); calculateTopSkin(part, min_infill_area, upskin); applySkinExpansion(original_outline, upskin, downskin); // now combine the resized upskin and downskin Polygons skin = upskin.unionPolygons(downskin); skin.removeSmallAreas(MIN_AREA_SIZE); if (process_infill) { // process infill when infill density > 0 // or when other infill meshes want to modify this infill generateInfill(part, skin); } for (PolygonsPart& skin_area_part : skin.splitIntoParts()) { part.skin_parts.emplace_back(); part.skin_parts.back().outline = skin_area_part; } }
void FffPolygonGenerator::processSkinsAndInfill(SliceMeshStorage& mesh, unsigned int layer_nr) { if (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") == ESurfaceMode::SURFACE) { return; } int wall_line_count = mesh.getSettingAsCount("wall_line_count"); int skin_extrusion_width = mesh.getSettingInMicrons("skin_line_width"); int innermost_wall_extrusion_width = (wall_line_count == 1)? mesh.getSettingInMicrons("wall_line_width_0") : mesh.getSettingInMicrons("wall_line_width_x"); generateSkins(layer_nr, mesh, skin_extrusion_width, mesh.getSettingAsCount("bottom_layers"), mesh.getSettingAsCount("top_layers"), wall_line_count, innermost_wall_extrusion_width, mesh.getSettingAsCount("skin_outline_count"), mesh.getSettingBoolean("skin_no_small_gaps_heuristic")); if (mesh.getSettingInMicrons("infill_line_distance") > 0) { int infill_skin_overlap = 0; bool infill_is_dense = mesh.getSettingInMicrons("infill_line_distance") < mesh.getSettingInMicrons("infill_line_width") + 10; if (!infill_is_dense && mesh.getSettingAsFillMethod("infill_pattern") != EFillMethod::CONCENTRIC) { infill_skin_overlap = skin_extrusion_width / 2; } generateInfill(layer_nr, mesh, innermost_wall_extrusion_width, infill_skin_overlap, wall_line_count); } }