mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-06 13:34:05 -06:00

* Adaptive Pressure advance options setup * Dynamic PA - PCHIP interpolator code and tests * Integrate dynamic PA with slicing code - emit new PA values per speed change * Link adaptive PA to role change instead of speed change * Adaptive PA - Alpha 2 Reduce the frequency of requested PA changes by introducing a "state" variable. Implement user toggle for adapting PA for external walls for overhangs * Hide adaptive PA for overhangs * Convert Adaptive PA to use volumetric flow model and start preparing for converting to Gcode post processor * Converted Dynamic PA to a post processing filter. Reverted changes in GCode cpp and created tagging mechanism to allow filter to apply PA changes. * Removed adaptive PA for overhangs * Foundations for two dimensional adaptive PA based on acceleration and volumetric flow speed * Minor code cleanup and updating of tooltips * Renaming files for better clarity and generate classes documentation * Update src/libslic3r/PrintConfig.cpp Co-authored-by: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> * Update src/libslic3r/PrintConfig.cpp Co-authored-by: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> * Update src/libslic3r/PrintConfig.cpp Co-authored-by: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> * Introduce average mm3_mm over the length of a multipath for adaptive PA * Updates for multipath handling part 2 * Introduce average mm3_mm over the length of a multipath for adaptive PA * Trigger PA evaluation more frequently to catch edge cases where speed changes across islands of the same feature type. * Updates for multipath handling part 2 * Adaptive PA: Implement average flow estimation on loops * Code formatting * Fix adaptive PA not adapting for small disconnected external wall line segments. * Updated to take max print speed of upcoming feature to calculate new PA value. This is to resolve issue of incorrect PA value used when starting a new feature at an overhang. * Code clean up * Performance tuning * Further performance tuning by reducing use of regex commands in the nested loops and fix bug preventing gcode line output * Further performance tuning and tweaks to stop searching for max speed after the first travel move. * Reduce debug information * Updated debug info * Fix an issue on seams on specific models when wipe before external perimeter was enabled. Also cleanup documentation and add new to-do's * Prepare for adaptive PA for overhangs, fix wipe bug & clean up code and comments * Initial commit for adapting PA when extruding fully overhanging perimeters * Ignore wipe command when identifying current print speed * Option to evaluate adaptive PA on overhang regions in preparation for Klipper experimental option testing * Update to issue PA changes for varying flow conditions within the same feature * Fix bug where adaptive PA was enabled erroneously for role changes and ignoring user's preference. * Refactored some code * More refactoring * Some bug fixes and enabled comments only when verbose g-code is enabled * Introduced dedicated PA option for bridges * Code refactoring to optimise initialisation of PA processor (making it faster). Fix a bug where PA was not always set after a toolchange. Improve general error handling and robustness. * Updates to adaptive PA tooltips * Bridging PA check with Epsilon instead of 0. * Adaptive PA: addressing comments --------- Co-authored-by: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com>
100 lines
2.7 KiB
C++
100 lines
2.7 KiB
C++
// PchipInterpolatorHelper.cpp
|
|
// OrcaSlicer
|
|
//
|
|
// Implementation file for the PchipInterpolatorHelper class
|
|
|
|
#include "PchipInterpolatorHelper.hpp"
|
|
#include <stdexcept>
|
|
#include <cmath>
|
|
#include <algorithm>
|
|
|
|
/**
|
|
* @brief Constructs the PCHIP interpolator with given data points.
|
|
* @param x The x-coordinates of the data points.
|
|
* @param y The y-coordinates of the data points.
|
|
*/
|
|
PchipInterpolatorHelper::PchipInterpolatorHelper(const std::vector<double>& x, const std::vector<double>& y) {
|
|
setData(x, y);
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the data points for the interpolator.
|
|
* @param x The x-coordinates of the data points.
|
|
* @param y The y-coordinates of the data points.
|
|
* @throw std::invalid_argument if x and y have different sizes or if they contain fewer than two points.
|
|
*/
|
|
void PchipInterpolatorHelper::setData(const std::vector<double>& x, const std::vector<double>& y) {
|
|
if (x.size() != y.size() || x.size() < 2) {
|
|
throw std::invalid_argument("Input vectors must have the same size and contain at least two points.");
|
|
}
|
|
x_ = x;
|
|
y_ = y;
|
|
sortData();
|
|
computePCHIP();
|
|
}
|
|
|
|
/**
|
|
* @brief Sorts the data points by x-coordinate.
|
|
*/
|
|
void PchipInterpolatorHelper::sortData() {
|
|
std::vector<std::pair<double, double>> data;
|
|
for (size_t i = 0; i < x_.size(); ++i) {
|
|
data.emplace_back(x_[i], y_[i]);
|
|
}
|
|
std::sort(data.begin(), data.end());
|
|
|
|
for (size_t i = 0; i < data.size(); ++i) {
|
|
x_[i] = data[i].first;
|
|
y_[i] = data[i].second;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Computes the PCHIP coefficients.
|
|
*/
|
|
void PchipInterpolatorHelper::computePCHIP() {
|
|
size_t n = x_.size() - 1;
|
|
h_.resize(n);
|
|
delta_.resize(n);
|
|
d_.resize(n+1);
|
|
|
|
for (size_t i = 0; i < n; ++i) {
|
|
h_[i] = h(i);
|
|
delta_[i] = delta(i);
|
|
}
|
|
|
|
d_[0] = delta_[0];
|
|
d_[n] = delta_[n-1];
|
|
for (size_t i = 1; i < n; ++i) {
|
|
if (delta_[i-1] * delta_[i] > 0) {
|
|
double w1 = 2 * h_[i] + h_[i-1];
|
|
double w2 = h_[i] + 2 * h_[i-1];
|
|
d_[i] = (w1 + w2) / (w1 / delta_[i-1] + w2 / delta_[i]);
|
|
} else {
|
|
d_[i] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Interpolates the value at a given point.
|
|
*/
|
|
double PchipInterpolatorHelper::interpolate(double xi) const {
|
|
if (xi <= x_.front()) return y_.front();
|
|
if (xi >= x_.back()) return y_.back();
|
|
|
|
auto it = std::lower_bound(x_.begin(), x_.end(), xi);
|
|
size_t i = std::distance(x_.begin(), it) - 1;
|
|
|
|
double h_i = h_[i];
|
|
double t = (xi - x_[i]) / h_i;
|
|
double t2 = t * t;
|
|
double t3 = t2 * t;
|
|
|
|
double h00 = 2 * t3 - 3 * t2 + 1;
|
|
double h10 = t3 - 2 * t2 + t;
|
|
double h01 = -2 * t3 + 3 * t2;
|
|
double h11 = t3 - t2;
|
|
|
|
return h00 * y_[i] + h10 * h_i * d_[i] + h01 * y_[i+1] + h11 * h_i * d_[i+1];
|
|
}
|