<commit_before>// Copyright (c) 2022 <NAME>.
// CuraEngine is released under the terms of the AGPLv3 or higher.
#include <algorithm>

#include "CenterDeviationBeadingStrategy.h"

namespace cura
{
CenterDeviationBeadingStrategy::CenterDeviationBeadingStrategy
(
    const coord_t pref_bead_width,
    const AngleRadians transitioning_angle,
    const Ratio wall_split_middle_threshold,
    const Ratio wall_add_middle_threshold
) :
    BeadingStrategy(pref_bead_width, wall_split_middle_threshold, wall_add_middle_threshold, pref_bead_width / 2, transitioning_angle)
{
    name = "CenterDeviationBeadingStrategy";
}

CenterDeviationBeadingStrategy::Beading CenterDeviationBeadingStrategy::compute(coord_t thickness, coord_t bead_count) const
{
    const coord_t minimum_line_width_split = optimal_width * wall_split_middle_threshold;
    const coord_t minimum_line_width_add = optimal_width * wall_add_middle_threshold;

    Beading ret;

    ret.total_thickness = thickness;
    if (bead_count > 0)
    {
        // Set the bead widths
        ret.bead_widths = std::vector<coord_t>(static_cast<size_t>(bead_count), optimal_width);
        const coord_t optimal_thickness = getOptimalThickness(bead_count);
        const coord_t diff_thickness = thickness - optimal_thickness; //Amount of deviation. Either spread out over the middle 2 lines, or concentrated in the center line.
        const size_t center_bead_idx = ret.bead_widths.size() / 2;
        if (bead_count % 2 == 0) // Even lines
        {
            const coord_t inner_bead_widths = optimal_width + diff_thickness / 2;
            if (inner_bead_widths < minimum_line_width_add)
            {
                return compute(thickness, bead_count - 1);
            }
            ret.bead_widths[center_bead_idx - 1] = inner_bead_widths;
            ret.bead_widths[center_bead_idx] = inner_bead_widths;
        }
        else // Uneven lines
        {
            const coord_t inner_bead_widths = optimal_width + diff_thickness;
            if (inner_bead_widths < minimum_line_width_split)
            {
                return compute(thickness, bead_count - 1);
            }
            ret.bead_widths[center_bead_idx] = inner_bead_widths;
        }

        // Set the center line location of the bead toolpaths.
        ret.toolpath_locations.resize(ret.bead_widths.size());
        ret.toolpath_locations.front() = ret.bead_widths.front() / 2;
        for (size_t bead_idx = 1; bead_idx < ret.bead_widths.size(); ++bead_idx)
        {
            ret.toolpath_locations[bead_idx] =
              ret.toolpath_locations[bead_idx - 1] + (ret.bead_widths[bead_idx] + ret.bead_widths[bead_idx - 1]) / 2;
        }
        ret.left_over = 0;
    }
    else
    {
        ret.left_over = thickness;
    }

    return ret;
}

coord_t CenterDeviationBeadingStrategy::getOptimalThickness(coord_t bead_count) const
{
    return bead_count * optimal_width;
}

coord_t CenterDeviationBeadingStrategy::getTransitionThickness(coord_t lower_bead_count) const
{
    return optimal_width * (lower_bead_count + (lower_bead_count % 2 == 1 ? wall_split_middle_threshold : wall_add_middle_threshold));
}

coord_t CenterDeviationBeadingStrategy::getOptimalBeadCount(coord_t thickness) const
{
    const coord_t naive_count = thickness / optimal_width; // How many lines we can fit in for sure.
    const coord_t remainder = thickness - naive_count * optimal_width; // Space left after fitting that many lines.
    const coord_t minimum_line_width = optimal_width * (naive_count % 2 == 1 ? wall_split_middle_threshold : wall_add_middle_threshold);
    return naive_count + (remainder > minimum_line_width); // If there's enough space, fit an extra one.
}

} // namespace cura<commit_msg>Assume bead-count is correct and leading for Center compute.<commit_after>// Copyright (c) 2022 <NAME>.V.
// CuraEngine is released under the terms of the AGPLv3 or higher.
#include <algorithm>

#include "CenterDeviationBeadingStrategy.h"

namespace cura
{
CenterDeviationBeadingStrategy::CenterDeviationBeadingStrategy
(
    const coord_t pref_bead_width,
    const AngleRadians transitioning_angle,
    const Ratio wall_split_middle_threshold,
    const Ratio wall_add_middle_threshold
) :
    BeadingStrategy(pref_bead_width, wall_split_middle_threshold, wall_add_middle_threshold, pref_bead_width / 2, transitioning_angle)
{
    name = "CenterDeviationBeadingStrategy";
}

CenterDeviationBeadingStrategy::Beading CenterDeviationBeadingStrategy::compute(coord_t thickness, coord_t bead_count) const
{
    Beading ret;

    ret.total_thickness = thickness;
    if (bead_count > 0)
    {
        // Set the bead widths
        ret.bead_widths = std::vector<coord_t>(static_cast<size_t>(bead_count), optimal_width);
        coord_t leftover_thickness = ret.total_thickness;
        for (size_t bead_index = 0; bead_index <= bead_count / 2; ++bead_index)
        {
            const size_t opposite_bead_index = bead_count - (1 + bead_index);
            switch (opposite_bead_index - bead_index)
            {
            case 0: // Single bead in the middle:
                ret.bead_widths[bead_index] = leftover_thickness;
                break;
            case 1: // Two beads in the middle:
                ret.bead_widths[bead_index] = leftover_thickness / 2;
                ret.bead_widths[opposite_bead_index] = leftover_thickness / 2;
                break;
            default: // Beads on the outside.
                ret.bead_widths[bead_index] = optimal_width;
                ret.bead_widths[opposite_bead_index] = optimal_width;
                break;
            }
            leftover_thickness -= ret.bead_widths[bead_index] + ret.bead_widths[opposite_bead_index]; // Incorrect when there is a last single middle line, but the loop will exit anyway then.
        }

        // Set the center line location of the bead toolpaths.
        ret.toolpath_locations.resize(ret.bead_widths.size());
        ret.toolpath_locations.front() = ret.bead_widths.front() / 2;
        for (size_t bead_idx = 1; bead_idx < ret.bead_widths.size(); ++bead_idx)
        {
            ret.toolpath_locations[bead_idx] =
              ret.toolpath_locations[bead_idx - 1] + (ret.bead_widths[bead_idx] + ret.bead_widths[bead_idx - 1]) / 2;
        }
        ret.left_over = 0;
    }
    else
    {
        ret.left_over = thickness;
    }

    return ret;
}

coord_t CenterDeviationBeadingStrategy::getOptimalThickness(coord_t bead_count) const
{
    return bead_count * optimal_width;
}

coord_t CenterDeviationBeadingStrategy::getTransitionThickness(coord_t lower_bead_count) const
{
    return optimal_width * (lower_bead_count + (lower_bead_count % 2 == 1 ? wall_split_middle_threshold : wall_add_middle_threshold));
}

coord_t CenterDeviationBeadingStrategy::getOptimalBeadCount(coord_t thickness) const
{
    const coord_t naive_count = thickness / optimal_width; // How many lines we can fit in for sure. (Note difference with Distributed.)
    const coord_t remainder = thickness - naive_count * optimal_width; // Space left after fitting that many lines.
    const coord_t minimum_line_width = optimal_width * (naive_count % 2 == 1 ? wall_split_middle_threshold : wall_add_middle_threshold);
    return naive_count + (remainder >= minimum_line_width); // If there's enough space, fit an extra one.
}

} // namespace cura
{'fraction_non_alphanumeric': 0.08039109179793591, 'fraction_numerical': 0.006653992395437262, 'mean_word_length': 3.2351926394479587, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '368968', 'n_tokens_mistral': 2445, 'n_tokens_neox': 2308, 'n_words': 506}