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))
+5 -5
View File
@@ -750,7 +750,7 @@ void PressureAdvanceWizard::on_cali_save()
CalibUtils::set_PA_calib_result({ new_pa_cali_result }, false);
}
MessageDialog msg_dlg(nullptr, _L("Flow Dynamics Calibration result has been saved to the printer"), wxEmptyString, wxOK);
MessageDialog msg_dlg(nullptr, _L("Flow Dynamics Calibration result has been saved to the printer."), wxEmptyString, wxOK);
msg_dlg.ShowModal();
}
else if (curr_obj->get_printer_series() == PrinterSeries::SERIES_P1P) {
@@ -817,7 +817,7 @@ void PressureAdvanceWizard::on_cali_save()
}
MessageDialog msg_dlg(nullptr, _L("Flow Dynamics Calibration result has been saved to the printer"), wxEmptyString, wxOK);
MessageDialog msg_dlg(nullptr, _L("Flow Dynamics Calibration result has been saved to the printer."), wxEmptyString, wxOK);
msg_dlg.ShowModal();
}
else {
@@ -1170,7 +1170,7 @@ void FlowRateWizard::on_cali_save()
}
}
MessageDialog msg_dlg(nullptr, _L("Flow rate calibration result has been saved to preset"), wxEmptyString, wxOK);
MessageDialog msg_dlg(nullptr, _L("Flow rate calibration result has been saved to preset."), wxEmptyString, wxOK);
msg_dlg.ShowModal();
}
else if (m_cali_method == CalibrationMethod::CALI_METHOD_MANUAL) {
@@ -1216,7 +1216,7 @@ void FlowRateWizard::on_cali_save()
return;
}
MessageDialog msg_dlg(nullptr, _L("Flow rate calibration result has been saved to preset"), wxEmptyString, wxOK);
MessageDialog msg_dlg(nullptr, _L("Flow rate calibration result has been saved to preset."), wxEmptyString, wxOK);
msg_dlg.ShowModal();
}
else {
@@ -1499,7 +1499,7 @@ void MaxVolumetricSpeedWizard::on_cali_save()
return;
}
MessageDialog msg_dlg(nullptr, _L("Max volumetric speed calibration result has been saved to preset"), wxEmptyString, wxOK);
MessageDialog msg_dlg(nullptr, _L("Max volumetric speed calibration result has been saved to preset."), wxEmptyString, wxOK);
msg_dlg.ShowModal();
show_step(start_step);
}
+1 -1
View File
@@ -1567,7 +1567,7 @@ void CalibrationFlowCoarseSavePage::set_curr_flow_ratio(const float value) {
bool CalibrationFlowCoarseSavePage::get_result(float* out_value, wxString* out_name) {
// Check if the value is valid
if (m_optimal_block_coarse->GetSelection() == -1 || m_coarse_flow_ratio <= 0.0 || m_coarse_flow_ratio >= 2.0) {
MessageDialog msg_dlg(nullptr, _L("Please choose a block with smoothest top surface"), wxEmptyString, wxICON_WARNING | wxOK);
MessageDialog msg_dlg(nullptr, _L("Please choose a block with smoothest top surface."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
@@ -216,11 +216,11 @@ void CalibrationFlowRateStartPage::create_page(wxWindow* parent)
m_top_sizer->Add(m_page_caption, 0, wxEXPAND, 0);
create_when(parent,
_L("When to use Flow Rate Calibration"),
_L("After using Flow Dynamics Calibration, there might still be some extrusion issues, such as:\
\n1. Over-Extrusion: Excess material on your printed object, forming blobs or zits, or the layers seem thicker than expected and not uniform.\
\n2. Under-Extrusion: Very thin layers, weak infill strength, or gaps in the top layer of the model, even when printing slowly.\
\n3. Poor Surface Quality: The surface of your prints seems rough or uneven.\
\n4. Weak Structural Integrity: Prints break easily or don't seem as sturdy as they should be."));
_L("After using Flow Dynamics Calibration, there might still be some extrusion issues, such as:\n"
"1. Over-Extrusion: Excess material on your printed object, forming blobs or zits, or the layers seem thicker than expected and not uniform\n"
"2. Under-Extrusion: Very thin layers, weak infill strength, or gaps in the top layer of the model, even when printing slowly\n"
"3. Poor Surface Quality: The surface of your prints seems rough or uneven\n"
"4. Weak Structural Integrity: Prints break easily or don't seem as sturdy as they should be"));
m_top_sizer->Add(m_when_title);
m_top_sizer->Add(m_when_content);
+17 -16
View File
@@ -38,27 +38,28 @@
namespace Slic3r {
namespace GUI {
static const std::vector<std::string> filament_vendors =
static const std::vector<std::string> filament_vendors =
{"3Dgenius", "3DJake", "3DXTECH", "3D BEST-Q", "3D Hero",
"3D-Fuel", "Aceaddity", "AddNorth", "Amazon Basics", "AMOLEN",
"Ankermake", "Anycubic", "Atomic", "AzureFilm", "BASF",
"Bblife", "BCN3D", "Beyond Plastic", "California Filament", "Capricorn",
"CC3D", "colorFabb", "Comgrow", "Cookiecad", "Creality",
"CERPRiSE", "Das Filament", "DO3D", "DOW", "DSM",
"Duramic", "ELEGOO", "Eryone", "Essentium", "eSUN",
"Extrudr", "Fiberforce", "Fiberlogy", "FilaCube", "Filamentive",
"Fillamentum", "FLASHFORGE", "Formfutura", "Francofil", "FusRock",
"FilamentOne", "Fil X", "GEEETECH", "Giantarm", "Gizmo Dorks",
"GreenGate3D", "HATCHBOX", "Hello3D", "IC3D", "IEMAI",
"IIID Max", "INLAND", "iProspect", "iSANMATE", "Justmaker",
"Keene Village Plastics", "Kexcelled", "LDO", "MakerBot", "MatterHackers",
"MIKA3D", "NinjaTek", "Nobufil", "Novamaker", "OVERTURE",
"OVVNYXE", "Polymaker", "Priline", "Printed Solid", "Protopasta",
"Prusament", "Push Plastic", "R3D", "Re-pet3D", "Recreus",
"Regen", "RatRig", "Sain SMART", "SliceWorx", "Snapmaker",
"SnoLabs", "Spectrum", "SUNLU", "TTYT3D", "Tianse",
"UltiMaker", "Valment", "Verbatim", "VO3D", "Voxelab",
"VOXELPLA", "YOOPAI", "Yousu", "Ziro", "Zyltech"};
"CERPRiSE", "Das Filament", "DO3D", "DOW", "DREMC",
"DSM", "Duramic", "ELEGOO", "Eryone", "Essentium",
"eSUN", "Extrudr", "Fiberforce", "Fiberlogy", "FilaCube",
"Filamentive", "Fillamentum", "FLASHFORGE", "Formfutura", "Francofil",
"FusRock", "FilamentOne", "Fil X", "GEEETECH", "Giantarm",
"Gizmo Dorks", "GreenGate3D", "HATCHBOX", "Hello3D", "IC3D",
"IEMAI", "IIID Max", "INLAND", "iProspect", "iSANMATE",
"Justmaker", "Keene Village Plastics", "Kexcelled", "LDO", "MakerBot",
"MatterHackers", "MIKA3D", "NinjaTek", "Nobufil", "Novamaker",
"OVERTURE", "OVVNYXE", "Polymaker", "Priline", "Printed Solid",
"Protopasta", "Prusament", "Push Plastic", "R3D", "Re-pet3D",
"Recreus", "Regen", "RatRig", "Sain SMART", "SliceWorx",
"Snapmaker", "SnoLabs", "Spectrum", "SUNLU", "TTYT3D",
"Tianse", "UltiMaker", "Valment", "Verbatim", "VO3D",
"Voxelab", "VOXELPLA", "YOOPAI", "Yousu", "Ziro",
"Zyltech"};
static const std::vector<std::string> filament_types = {"PLA", "rPLA", "PLA+", "PLA Tough", "PETG", "ABS", "ASA", "FLEX", "HIPS", "PA", "PACF",
"NYLON", "PVA", "PVB", "PC", "PCABS", "PCTG", "PCCF", "PHA", "PP", "PEI", "PET",
+1 -1
View File
@@ -4154,7 +4154,7 @@ void GUI_App::on_http_error(wxCommandEvent &evt)
// Version limit
if (code == HttpErrorVersionLimited) {
MessageDialog msg_dlg(nullptr, _L("The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally"), "", wxAPPLY | wxOK);
MessageDialog msg_dlg(nullptr, _L("The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally."), "", wxAPPLY | wxOK);
if (msg_dlg.ShowModal() == wxOK) {
}
+11 -11
View File
@@ -2631,15 +2631,15 @@ void MainFrame::init_menubar_as_editor()
"", nullptr, [this](){return can_deselect(); }, this);
//editMenu->AppendSeparator();
//append_menu_check_item(editMenu, wxID_ANY, _L("Show Model Mesh(TODO)"),
// _L("Display triangles of models"), [this](wxCommandEvent& evt) {
// _L("Display triangles of models."), [this](wxCommandEvent& evt) {
// wxGetApp().app_config->set_bool("show_model_mesh", evt.GetInt() == 1);
// }, nullptr, [this]() {return can_select(); }, [this]() { return wxGetApp().app_config->get("show_model_mesh").compare("true") == 0; }, this);
//append_menu_check_item(editMenu, wxID_ANY, _L("Show Model Shadow(TODO)"), _L("Display shadow of objects"),
//append_menu_check_item(editMenu, wxID_ANY, _L("Show Model Shadow(TODO)"), _L("Display shadow of objects."),
// [this](wxCommandEvent& evt) {
// wxGetApp().app_config->set_bool("show_model_shadow", evt.GetInt() == 1);
// }, nullptr, [this]() {return can_select(); }, [this]() { return wxGetApp().app_config->get("show_model_shadow").compare("true") == 0; }, this);
//editMenu->AppendSeparator();
//append_menu_check_item(editMenu, wxID_ANY, _L("Show Printable Box(TODO)"), _L("Display printable box"),
//append_menu_check_item(editMenu, wxID_ANY, _L("Show Printable Box(TODO)"), _L("Display printable box."),
// [this](wxCommandEvent& evt) {
// wxGetApp().app_config->set_bool("show_printable_box", evt.GetInt() == 1);
// }, nullptr, [this]() {return can_select(); }, [this]() { return wxGetApp().app_config->get("show_printable_box").compare("true") == 0; }, this);
@@ -2681,7 +2681,7 @@ void MainFrame::init_menubar_as_editor()
else
viewMenu->Check(wxID_CAMERA_ORTHOGONAL + camera_id_base, true);
}, perspective_item->GetId());
append_menu_check_item(viewMenu, wxID_ANY, _L("Auto Perspective"), _L("Automatically switch between orthographic and perspective when changing from top/bottom/side views"),
append_menu_check_item(viewMenu, wxID_ANY, _L("Auto Perspective"), _L("Automatically switch between orthographic and perspective when changing from top/bottom/side views."),
[this](wxCommandEvent&) {
wxGetApp().app_config->set_bool("auto_perspective", !wxGetApp().app_config->get_bool("auto_perspective"));
m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT));
@@ -2690,7 +2690,7 @@ void MainFrame::init_menubar_as_editor()
[this]() { return wxGetApp().app_config->get_bool("auto_perspective"); }, this);
viewMenu->AppendSeparator();
append_menu_check_item(viewMenu, wxID_ANY, _L("Show &G-code Window") + sep + "C", _L("Show G-code window in Preview scene"),
append_menu_check_item(viewMenu, wxID_ANY, _L("Show &G-code Window") + sep + "C", _L("Show G-code window in Preview scene."),
[this](wxCommandEvent &) {
wxGetApp().toggle_show_gcode_window();
m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT));
@@ -2699,7 +2699,7 @@ void MainFrame::init_menubar_as_editor()
[this]() { return wxGetApp().show_gcode_window(); }, this);
append_menu_check_item(
viewMenu, wxID_ANY, _L("Show 3D Navigator"), _L("Show 3D navigator in Prepare and Preview scene"),
viewMenu, wxID_ANY, _L("Show 3D Navigator"), _L("Show 3D navigator in Prepare and Preview scene."),
[this](wxCommandEvent&) {
wxGetApp().toggle_show_3d_navigator();
m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT));
@@ -2717,11 +2717,11 @@ void MainFrame::init_menubar_as_editor()
this);
viewMenu->AppendSeparator();
append_menu_check_item(viewMenu, wxID_ANY, _L("Show &Labels") + "\t" + ctrl + "E", _L("Show object labels in 3D scene"),
append_menu_check_item(viewMenu, wxID_ANY, _L("Show &Labels") + "\t" + ctrl + "E", _L("Show object labels in 3D scene."),
[this](wxCommandEvent&) { m_plater->show_view3D_labels(!m_plater->are_view3D_labels_shown()); m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT)); }, this,
[this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->are_view3D_labels_shown(); }, this);
append_menu_check_item(viewMenu, wxID_ANY, _L("Show &Overhang"), _L("Show object overhang highlight in 3D scene"),
append_menu_check_item(viewMenu, wxID_ANY, _L("Show &Overhang"), _L("Show object overhang highlight in 3D scene."),
[this](wxCommandEvent &) {
m_plater->show_view3D_overhang(!m_plater->is_view3D_overhang_shown());
m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT));
@@ -2729,7 +2729,7 @@ void MainFrame::init_menubar_as_editor()
this, [this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->is_view3D_overhang_shown(); }, this);
append_menu_check_item(
viewMenu, wxID_ANY, _L("Show Selected Outline (beta)"), _L("Show outline around selected object in 3D scene"),
viewMenu, wxID_ANY, _L("Show Selected Outline (beta)"), _L("Show outline around selected object in 3D scene."),
[this](wxCommandEvent&) {
wxGetApp().toggle_show_outline();
m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT));
@@ -2738,13 +2738,13 @@ void MainFrame::init_menubar_as_editor()
[this]() { return wxGetApp().show_outline(); }, this);
/*viewMenu->AppendSeparator();
append_menu_check_item(viewMenu, wxID_ANY, _L("Show &Wireframe") + "\tCtrl+Shift+Enter", _L("Show wireframes in 3D scene"),
append_menu_check_item(viewMenu, wxID_ANY, _L("Show &Wireframe") + "\tCtrl+Shift+Enter", _L("Show wireframes in 3D scene."),
[this](wxCommandEvent&) { m_plater->toggle_show_wireframe(); m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT)); }, this,
[this]() { return m_plater->is_wireframe_enabled(); }, [this]() { return m_plater->is_show_wireframe(); }, this);*/
//viewMenu->AppendSeparator();
////BBS orthogonal view
//append_menu_check_item(viewMenu, wxID_ANY, _L("Show Edges(TODO)"), _L("Show Edges"),
//append_menu_check_item(viewMenu, wxID_ANY, _L("Show Edges(TODO)"), _L("Show Edges."),
// [this](wxCommandEvent& evt) {
// wxGetApp().app_config->set("show_build_edges", evt.GetInt() == 1 ? "true" : "false");
// }, nullptr, [this]() {return can_select(); }, [this]() {
+1 -1
View File
@@ -1274,7 +1274,7 @@ void NotificationManager::UpdatedItemsInfoNotification::add_type(InfoItemType ty
case InfoItemType::MmuSegmentation: text += format(_L_PLURAL("%1$d Object has color painting.", "%1$d Objects have color painting.",(*it).second), (*it).second) + "\n"; break;
// BBS
//case InfoItemType::Sinking: text += format(("%1$d Object has partial sinking.", "%1$d Objects have partial sinking.", (*it).second), (*it).second) + "\n"; break;
case InfoItemType::CutConnectors: text += format(_L_PLURAL("%1$d object was loaded as a part of cut object.", "%1$d objects were loaded as parts of cut object", (*it).second), (*it).second) + "\n"; break;
case InfoItemType::CutConnectors: text += format(_L_PLURAL("%1$d object was loaded as a part of cut object.", "%1$d objects were loaded as parts of cut object.", (*it).second), (*it).second) + "\n"; break;
default: BOOST_LOG_TRIVIAL(error) << "Unknown InfoItemType: " << (*it).second; break;
}
}
+2 -2
View File
@@ -3644,7 +3644,7 @@ void StatusPanel::on_ams_setting_click(SimpleEvent &event)
m_ams_setting_dlg->update_ams_img(DeviceManager::get_printer_ams_img(obj->printer_type));
std::string ams_id = m_ams_control->GetCurentShowAms();
if (obj->amsList.size() == 0) {
/* wxString txt = _L("AMS settings are not supported for external spool");
/* wxString txt = _L("AMS settings are not supported for external spool.");
MessageDialog msg_dlg(nullptr, txt, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();*/
return;
@@ -3672,7 +3672,7 @@ void StatusPanel::on_filament_extrusion_cali(wxCommandEvent &event)
std::string ams_id = m_ams_control->GetCurentAms();
std::string tray_id = m_ams_control->GetCurrentCan(ams_id);
if (tray_id.empty() && ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) != 0) {
wxString txt = _L("Please select an AMS slot before calibration");
wxString txt = _L("Please select an AMS slot before calibration.");
MessageDialog msg_dlg(nullptr, txt, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
+17 -2
View File
@@ -2206,6 +2206,7 @@ void TabPrint::build()
optgroup->append_single_option_line("support_interface_speed");
optgroup = page->new_optgroup(L("Overhang speed"), L"param_overhang_speed", 15);
optgroup->append_single_option_line("enable_overhang_speed", "slow-down-for-overhang");
// Orca: DEPRECATED
// optgroup->append_single_option_line("overhang_speed_classic", "slow-down-for-overhang");
optgroup->append_single_option_line("slowdown_for_curled_perimeters");
@@ -4166,6 +4167,17 @@ PageShp TabPrinter::build_kinematics_page()
}
auto optgroup = page->new_optgroup(L("Advanced"), "param_advanced");
optgroup->append_single_option_line("emit_machine_limits_to_gcode");
// resonance avoidance ported over from qidi slicer
optgroup = page->new_optgroup(L("Resonance Avoidance"));
optgroup->append_single_option_line("resonance_avoidance");
// Resonance‑avoidance speed inputs
{
Line resonance_line = {L("Resonance Avoidance Speed"), L("")};
resonance_line.append_option(optgroup->get_option("min_resonance_avoidance_speed"));
resonance_line.append_option(optgroup->get_option("max_resonance_avoidance_speed"));
optgroup->append_line(resonance_line);
}
const std::vector<std::string> speed_axes{
"machine_max_speed_x",
@@ -4424,7 +4436,6 @@ if (is_marlin_flavor)
optgroup->append_single_option_line("deretraction_speed", "", extruder_idx);
optgroup->append_single_option_line("retraction_minimum_travel", "", extruder_idx);
optgroup->append_single_option_line("retract_when_changing_layer", "", extruder_idx);
optgroup->append_single_option_line("retract_on_top_layer", "", extruder_idx);
optgroup->append_single_option_line("wipe", "", extruder_idx);
optgroup->append_single_option_line("wipe_distance", "", extruder_idx);
optgroup->append_single_option_line("retract_before_wipe", "", extruder_idx);
@@ -4644,7 +4655,7 @@ void TabPrinter::toggle_options()
// user can customize other retraction options if retraction is enabled
//BBS
bool retraction = have_retract_length || use_firmware_retraction;
std::vector<std::string> vec = {"z_hop", "retract_when_changing_layer", "retract_on_top_layer"};
std::vector<std::string> vec = {"z_hop", "retract_when_changing_layer"};
for (auto el : vec)
toggle_option(el, retraction, i);
@@ -4709,6 +4720,10 @@ void TabPrinter::toggle_options()
for (int i = 0; i < max_field; ++i)
toggle_option("machine_max_junction_deviation", gcf == gcfMarlinFirmware, i);
toggle_line("machine_max_junction_deviation", gcf == gcfMarlinFirmware);
bool resonance_avoidance = m_config->opt_bool("resonance_avoidance");
toggle_option("min_resonance_avoidance_speed", resonance_avoidance);
toggle_option("max_resonance_avoidance_speed", resonance_avoidance);
}
}