mirror of
https://github.com/QIDITECH/QIDISlicer.git
synced 2026-01-30 23:48:44 +03:00
add scarf seam
This commit is contained in:
@@ -9,6 +9,9 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
//w37
|
||||||
|
#include "libslic3r/Utils.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
void ExtrusionPath::intersect_expolygons(const ExPolygons &collection, ExtrusionEntityCollection* retval) const
|
void ExtrusionPath::intersect_expolygons(const ExPolygons &collection, ExtrusionEntityCollection* retval) const
|
||||||
@@ -334,4 +337,48 @@ double ExtrusionLoop::min_mm3_per_mm() const
|
|||||||
return min_mm3_per_mm;
|
return min_mm3_per_mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//w37
|
||||||
|
bool ExtrusionLoop::check_seam_point_angle(double angle_threshold, double min_arm_length) const
|
||||||
|
{
|
||||||
|
// go through all the points in the loop and check if the angle between two segments(AB and BC) is less than the threshold
|
||||||
|
size_t idx_prev = 0;
|
||||||
|
size_t idx_curr = 0;
|
||||||
|
size_t idx_next = 0;
|
||||||
|
|
||||||
|
float distance_to_prev = 0;
|
||||||
|
float distance_to_next = 0;
|
||||||
|
|
||||||
|
const auto _polygon = polygon();
|
||||||
|
const Points &points = _polygon.points;
|
||||||
|
|
||||||
|
std::vector<float> lengths{};
|
||||||
|
for (size_t point_idx = 0; point_idx < points.size() - 1; ++point_idx) {
|
||||||
|
lengths.push_back((unscale(points[point_idx]) - unscale(points[point_idx + 1])).norm());
|
||||||
|
}
|
||||||
|
lengths.push_back(std::max((unscale(points[0]) - unscale(points[points.size() - 1])).norm(), 0.1));
|
||||||
|
|
||||||
|
// push idx_prev far enough back as initialization
|
||||||
|
while (distance_to_prev < min_arm_length) {
|
||||||
|
idx_prev = Slic3r::prev_idx_modulo(idx_prev, points.size());
|
||||||
|
distance_to_prev += lengths[idx_prev];
|
||||||
|
}
|
||||||
|
|
||||||
|
// push idx_next forward as far as needed
|
||||||
|
while (distance_to_next < min_arm_length) {
|
||||||
|
distance_to_next += lengths[idx_next];
|
||||||
|
idx_next = Slic3r::next_idx_modulo(idx_next, points.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate angle between idx_prev, idx_curr, idx_next.
|
||||||
|
const Point &p0 = points[idx_prev];
|
||||||
|
const Point &p1 = points[idx_curr];
|
||||||
|
const Point &p2 = points[idx_next];
|
||||||
|
const auto a = angle(p0 - p1, p2 - p1);
|
||||||
|
if (a > 0 ? a < angle_threshold : a > -angle_threshold) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,6 +326,8 @@ public:
|
|||||||
append(dst, p.polyline.points);
|
append(dst, p.polyline.points);
|
||||||
}
|
}
|
||||||
double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
|
double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
|
||||||
|
//w37
|
||||||
|
bool check_seam_point_angle(double angle_threshold = 0.174, double min_arm_length = 0.025) const;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
bool validate() const {
|
bool validate() const {
|
||||||
|
|||||||
@@ -2952,10 +2952,12 @@ std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &loop_src, const GC
|
|||||||
// Extrude all loops CCW.
|
// Extrude all loops CCW.
|
||||||
bool is_hole = loop_src.is_clockwise();
|
bool is_hole = loop_src.is_clockwise();
|
||||||
Point seam_point = this->last_position.has_value() ? *this->last_position : Point::Zero();
|
Point seam_point = this->last_position.has_value() ? *this->last_position : Point::Zero();
|
||||||
if (! m_config.spiral_vase && comment_is_perimeter(description)) {
|
//w37
|
||||||
|
if ((!m_config.spiral_vase && comment_is_perimeter(description)) || (this->config().seam_slope_type == SeamScarfType::None) &&comment_is_perimeter(description) ) {
|
||||||
assert(m_layer != nullptr);
|
assert(m_layer != nullptr);
|
||||||
seam_point = m_seam_placer.place_seam(m_layer, loop_src, m_config.external_perimeters_first, seam_point);
|
seam_point = m_seam_placer.place_seam(m_layer, loop_src, m_config.external_perimeters_first, seam_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Because the G-code export has 1um resolution, don't generate segments shorter than 1.5 microns,
|
// Because the G-code export has 1um resolution, don't generate segments shorter than 1.5 microns,
|
||||||
// thus empty path segments will not be produced by G-code export.
|
// thus empty path segments will not be produced by G-code export.
|
||||||
GCode::SmoothPath smooth_path = smooth_path_cache.resolve_or_fit_split_with_seam(
|
GCode::SmoothPath smooth_path = smooth_path_cache.resolve_or_fit_split_with_seam(
|
||||||
@@ -2978,8 +2980,95 @@ std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &loop_src, const GC
|
|||||||
|
|
||||||
// Extrude along the smooth path.
|
// Extrude along the smooth path.
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
for (const GCode::SmoothPathElement &el : smooth_path)
|
|
||||||
gcode += this->_extrude(el.path_attributes, el.path, description, speed);
|
//w37
|
||||||
|
double ext_length = 0;
|
||||||
|
double inner_length = 0;
|
||||||
|
double start_height = 0;
|
||||||
|
bool enable_seam_slope = loop_src.check_seam_point_angle(m_config.scarf_angle_threshold.value * M_PI / 180.0);
|
||||||
|
if (this->config().seam_slope_start_height.percent)
|
||||||
|
start_height = this->config().seam_slope_start_height * this->config().layer_height / 100;
|
||||||
|
else
|
||||||
|
start_height = this->config().seam_slope_start_height;
|
||||||
|
double height_for_lift = this->config().layer_height - start_height;
|
||||||
|
if (enable_seam_slope)
|
||||||
|
for (const GCode::SmoothPathElement &el : smooth_path) {
|
||||||
|
Vec2d prev_exact = this->point_to_gcode(el.path.front().point);
|
||||||
|
Vec2d prev = GCodeFormatter::quantize(prev_exact);
|
||||||
|
auto it = el.path.begin();
|
||||||
|
auto end = el.path.end();
|
||||||
|
double sum_lift = 0;
|
||||||
|
for (++it; it != end; ++it) {
|
||||||
|
Vec2d p_exact = this->point_to_gcode(it->point);
|
||||||
|
Vec2d p = GCodeFormatter::quantize(p_exact);
|
||||||
|
double line_length = (p - prev).norm();
|
||||||
|
/* if (el.path_attributes.role.is_external_perimeter())
|
||||||
|
ext_length += line_length;
|
||||||
|
if (el.path_attributes.role.is_perimeter())
|
||||||
|
inner_length += line_length;*/
|
||||||
|
double x1 = prev.x();
|
||||||
|
double x2 = p.x();
|
||||||
|
double y1 = prev.y();
|
||||||
|
double y2 = p.y();
|
||||||
|
double temp_length = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
|
||||||
|
if (el.path_attributes.role.is_external_perimeter())
|
||||||
|
ext_length += temp_length;
|
||||||
|
if (el.path_attributes.role.is_perimeter())
|
||||||
|
inner_length += temp_length;
|
||||||
|
prev = p;
|
||||||
|
prev_exact = p_exact;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* for (int i = 0; i < el.path.size() - 1; i++) {
|
||||||
|
double x1 = el.path[i].point.x();
|
||||||
|
double x2 = el.path[i + 1].point.x();
|
||||||
|
double y1 = el.path[i].point.y();
|
||||||
|
double y2 = el.path[i+1].point.y();
|
||||||
|
double temp_length = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
|
||||||
|
if (el.path_attributes.role.is_external_perimeter())
|
||||||
|
ext_length += temp_length;
|
||||||
|
if (el.path_attributes.role.is_perimeter())
|
||||||
|
inner_length += temp_length;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
//w37
|
||||||
|
double ext_ratio = 0;
|
||||||
|
if (ext_length != 0)
|
||||||
|
ext_ratio = height_for_lift / ext_length;
|
||||||
|
double inner_ratio = 0;
|
||||||
|
if (inner_length != 0)
|
||||||
|
inner_ratio = height_for_lift / inner_length;
|
||||||
|
if (!this->config().seam_slope_entire_loop && ext_length > this->config().seam_slope_min_length) {
|
||||||
|
ext_ratio = height_for_lift / this->config().seam_slope_min_length;
|
||||||
|
}
|
||||||
|
if (!this->config().seam_slope_entire_loop && inner_length > this->config().seam_slope_min_length) {
|
||||||
|
inner_ratio = height_for_lift / this->config().seam_slope_min_length;
|
||||||
|
}
|
||||||
|
//GCode::SmoothPath new_path = smooth_path;
|
||||||
|
//if (this->config().seam_slope_type != SeamScarfType::None) {
|
||||||
|
//GCode::SmoothPath new_path = smooth_path;
|
||||||
|
// set_step_path(new_path, this->config().seam_slope_steps);
|
||||||
|
//}
|
||||||
|
//w37
|
||||||
|
for (const GCode::SmoothPathElement &el : smooth_path) {
|
||||||
|
if (((this->config().seam_slope_type == SeamScarfType::None) || (this->config().seam_slope_type == SeamScarfType::External && is_hole))|| !enable_seam_slope)
|
||||||
|
gcode += this->_extrude(el.path_attributes, el.path, description, speed);
|
||||||
|
else {
|
||||||
|
if (el.path_attributes.role.is_external_perimeter() && this->config().seam_slope_type != SeamScarfType::None)
|
||||||
|
gcode += this->_extrude(el.path_attributes, el.path, description, speed, ext_ratio);
|
||||||
|
else if (el.path_attributes.role.is_perimeter() && this->config().seam_slope_type != SeamScarfType::None &&
|
||||||
|
this->config().seam_slope_inner_walls)
|
||||||
|
gcode += this->_extrude(el.path_attributes, el.path, description, speed, inner_ratio);
|
||||||
|
else if (el.path_attributes.role.is_perimeter() && this->config().seam_slope_type != SeamScarfType::None &&
|
||||||
|
!this->config().seam_slope_inner_walls)
|
||||||
|
gcode += this->_extrude(el.path_attributes, el.path, description, speed);
|
||||||
|
}
|
||||||
|
//this->sum_lift_z = 0;
|
||||||
|
//this->sum_lift_z_ext = 0;
|
||||||
|
}
|
||||||
|
this->sum_lift_z = 0;
|
||||||
|
this->sum_lift_z_ext = 0;
|
||||||
|
|
||||||
// reset acceleration
|
// reset acceleration
|
||||||
gcode += m_writer.set_print_acceleration(fast_round_up<unsigned int>(m_config.default_acceleration.value));
|
gcode += m_writer.set_print_acceleration(fast_round_up<unsigned int>(m_config.default_acceleration.value));
|
||||||
@@ -3220,7 +3309,19 @@ std::string GCodeGenerator::travel_to_first_position(const Vec3crd& point, const
|
|||||||
|
|
||||||
gcode += insert_gcode();
|
gcode += insert_gcode();
|
||||||
gcode += this->writer().get_travel_to_xy_gcode(gcode_point.head<2>(), comment);
|
gcode += this->writer().get_travel_to_xy_gcode(gcode_point.head<2>(), comment);
|
||||||
gcode += this->writer().get_travel_to_z_gcode(gcode_point.z(), comment);
|
//w37
|
||||||
|
//gcode += this->writer().get_travel_to_z_gcode(gcode_point.z(), comment);
|
||||||
|
//w37
|
||||||
|
double start_height = 0;
|
||||||
|
if (this->config().seam_slope_start_height.percent)
|
||||||
|
start_height = this->config().seam_slope_start_height * this->config().layer_height / 100;
|
||||||
|
else
|
||||||
|
start_height = this->config().seam_slope_start_height;
|
||||||
|
double height_for_lift = this->config().layer_height - start_height;
|
||||||
|
if (this->config().seam_slope_type != SeamScarfType::None && (role.is_external_perimeter() ||role.is_perimeter())&& !this->on_first_layer())
|
||||||
|
gcode += this->writer().get_travel_to_z_gcode(gcode_point.z() - height_for_lift, comment);
|
||||||
|
else
|
||||||
|
gcode += this->writer().get_travel_to_z_gcode(gcode_point.z(), comment);
|
||||||
|
|
||||||
this->m_avoid_crossing_perimeters.reset_once_modifiers();
|
this->m_avoid_crossing_perimeters.reset_once_modifiers();
|
||||||
this->last_position = point.head<2>();
|
this->last_position = point.head<2>();
|
||||||
@@ -3247,7 +3348,9 @@ std::string GCodeGenerator::_extrude(
|
|||||||
const ExtrusionAttributes &path_attr,
|
const ExtrusionAttributes &path_attr,
|
||||||
const Geometry::ArcWelder::Path &path,
|
const Geometry::ArcWelder::Path &path,
|
||||||
const std::string_view description,
|
const std::string_view description,
|
||||||
double speed)
|
double speed,
|
||||||
|
//w37
|
||||||
|
double radio)
|
||||||
{
|
{
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
const std::string_view description_bridge = path_attr.role.is_bridge() ? " (bridge)"sv : ""sv;
|
const std::string_view description_bridge = path_attr.role.is_bridge() ? " (bridge)"sv : ""sv;
|
||||||
@@ -3281,6 +3384,18 @@ std::string GCodeGenerator::_extrude(
|
|||||||
return m_writer.multiple_extruders ? "" : m_label_objects.maybe_change_instance(m_writer);
|
return m_writer.multiple_extruders ? "" : m_label_objects.maybe_change_instance(m_writer);
|
||||||
})};
|
})};
|
||||||
gcode += travel_gcode;
|
gcode += travel_gcode;
|
||||||
|
//w37
|
||||||
|
if (this->config().seam_slope_type != SeamScarfType::None &&
|
||||||
|
(path_attr.role.is_external_perimeter() || path_attr.role.is_perimeter()) && !this->on_first_layer()) {
|
||||||
|
double start_height = 0;
|
||||||
|
if (this->config().seam_slope_start_height.percent)
|
||||||
|
start_height = this->config().seam_slope_start_height * this->config().layer_height / 100;
|
||||||
|
else
|
||||||
|
start_height = this->config().seam_slope_start_height;
|
||||||
|
double height_for_lift = this->config().layer_height - start_height;
|
||||||
|
|
||||||
|
gcode += this->m_writer.get_travel_to_z_gcode(this->m_last_layer_z - height_for_lift, comment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3483,10 +3598,30 @@ std::string GCodeGenerator::_extrude(
|
|||||||
comment = description;
|
comment = description;
|
||||||
comment += description_bridge;
|
comment += description_bridge;
|
||||||
}
|
}
|
||||||
|
//w37
|
||||||
|
//Geometry::ArcWelder::Path new_path = path;
|
||||||
|
int seam_slope_steps = this->config().seam_slope_steps;
|
||||||
|
// if (path.size() < seam_slope_steps)
|
||||||
|
// set_step_path(&new_path, seam_slope_steps);
|
||||||
Vec2d prev_exact = this->point_to_gcode(path.front().point);
|
Vec2d prev_exact = this->point_to_gcode(path.front().point);
|
||||||
Vec2d prev = GCodeFormatter::quantize(prev_exact);
|
Vec2d prev = GCodeFormatter::quantize(prev_exact);
|
||||||
auto it = path.begin();
|
auto it = path.begin();
|
||||||
auto end = path.end();
|
auto end = path.end();
|
||||||
|
|
||||||
|
//w37
|
||||||
|
double sum_lift = 0;
|
||||||
|
double start_height = 0;
|
||||||
|
if (this->config().seam_slope_start_height.percent)
|
||||||
|
start_height = this->config().seam_slope_start_height * this->config().layer_height / 100;
|
||||||
|
else
|
||||||
|
start_height = this->config().seam_slope_start_height;
|
||||||
|
double height_for_lift = this->config().layer_height - start_height;
|
||||||
|
std::vector<Vec3d> point_lift;
|
||||||
|
std::vector<double> length_vec;
|
||||||
|
std::vector<double> radio_vec;
|
||||||
|
bool is_first_loop = true ;
|
||||||
|
Vec2d first_point ;
|
||||||
|
Vec2d end_point;
|
||||||
for (++ it; it != end; ++ it) {
|
for (++ it; it != end; ++ it) {
|
||||||
Vec2d p_exact = this->point_to_gcode(it->point);
|
Vec2d p_exact = this->point_to_gcode(it->point);
|
||||||
Vec2d p = GCodeFormatter::quantize(p_exact);
|
Vec2d p = GCodeFormatter::quantize(p_exact);
|
||||||
@@ -3511,8 +3646,57 @@ std::string GCodeGenerator::_extrude(
|
|||||||
}
|
}
|
||||||
if (radius == 0) {
|
if (radius == 0) {
|
||||||
// Extrude line segment.
|
// Extrude line segment.
|
||||||
if (const double line_length = (p - prev).norm(); line_length > 0)
|
//w37
|
||||||
gcode += m_writer.extrude_to_xy(p, e_per_mm * line_length, comment);
|
double curt_length = 0;
|
||||||
|
if (radio!=0) {
|
||||||
|
double x1 = p.x();
|
||||||
|
double x2 = prev.x();
|
||||||
|
double y1 = p.y();
|
||||||
|
double y2 = prev.y();
|
||||||
|
curt_length = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
|
||||||
|
}
|
||||||
|
if (const double line_length = (p - prev).norm(); line_length > 0) {
|
||||||
|
if (curt_length == 0 || this->on_first_layer() || this->sum_lift_z >= height_for_lift)
|
||||||
|
gcode += m_writer.extrude_to_xy(p, e_per_mm * line_length, comment);
|
||||||
|
else {
|
||||||
|
/* if (path_attr.role.is_external_perimeter()) {
|
||||||
|
double cur_lift = curt_length * radio;
|
||||||
|
if (this->sum_lift_z_ext + cur_lift >= height_for_lift)
|
||||||
|
cur_lift = height_for_lift - this->sum_lift_z_ext;
|
||||||
|
Vec3d new_p(p.x(), p.y(), this->m_last_layer_z - height_for_lift + this->sum_lift_z_ext + cur_lift);
|
||||||
|
gcode += m_writer.extrude_to_xyz(new_p, e_per_mm * line_length, comment);
|
||||||
|
this->sum_lift_z_ext += cur_lift;
|
||||||
|
}
|
||||||
|
if (path_attr.role.is_perimeter()) {
|
||||||
|
double cur_lift = curt_length * radio;
|
||||||
|
if (this->sum_lift_z + cur_lift >= height_for_lift)
|
||||||
|
cur_lift = height_for_lift - this->sum_lift_z;
|
||||||
|
Vec3d new_p(p.x(), p.y(), this->m_last_layer_z - height_for_lift + this->sum_lift_z + cur_lift);
|
||||||
|
gcode += m_writer.extrude_to_xyz(new_p, e_per_mm * line_length, comment);
|
||||||
|
this->sum_lift_z += cur_lift;
|
||||||
|
}*/
|
||||||
|
double cur_lift = curt_length * radio;
|
||||||
|
if (this->sum_lift_z + cur_lift >= height_for_lift)
|
||||||
|
cur_lift = height_for_lift - this->sum_lift_z;
|
||||||
|
double lift_radio = 0;
|
||||||
|
lift_radio = (start_height + this->sum_lift_z + cur_lift) / this->config().layer_height;
|
||||||
|
|
||||||
|
Vec3d new_p(p.x(), p.y(), this->m_last_layer_z - height_for_lift + this->sum_lift_z + cur_lift);
|
||||||
|
if (is_first_loop) {
|
||||||
|
first_point = prev;
|
||||||
|
is_first_loop = false;
|
||||||
|
}
|
||||||
|
end_point = p;
|
||||||
|
point_lift.emplace_back(new_p);
|
||||||
|
length_vec.emplace_back(line_length);
|
||||||
|
radio_vec.emplace_back(lift_radio);
|
||||||
|
//lift_radio += 0.2;
|
||||||
|
//if (lift_radio > 1)
|
||||||
|
// lift_radio = 1;
|
||||||
|
gcode += m_writer.extrude_to_xyz(new_p, e_per_mm * line_length * lift_radio , comment);
|
||||||
|
this->sum_lift_z += cur_lift;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
double angle = Geometry::ArcWelder::arc_angle(prev.cast<double>(), p.cast<double>(), double(radius));
|
double angle = Geometry::ArcWelder::arc_angle(prev.cast<double>(), p.cast<double>(), double(radius));
|
||||||
assert(angle > 0);
|
assert(angle > 0);
|
||||||
@@ -3526,6 +3710,65 @@ std::string GCodeGenerator::_extrude(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//w37
|
||||||
|
if (this->config().seam_slope_type != SeamScarfType::None &&
|
||||||
|
(path_attr.role.is_external_perimeter() || path_attr.role.is_perimeter()) && !this->on_first_layer() && radio != 0) {
|
||||||
|
prev_exact = this->point_to_gcode(path.front().point);
|
||||||
|
prev = GCodeFormatter::quantize(prev_exact);
|
||||||
|
it = path.begin();
|
||||||
|
end = path.end();
|
||||||
|
length_vec[0] += (first_point - end_point).norm();
|
||||||
|
for (int i = 0; i < point_lift.size(); i++) {
|
||||||
|
Vec3d cur_point = point_lift[i];
|
||||||
|
double line_length = length_vec[i];
|
||||||
|
double wipe_radio = radio_vec[i];
|
||||||
|
Vec2d cur_point2d(cur_point.x(), cur_point.y());
|
||||||
|
gcode += m_writer.extrude_to_xy(cur_point2d, e_per_mm * line_length * (1 - wipe_radio), comment);
|
||||||
|
}
|
||||||
|
/* for (++it; it != end; ++it) {
|
||||||
|
Vec2d p_exact = this->point_to_gcode(it->point);
|
||||||
|
Vec2d p = GCodeFormatter::quantize(p_exact);
|
||||||
|
assert(p != prev);
|
||||||
|
if (p != prev) {
|
||||||
|
// Center of the radius to be emitted into the G-code: Either by radius or by center offset.
|
||||||
|
double radius = 0;
|
||||||
|
Vec2d ij;
|
||||||
|
if (it->radius != 0) {
|
||||||
|
// Extrude an arc.
|
||||||
|
assert(m_config.arc_fitting == ArcFittingType::EmitCenter);
|
||||||
|
radius = unscaled<double>(it->radius);
|
||||||
|
{
|
||||||
|
// Calculate quantized IJ circle center offset.
|
||||||
|
ij = GCodeFormatter::quantize(Vec2d(
|
||||||
|
Geometry::ArcWelder::arc_center(prev_exact.cast<double>(), p_exact.cast<double>(), double(radius), it->ccw()) -
|
||||||
|
prev));
|
||||||
|
if (ij == Vec2d::Zero())
|
||||||
|
// Don't extrude a degenerated circle.
|
||||||
|
radius = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (radius == 0) {
|
||||||
|
// Extrude line segment.
|
||||||
|
double curt_length = 0;
|
||||||
|
if (radio != 0) {
|
||||||
|
double x1 = p.x();
|
||||||
|
double x2 = prev.x();
|
||||||
|
double y1 = p.y();
|
||||||
|
double y2 = prev.y();
|
||||||
|
curt_length = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
|
||||||
|
}
|
||||||
|
if (const double line_length = (p - prev).norm(); line_length > 0) {
|
||||||
|
if (curt_length != 0 || !this->on_first_layer())
|
||||||
|
gcode += m_writer.extrude_to_xy(p, e_per_mm * line_length/10, comment);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev = p;
|
||||||
|
prev_exact = p_exact;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
if (m_enable_cooling_markers)
|
if (m_enable_cooling_markers)
|
||||||
gcode += path_attr.role.is_bridge() ? ";_BRIDGE_FAN_END\n" : ";_EXTRUDE_END\n";
|
gcode += path_attr.role.is_bridge() ? ";_BRIDGE_FAN_END\n" : ";_EXTRUDE_END\n";
|
||||||
|
|
||||||
|
|||||||
@@ -166,6 +166,10 @@ public:
|
|||||||
|
|
||||||
std::optional<Point> last_position;
|
std::optional<Point> last_position;
|
||||||
|
|
||||||
|
//w37
|
||||||
|
double sum_lift_z_ext = 0;
|
||||||
|
double sum_lift_z = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class GCodeOutputStream {
|
class GCodeOutputStream {
|
||||||
public:
|
public:
|
||||||
@@ -267,6 +271,45 @@ private:
|
|||||||
std::string extrude_multi_path(const ExtrusionMultiPath &multipath, bool reverse, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
|
std::string extrude_multi_path(const ExtrusionMultiPath &multipath, bool reverse, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
|
||||||
std::string extrude_path(const ExtrusionPath &path, bool reverse, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
|
std::string extrude_path(const ExtrusionPath &path, bool reverse, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
|
||||||
|
|
||||||
|
//w37
|
||||||
|
void set_step_path(GCode::SmoothPath &path, const int steps)
|
||||||
|
{
|
||||||
|
double max_line_length =0;
|
||||||
|
double nums_line = 0;
|
||||||
|
int p1_i_index=-1;
|
||||||
|
int p1_j_index=-1;
|
||||||
|
Line max_line;
|
||||||
|
for (int i = 0; i < path.size(); i++) {
|
||||||
|
nums_line += path[i].path.size() - 1;
|
||||||
|
}
|
||||||
|
while (nums_line < steps) {
|
||||||
|
for (int i = 0; i < path.size(); i++) {
|
||||||
|
for (int j = 0; j < path[i].path.size() - 1; j++) {
|
||||||
|
Point p1 = path[i].path[j].point;
|
||||||
|
Point p2 = path[i].path[j + 1].point;
|
||||||
|
Line cur_l(p1, p2);
|
||||||
|
if (cur_l.length() > max_line_length) {
|
||||||
|
max_line_length = cur_l.length();
|
||||||
|
p1_i_index = i;
|
||||||
|
p1_j_index = j;
|
||||||
|
max_line = cur_l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p1_i_index >= 0 && p1_j_index >= 0) {
|
||||||
|
Point midpt = max_line.midpoint();
|
||||||
|
Geometry::ArcWelder::Segment temp_val;
|
||||||
|
temp_val.point = midpt;
|
||||||
|
path[p1_i_index].path.insert(path[p1_i_index].path.begin() +1+ p1_j_index, temp_val);
|
||||||
|
}
|
||||||
|
nums_line = 0;
|
||||||
|
for (int i = 0; i < path.size(); i++) {
|
||||||
|
nums_line += path[i].path.size() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
struct InstanceToPrint
|
struct InstanceToPrint
|
||||||
{
|
{
|
||||||
InstanceToPrint(size_t object_layer_to_print_id, const PrintObject &print_object, size_t instance_id) :
|
InstanceToPrint(size_t object_layer_to_print_id, const PrintObject &print_object, size_t instance_id) :
|
||||||
@@ -457,8 +500,9 @@ private:
|
|||||||
|
|
||||||
// Back-pointer to Print (const).
|
// Back-pointer to Print (const).
|
||||||
const Print* m_print;
|
const Print* m_print;
|
||||||
|
//w37
|
||||||
std::string _extrude(
|
std::string _extrude(
|
||||||
const ExtrusionAttributes &attribs, const Geometry::ArcWelder::Path &path, const std::string_view description, double speed = -1);
|
const ExtrusionAttributes &attribs, const Geometry::ArcWelder::Path &path, const std::string_view description, double speed = -1,double ratio = 0);
|
||||||
void print_machine_envelope(GCodeOutputStream &file, const Print &print);
|
void print_machine_envelope(GCodeOutputStream &file, const Print &print);
|
||||||
void _print_first_layer_bed_temperature(GCodeOutputStream &file, const Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
|
void _print_first_layer_bed_temperature(GCodeOutputStream &file, const Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
|
||||||
void _print_first_layer_extruder_temperatures(GCodeOutputStream &file, const Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
|
void _print_first_layer_extruder_temperatures(GCodeOutputStream &file, const Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
|
||||||
|
|||||||
@@ -668,8 +668,14 @@ for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::
|
|||||||
m_result.max_print_height = config.max_print_height;
|
m_result.max_print_height = config.max_print_height;
|
||||||
|
|
||||||
const ConfigOptionBool* spiral_vase = config.option<ConfigOptionBool>("spiral_vase");
|
const ConfigOptionBool* spiral_vase = config.option<ConfigOptionBool>("spiral_vase");
|
||||||
|
//w37
|
||||||
if (spiral_vase != nullptr)
|
if (spiral_vase != nullptr)
|
||||||
m_spiral_vase_active = spiral_vase->value;
|
m_detect_layer_based_on_tag = spiral_vase->value;//m_spiral_vase_active = spiral_vase->value;
|
||||||
|
|
||||||
|
//w37
|
||||||
|
const ConfigOptionBool *has_scarf_joint_seam = config.option<ConfigOptionBool>("has_scarf_joint_seam");
|
||||||
|
if (has_scarf_joint_seam != nullptr)
|
||||||
|
m_detect_layer_based_on_tag = m_detect_layer_based_on_tag || has_scarf_joint_seam->value;
|
||||||
|
|
||||||
const ConfigOptionFloat* z_offset = config.option<ConfigOptionFloat>("z_offset");
|
const ConfigOptionFloat* z_offset = config.option<ConfigOptionFloat>("z_offset");
|
||||||
if (z_offset != nullptr)
|
if (z_offset != nullptr)
|
||||||
@@ -950,8 +956,14 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
|||||||
m_result.max_print_height = max_print_height->value;
|
m_result.max_print_height = max_print_height->value;
|
||||||
|
|
||||||
const ConfigOptionBool* spiral_vase = config.option<ConfigOptionBool>("spiral_vase");
|
const ConfigOptionBool* spiral_vase = config.option<ConfigOptionBool>("spiral_vase");
|
||||||
|
//w37
|
||||||
if (spiral_vase != nullptr)
|
if (spiral_vase != nullptr)
|
||||||
m_spiral_vase_active = spiral_vase->value;
|
m_detect_layer_based_on_tag = spiral_vase->value;//m_spiral_vase_active = spiral_vase->value;
|
||||||
|
|
||||||
|
//w37
|
||||||
|
const ConfigOptionBool *has_scarf_joint_seam = config.option<ConfigOptionBool>("has_scarf_joint_seam");
|
||||||
|
if (has_scarf_joint_seam != nullptr)
|
||||||
|
m_detect_layer_based_on_tag = m_detect_layer_based_on_tag || has_scarf_joint_seam->value;
|
||||||
|
|
||||||
const ConfigOptionFloat* z_offset = config.option<ConfigOptionFloat>("z_offset");
|
const ConfigOptionFloat* z_offset = config.option<ConfigOptionFloat>("z_offset");
|
||||||
if (z_offset != nullptr)
|
if (z_offset != nullptr)
|
||||||
@@ -1022,7 +1034,11 @@ void GCodeProcessor::reset()
|
|||||||
|
|
||||||
m_options_z_corrector.reset();
|
m_options_z_corrector.reset();
|
||||||
|
|
||||||
m_spiral_vase_active = false;
|
//w37
|
||||||
|
//m_spiral_vase_active = false;
|
||||||
|
m_detect_layer_based_on_tag = false;
|
||||||
|
m_seams_count = 0;
|
||||||
|
|
||||||
m_kissslicer_toolchange_time_correction = 0.0f;
|
m_kissslicer_toolchange_time_correction = 0.0f;
|
||||||
|
|
||||||
m_single_extruder_multi_material = false;
|
m_single_extruder_multi_material = false;
|
||||||
@@ -1989,12 +2005,14 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers
|
|||||||
// layer change tag
|
// layer change tag
|
||||||
if (comment == reserved_tag(ETags::Layer_Change)) {
|
if (comment == reserved_tag(ETags::Layer_Change)) {
|
||||||
++m_layer_id;
|
++m_layer_id;
|
||||||
if (m_spiral_vase_active) {
|
//w37
|
||||||
|
if (m_detect_layer_based_on_tag) { // if (m_spiral_vase_active) {
|
||||||
if (m_result.moves.empty() || m_result.spiral_vase_layers.empty())
|
if (m_result.moves.empty() || m_result.spiral_vase_layers.empty())
|
||||||
// add a placeholder for layer height. the actual value will be set inside process_G1() method
|
// add a placeholder for layer height. the actual value will be set inside process_G1() method
|
||||||
m_result.spiral_vase_layers.push_back({ FLT_MAX, { 0, 0 } });
|
m_result.spiral_vase_layers.push_back({ FLT_MAX, { 0, 0 } });
|
||||||
else {
|
else {
|
||||||
const size_t move_id = m_result.moves.size() - 1;
|
//w37
|
||||||
|
const size_t move_id = m_result.moves.size() - 1 - m_seams_count;//const size_t move_id = m_result.moves.size() - 1;
|
||||||
if (!m_result.spiral_vase_layers.empty())
|
if (!m_result.spiral_vase_layers.empty())
|
||||||
m_result.spiral_vase_layers.back().second.second = move_id;
|
m_result.spiral_vase_layers.back().second.second = move_id;
|
||||||
// add a placeholder for layer height. the actual value will be set inside process_G1() method
|
// add a placeholder for layer height. the actual value will be set inside process_G1() method
|
||||||
@@ -2880,7 +2898,8 @@ void GCodeProcessor::process_G1(const std::array<std::optional<double>, 4>& axes
|
|||||||
m_seams_detector.set_first_vertex(m_result.moves.back().position - m_extruder_offsets[m_extruder_id]);
|
m_seams_detector.set_first_vertex(m_result.moves.back().position - m_extruder_offsets[m_extruder_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_spiral_vase_active && !m_result.spiral_vase_layers.empty()) {
|
//w37
|
||||||
|
if (m_detect_layer_based_on_tag && !m_result.spiral_vase_layers.empty()) {//if (m_spiral_vase_active && !m_result.spiral_vase_layers.empty()) {
|
||||||
if (m_result.spiral_vase_layers.back().first == FLT_MAX && delta_pos[Z] >= 0.0)
|
if (m_result.spiral_vase_layers.back().first == FLT_MAX && delta_pos[Z] >= 0.0)
|
||||||
// replace layer height placeholder with correct value
|
// replace layer height placeholder with correct value
|
||||||
m_result.spiral_vase_layers.back().first = static_cast<float>(m_end_position[Z]);
|
m_result.spiral_vase_layers.back().first = static_cast<float>(m_end_position[Z]);
|
||||||
@@ -4437,6 +4456,11 @@ void GCodeProcessor::store_move_vertex(EMoveType type, bool internal_only)
|
|||||||
internal_only
|
internal_only
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//w37
|
||||||
|
if (type == EMoveType::Seam) {
|
||||||
|
m_seams_count++;
|
||||||
|
}
|
||||||
|
|
||||||
// stores stop time placeholders for later use
|
// stores stop time placeholders for later use
|
||||||
if (type == EMoveType::Color_change || type == EMoveType::Pause_Print) {
|
if (type == EMoveType::Color_change || type == EMoveType::Pause_Print) {
|
||||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||||
|
|||||||
@@ -596,7 +596,10 @@ namespace Slic3r {
|
|||||||
SeamsDetector m_seams_detector;
|
SeamsDetector m_seams_detector;
|
||||||
OptionsZCorrector m_options_z_corrector;
|
OptionsZCorrector m_options_z_corrector;
|
||||||
size_t m_last_default_color_id;
|
size_t m_last_default_color_id;
|
||||||
bool m_spiral_vase_active;
|
//w37
|
||||||
|
//bool m_spiral_vase_active;
|
||||||
|
bool m_detect_layer_based_on_tag{false};
|
||||||
|
int m_seams_count;
|
||||||
float m_kissslicer_toolchange_time_correction;
|
float m_kissslicer_toolchange_time_correction;
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
std::chrono::time_point<std::chrono::high_resolution_clock> m_start_time;
|
std::chrono::time_point<std::chrono::high_resolution_clock> m_start_time;
|
||||||
@@ -676,6 +679,10 @@ namespace Slic3r {
|
|||||||
std::vector<std::pair<EMoveType, float>> get_moves_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
std::vector<std::pair<EMoveType, float>> get_moves_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
std::vector<std::pair<GCodeExtrusionRole, float>> get_roles_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
std::vector<std::pair<GCodeExtrusionRole, float>> get_roles_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
std::vector<float> get_layers_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
std::vector<float> get_layers_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
|
//w37
|
||||||
|
void detect_layer_based_on_tag(bool enabled) {
|
||||||
|
m_detect_layer_based_on_tag = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void apply_config(const DynamicPrintConfig& config);
|
void apply_config(const DynamicPrintConfig& config);
|
||||||
|
|||||||
@@ -444,7 +444,8 @@ std::string GCodeWriter::extrude_to_xy_G2G3IJ(const Vec2d &point, const Vec2d &i
|
|||||||
return w.string();
|
return w.string();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
//w37
|
||||||
|
//#if 0
|
||||||
std::string GCodeWriter::extrude_to_xyz(const Vec3d &point, double dE, const std::string_view comment)
|
std::string GCodeWriter::extrude_to_xyz(const Vec3d &point, double dE, const std::string_view comment)
|
||||||
{
|
{
|
||||||
m_pos = point;
|
m_pos = point;
|
||||||
@@ -453,11 +454,12 @@ std::string GCodeWriter::extrude_to_xyz(const Vec3d &point, double dE, const std
|
|||||||
|
|
||||||
GCodeG1Formatter w;
|
GCodeG1Formatter w;
|
||||||
w.emit_xyz(point);
|
w.emit_xyz(point);
|
||||||
w.emit_e(m_extrusion_axis, m_extruder->E());
|
//w37
|
||||||
|
w.emit_e(m_extrusion_axis, m_extruder->extrude(dE).second);
|
||||||
w.emit_comment(this->config.gcode_comments, comment);
|
w.emit_comment(this->config.gcode_comments, comment);
|
||||||
return w.string();
|
return w.string();
|
||||||
}
|
}
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
std::string GCodeWriter::retract(bool before_wipe)
|
std::string GCodeWriter::retract(bool before_wipe)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -84,7 +84,8 @@ public:
|
|||||||
std::string travel_to_z(double z, const std::string_view comment = {});
|
std::string travel_to_z(double z, const std::string_view comment = {});
|
||||||
std::string extrude_to_xy(const Vec2d &point, double dE, const std::string_view comment = {});
|
std::string extrude_to_xy(const Vec2d &point, double dE, const std::string_view comment = {});
|
||||||
std::string extrude_to_xy_G2G3IJ(const Vec2d &point, const Vec2d &ij, const bool ccw, double dE, const std::string_view comment);
|
std::string extrude_to_xy_G2G3IJ(const Vec2d &point, const Vec2d &ij, const bool ccw, double dE, const std::string_view comment);
|
||||||
// std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string_view comment = {});
|
//w37
|
||||||
|
std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string_view comment = {});
|
||||||
std::string retract(bool before_wipe = false);
|
std::string retract(bool before_wipe = false);
|
||||||
std::string retract_for_toolchange(bool before_wipe = false);
|
std::string retract_for_toolchange(bool before_wipe = false);
|
||||||
std::string unretract();
|
std::string unretract();
|
||||||
|
|||||||
@@ -367,6 +367,16 @@ public:
|
|||||||
Model* get_model() { return m_model; }
|
Model* get_model() { return m_model; }
|
||||||
const Model* get_model() const { return m_model; }
|
const Model* get_model() const { return m_model; }
|
||||||
|
|
||||||
|
//w37
|
||||||
|
int get_backup_id() const;
|
||||||
|
template<typename T> const T *get_config_value(const DynamicPrintConfig &global_config, const std::string &config_option)
|
||||||
|
{
|
||||||
|
if (config.has(config_option))
|
||||||
|
return static_cast<const T *>(config.option(config_option));
|
||||||
|
else
|
||||||
|
return global_config.option<T>(config_option);
|
||||||
|
}
|
||||||
|
|
||||||
ModelVolume* add_volume(const TriangleMesh &mesh);
|
ModelVolume* add_volume(const TriangleMesh &mesh);
|
||||||
ModelVolume* add_volume(TriangleMesh &&mesh, ModelVolumeType type = ModelVolumeType::MODEL_PART);
|
ModelVolume* add_volume(TriangleMesh &&mesh, ModelVolumeType type = ModelVolumeType::MODEL_PART);
|
||||||
ModelVolume* add_volume(const ModelVolume &volume, ModelVolumeType type = ModelVolumeType::INVALID);
|
ModelVolume* add_volume(const ModelVolume &volume, ModelVolumeType type = ModelVolumeType::INVALID);
|
||||||
|
|||||||
@@ -495,6 +495,9 @@ static std::vector<std::string> s_Preset_print_options {
|
|||||||
,"top_solid_infill_flow_ratio", "bottom_solid_infill_flow_ratio"
|
,"top_solid_infill_flow_ratio", "bottom_solid_infill_flow_ratio"
|
||||||
//w33
|
//w33
|
||||||
,"ironing_pattern"
|
,"ironing_pattern"
|
||||||
|
//w37
|
||||||
|
,"seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length",
|
||||||
|
"seam_slope_steps", "seam_slope_inner_walls"
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<std::string> s_Preset_filament_options {
|
static std::vector<std::string> s_Preset_filament_options {
|
||||||
|
|||||||
@@ -980,6 +980,28 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
new_full_config.option("physical_printer_settings_id", true);
|
new_full_config.option("physical_printer_settings_id", true);
|
||||||
new_full_config.normalize_fdm();
|
new_full_config.normalize_fdm();
|
||||||
|
|
||||||
|
//w37
|
||||||
|
{
|
||||||
|
const auto &o = model.objects;
|
||||||
|
const auto opt_has_scarf_joint_seam = [](const DynamicConfig &c) {
|
||||||
|
return c.has("seam_slope_type") && c.opt_enum<SeamScarfType>("seam_slope_type") != SeamScarfType::None;
|
||||||
|
};
|
||||||
|
const bool has_scarf_joint_seam = std::any_of(o.begin(), o.end(), [&new_full_config, &opt_has_scarf_joint_seam](ModelObject *obj) {
|
||||||
|
return obj->get_config_value<ConfigOptionEnum<SeamScarfType>>(new_full_config, "seam_slope_type")->value !=
|
||||||
|
SeamScarfType::None ||
|
||||||
|
std::any_of(obj->volumes.begin(), obj->volumes.end(),
|
||||||
|
[&opt_has_scarf_joint_seam](const ModelVolume *v) { return opt_has_scarf_joint_seam(v->config.get()); }) ||
|
||||||
|
std::any_of(obj->layer_config_ranges.begin(), obj->layer_config_ranges.end(),
|
||||||
|
[&opt_has_scarf_joint_seam](const auto &r) { return opt_has_scarf_joint_seam(r.second.get()); });
|
||||||
|
});
|
||||||
|
|
||||||
|
if (has_scarf_joint_seam) {
|
||||||
|
new_full_config.set("has_scarf_joint_seam", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", has_scarf_joint_seam:" << has_scarf_joint_seam;
|
||||||
|
}
|
||||||
|
|
||||||
// Find modified keys of the various configs. Resolve overrides extruder retract values by filament profiles.
|
// Find modified keys of the various configs. Resolve overrides extruder retract values by filament profiles.
|
||||||
DynamicPrintConfig filament_overrides;
|
DynamicPrintConfig filament_overrides;
|
||||||
t_config_option_keys print_diff = print_config_diffs(m_config, new_full_config, filament_overrides);
|
t_config_option_keys print_diff = print_config_diffs(m_config, new_full_config, filament_overrides);
|
||||||
|
|||||||
@@ -170,6 +170,14 @@ static const t_config_enum_values s_keys_map_SeamPosition {
|
|||||||
};
|
};
|
||||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SeamPosition)
|
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SeamPosition)
|
||||||
|
|
||||||
|
//w37
|
||||||
|
static t_config_enum_values s_keys_map_SeamScarfType{
|
||||||
|
{"none", int(SeamScarfType::None)},
|
||||||
|
{"external", int(SeamScarfType::External)},
|
||||||
|
{"all", int(SeamScarfType::All)},
|
||||||
|
};
|
||||||
|
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SeamScarfType)
|
||||||
|
|
||||||
static const t_config_enum_values s_keys_map_SLADisplayOrientation = {
|
static const t_config_enum_values s_keys_map_SLADisplayOrientation = {
|
||||||
{ "landscape", sladoLandscape},
|
{ "landscape", sladoLandscape},
|
||||||
{ "portrait", sladoPortrait}
|
{ "portrait", sladoPortrait}
|
||||||
@@ -1984,6 +1992,11 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionEnum<MachineLimitsUsage>(MachineLimitsUsage::TimeEstimateOnly));
|
def->set_default_value(new ConfigOptionEnum<MachineLimitsUsage>(MachineLimitsUsage::TimeEstimateOnly));
|
||||||
|
|
||||||
|
//w37
|
||||||
|
def = this->add("has_scarf_joint_seam", coBool);
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionBool(false));
|
||||||
|
|
||||||
{
|
{
|
||||||
struct AxisDefault {
|
struct AxisDefault {
|
||||||
std::string name;
|
std::string name;
|
||||||
@@ -2679,6 +2692,69 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def->mode = comExpert;
|
def->mode = comExpert;
|
||||||
def->set_default_value(new ConfigOptionPercent(15));
|
def->set_default_value(new ConfigOptionPercent(15));
|
||||||
|
|
||||||
|
//w37
|
||||||
|
def = this->add("seam_slope_type", coEnum);
|
||||||
|
def->label = L("Scarf joint seam (beta)");
|
||||||
|
def->tooltip = L("Use scarf joint to minimize seam visibility and increase seam strength.");
|
||||||
|
def->set_enum<SeamScarfType>({{"none", L("None")}, {"external", L("Contour")}, {"all", L("Contour and hole")}});
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionEnum<SeamScarfType>(SeamScarfType::None));
|
||||||
|
|
||||||
|
def = this->add("seam_slope_conditional", coBool);
|
||||||
|
def->label = L("Conditional scarf joint");
|
||||||
|
def->tooltip = L(
|
||||||
|
"Apply scarf joints only to smooth perimeters where traditional seams do not conceal the seams at sharp corners effectively.");
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionBool(true));
|
||||||
|
|
||||||
|
def = this->add("scarf_angle_threshold", coInt);
|
||||||
|
def->label = L("Conditional angle threshold");
|
||||||
|
def->tooltip = L(
|
||||||
|
"This option sets the threshold angle for applying a conditional scarf joint seam.\nIf the maximum angle within the perimeter loop "
|
||||||
|
"exceeds this value (indicating the absence of sharp corners), a scarf joint seam will be used. The default value is 155°.");
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->sidetext = L("°");
|
||||||
|
def->min = 0;
|
||||||
|
def->max = 180;
|
||||||
|
def->set_default_value(new ConfigOptionInt(155));
|
||||||
|
|
||||||
|
def = this->add("seam_slope_start_height", coFloatOrPercent);
|
||||||
|
def->label = L("Scarf start height");
|
||||||
|
def->tooltip = L("Start height of the scarf.\n"
|
||||||
|
"This amount can be specified in millimeters or as a percentage of the current layer height. The default value for "
|
||||||
|
"this parameter is 0.");
|
||||||
|
def->sidetext = L("mm or %");
|
||||||
|
def->min = 0;
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionFloatOrPercent(0.1, false));
|
||||||
|
|
||||||
|
def = this->add("seam_slope_entire_loop", coBool);
|
||||||
|
def->label = L("Scarf around entire wall");
|
||||||
|
def->tooltip = L("The scarf extends to the entire length of the wall.");
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionBool(false));
|
||||||
|
|
||||||
|
def = this->add("seam_slope_min_length", coFloat);
|
||||||
|
def->label = L("Scarf length");
|
||||||
|
def->tooltip = L("Length of the scarf. Setting this parameter to zero effectively disables the scarf.");
|
||||||
|
def->sidetext = L("mm");
|
||||||
|
def->min = 0;
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionFloat(10));
|
||||||
|
|
||||||
|
def = this->add("seam_slope_steps", coInt);
|
||||||
|
def->label = L("Scarf steps");
|
||||||
|
def->tooltip = L("Minimum number of segments of each scarf.");
|
||||||
|
def->min = 1;
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionInt(10));
|
||||||
|
|
||||||
|
def = this->add("seam_slope_inner_walls", coBool);
|
||||||
|
def->label = L("Scarf joint for inner walls");
|
||||||
|
def->tooltip = L("Use scarf joint for inner walls as well.");
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionBool(true));
|
||||||
|
|
||||||
def = this->add("staggered_inner_seams", coBool);
|
def = this->add("staggered_inner_seams", coBool);
|
||||||
def->label = L("Staggered inner seams");
|
def->label = L("Staggered inner seams");
|
||||||
// TRN PrintSettings: "Staggered inner seams"
|
// TRN PrintSettings: "Staggered inner seams"
|
||||||
|
|||||||
@@ -106,6 +106,13 @@ enum SeamPosition {
|
|||||||
spRandom, spNearest, spAligned, spRear
|
spRandom, spNearest, spAligned, spRear
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//w37
|
||||||
|
enum class SeamScarfType {
|
||||||
|
None,
|
||||||
|
External,
|
||||||
|
All,
|
||||||
|
};
|
||||||
|
|
||||||
enum SLAMaterial {
|
enum SLAMaterial {
|
||||||
slamTough,
|
slamTough,
|
||||||
slamFlex,
|
slamFlex,
|
||||||
@@ -168,6 +175,8 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SupportMaterialPattern)
|
|||||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SupportMaterialStyle)
|
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SupportMaterialStyle)
|
||||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SupportMaterialInterfacePattern)
|
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SupportMaterialInterfacePattern)
|
||||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SeamPosition)
|
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SeamPosition)
|
||||||
|
//w37
|
||||||
|
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SeamScarfType)
|
||||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SLADisplayOrientation)
|
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SLADisplayOrientation)
|
||||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SLAPillarConnectionMode)
|
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SLAPillarConnectionMode)
|
||||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SLASupportTreeType)
|
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SLASupportTreeType)
|
||||||
@@ -607,6 +616,15 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||||||
((ConfigOptionBool, only_one_wall_first_layer))
|
((ConfigOptionBool, only_one_wall_first_layer))
|
||||||
//w27
|
//w27
|
||||||
((ConfigOptionBool, precise_z_height))
|
((ConfigOptionBool, precise_z_height))
|
||||||
|
//w37
|
||||||
|
((ConfigOptionEnum<SeamScarfType>, seam_slope_type))
|
||||||
|
((ConfigOptionBool, seam_slope_conditional))
|
||||||
|
((ConfigOptionInt, scarf_angle_threshold))
|
||||||
|
((ConfigOptionFloatOrPercent, seam_slope_start_height))
|
||||||
|
((ConfigOptionBool, seam_slope_entire_loop))
|
||||||
|
((ConfigOptionFloat, seam_slope_min_length))
|
||||||
|
((ConfigOptionInt, seam_slope_steps))
|
||||||
|
((ConfigOptionBool, seam_slope_inner_walls))
|
||||||
)
|
)
|
||||||
|
|
||||||
PRINT_CONFIG_CLASS_DEFINE(
|
PRINT_CONFIG_CLASS_DEFINE(
|
||||||
@@ -707,6 +725,8 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||||||
((ConfigOptionFloats, machine_min_travel_rate))
|
((ConfigOptionFloats, machine_min_travel_rate))
|
||||||
// M205 S... [mm/sec]
|
// M205 S... [mm/sec]
|
||||||
((ConfigOptionFloats, machine_min_extruding_rate))
|
((ConfigOptionFloats, machine_min_extruding_rate))
|
||||||
|
//w37
|
||||||
|
((ConfigOptionBool, has_scarf_joint_seam))
|
||||||
)
|
)
|
||||||
|
|
||||||
PRINT_CONFIG_CLASS_DEFINE(
|
PRINT_CONFIG_CLASS_DEFINE(
|
||||||
|
|||||||
@@ -884,6 +884,16 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||||||
|| opt_key == "seam_gap"
|
|| opt_key == "seam_gap"
|
||||||
|| opt_key == "seam_preferred_direction"
|
|| opt_key == "seam_preferred_direction"
|
||||||
|| opt_key == "seam_preferred_direction_jitter"
|
|| opt_key == "seam_preferred_direction_jitter"
|
||||||
|
//w37
|
||||||
|
|| opt_key == "seam_slope_type"
|
||||||
|
|| opt_key == "seam_slope_conditional"
|
||||||
|
|| opt_key == "scarf_angle_threshold"
|
||||||
|
|| opt_key == "seam_slope_start_height"
|
||||||
|
|| opt_key == "seam_slope_entire_loop"
|
||||||
|
|| opt_key == "seam_slope_min_length"
|
||||||
|
|| opt_key == "seam_slope_steps"
|
||||||
|
|| opt_key == "seam_slope_inner_walls"
|
||||||
|
|
||||||
|| opt_key == "support_material_speed"
|
|| opt_key == "support_material_speed"
|
||||||
|| opt_key == "support_material_interface_speed"
|
|| opt_key == "support_material_interface_speed"
|
||||||
|| opt_key == "bridge_speed"
|
|| opt_key == "bridge_speed"
|
||||||
|
|||||||
@@ -380,6 +380,17 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
|||||||
bool is_top_one_wall = config->opt_enum<TopOneWallType>("top_one_wall_type") != TopOneWallType::Disable;
|
bool is_top_one_wall = config->opt_enum<TopOneWallType>("top_one_wall_type") != TopOneWallType::Disable;
|
||||||
toggle_field("top_area_threshold", is_top_one_wall);
|
toggle_field("top_area_threshold", is_top_one_wall);
|
||||||
|
|
||||||
|
//w37
|
||||||
|
toggle_field("seam_slope_type", !has_spiral_vase);
|
||||||
|
bool has_seam_slope = !has_spiral_vase && config->opt_enum<SeamScarfType>("seam_slope_type") != SeamScarfType::None;
|
||||||
|
toggle_field("seam_slope_conditional", has_seam_slope);
|
||||||
|
toggle_field("scarf_angle_threshold", has_seam_slope && config->opt_bool("seam_slope_conditional"));
|
||||||
|
toggle_field("seam_slope_start_height", has_seam_slope);
|
||||||
|
toggle_field("seam_slope_entire_loop", has_seam_slope);
|
||||||
|
toggle_field("seam_slope_min_length", has_seam_slope);
|
||||||
|
toggle_field("seam_slope_steps", has_seam_slope);
|
||||||
|
toggle_field("seam_slope_inner_walls", has_seam_slope);
|
||||||
|
toggle_field("seam_slope_min_length", !config->opt_bool("seam_slope_entire_loop"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigManipulation::toggle_print_sla_options(DynamicPrintConfig* config)
|
void ConfigManipulation::toggle_print_sla_options(DynamicPrintConfig* config)
|
||||||
|
|||||||
@@ -1465,6 +1465,18 @@ void TabPrint::build()
|
|||||||
//Y21
|
//Y21
|
||||||
optgroup->append_single_option_line("seam_gap", category_path + "seam-gap");
|
optgroup->append_single_option_line("seam_gap", category_path + "seam-gap");
|
||||||
optgroup->append_single_option_line("staggered_inner_seams", category_path + "staggered-inner-seams");
|
optgroup->append_single_option_line("staggered_inner_seams", category_path + "staggered-inner-seams");
|
||||||
|
|
||||||
|
//w37
|
||||||
|
optgroup->append_single_option_line("seam_slope_type");
|
||||||
|
optgroup->append_single_option_line("seam_slope_conditional");
|
||||||
|
optgroup->append_single_option_line("scarf_angle_threshold");
|
||||||
|
optgroup->append_single_option_line("seam_slope_start_height");
|
||||||
|
optgroup->append_single_option_line("seam_slope_entire_loop");
|
||||||
|
optgroup->append_single_option_line("seam_slope_min_length");
|
||||||
|
//optgroup->append_single_option_line("seam_slope_steps");
|
||||||
|
optgroup->append_single_option_line("seam_slope_inner_walls");
|
||||||
|
|
||||||
|
|
||||||
optgroup->append_single_option_line("external_perimeters_first", category_path + "external-perimeters-first");
|
optgroup->append_single_option_line("external_perimeters_first", category_path + "external-perimeters-first");
|
||||||
optgroup->append_single_option_line("gap_fill_enabled", category_path + "fill-gaps");
|
optgroup->append_single_option_line("gap_fill_enabled", category_path + "fill-gaps");
|
||||||
optgroup->append_single_option_line("perimeter_generator");
|
optgroup->append_single_option_line("perimeter_generator");
|
||||||
|
|||||||
Reference in New Issue
Block a user