void PrimeTower::generatePaths3(SliceDataStorage& storage) { int n_patterns = 2; // alternating patterns between layers int infill_overlap = 60; // so that it can't be zero; EDIT: wtf? int extra_infill_shift = 0; generateGroundpoly(storage); int64_t z = 0; // (TODO) because the prime tower stores the paths for each extruder for once instead of generating each layer, we don't know the z position for (int extruder = 0; extruder < extruder_count; extruder++) { int line_width = storage.meshgroup->getExtruderTrain(extruder)->getSettingInMicrons("prime_tower_line_width"); patterns_per_extruder.emplace_back(n_patterns); std::vector<Polygons>& patterns = patterns_per_extruder.back(); for (int pattern_idx = 0; pattern_idx < n_patterns; pattern_idx++) { Polygons result_polygons; // should remain empty, since we generate lines pattern! int outline_offset = -line_width/2; int line_distance = line_width; double fill_angle = 45 + pattern_idx * 90; Polygons& result_lines = patterns[pattern_idx]; Infill infill_comp(EFillMethod::LINES, ground_poly, outline_offset, line_width, line_distance, infill_overlap, fill_angle, z, extra_infill_shift); infill_comp.generate(result_polygons, result_lines); } } }
void PrimeTower::generatePaths_denseInfill(const SliceDataStorage& storage) { int n_patterns = 2; // alternating patterns between layers int infill_overlap = 60; // so that it can't be zero; EDIT: wtf? int extra_infill_shift = 0; int64_t z = 0; // (TODO) because the prime tower stores the paths for each extruder for once instead of generating each layer, we don't know the z position for (int extruder = 0; extruder < extruder_count; extruder++) { int line_width = storage.meshgroup->getExtruderTrain(extruder)->getSettingInMicrons("prime_tower_line_width"); patterns_per_extruder.emplace_back(n_patterns); std::vector<ExtrusionMoves>& patterns = patterns_per_extruder.back(); patterns.resize(n_patterns); for (int pattern_idx = 0; pattern_idx < n_patterns; pattern_idx++) { patterns[pattern_idx].polygons = ground_poly.offset(-line_width / 2); Polygons& result_lines = patterns[pattern_idx].lines; int outline_offset = -line_width; int line_distance = line_width; double fill_angle = 45 + pattern_idx * 90; Polygons result_polygons; // should remain empty, since we generate lines pattern! constexpr bool zig_zaggify_infill = false; Infill infill_comp(EFillMethod::LINES, zig_zaggify_infill, ground_poly, outline_offset, line_width, line_distance, infill_overlap, fill_angle, z, extra_infill_shift); infill_comp.generate(result_polygons, result_lines); } int line_width_layer0 = line_width; if (storage.getSettingAsPlatformAdhesion("adhesion_type") != EPlatformAdhesion::RAFT) { line_width_layer0 *= storage.meshgroup->getExtruderTrain(extruder)->getSettingAsRatio("initial_layer_line_width_factor"); } pattern_per_extruder_layer0.emplace_back(); ExtrusionMoves& pattern = pattern_per_extruder_layer0.back(); pattern.polygons = ground_poly.offset(-line_width_layer0 / 2); int outline_offset = -line_width_layer0; int line_distance = line_width_layer0; double fill_angle = 45; Polygons result_polygons; constexpr bool zig_zaggify_infill = false; Infill infill_comp(EFillMethod::LINES, zig_zaggify_infill, ground_poly, outline_offset, line_width_layer0, line_distance, infill_overlap, fill_angle, z, extra_infill_shift); infill_comp.generate(result_polygons, pattern.lines); } }
bool SpaghettiInfillPathGenerator::processSpaghettiInfill(const SliceDataStorage& storage, const FffGcodeWriter& fff_gcode_writer, LayerPlan& gcode_layer, const SliceMeshStorage& mesh, const int extruder_nr, const PathConfigStorage::MeshPathConfigs& mesh_config, const SliceLayerPart& part, int infill_line_distance, int infill_overlap, int infill_angle, const Point& infill_origin) { if (extruder_nr != mesh.getSettingAsExtruderNr("infill_extruder_nr")) { return false; } bool added_something = false; const GCodePathConfig& config = mesh_config.infill_config[0]; const EFillMethod pattern = mesh.getSettingAsFillMethod("infill_pattern"); const bool zig_zaggify_infill = mesh.getSettingBoolean("zig_zaggify_infill"); const bool connect_polygons = true; // spaghetti infill should have as least as possible travel moves const unsigned int infill_line_width = config.getLineWidth(); constexpr int infill_multiplier = 1; const int64_t infill_shift = 0; constexpr int wall_line_count = 0; const int64_t outline_offset = 0; const double layer_height_mm = (gcode_layer.getLayerNr() == 0) ? mesh.getSettingInMillimeters("layer_height_0") : mesh.getSettingInMillimeters("layer_height"); // For each part on this layer which is used to fill that part and parts below: for (const std::pair<Polygons, double>& filling_area : part.spaghetti_infill_volumes) { Polygons infill_lines; Polygons infill_polygons; const Polygons& area = filling_area.first; // Area of the top within which to move while extruding (might be empty if the spaghetti_inset was too large) const double total_volume = filling_area.second * mesh.getSettingAsRatio("spaghetti_flow") + mesh.getSettingInCubicMillimeters("spaghetti_infill_extra_volume"); // volume to be extruded if (total_volume <= 0.0) { continue; } // generate zigzag print head paths Polygons* perimeter_gaps_output = nullptr; const bool connected_zigzags = true; const bool use_endpieces = false; Infill infill_comp(pattern, zig_zaggify_infill, connect_polygons, area, outline_offset , infill_line_width, infill_line_distance, infill_overlap, infill_multiplier, infill_angle, gcode_layer.z, infill_shift, wall_line_count, infill_origin, perimeter_gaps_output, connected_zigzags, use_endpieces , mesh.getSettingInMicrons("cross_infill_pocket_size")); // cross_fill_patterns is only generated when spaghetti infill is not used, // so we pass nullptr here. infill_comp.generate(infill_polygons, infill_lines, nullptr, &mesh); // add paths to plan with a higher flow ratio in order to extrude the required amount. const coord_t total_length = infill_polygons.polygonLength() + infill_lines.polyLineLength(); if (total_length > 0) { // zigzag path generation actually generated paths // calculate the normal volume extruded when using the layer height and line width to calculate extrusion const double normal_volume = INT2MM(INT2MM(total_length * infill_line_width)) * layer_height_mm; assert(normal_volume > 0.0); const float flow_ratio = total_volume / normal_volume; assert(flow_ratio / mesh.getSettingAsRatio("spaghetti_flow") >= 0.9); assert(!std::isnan(flow_ratio) && !std::isinf(flow_ratio)); if (!infill_polygons.empty() || !infill_lines.empty()) { added_something = true; fff_gcode_writer.setExtruder_addPrime(storage, gcode_layer, extruder_nr); if (!infill_polygons.empty()) { constexpr bool force_comb_retract = false; gcode_layer.addTravel(infill_polygons[0][0], force_comb_retract); gcode_layer.addPolygonsByOptimizer(infill_polygons, config, nullptr, ZSeamConfig(), 0, false, flow_ratio); } const bool is_zigzag = mesh.getSettingBoolean("zig_zaggify_infill") || pattern == EFillMethod::ZIG_ZAG; const coord_t wipe_dist = is_zigzag ? 0 : -mesh.getSettingInMicrons("infill_wipe_dist"); const SpaceFillType line_type = is_zigzag ? SpaceFillType::Lines : SpaceFillType::PolyLines; gcode_layer.addLinesByOptimizer(infill_lines, config, line_type, false, wipe_dist, flow_ratio); } } else { // zigzag path generation couldn't generate paths, probably because the area was too small // generate small path near the middle of the filling area // note that we need a path with positive length because that is currently the only way to insert an extrusion in a layer plan constexpr int path_length = 10; Point middle = AABB(area).getMiddle(); if (!area.inside(middle)) { PolygonUtils::ensureInsideOrOutside(area, middle, infill_line_width / 2); } const double normal_volume = INT2MM(INT2MM(path_length * infill_line_width)) * layer_height_mm; const float flow_ratio = total_volume / normal_volume; gcode_layer.addTravel(middle); gcode_layer.addExtrusionMove(middle + Point(0, path_length), config, SpaceFillType::Lines, flow_ratio); } } return added_something; }