Merge branch 'main' into dev/bbl-network-upd

This commit is contained in:
Noisyfox
2025-06-16 14:02:04 +08:00
committed by GitHub
124 changed files with 7827 additions and 6123 deletions
+2
View File
@@ -101,6 +101,8 @@ set(lisbslic3r_sources
Fill/FillHoneycomb.hpp
Fill/FillGyroid.cpp
Fill/FillGyroid.hpp
Fill/FillTpmsD.cpp
Fill/FillTpmsD.hpp
Fill/FillPlanePath.cpp
Fill/FillPlanePath.hpp
Fill/FillLine.cpp
+2
View File
@@ -14,6 +14,7 @@
#include "FillRectilinear.hpp"
#include "FillLightning.hpp"
#include "FillConcentricInternal.hpp"
#include "FillTpmsD.hpp"
#include "FillConcentric.hpp"
#include "libslic3r.h"
@@ -1047,6 +1048,7 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc
case ipHoneycomb:
case ip3DHoneycomb:
case ipGyroid:
case ipTpmsD:
case ipHilbertCurve:
case ipArchimedeanChords:
case ipOctagramSpiral: break;
+2
View File
@@ -16,6 +16,7 @@
#include "FillHoneycomb.hpp"
#include "Fill3DHoneycomb.hpp"
#include "FillGyroid.hpp"
#include "FillTpmsD.hpp"
#include "FillPlanePath.hpp"
#include "FillLine.hpp"
#include "FillRectilinear.hpp"
@@ -41,6 +42,7 @@ Fill* Fill::new_from_type(const InfillPattern type)
case ipHoneycomb: return new FillHoneycomb();
case ip3DHoneycomb: return new Fill3DHoneycomb();
case ipGyroid: return new FillGyroid();
case ipTpmsD: return new FillTpmsD();//from creality print
case ipRectilinear: return new FillRectilinear();
case ipAlignedRectilinear: return new FillAlignedRectilinear();
case ipCrossHatch: return new FillCrossHatch();
+446
View File
@@ -0,0 +1,446 @@
#include "../ClipperUtils.hpp"
#include "FillTpmsD.hpp"
#include <cmath>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <tbb/parallel_for.h>
// From Creality Print
namespace Slic3r {
using namespace std;
struct myPoint
{
coord_t x, y;
};
class LineSegmentMerger
{
public:
void mergeSegments(const vector<pair<myPoint, myPoint>>& segments, vector<vector<myPoint>>& polylines2)
{
std::unordered_map<int, myPoint> point_id_xy;
std::set<std::pair<int, int>> segment_ids;
std::unordered_map<int64_t, int> map_keyxy_pointid;
auto get_itr = [&](coord_t x, coord_t y) {
for (auto i : {0}) //,-2,2
{
for (auto j : {0}) //,-2,2
{
int64_t combined_key1 = static_cast<int64_t>(x + i) << 32 | static_cast<uint32_t>(y + j);
auto itr1 = map_keyxy_pointid.find(combined_key1);
if (itr1 != map_keyxy_pointid.end()) {
return itr1;
}
}
}
return map_keyxy_pointid.end();
};
int pointid = 0;
for (const auto& segment : segments) {
coord_t x = segment.first.x;
coord_t y = segment.first.y;
auto itr = get_itr(x, y);
int segmentid0 = -1;
if (itr == map_keyxy_pointid.end()) {
int64_t combined_key = static_cast<int64_t>(x) << 32 | static_cast<uint32_t>(y);
segmentid0 = pointid;
point_id_xy[pointid] = segment.first;
map_keyxy_pointid[combined_key] = pointid++;
} else {
segmentid0 = itr->second;
}
int segmentid1 = -1;
x = segment.second.x;
y = segment.second.y;
itr = get_itr(x, y);
if (itr == map_keyxy_pointid.end()) {
int64_t combined_key = static_cast<int64_t>(x) << 32 | static_cast<uint32_t>(y);
segmentid1 = pointid;
point_id_xy[pointid] = segment.second;
map_keyxy_pointid[combined_key] = pointid++;
} else {
segmentid1 = itr->second;
}
if (segmentid0 != segmentid1) {
segment_ids.insert(segmentid0 < segmentid1 ? std::make_pair(segmentid0, segmentid1) :
std::make_pair(segmentid1, segmentid0));
}
}
unordered_map<int, vector<int>> graph;
unordered_set<int> visited;
vector<vector<int>> polylines;
// Build the graph
for (const auto& segment : segment_ids) {
graph[segment.first].push_back(segment.second);
graph[segment.second].push_back(segment.first);
}
vector<int> startnodes;
for (const auto& node : graph) {
if (node.second.size() == 1) {
startnodes.push_back(node.first);
}
}
// Find all connected components
for (const auto& point_first : startnodes) {
if (visited.find(point_first) == visited.end()) {
vector<int> polyline;
dfs(point_first, graph, visited, polyline);
polylines.push_back(std::move(polyline));
}
}
for (const auto& point : graph) {
if (visited.find(point.first) == visited.end()) {
vector<int> polyline;
dfs(point.first, graph, visited, polyline);
polylines.push_back(std::move(polyline));
}
}
for (auto& pl : polylines) {
vector<myPoint> tmpps;
for (auto& pid : pl) {
tmpps.push_back(point_id_xy[pid]);
}
polylines2.push_back(tmpps);
}
}
private:
void dfs(const int& start_node,
std::unordered_map<int, std::vector<int>>& graph,
std::unordered_set<int>& visited,
std::vector<int>& polyline)
{
std::vector<int> stack;
stack.reserve(graph.size());
stack.push_back(start_node);
while (!stack.empty()) {
int node = stack.back();
stack.pop_back();
if (!visited.insert(node).second) {
continue;
}
polyline.push_back(node);
auto& neighbors = graph[node];
for (const auto& neighbor : neighbors) {
if (visited.find(neighbor) == visited.end()) {
stack.push_back(neighbor);
}
}
}
}
};
namespace MarchingSquares {
struct Point
{
double x, y;
};
vector<double> getGridValues(int i, int j, vector<vector<double>>& data)
{
vector<double> values;
values.push_back(data[i][j + 1]);
values.push_back(data[i + 1][j + 1]);
values.push_back(data[i + 1][j]);
values.push_back(data[i][j]);
return values;
}
bool needContour(double value, double contourValue) { return value >= contourValue; }
Point interpolate(std::vector<std::vector<MarchingSquares::Point>>& posxy,
std::vector<int> p1ij,
std::vector<int> p2ij,
double v1,
double v2,
double contourValue)
{
Point p1;
p1.x = posxy[p1ij[0]][p1ij[1]].x;
p1.y = posxy[p1ij[0]][p1ij[1]].y;
Point p2;
p2.x = posxy[p2ij[0]][p2ij[1]].x;
p2.y = posxy[p2ij[0]][p2ij[1]].y;
double mu = (contourValue - v1) / (v2 - v1);
Point p;
p.x = p1.x + mu * (p2.x - p1.x);
p.y = p1.y + mu * (p2.y - p1.y);
return p;
}
void process_block(int i,
int j,
vector<vector<double>>& data,
double contourValue,
std::vector<std::vector<MarchingSquares::Point>>& posxy,
vector<Point>& contourPoints)
{
vector<double> values = getGridValues(i, j, data);
vector<bool> isNeedContour;
for (double value : values) {
isNeedContour.push_back(needContour(value, contourValue));
}
int index = 0;
if (isNeedContour[0])
index |= 1;
if (isNeedContour[1])
index |= 2;
if (isNeedContour[2])
index |= 4;
if (isNeedContour[3])
index |= 8;
vector<Point> points;
switch (index) {
case 0:
case 15: break;
case 1:
points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue));
points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue));
break;
case 14:
points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue));
points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue));
break;
case 2:
points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue));
points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue));
break;
case 13:
points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue));
points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue));
break;
case 3:
points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue));
points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue));
break;
case 12:
points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue));
points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue));
break;
case 4:
points.push_back(interpolate(posxy, {i + 1, j}, {i, j}, values[2], values[3], contourValue));
points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue));
break;
case 11:
points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue));
points.push_back(interpolate(posxy, {i + 1, j}, {i, j}, values[2], values[3], contourValue));
break;
case 5:
points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue));
points.push_back(interpolate(posxy, {i, j}, {i + 1, j}, values[3], values[2], contourValue));
points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue));
points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue));
break;
case 6:
points.push_back(interpolate(posxy, {i + 1, j}, {i, j}, values[2], values[3], contourValue));
points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue));
break;
case 9:
points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue));
points.push_back(interpolate(posxy, {i + 1, j}, {i, j}, values[2], values[3], contourValue));
break;
case 7:
points.push_back(interpolate(posxy, {i + 1, j}, {i, j}, values[2], values[3], contourValue));
points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue));
break;
case 8:
points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue));
points.push_back(interpolate(posxy, {i + 1, j}, {i, j}, values[2], values[3], contourValue));
break;
case 10:
points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue));
points.push_back(interpolate(posxy, {i, j}, {i + 1, j}, values[3], values[2], contourValue));
points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue));
points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue));
break;
}
for (Point& p : points) {
contourPoints.push_back(p);
}
}
void drawContour(double contourValue,
int gridSize_w,
int gridSize_h,
vector<vector<double>>& data,
std::vector<std::vector<MarchingSquares::Point>>& posxy,
Polylines& repls)
{
vector<Point> contourPoints;
int total_size = (gridSize_h - 1) * (gridSize_w - 1);
vector<vector<Point>> contourPointss;
contourPointss.resize(total_size);
tbb::parallel_for(tbb::blocked_range<size_t>(0, total_size),
[&contourValue, &posxy, &contourPointss, &data, &gridSize_w](const tbb::blocked_range<size_t>& range) {
for (size_t k = range.begin(); k < range.end(); ++k) {
int i = k / (gridSize_w - 1); //
int j = k % (gridSize_w - 1); //
process_block(i, j, data, contourValue, posxy, contourPointss[k]);
}
});
vector<pair<myPoint, myPoint>> segments2;
myPoint p1, p2;
for (int k = 0; k < total_size; k++) {
for (int i = 0; i < contourPointss[k].size() / 2; i++) {
p1.x = scale_(contourPointss[k][i * 2].x);
p1.y = scale_(contourPointss[k][i * 2].y);
p2.x = scale_(contourPointss[k][i * 2 + 1].x);
p2.y = scale_(contourPointss[k][i * 2 + 1].y);
segments2.push_back({p1, p2});
}
}
LineSegmentMerger merger;
vector<vector<myPoint>> result;
merger.mergeSegments(segments2, result);
for (vector<myPoint>& p : result) {
Polyline repltmp;
for (myPoint& pt : p) {
repltmp.points.push_back(Slic3r::Point(pt.x, pt.y));
}
repltmp.simplify(scale_(0.05f));
repls.push_back(repltmp);
}
}
} // namespace MarchingSquares
static float sin_table[360];
static float cos_table[360];
static bool g_is_init = false;
#define PIratio 57.29577951308232 // 180/PI
static void initialize_lookup_tables()
{
for (int i = 0; i < 360; ++i) {
float angle = i * (M_PI / 180.0);
sin_table[i] = std::sin(angle);
cos_table[i] = std::cos(angle);
}
}
static float get_sin(float angle)
{
angle = angle * PIratio;
int index = static_cast<int>(std::fmod(angle, 360) + 360) % 360;
return sin_table[index];
}
static float get_cos(float angle)
{
angle = angle * PIratio;
int index = static_cast<int>(std::fmod(angle, 360) + 360) % 360;
return cos_table[index];
}
FillTpmsD::FillTpmsD()
{
if (!g_is_init) {
initialize_lookup_tables();
g_is_init = true;
}
}
void FillTpmsD::_fill_surface_single(const FillParams& params,
unsigned int thickness_layers,
const std::pair<float, Point>& direction,
ExPolygon expolygon,
Polylines& polylines_out)
{
auto infill_angle = float(this->angle - (CorrectionAngle * 2 * M_PI) / 360.);
if (std::abs(infill_angle) >= EPSILON)
expolygon.rotate(-infill_angle);
float vari_T = 2.98 * spacing / params.density; // Infill density adjustment factor for TPMS-D
BoundingBox bb = expolygon.contour.bounding_box();
auto cenpos = unscale(bb.center());
auto boxsize = unscale(bb.size());
float xlen = boxsize.x();
float ylen = boxsize.y();
float delta = 0.25f;
float myperiod = 2 * PI / vari_T;
float c_z = myperiod * this->z;
float cos_z = get_cos(c_z);
float sin_z = get_sin(c_z);
auto scalar_field = [&](float x, float y) {
// TPMS-D
float a_x = myperiod * x;
float b_y = myperiod * y;
float r = get_cos(a_x) * get_cos(b_y) * cos_z - get_sin(a_x) * get_sin(b_y) * sin_z;
return r;
};
std::vector<std::vector<MarchingSquares::Point>> posxy;
int i = 0, j = 0;
std::vector<MarchingSquares::Point> allptpos;
for (float y = -(ylen) / 2.0f - 2; y < (ylen) / 2.0f + 2; y = y + delta, i++) {
j = 0;
std::vector<MarchingSquares::Point> colposxy;
for (float x = -(xlen) / 2.0f - 2; x < (xlen) / 2.0f + 2; x = x + delta, j++) {
MarchingSquares::Point pt;
pt.x = cenpos.x() + x;
pt.y = cenpos.y() + y;
colposxy.push_back(pt);
}
posxy.push_back(colposxy);
}
std::vector<std::vector<double>> data(posxy.size(), std::vector<double>(posxy[0].size()));
int width = posxy[0].size();
int height = posxy.size();
int total_size = (height) * (width);
tbb::parallel_for(tbb::blocked_range<size_t>(0, total_size),
[&width, &scalar_field, &data, &posxy](const tbb::blocked_range<size_t>& range) {
for (size_t k = range.begin(); k < range.end(); ++k) {
int i = k / (width);
int j = k % (width);
data[i][j] = scalar_field(posxy[i][j].x, posxy[i][j].y);
}
});
Polylines polylines;
MarchingSquares::drawContour(0, j, i, data, posxy, polylines);
polylines = intersection_pl(polylines, expolygon);
if (!polylines.empty()) {
// connect lines
size_t polylines_out_first_idx = polylines_out.size();
if (params.dont_connect())
append(polylines_out, chain_polylines(polylines));
else
this->connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params);
// new paths must be rotated back
if (std::abs(infill_angle) >= EPSILON) {
for (auto it = polylines_out.begin() + polylines_out_first_idx; it != polylines_out.end(); ++it)
it->rotate(infill_angle);
}
}
}
} // namespace Slic3r
+31
View File
@@ -0,0 +1,31 @@
#ifndef slic3r_FillTpmsD_hpp_
#define slic3r_FillTpmsD_hpp_
#include "../libslic3r.h"
#include "FillBase.hpp"
namespace Slic3r {
class FillTpmsD : public Fill
{
public:
FillTpmsD();
Fill* clone() const override { return new FillTpmsD(*this); }
// require bridge flow since most of this pattern hangs in air
bool use_bridge_flow() const override { return false; }
// Correction applied to regular infill angle to maximize printing
// speed in default configuration (degrees)
static constexpr float CorrectionAngle = -45.;
void _fill_surface_single(const FillParams& params,
unsigned int thickness_layers,
const std::pair<float, Point>& direction,
ExPolygon expolygon,
Polylines& polylines_out) override;
};
} // namespace Slic3r
#endif // slic3r_FillTpmsD_hpp_
+54 -13
View File
@@ -5177,6 +5177,25 @@ double GCode::get_overhang_degree_corr_speed(float normal_speed, double path_deg
return speed_out;
}
bool GCode::_needSAFC(const ExtrusionPath &path)
{
if (!m_small_area_infill_flow_compensator || !m_config.small_area_infill_flow_compensation.value)
return false;
static const InfillPattern supported_patterns[] = {
InfillPattern::ipRectilinear,
InfillPattern::ipAlignedRectilinear,
InfillPattern::ipMonotonic,
InfillPattern::ipMonotonicLine,
};
return std::any_of(std::begin(supported_patterns), std::end(supported_patterns), [&](const InfillPattern pattern) {
return this->on_first_layer() && this->config().bottom_surface_pattern == pattern ||
path.role() == erSolidInfill && this->config().internal_solid_infill_pattern == pattern ||
path.role() == erTopSolidInfill && this->config().top_surface_pattern == pattern;
});
}
std::string GCode::_extrude(const ExtrusionPath &path, std::string description, double speed)
{
std::string gcode;
@@ -5385,12 +5404,37 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
//}
if (EXTRUDER_CONFIG(filament_max_volumetric_speed) > 0) {
// cap speed with max_volumetric_speed anyway (even if user is not using autospeed)
speed = std::min(
speed,
EXTRUDER_CONFIG(filament_max_volumetric_speed) / _mm3_per_mm
);
speed = std::min(speed, EXTRUDER_CONFIG(filament_max_volumetric_speed) / _mm3_per_mm);
}
// ORCA: resonance‑avoidance on short external perimeters
{
double ref_speed = speed; // stash the pre‑cap speed
if (path.role() == erExternalPerimeter
&& m_config.resonance_avoidance.value) {
// if our original speed was above “max”, disable RA for this loop
if (ref_speed > m_config.max_resonance_avoidance_speed.value) {
m_resonance_avoidance = false;
}
// re‑apply volumetric cap
if (EXTRUDER_CONFIG(filament_max_volumetric_speed) > 0) {
speed = std::min(
speed,
EXTRUDER_CONFIG(filament_max_volumetric_speed) / _mm3_per_mm
);
}
// if still in avoidance mode and under “max”, clamp to “min”
if (m_resonance_avoidance
&& speed <= m_config.max_resonance_avoidance_speed.value) {
speed = std::min(speed, m_config.min_resonance_avoidance_speed.value);
}
// reset flag for next segment
m_resonance_avoidance = true;
}
}
bool variable_speed = false;
std::vector<ProcessedPoint> new_points {};
@@ -5731,8 +5775,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
continue;
path_length += line_length;
auto dE = e_per_mm * line_length;
if (!this->on_first_layer() && m_small_area_infill_flow_compensator
&& m_config.small_area_infill_flow_compensation.value) {
if (_needSAFC(path)) {
auto oldE = dE;
dE = m_small_area_infill_flow_compensator->modify_flow(line_length, dE, path.role());
@@ -5773,8 +5816,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
if (line_length < EPSILON)
continue;
auto dE = e_per_mm * line_length;
if (!this->on_first_layer() && m_small_area_infill_flow_compensator
&& m_config.small_area_infill_flow_compensation.value) {
if (_needSAFC(path)) {
auto oldE = dE;
dE = m_small_area_infill_flow_compensator->modify_flow(line_length, dE, path.role());
@@ -5797,8 +5839,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
continue;
const Vec2d center_offset = this->point_to_gcode(arc.center) - this->point_to_gcode(arc.start_point);
auto dE = e_per_mm * arc_length;
if (!this->on_first_layer() && m_small_area_infill_flow_compensator
&& m_config.small_area_infill_flow_compensation.value) {
if (_needSAFC(path)) {
auto oldE = dE;
dE = m_small_area_infill_flow_compensator->modify_flow(arc_length, dE, path.role());
@@ -5952,8 +5993,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
last_set_speed = F;
}
auto dE = e_per_mm * line_length;
if (!this->on_first_layer() && m_small_area_infill_flow_compensator
&& m_config.small_area_infill_flow_compensation.value) {
if (_needSAFC(path)) {
auto oldE = dE;
dE = m_small_area_infill_flow_compensator->modify_flow(line_length, dE, path.role());
@@ -6334,7 +6374,8 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li
(the extruder might be already retracted fully or partially). We call these
methods even if we performed wipe, since this will ensure the entire retraction
length is honored in case wipe path was too short. */
if (role != erTopSolidInfill || EXTRUDER_CONFIG(retract_on_top_layer))
if ((!this->on_first_layer() || this->config().bottom_surface_pattern != InfillPattern::ipHilbertCurve) &&
(role != erTopSolidInfill || this->config().top_surface_pattern != InfillPattern::ipHilbertCurve))
gcode += toolchange ? m_writer.retract_for_toolchange() : m_writer.retract();
gcode += m_writer.reset_e();
+4
View File
@@ -165,6 +165,7 @@ public:
GCode() :
m_origin(Vec2d::Zero()),
m_enable_loop_clipping(true),
m_resonance_avoidance(true),
m_enable_cooling_markers(false),
m_enable_extrusion_role_markers(false),
m_last_processor_extrusion_role(erNone),
@@ -506,6 +507,8 @@ private:
AvoidCrossingPerimeters m_avoid_crossing_perimeters;
RetractWhenCrossingPerimeters m_retract_when_crossing_perimeters;
bool m_enable_loop_clipping;
//resonance avoidance
bool m_resonance_avoidance;
// If enabled, the G-code generator will put following comments at the ends
// of the G-code lines: _EXTRUDE_SET_SPEED, _WIPE, _OVERHANG_FAN_START, _OVERHANG_FAN_END
// Those comments are received and consumed (removed from the G-code) by the CoolingBuffer.pm Perl module.
@@ -602,6 +605,7 @@ private:
int get_bed_temperature(const int extruder_id, const bool is_first_layer, const BedType bed_type) const;
std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1);
bool _needSAFC(const ExtrusionPath &path);
double get_overhang_degree_corr_speed(float speed, double path_degree);
void print_machine_envelope(GCodeOutputStream &file, Print &print);
void _print_first_layer_bed_temperature(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
+1
View File
@@ -383,6 +383,7 @@ coordf_t Layer::get_sparse_infill_max_void_area()
case ipRectilinear:
case ipLine:
case ipGyroid:
case ipTpmsD:
case ipAlignedRectilinear:
case ipOctagramSpiral:
case ipHilbertCurve:
+3 -1
View File
@@ -837,7 +837,7 @@ static std::vector<std::string> s_Preset_print_options {
"hole_to_polyhole", "hole_to_polyhole_threshold", "hole_to_polyhole_twisted", "mmu_segmented_region_max_width", "mmu_segmented_region_interlocking_depth",
"small_area_infill_flow_compensation", "small_area_infill_flow_compensation_model",
"seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "scarf_joint_speed", "scarf_joint_flow_ratio", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", "scarf_overhang_threshold",
"interlocking_beam", "interlocking_orientation", "interlocking_beam_layer_count", "interlocking_depth", "interlocking_boundary_avoidance", "interlocking_beam_width","calib_flowrate_topinfill_special_order"
"interlocking_beam", "interlocking_orientation", "interlocking_beam_layer_count", "interlocking_depth", "interlocking_boundary_avoidance", "interlocking_beam_width","calib_flowrate_topinfill_special_order",
};
static std::vector<std::string> s_Preset_filament_options {
@@ -878,6 +878,8 @@ static std::vector<std::string> s_Preset_machine_limits_options {
"machine_min_extruding_rate", "machine_min_travel_rate",
"machine_max_jerk_x", "machine_max_jerk_y", "machine_max_jerk_z", "machine_max_jerk_e",
"machine_max_junction_deviation",
//resonance avoidance ported from qidi slicer
"resonance_avoidance", "min_resonance_avoidance_speed", "max_resonance_avoidance_speed",
};
static std::vector<std::string> s_Preset_printer_options {
+8 -9
View File
@@ -150,7 +150,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
"retraction_minimum_travel",
"retract_before_wipe",
"retract_when_changing_layer",
"retract_on_top_layer",
"retraction_length",
"retract_length_toolchange",
"z_hop",
@@ -1039,7 +1038,7 @@ StringObjectException Print::check_multi_filament_valid(const Print& print)
filament_types.push_back(print_config.filament_type.get_at(extruder_idx));
if (!check_multi_filaments_compatibility(filament_types))
return { L("Cannot print multiple filaments which have large difference of temperature together. Otherwise, the extruder and nozzle may be blocked or damaged during printing") };
return {L("Cannot print multiple filaments which have large difference of temperature together. Otherwise, the extruder and nozzle may be blocked or damaged during printing.")};
return {std::string()};
}
@@ -1209,7 +1208,7 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
double gap_layers = slicing_params.gap_object_support / slicing_params.layer_height;
if (gap_layers - (int)gap_layers > EPSILON) {
return { L("The prime tower requires \"support gap\" to be multiple of layer height"), object };
return {L("The prime tower requires \"support gap\" to be multiple of layer height."), object};
}
}
#endif
@@ -1222,14 +1221,14 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
const SlicingParameters &slicing_params = object->slicing_parameters();
if (std::abs(slicing_params.first_print_layer_height - slicing_params0.first_print_layer_height) > EPSILON ||
std::abs(slicing_params.layer_height - slicing_params0.layer_height ) > EPSILON)
return {L("The prime tower requires that all objects have the same layer heights"), object, "initial_layer_print_height"};
return {L("The prime tower requires that all objects have the same layer heights."), object, "initial_layer_print_height"};
if (slicing_params.raft_layers() != slicing_params0.raft_layers())
return {L("The prime tower requires that all objects are printed over the same number of raft layers"), object, "raft_layers"};
return {L("The prime tower requires that all objects are printed over the same number of raft layers."), object, "raft_layers"};
// BBS: support gap can be multiple of object layer height, remove _L()
#if 0
if (slicing_params0.gap_object_support != slicing_params.gap_object_support ||
slicing_params0.gap_support_object != slicing_params.gap_support_object)
return {L("The prime tower is only supported for multiple objects if they are printed with the same support_top_z_distance"), object};
return {L("The prime tower is only supported for multiple objects if they are printed with the same support_top_z_distance."), object};
#endif
if (!equal_layering(slicing_params, slicing_params0))
return { L("The prime tower requires that all objects are sliced with the same layer heights."), object };
@@ -1264,7 +1263,7 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
//if (i % 2 == 0 && layer_height_profiles[tallest_object_idx][i] > layer_height_profiles[idx_object][layer_height_profiles[idx_object].size() - 2])
// break;
if (std::abs(layer_height_profiles[idx_object][i] - layer_height_profiles[tallest_object_idx][i]) > eps)
return {L("The prime tower is only supported if all objects have the same variable layer height")};
return {L("The prime tower is only supported if all objects have the same variable layer height.")};
++i;
}
}
@@ -1373,12 +1372,12 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
first_layer_min_nozzle_diameter = min_nozzle_diameter;
}
if (initial_layer_print_height > first_layer_min_nozzle_diameter)
return {L("Layer height cannot exceed nozzle diameter"), object, "initial_layer_print_height"};
return {L("Layer height cannot exceed nozzle diameter."), object, "initial_layer_print_height"};
// validate layer_height
double layer_height = object->config().layer_height.value;
if (layer_height > min_nozzle_diameter)
return {L("Layer height cannot exceed nozzle diameter"), object, "layer_height"};
return {L("Layer height cannot exceed nozzle diameter."), object, "layer_height"};
// Validate extrusion widths.
std::string err_msg;
File diff suppressed because it is too large Load Diff
+6 -4
View File
@@ -58,7 +58,7 @@ enum AuthorizationType {
};
enum InfillPattern : int {
ipConcentric, ipRectilinear, ipGrid, ip2DLattice, ipLine, ipCubic, ipTriangles, ipStars, ipGyroid, ipHoneycomb, ipAdaptiveCubic, ipMonotonic, ipMonotonicLine, ipAlignedRectilinear, ip3DHoneycomb,
ipConcentric, ipRectilinear, ipGrid, ip2DLattice, ipLine, ipCubic, ipTriangles, ipStars, ipGyroid, ipTpmsD, ipHoneycomb, ipAdaptiveCubic, ipMonotonic, ipMonotonicLine, ipAlignedRectilinear, ip3DHoneycomb,
ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipSupportCubic, ipSupportBase, ipConcentricInternal,
ipLightning, ipCrossHatch, ipQuarterCubic,
ipCount,
@@ -1062,8 +1062,6 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloatOrPercent, scarf_joint_speed))
((ConfigOptionFloat, scarf_joint_flow_ratio))
((ConfigOptionPercent, scarf_overhang_threshold))
)
PRINT_CONFIG_CLASS_DEFINE(
@@ -1098,6 +1096,11 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloats, machine_min_travel_rate))
// M205 S... [mm/sec]
((ConfigOptionFloats, machine_min_extruding_rate))
//resonance avoidance ported from qidi slicer
((ConfigOptionBool, resonance_avoidance))
((ConfigOptionFloat, min_resonance_avoidance_speed))
((ConfigOptionFloat, max_resonance_avoidance_speed))
)
// This object is mapped to Perl as Slic3r::Config::GCode.
@@ -1308,7 +1311,6 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionFloat, resolution))
((ConfigOptionFloats, retraction_minimum_travel))
((ConfigOptionBools, retract_when_changing_layer))
((ConfigOptionBools, retract_on_top_layer))
((ConfigOptionFloat, skirt_distance))
((ConfigOptionInt, skirt_height))
((ConfigOptionInt, skirt_loops))