mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-20 11:53:48 +00:00
Various ZAA fixes.
- Handle z contouring in variable speed flow when emitting GCode - Add logic to restore nominnal z height for regular extrusions - preserve z_contoured flag when splitting extrusion paths
This commit is contained in:
@@ -161,10 +161,11 @@ namespace AABBTreeLines {
|
|||||||
// on centroids of the lines.
|
// on centroids of the lines.
|
||||||
// Epsilon is applied to the bounding boxes of the AABB Tree to cope with numeric inaccuracies
|
// Epsilon is applied to the bounding boxes of the AABB Tree to cope with numeric inaccuracies
|
||||||
// during tree traversal.
|
// during tree traversal.
|
||||||
template <typename LineType>
|
template<typename LineType>
|
||||||
inline AABBTreeIndirect::Tree<2, typename LineType::Scalar> build_aabb_tree_over_indexed_lines(const std::vector<LineType>& lines)
|
inline AABBTreeIndirect::Tree<LineType::Dim, typename LineType::Scalar> build_aabb_tree_over_indexed_lines(
|
||||||
|
const std::vector<LineType>& lines)
|
||||||
{
|
{
|
||||||
using TreeType = AABBTreeIndirect::Tree<2, typename LineType::Scalar>;
|
using TreeType = AABBTreeIndirect::Tree<LineType::Dim, typename LineType::Scalar>;
|
||||||
// using CoordType = typename TreeType::CoordType;
|
// using CoordType = typename TreeType::CoordType;
|
||||||
using VectorType = typename TreeType::VectorType;
|
using VectorType = typename TreeType::VectorType;
|
||||||
using BoundingBox = typename TreeType::BoundingBox;
|
using BoundingBox = typename TreeType::BoundingBox;
|
||||||
@@ -303,7 +304,7 @@ namespace AABBTreeLines {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<LineType> lines;
|
std::vector<LineType> lines;
|
||||||
AABBTreeIndirect::Tree<2, Scalar> tree;
|
AABBTreeIndirect::Tree<LineType::Dim, Scalar> tree;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LinesDistancer(const std::vector<LineType>& lines)
|
explicit LinesDistancer(const std::vector<LineType>& lines)
|
||||||
@@ -321,15 +322,15 @@ namespace AABBTreeLines {
|
|||||||
LinesDistancer() = default;
|
LinesDistancer() = default;
|
||||||
|
|
||||||
// 1 true, -1 false, 0 cannot determine
|
// 1 true, -1 false, 0 cannot determine
|
||||||
int outside(const Vec<2, Scalar>& point) const { return point_outside_closed_contours(lines, tree, point); }
|
int outside(const Vec<LineType::Dim, Scalar>& point) const { return point_outside_closed_contours(lines, tree, point); }
|
||||||
|
|
||||||
// negative sign means inside
|
// negative sign means inside
|
||||||
template <bool SIGNED_DISTANCE>
|
template<bool SIGNED_DISTANCE>
|
||||||
std::tuple<Floating, size_t, Vec<2, Floating>> distance_from_lines_extra(const Vec<2, Scalar>& point) const
|
std::tuple<Floating, size_t, Vec<LineType::Dim, Floating>> distance_from_lines_extra(const Vec<LineType::Dim, Scalar>& point) const
|
||||||
{
|
{
|
||||||
size_t nearest_line_index_out = size_t(-1);
|
size_t nearest_line_index_out = size_t(-1);
|
||||||
Vec<2, Floating> nearest_point_out = Vec<2, Floating>::Zero();
|
Vec<LineType::Dim, Floating> nearest_point_out = Vec<LineType::Dim, Floating>::Zero();
|
||||||
Vec<2, Floating> p = point.template cast<Floating>();
|
Vec<LineType::Dim, Floating> p = point.template cast<Floating>();
|
||||||
auto distance = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, p, nearest_line_index_out, nearest_point_out);
|
auto distance = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, p, nearest_line_index_out, nearest_point_out);
|
||||||
|
|
||||||
if (distance < 0) {
|
if (distance < 0) {
|
||||||
@@ -344,22 +345,20 @@ namespace AABBTreeLines {
|
|||||||
return { distance, nearest_line_index_out, nearest_point_out };
|
return { distance, nearest_line_index_out, nearest_point_out };
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool SIGNED_DISTANCE>
|
template<bool SIGNED_DISTANCE> Floating distance_from_lines(const Vec<LineType::Dim, typename LineType::Scalar>& point) const
|
||||||
Floating distance_from_lines(const Vec<2, typename LineType::Scalar>& point) const
|
|
||||||
{
|
{
|
||||||
auto [dist, idx, np] = distance_from_lines_extra<SIGNED_DISTANCE>(point);
|
auto [dist, idx, np] = distance_from_lines_extra<SIGNED_DISTANCE>(point);
|
||||||
return dist;
|
return dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<size_t> all_lines_in_radius(const Vec<2, Scalar> &point, Floating radius)
|
std::vector<size_t> all_lines_in_radius(const Vec<LineType::Dim, Scalar>& point, Floating radius)
|
||||||
{
|
|
||||||
return AABBTreeLines::all_lines_in_radius(this->lines, this->tree, point.template cast<Floating>(), radius * radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <bool sorted>
|
|
||||||
std::vector<std::pair<Vec<2, Scalar>, size_t>> intersections_with_line(const LineType& line) const
|
|
||||||
{
|
{
|
||||||
return get_intersections_with_line<sorted, Vec<2, Scalar>>(lines, tree, line);
|
return AABBTreeLines::all_lines_in_radius(this->lines, this->tree, point.template cast<Floating>(), radius * radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool sorted> std::vector<std::pair<Vec<LineType::Dim, Scalar>, size_t>> intersections_with_line(const LineType& line) const
|
||||||
|
{
|
||||||
|
return get_intersections_with_line<sorted, Vec<LineType::Dim, Scalar>>(lines, tree, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
const LineType& get_line(size_t line_idx) const { return lines[line_idx]; }
|
const LineType& get_line(size_t line_idx) const { return lines[line_idx]; }
|
||||||
|
|||||||
@@ -225,8 +225,8 @@ static void handle_extrusion_collection(LayerRegion *region, const sla::IndexedM
|
|||||||
void Layer::make_contour_z(const sla::IndexedMesh &mesh)
|
void Layer::make_contour_z(const sla::IndexedMesh &mesh)
|
||||||
{
|
{
|
||||||
for (LayerRegion *region : this->regions()) {
|
for (LayerRegion *region : this->regions()) {
|
||||||
handle_extrusion_collection(region, mesh, region->fills, {erTopSolidInfill, erIroning, erExternalPerimeter, erMixed});
|
handle_extrusion_collection(region, mesh, region->fills, {erTopSolidInfill, erIroning, erPerimeter, erExternalPerimeter, erMixed});
|
||||||
handle_extrusion_collection(region, mesh, region->perimeters, {erExternalPerimeter, erMixed});
|
handle_extrusion_collection(region, mesh, region->perimeters, {erPerimeter, erExternalPerimeter, erMixed});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|||||||
@@ -192,6 +192,25 @@ inline Linesf to_unscaled_linesf(const ExPolygons &src)
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Linesf3 to_unscaled_linesf3(const ExPolygons& src)
|
||||||
|
{
|
||||||
|
Linesf3 lines;
|
||||||
|
lines.reserve(count_points(src));
|
||||||
|
for (ExPolygons::const_iterator it_expoly = src.begin(); it_expoly != src.end(); ++it_expoly) {
|
||||||
|
for (size_t i = 0; i <= it_expoly->holes.size(); ++i) {
|
||||||
|
const Points& points = ((i == 0) ? it_expoly->contour : it_expoly->holes[i - 1]).points;
|
||||||
|
Vec2d unscaled_a = unscaled(points.front());
|
||||||
|
Vec2d unscaled_b = unscaled_a;
|
||||||
|
for (Points::const_iterator it = points.begin() + 1; it != points.end(); ++it) {
|
||||||
|
unscaled_b = unscaled(*(it));
|
||||||
|
lines.push_back(Linef3(unscaled_a, unscaled_b, 0));
|
||||||
|
unscaled_a = unscaled_b;
|
||||||
|
}
|
||||||
|
lines.push_back(Linef3(unscaled_a, unscaled(points.front()), 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
inline Points to_points(const ExPolygons &src)
|
inline Points to_points(const ExPolygons &src)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -286,6 +286,7 @@ void ExtrusionLoop::split_at(const Point &point, bool prefer_non_overhang, const
|
|||||||
const ExtrusionPath &path = this->paths[path_idx];
|
const ExtrusionPath &path = this->paths[path_idx];
|
||||||
ExtrusionPath p1(path.role(), path.mm3_per_mm, path.width, path.height);
|
ExtrusionPath p1(path.role(), path.mm3_per_mm, path.width, path.height);
|
||||||
ExtrusionPath p2(path.role(), path.mm3_per_mm, path.width, path.height);
|
ExtrusionPath p2(path.role(), path.mm3_per_mm, path.width, path.height);
|
||||||
|
p1.z_contoured = p2.z_contoured = path.z_contoured;
|
||||||
path.polyline.split_at(p, &p1.polyline, &p2.polyline);
|
path.polyline.split_at(p, &p1.polyline, &p2.polyline);
|
||||||
|
|
||||||
if (this->paths.size() == 1) {
|
if (this->paths.size() == 1) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "BoundingBox.hpp"
|
#include "BoundingBox.hpp"
|
||||||
#include "Config.hpp"
|
#include "Config.hpp"
|
||||||
|
#include "GCodeWriter.hpp"
|
||||||
#include "Polygon.hpp"
|
#include "Polygon.hpp"
|
||||||
#include "PrintConfig.hpp"
|
#include "PrintConfig.hpp"
|
||||||
#include "libslic3r.h"
|
#include "libslic3r.h"
|
||||||
@@ -5817,7 +5818,7 @@ std::string GCode::extrude_loop(const ExtrusionLoop& loop_ref,
|
|||||||
const Point3 ¢er3 = paths.front().polyline.points.front();
|
const Point3 ¢er3 = paths.front().polyline.points.front();
|
||||||
pt.rotate(angle, Point(center3.x(), center3.y()));
|
pt.rotate(angle, Point(center3.x(), center3.y()));
|
||||||
// generate the travel move
|
// generate the travel move
|
||||||
gcode += m_writer.extrude_to_xy(this->point_to_gcode(pt), 0,"move inwards before travel",true);
|
gcode += m_writer.extrude_to_xy(this->point_to_gcode(pt), 0, "move inwards before travel", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return gcode;
|
return gcode;
|
||||||
@@ -6150,19 +6151,13 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||||||
// Move to first point of extrusion path
|
// Move to first point of extrusion path
|
||||||
// path is 2D. But in slope lift case, lift z is done in travel_to function.
|
// path is 2D. But in slope lift case, lift z is done in travel_to function.
|
||||||
// Add m_need_change_layer_lift_z when change_layer in case of no lift if m_last_pos is equal to path.first_point() by chance
|
// Add m_need_change_layer_lift_z when change_layer in case of no lift if m_last_pos is equal to path.first_point() by chance
|
||||||
Point3 first_point = path.first_point3();
|
Point first_point = path.first_point();
|
||||||
if (!m_last_pos_defined || m_last_pos != first_point || m_need_change_layer_lift_z || slope_need_z_travel) {
|
if (!m_last_pos_defined || m_last_pos.to_point() != first_point || m_need_change_layer_lift_z || slope_need_z_travel) {
|
||||||
const bool _last_pos_undefined = !m_last_pos_defined;
|
const bool _last_pos_undefined = !m_last_pos_defined;
|
||||||
double z = DBL_MAX;
|
|
||||||
if (sloped != nullptr) {
|
gcode += this->travel_to(path.first_point(), path.role(), "move to first " + description + " point",
|
||||||
z = get_sloped_z(sloped->slope_begin.z_ratio);
|
sloped == nullptr ? DBL_MAX : get_sloped_z(sloped->slope_begin.z_ratio));
|
||||||
} else if ((!m_last_pos_defined && first_point.z() != 0) || m_last_pos.z() != first_point.z()) {
|
|
||||||
z = m_nominal_z + unscale_(first_point.z());
|
|
||||||
if (z < 0.1) {
|
|
||||||
throw RuntimeError("GCode: very low z");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gcode += this->travel_to(path.first_point(), path.role(), "move to first " + description + " point", z);
|
|
||||||
m_need_change_layer_lift_z = false;
|
m_need_change_layer_lift_z = false;
|
||||||
// Orca: ensure Z matches planned layer height
|
// Orca: ensure Z matches planned layer height
|
||||||
if (_last_pos_undefined && !slope_need_z_travel) {
|
if (_last_pos_undefined && !slope_need_z_travel) {
|
||||||
@@ -6170,6 +6165,20 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (path.z_contoured && !path.polyline.lines().empty()) {
|
||||||
|
double current_z = m_writer.get_position().z();
|
||||||
|
;
|
||||||
|
double first_z = unscale_(path.polyline.lines().begin()->a.z()) + m_nominal_z;
|
||||||
|
if (GCodeFormatter::quantize_xyzf(first_z) != GCodeFormatter::quantize_xyzf(current_z)) {
|
||||||
|
gcode += m_writer.travel_to_z(first_z, "set Z for contouring", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!path.z_contoured) {
|
||||||
|
double current_z = m_writer.get_position().z();
|
||||||
|
if (GCodeFormatter::quantize_xyzf(current_z) != GCodeFormatter::quantize_xyzf(m_nominal_z)) {
|
||||||
|
gcode += this->writer().travel_to_z(m_nominal_z, "reset Z after contouring", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if needed, write the gcode_label_objects_end then gcode_label_objects_start
|
// if needed, write the gcode_label_objects_end then gcode_label_objects_start
|
||||||
// should be already done by travel_to, but just in case
|
// should be already done by travel_to, but just in case
|
||||||
@@ -6729,6 +6738,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||||||
if (!m_config.enable_arc_fitting || path.polyline.fitting_result.empty() || m_config.spiral_mode || sloped != nullptr || path.z_contoured) {
|
if (!m_config.enable_arc_fitting || path.polyline.fitting_result.empty() || m_config.spiral_mode || sloped != nullptr || path.z_contoured) {
|
||||||
double path_length = 0.;
|
double path_length = 0.;
|
||||||
double total_length = sloped == nullptr ? 0. : path.polyline.length() * SCALING_FACTOR;
|
double total_length = sloped == nullptr ? 0. : path.polyline.length() * SCALING_FACTOR;
|
||||||
|
double saved_z = m_writer.get_position().z();
|
||||||
|
|
||||||
for (const Line3& line : path.polyline.lines()) {
|
for (const Line3& line : path.polyline.lines()) {
|
||||||
std::string tempDescription = description;
|
std::string tempDescription = description;
|
||||||
const double line_length = line.length() * SCALING_FACTOR;
|
const double line_length = line.length() * SCALING_FACTOR;
|
||||||
@@ -6849,14 +6860,14 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||||||
double total_length = 0;
|
double total_length = 0;
|
||||||
if (sloped != nullptr) {
|
if (sloped != nullptr) {
|
||||||
// Calculate total extrusion length
|
// Calculate total extrusion length
|
||||||
Points p;
|
Points3 p;
|
||||||
p.reserve(new_points.size());
|
p.reserve(new_points.size());
|
||||||
std::transform(new_points.begin(), new_points.end(), std::back_inserter(p), [](const ProcessedPoint& pp) { return pp.p; });
|
std::transform(new_points.begin(), new_points.end(), std::back_inserter(p), [](const ProcessedPoint& pp) { return pp.p; });
|
||||||
Polyline l(p);
|
Polyline3 l(p);
|
||||||
total_length = l.length() * SCALING_FACTOR;
|
total_length = l.length() * SCALING_FACTOR;
|
||||||
}
|
}
|
||||||
gcode += m_writer.set_speed(last_set_speed, "", comment);
|
gcode += m_writer.set_speed(last_set_speed, "", comment);
|
||||||
Vec2d prev = this->point_to_gcode_quantized(new_points[0].p);
|
Vec3d prev = this->point_to_gcode_quantized(new_points[0].p);
|
||||||
bool pre_fan_enabled = false;
|
bool pre_fan_enabled = false;
|
||||||
bool cur_fan_enabled = false;
|
bool cur_fan_enabled = false;
|
||||||
if( m_enable_cooling_markers && enable_overhang_bridge_fan)
|
if( m_enable_cooling_markers && enable_overhang_bridge_fan)
|
||||||
@@ -6870,7 +6881,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||||||
std::string tempDescription = description;
|
std::string tempDescription = description;
|
||||||
const ProcessedPoint &processed_point = new_points[i];
|
const ProcessedPoint &processed_point = new_points[i];
|
||||||
const ProcessedPoint &pre_processed_point = new_points[i-1];
|
const ProcessedPoint &pre_processed_point = new_points[i-1];
|
||||||
Vec2d p = this->point_to_gcode_quantized(processed_point.p);
|
Vec3d p = this->point_to_gcode_quantized(processed_point.p);
|
||||||
if (m_enable_cooling_markers) {
|
if (m_enable_cooling_markers) {
|
||||||
if (enable_overhang_bridge_fan) {
|
if (enable_overhang_bridge_fan) {
|
||||||
cur_fan_enabled = check_overhang_fan(processed_point.overlap, path.role());
|
cur_fan_enabled = check_overhang_fan(processed_point.overlap, path.role());
|
||||||
@@ -6952,9 +6963,26 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||||||
tempDescription += Slic3r::format(" | Old Flow Value: %0.5f Length: %0.5f",oldE, line_length);
|
tempDescription += Slic3r::format(" | Old Flow Value: %0.5f Length: %0.5f",oldE, line_length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sloped == nullptr) {
|
if (path.z_contoured) {
|
||||||
|
Vec2d dest2d = p.head<2>();
|
||||||
|
coordf_t z_diff = unscale_(processed_point.p.z());
|
||||||
|
|
||||||
|
double extrusion_ratio = 1;
|
||||||
|
if (path.role() != erIroning) {
|
||||||
|
extrusion_ratio = (path.height + z_diff) / path.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
double e = dE * extrusion_ratio;
|
||||||
|
|
||||||
|
double z = m_nominal_z + z_diff;
|
||||||
|
if (z < 0.1) {
|
||||||
|
throw RuntimeError("GCode: very low z");
|
||||||
|
}
|
||||||
|
gcode += m_writer.extrude_to_xyz(Vec3d(dest2d.x(), dest2d.y(), z), e,
|
||||||
|
GCodeWriter::full_gcode_comment ? tempDescription : "");
|
||||||
|
} else if (sloped == nullptr) {
|
||||||
// Normal extrusion
|
// Normal extrusion
|
||||||
gcode += m_writer.extrude_to_xy(p, dE, GCodeWriter::full_gcode_comment ? tempDescription : "");
|
gcode += m_writer.extrude_to_xy(p.head<2>(), dE, GCodeWriter::full_gcode_comment ? tempDescription : "");
|
||||||
} else {
|
} else {
|
||||||
// Sloped extrusion
|
// Sloped extrusion
|
||||||
const auto [z_ratio, e_ratio] = sloped->interpolate(path_length / total_length);
|
const auto [z_ratio, e_ratio] = sloped->interpolate(path_length / total_length);
|
||||||
@@ -7811,6 +7839,13 @@ Vec2d GCode::point_to_gcode(const Point &point) const
|
|||||||
return unscale(point) + m_origin - extruder_offset;
|
return unscale(point) + m_origin - extruder_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec3d GCode::point_to_gcode(const Point3& point) const
|
||||||
|
{
|
||||||
|
Vec2d extruder_offset = EXTRUDER_CONFIG(extruder_offset);
|
||||||
|
Vec2d xy = unscale(point.to_point()) + m_origin - extruder_offset;
|
||||||
|
return Vec3d(xy.x(), xy.y(), unscale_(point.z()));
|
||||||
|
}
|
||||||
|
|
||||||
// convert a model-space scaled point into G-code coordinates
|
// convert a model-space scaled point into G-code coordinates
|
||||||
Point GCode::gcode_to_point(const Vec2d &point) const
|
Point GCode::gcode_to_point(const Vec2d &point) const
|
||||||
{
|
{
|
||||||
@@ -7828,6 +7863,11 @@ Vec2d GCode::point_to_gcode_quantized(const Point& point) const
|
|||||||
return { GCodeFormatter::quantize_xyzf(p.x()), GCodeFormatter::quantize_xyzf(p.y()) };
|
return { GCodeFormatter::quantize_xyzf(p.x()), GCodeFormatter::quantize_xyzf(p.y()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec3d GCode::point_to_gcode_quantized(const Point3& point) const
|
||||||
|
{
|
||||||
|
Vec3d p = this->point_to_gcode(point);
|
||||||
|
return {GCodeFormatter::quantize_xyzf(p.x()), GCodeFormatter::quantize_xyzf(p.y()), GCodeFormatter::quantize_xyzf(p.z())};
|
||||||
|
}
|
||||||
|
|
||||||
// Goes through by_region std::vector and returns reference to a subvector of entities, that are to be printed
|
// Goes through by_region std::vector and returns reference to a subvector of entities, that are to be printed
|
||||||
// during infill/perimeter wiping, or normally (depends on wiping_entities parameter)
|
// during infill/perimeter wiping, or normally (depends on wiping_entities parameter)
|
||||||
|
|||||||
@@ -223,8 +223,10 @@ public:
|
|||||||
void set_origin(const coordf_t x, const coordf_t y) { this->set_origin(Vec2d(x, y)); }
|
void set_origin(const coordf_t x, const coordf_t y) { this->set_origin(Vec2d(x, y)); }
|
||||||
Point last_pos() const { return m_last_pos.to_point(); }
|
Point last_pos() const { return m_last_pos.to_point(); }
|
||||||
Vec2d point_to_gcode(const Point &point) const;
|
Vec2d point_to_gcode(const Point &point) const;
|
||||||
|
Vec3d point_to_gcode(const Point3& point) const;
|
||||||
Point gcode_to_point(const Vec2d &point) const;
|
Point gcode_to_point(const Vec2d &point) const;
|
||||||
Vec2d point_to_gcode_quantized(const Point& point) const;
|
Vec2d point_to_gcode_quantized(const Point& point) const;
|
||||||
|
Vec3d point_to_gcode_quantized(const Point3& point) const;
|
||||||
const FullPrintConfig &config() const { return m_config; }
|
const FullPrintConfig &config() const { return m_config; }
|
||||||
const Layer* layer() const { return m_layer; }
|
const Layer* layer() const { return m_layer; }
|
||||||
GCodeWriter& writer() { return m_writer; }
|
GCodeWriter& writer() { return m_writer; }
|
||||||
|
|||||||
@@ -27,19 +27,19 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
struct ExtendedPoint
|
template<int Dim> struct ExtendedPoint
|
||||||
{
|
{
|
||||||
Vec2d position;
|
Eigen::Matrix<double, Dim, 1, Eigen::DontAlign> position;
|
||||||
float distance;
|
float distance;
|
||||||
float curvature;
|
float curvature;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<bool SCALED_INPUT, bool ADD_INTERSECTIONS, bool PREV_LAYER_BOUNDARY_OFFSET, bool SIGNED_DISTANCE, typename POINTS, typename L>
|
template<bool SCALED_INPUT, bool ADD_INTERSECTIONS, bool PREV_LAYER_BOUNDARY_OFFSET, bool SIGNED_DISTANCE, typename POINTS, typename L>
|
||||||
std::vector<ExtendedPoint> estimate_points_properties(const POINTS &input_points,
|
std::vector<ExtendedPoint<L::Dim>> estimate_points_properties(const POINTS& input_points,
|
||||||
const AABBTreeLines::LinesDistancer<L> &unscaled_prev_layer,
|
const AABBTreeLines::LinesDistancer<L>& unscaled_prev_layer,
|
||||||
float flow_width,
|
float flow_width,
|
||||||
float max_line_length = -1.0f,
|
float max_line_length = -1.0f,
|
||||||
float min_distance = -1.0f)
|
float min_distance = -1.0f)
|
||||||
{
|
{
|
||||||
bool looped = input_points.front() == input_points.back();
|
bool looped = input_points.front() == input_points.back();
|
||||||
std::function<size_t(size_t,size_t)> get_prev_index = [](size_t idx, size_t count) {
|
std::function<size_t(size_t,size_t)> get_prev_index = [](size_t idx, size_t count) {
|
||||||
@@ -78,47 +78,36 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||||||
double min_spacing = flow_width*0.25;
|
double min_spacing = flow_width*0.25;
|
||||||
|
|
||||||
using AABBScalar = typename AABBTreeLines::LinesDistancer<L>::Scalar;
|
using AABBScalar = typename AABBTreeLines::LinesDistancer<L>::Scalar;
|
||||||
|
using Vec = Eigen::Matrix<double, L::Dim, 1, Eigen::DontAlign>;
|
||||||
if (input_points.empty())
|
if (input_points.empty())
|
||||||
return {};
|
return {};
|
||||||
float boundary_offset = PREV_LAYER_BOUNDARY_OFFSET ? 0.5 * flow_width : 0.0f;
|
float boundary_offset = PREV_LAYER_BOUNDARY_OFFSET ? 0.5 * flow_width : 0.0f;
|
||||||
auto maybe_unscale = [](const P &p) -> Vec2d {
|
auto maybe_unscale = [](const P& p) -> Vec { return SCALED_INPUT ? unscaled(p) : p.template cast<double>(); };
|
||||||
if constexpr (P::RowsAtCompileTime == 3) {
|
|
||||||
// 3D point - extract XY only
|
|
||||||
if constexpr (SCALED_INPUT) {
|
|
||||||
return unscaled(p).template head<2>();
|
|
||||||
} else {
|
|
||||||
return p.template head<2>().template cast<double>();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 2D point - use as is
|
|
||||||
return SCALED_INPUT ? unscaled(p) : p.template cast<double>();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<ExtendedPoint> points;
|
std::vector<ExtendedPoint<L::Dim>> points;
|
||||||
points.reserve(input_points.size() * (ADD_INTERSECTIONS ? 1.5 : 1));
|
points.reserve(input_points.size() * (ADD_INTERSECTIONS ? 1.5 : 1));
|
||||||
|
|
||||||
{
|
{
|
||||||
ExtendedPoint start_point{maybe_unscale(input_points.front())};
|
ExtendedPoint<L::Dim> start_point{maybe_unscale(input_points.front())};
|
||||||
auto [distance, nearest_line,
|
auto [distance, nearest_line, x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(
|
||||||
x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(start_point.position.cast<AABBScalar>());
|
start_point.position.template cast<AABBScalar>());
|
||||||
start_point.distance = distance + boundary_offset;
|
start_point.distance = distance + boundary_offset;
|
||||||
points.push_back(start_point);
|
points.push_back(start_point);
|
||||||
}
|
}
|
||||||
for (size_t i = 1; i < input_points.size(); i++) {
|
for (size_t i = 1; i < input_points.size(); i++) {
|
||||||
ExtendedPoint next_point{maybe_unscale(input_points[i])};
|
ExtendedPoint<L::Dim> next_point{maybe_unscale(input_points[i])};
|
||||||
auto [distance, nearest_line,
|
auto [distance, nearest_line,
|
||||||
x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(next_point.position.cast<AABBScalar>());
|
x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(next_point.position.template cast<AABBScalar>());
|
||||||
next_point.distance = distance + boundary_offset;
|
next_point.distance = distance + boundary_offset;
|
||||||
|
|
||||||
// Intersection handling
|
// Intersection handling
|
||||||
if (ADD_INTERSECTIONS &&
|
if (ADD_INTERSECTIONS &&
|
||||||
((points.back().distance > boundary_offset + EPSILON) != (next_point.distance > boundary_offset + EPSILON))) {
|
((points.back().distance > boundary_offset + EPSILON) != (next_point.distance > boundary_offset + EPSILON))) {
|
||||||
const ExtendedPoint &prev_point = points.back();
|
const ExtendedPoint<L::Dim>& prev_point = points.back();
|
||||||
auto intersections = unscaled_prev_layer.template intersections_with_line<true>(
|
auto intersections = unscaled_prev_layer.template intersections_with_line<true>(
|
||||||
L{prev_point.position.cast<AABBScalar>(), next_point.position.cast<AABBScalar>()});
|
L{prev_point.position.template cast<AABBScalar>(), next_point.position.template cast<AABBScalar>()});
|
||||||
for (const auto &intersection : intersections) {
|
for (const auto &intersection : intersections) {
|
||||||
ExtendedPoint p{};
|
ExtendedPoint<L::Dim> p{};
|
||||||
p.position = intersection.first.template cast<double>();
|
p.position = intersection.first.template cast<double>();
|
||||||
p.distance = boundary_offset;
|
p.distance = boundary_offset;
|
||||||
// ORCA: Filter out points that are introduced at intersections if their distance from the previous or next point is not meaningful
|
// ORCA: Filter out points that are introduced at intersections if their distance from the previous or next point is not meaningful
|
||||||
@@ -133,12 +122,12 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||||||
|
|
||||||
// Segmentation handling
|
// Segmentation handling
|
||||||
if (PREV_LAYER_BOUNDARY_OFFSET && ADD_INTERSECTIONS) {
|
if (PREV_LAYER_BOUNDARY_OFFSET && ADD_INTERSECTIONS) {
|
||||||
std::vector<ExtendedPoint> new_points;
|
std::vector<ExtendedPoint<L::Dim>> new_points;
|
||||||
new_points.reserve(points.size() * 2);
|
new_points.reserve(points.size() * 2);
|
||||||
new_points.push_back(points.front());
|
new_points.push_back(points.front());
|
||||||
for (int point_idx = 0; point_idx < int(points.size()) - 1; ++point_idx) {
|
for (int point_idx = 0; point_idx < int(points.size()) - 1; ++point_idx) {
|
||||||
const ExtendedPoint &curr = points[point_idx];
|
const ExtendedPoint<L::Dim>& curr = points[point_idx];
|
||||||
const ExtendedPoint &next = points[point_idx + 1];
|
const ExtendedPoint<L::Dim>& next = points[point_idx + 1];
|
||||||
|
|
||||||
if ((curr.distance > -boundary_offset && curr.distance < boundary_offset + 2.0f) ||
|
if ((curr.distance > -boundary_offset && curr.distance < boundary_offset + 2.0f) ||
|
||||||
(next.distance > -boundary_offset && next.distance < boundary_offset + 2.0f)) {
|
(next.distance > -boundary_offset && next.distance < boundary_offset + 2.0f)) {
|
||||||
@@ -156,10 +145,10 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||||||
double t1 = std::max(a0, a1);
|
double t1 = std::max(a0, a1);
|
||||||
|
|
||||||
if (t0 < 1.0) {
|
if (t0 < 1.0) {
|
||||||
Vec2d p0 = curr.position + t0 * (next.position - curr.position);
|
Vec p0 = curr.position + t0 * (next.position - curr.position);
|
||||||
auto [p0_dist, p0_near_l,
|
auto [p0_dist, p0_near_l, p0_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(
|
||||||
p0_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(p0.cast<AABBScalar>());
|
p0.template cast<AABBScalar>());
|
||||||
ExtendedPoint new_p{};
|
ExtendedPoint<L::Dim> new_p{};
|
||||||
new_p.position = p0;
|
new_p.position = p0;
|
||||||
new_p.distance = float(p0_dist + boundary_offset);
|
new_p.distance = float(p0_dist + boundary_offset);
|
||||||
// ORCA: only create a new point in the path if the new point overhang distance will be used to generate a speed change
|
// ORCA: only create a new point in the path if the new point overhang distance will be used to generate a speed change
|
||||||
@@ -173,10 +162,10 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (t1 > 0.0) {
|
if (t1 > 0.0) {
|
||||||
Vec2d p1 = curr.position + t1 * (next.position - curr.position);
|
Vec p1 = curr.position + t1 * (next.position - curr.position);
|
||||||
auto [p1_dist, p1_near_l,
|
auto [p1_dist, p1_near_l, p1_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(
|
||||||
p1_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(p1.cast<AABBScalar>());
|
p1.template cast<AABBScalar>());
|
||||||
ExtendedPoint new_p{};
|
ExtendedPoint<L::Dim> new_p{};
|
||||||
new_p.position = p1;
|
new_p.position = p1;
|
||||||
new_p.distance = float(p1_dist + boundary_offset);
|
new_p.distance = float(p1_dist + boundary_offset);
|
||||||
// ORCA: only create a new point in the path if the new point overhang distance will be used to generate a speed change
|
// ORCA: only create a new point in the path if the new point overhang distance will be used to generate a speed change
|
||||||
@@ -198,21 +187,21 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||||||
|
|
||||||
// Maximum line length handling
|
// Maximum line length handling
|
||||||
if (max_line_length > 0) {
|
if (max_line_length > 0) {
|
||||||
std::vector<ExtendedPoint> new_points;
|
std::vector<ExtendedPoint<L::Dim>> new_points;
|
||||||
new_points.reserve(points.size() * 2);
|
new_points.reserve(points.size() * 2);
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i + 1 < points.size(); i++) {
|
for (size_t i = 0; i + 1 < points.size(); i++) {
|
||||||
const ExtendedPoint &curr = points[i];
|
const ExtendedPoint<L::Dim>& curr = points[i];
|
||||||
const ExtendedPoint &next = points[i + 1];
|
const ExtendedPoint<L::Dim>& next = points[i + 1];
|
||||||
new_points.push_back(curr);
|
new_points.push_back(curr);
|
||||||
double len = (next.position - curr.position).squaredNorm();
|
double len = (next.position - curr.position).squaredNorm();
|
||||||
double t = sqrt((max_line_length * max_line_length) / len);
|
double t = sqrt((max_line_length * max_line_length) / len);
|
||||||
size_t new_point_count = 1.0 / t;
|
size_t new_point_count = 1.0 / t;
|
||||||
for (size_t j = 1; j < new_point_count + 1; j++) {
|
for (size_t j = 1; j < new_point_count + 1; j++) {
|
||||||
Vec2d pos = curr.position * (1.0 - j * t) + next.position * (j * t);
|
Vec pos = curr.position * (1.0 - j * t) + next.position * (j * t);
|
||||||
auto [p_dist, p_near_l,
|
auto [p_dist, p_near_l,
|
||||||
p_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(pos.cast<AABBScalar>());
|
p_x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(pos.template cast<AABBScalar>());
|
||||||
ExtendedPoint new_p{};
|
ExtendedPoint<L::Dim> new_p{};
|
||||||
new_p.position = pos;
|
new_p.position = pos;
|
||||||
new_p.distance = float(p_dist + boundary_offset);
|
new_p.distance = float(p_dist + boundary_offset);
|
||||||
|
|
||||||
@@ -231,8 +220,8 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||||||
float accumulated_distance = 0;
|
float accumulated_distance = 0;
|
||||||
std::vector<float> distances_for_curvature(points.size());
|
std::vector<float> distances_for_curvature(points.size());
|
||||||
for (size_t point_idx = 0; point_idx < points.size(); ++point_idx) {
|
for (size_t point_idx = 0; point_idx < points.size(); ++point_idx) {
|
||||||
const ExtendedPoint &a = points[point_idx];
|
const ExtendedPoint<L::Dim>& a = points[point_idx];
|
||||||
const ExtendedPoint &b = points[get_prev_index(point_idx, points.size())];
|
const ExtendedPoint<L::Dim>& b = points[get_prev_index(point_idx, points.size())];
|
||||||
|
|
||||||
distances_for_curvature[point_idx] = (b.position - a.position).norm();
|
distances_for_curvature[point_idx] = (b.position - a.position).norm();
|
||||||
accumulated_distance += distances_for_curvature[point_idx];
|
accumulated_distance += distances_for_curvature[point_idx];
|
||||||
@@ -241,9 +230,9 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||||||
if (accumulated_distance > EPSILON)
|
if (accumulated_distance > EPSILON)
|
||||||
for (float window_size : {3.0f, 9.0f, 16.0f}) {
|
for (float window_size : {3.0f, 9.0f, 16.0f}) {
|
||||||
for (int point_idx = 0; point_idx < int(points.size()); ++point_idx) {
|
for (int point_idx = 0; point_idx < int(points.size()); ++point_idx) {
|
||||||
ExtendedPoint ¤t = points[point_idx];
|
ExtendedPoint<L::Dim>& current = points[point_idx];
|
||||||
|
|
||||||
Vec2d back_position = current.position;
|
Vec back_position = current.position;
|
||||||
{
|
{
|
||||||
size_t back_point_index = point_idx;
|
size_t back_point_index = point_idx;
|
||||||
float dist_backwards = 0;
|
float dist_backwards = 0;
|
||||||
@@ -263,7 +252,7 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2d front_position = current.position;
|
Vec front_position = current.position;
|
||||||
{
|
{
|
||||||
size_t front_point_index = point_idx;
|
size_t front_point_index = point_idx;
|
||||||
float dist_forwards = 0;
|
float dist_forwards = 0;
|
||||||
@@ -283,7 +272,9 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float new_curvature = angle(current.position - back_position, front_position - current.position) / window_size;
|
float new_curvature = angle((current.position - back_position).template head<2>(),
|
||||||
|
(front_position - current.position).template head<2>()) /
|
||||||
|
window_size;
|
||||||
if (abs(current.curvature) < abs(new_curvature)) {
|
if (abs(current.curvature) < abs(new_curvature)) {
|
||||||
current.curvature = new_curvature;
|
current.curvature = new_curvature;
|
||||||
}
|
}
|
||||||
@@ -295,15 +286,15 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
|
|||||||
|
|
||||||
struct ProcessedPoint
|
struct ProcessedPoint
|
||||||
{
|
{
|
||||||
Point p;
|
Point3 p;
|
||||||
float speed = 1.0f;
|
float speed = 1.0f;
|
||||||
float overlap = 1.0f;
|
float overlap = 1.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExtrusionQualityEstimator
|
class ExtrusionQualityEstimator
|
||||||
{
|
{
|
||||||
std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<Linef>> prev_layer_boundaries;
|
std::unordered_map<const PrintObject*, AABBTreeLines::LinesDistancer<Linef3>> prev_layer_boundaries;
|
||||||
std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<Linef>> next_layer_boundaries;
|
std::unordered_map<const PrintObject*, AABBTreeLines::LinesDistancer<Linef3>> next_layer_boundaries;
|
||||||
std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<CurledLine>> prev_curled_extrusions;
|
std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<CurledLine>> prev_curled_extrusions;
|
||||||
std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<CurledLine>> next_curled_extrusions;
|
std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<CurledLine>> next_curled_extrusions;
|
||||||
const PrintObject *current_object;
|
const PrintObject *current_object;
|
||||||
@@ -316,7 +307,7 @@ public:
|
|||||||
if (layer == nullptr) return;
|
if (layer == nullptr) return;
|
||||||
const PrintObject *object = obj;
|
const PrintObject *object = obj;
|
||||||
prev_layer_boundaries[object] = next_layer_boundaries[object];
|
prev_layer_boundaries[object] = next_layer_boundaries[object];
|
||||||
next_layer_boundaries[object] = AABBTreeLines::LinesDistancer<Linef>{to_unscaled_linesf(layer->lslices)};
|
next_layer_boundaries[object] = AABBTreeLines::LinesDistancer<Linef3>{to_unscaled_linesf3(layer->lslices)};
|
||||||
prev_curled_extrusions[object] = next_curled_extrusions[object];
|
prev_curled_extrusions[object] = next_curled_extrusions[object];
|
||||||
next_curled_extrusions[object] = AABBTreeLines::LinesDistancer<CurledLine>{layer->curled_lines};
|
next_curled_extrusions[object] = AABBTreeLines::LinesDistancer<CurledLine>{layer->curled_lines};
|
||||||
}
|
}
|
||||||
@@ -371,56 +362,54 @@ public:
|
|||||||
smallest_distance_with_lower_speed=-1.f;
|
smallest_distance_with_lower_speed=-1.f;
|
||||||
|
|
||||||
// Orca: Pass to the point properties estimator the smallest ovehang distance that triggers a slowdown (smallest_distance_with_lower_speed)
|
// Orca: Pass to the point properties estimator the smallest ovehang distance that triggers a slowdown (smallest_distance_with_lower_speed)
|
||||||
std::vector<ExtendedPoint> extended_points = estimate_points_properties<true, true, true, true>
|
std::vector<ExtendedPoint<3>> extended_points =
|
||||||
(path.polyline.points,
|
estimate_points_properties<true, true, true, true>(path.polyline.points, prev_layer_boundaries[current_object], path.width, -1,
|
||||||
prev_layer_boundaries[current_object],
|
smallest_distance_with_lower_speed);
|
||||||
path.width,
|
|
||||||
-1,
|
|
||||||
smallest_distance_with_lower_speed);
|
|
||||||
const auto width_inv = 1.0f / path.width;
|
const auto width_inv = 1.0f / path.width;
|
||||||
std::vector<ProcessedPoint> processed_points;
|
std::vector<ProcessedPoint> processed_points;
|
||||||
processed_points.reserve(extended_points.size());
|
processed_points.reserve(extended_points.size());
|
||||||
for (size_t i = 0; i < extended_points.size(); i++) {
|
for (size_t i = 0; i < extended_points.size(); i++) {
|
||||||
const ExtendedPoint &curr = extended_points[i];
|
const ExtendedPoint<3>& curr = extended_points[i];
|
||||||
const ExtendedPoint &next = extended_points[i + 1 < extended_points.size() ? i + 1 : i];
|
const ExtendedPoint<3>& next = extended_points[i + 1 < extended_points.size() ? i + 1 : i];
|
||||||
|
|
||||||
float artificial_distance_to_curled_lines = 0.0;
|
float artificial_distance_to_curled_lines = 0.0;
|
||||||
if(slowdown_for_curled_edges) {
|
if(slowdown_for_curled_edges) {
|
||||||
// The following code artifically increases the distance to provide slowdown for extrusions that are over curled lines
|
// The following code artifically increases the distance to provide slowdown for extrusions that are over curled lines
|
||||||
const double dist_limit = 10.0 * path.width;
|
const double dist_limit = 10.0 * path.width;
|
||||||
{
|
{
|
||||||
Vec2d middle = 0.5 * (curr.position + next.position);
|
Vec3d middle = 0.5 * (curr.position + next.position);
|
||||||
auto line_indices = prev_curled_extrusions[current_object].all_lines_in_radius(Point::new_scale(middle), scale_(dist_limit));
|
auto line_indices = prev_curled_extrusions[current_object].all_lines_in_radius(Point::new_scale(middle),
|
||||||
if (!line_indices.empty()) {
|
scale_(dist_limit));
|
||||||
double len = (next.position - curr.position).norm();
|
if (!line_indices.empty()) {
|
||||||
// For long lines, there is a problem with the additional slowdown. If by accident, there is small curled line near the middle of this long line
|
double len = (next.position - curr.position).norm();
|
||||||
|
// For long lines, there is a problem with the additional slowdown. If by accident, there is small curled line near the middle of this long line
|
||||||
// The whole segment gets slower unnecesarily. For these long lines, we do additional check whether it is worth slowing down.
|
// The whole segment gets slower unnecesarily. For these long lines, we do additional check whether it is worth slowing down.
|
||||||
// NOTE that this is still quite rough approximation, e.g. we are still checking lines only near the middle point
|
// NOTE that this is still quite rough approximation, e.g. we are still checking lines only near the middle point
|
||||||
// TODO maybe split the lines into smaller segments before running this alg? but can be demanding, and GCode will be huge
|
// TODO maybe split the lines into smaller segments before running this alg? but can be demanding, and GCode will be huge
|
||||||
if (len > 2) {
|
if (len > 2) {
|
||||||
Vec2d dir = Vec2d(next.position - curr.position) / len;
|
Vec2d dir = Vec2d(next.position.head<2>() - curr.position.head<2>()) / len;
|
||||||
Vec2d right = Vec2d(-dir.y(), dir.x());
|
Vec2d right = Vec2d(-dir.y(), dir.x());
|
||||||
|
|
||||||
Polygon box_of_influence = {
|
Polygon box_of_influence = {
|
||||||
scaled(Vec2d(curr.position + right * dist_limit)),
|
scaled(Vec2d(curr.position.head<2>() + right * dist_limit)),
|
||||||
scaled(Vec2d(next.position + right * dist_limit)),
|
scaled(Vec2d(next.position.head<2>() + right * dist_limit)),
|
||||||
scaled(Vec2d(next.position - right * dist_limit)),
|
scaled(Vec2d(next.position.head<2>() - right * dist_limit)),
|
||||||
scaled(Vec2d(curr.position - right * dist_limit)),
|
scaled(Vec2d(curr.position.head<2>() - right * dist_limit)),
|
||||||
};
|
};
|
||||||
|
|
||||||
double projected_lengths_sum = 0;
|
double projected_lengths_sum = 0;
|
||||||
for (size_t idx : line_indices) {
|
for (size_t idx : line_indices) {
|
||||||
const CurledLine &line = prev_curled_extrusions[current_object].get_line(idx);
|
const CurledLine& line = prev_curled_extrusions[current_object].get_line(idx);
|
||||||
Lines inside = intersection_ln({{line.a, line.b}}, {box_of_influence});
|
Lines inside = intersection_ln({{line.a, line.b}}, {box_of_influence});
|
||||||
if (inside.empty())
|
if (inside.empty())
|
||||||
continue;
|
continue;
|
||||||
double projected_length = abs(dir.dot(unscaled(Vec2d((inside.back().b - inside.back().a).cast<double>()))));
|
double projected_length = abs(dir.dot(unscaled(Vec2d((inside.back().b - inside.back().a).cast<double>()))));
|
||||||
projected_lengths_sum += projected_length;
|
projected_lengths_sum += projected_length;
|
||||||
}
|
}
|
||||||
if (projected_lengths_sum < 0.4 * len) {
|
if (projected_lengths_sum < 0.4 * len) {
|
||||||
line_indices.clear();
|
line_indices.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t idx : line_indices) {
|
for (size_t idx : line_indices) {
|
||||||
const CurledLine &line = prev_curled_extrusions[current_object].get_line(idx);
|
const CurledLine &line = prev_curled_extrusions[current_object].get_line(idx);
|
||||||
@@ -430,9 +419,9 @@ public:
|
|||||||
(line.curled_height / (path.height * 10.0f)); // max_curled_height_factor from SupportSpotGenerator
|
(line.curled_height / (path.height * 10.0f)); // max_curled_height_factor from SupportSpotGenerator
|
||||||
artificial_distance_to_curled_lines = std::max(artificial_distance_to_curled_lines, dist);
|
artificial_distance_to_curled_lines = std::max(artificial_distance_to_curled_lines, dist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto calculate_speed = [&speed_sections, &original_speed](float distance) {
|
auto calculate_speed = [&speed_sections, &original_speed](float distance) {
|
||||||
float final_speed;
|
float final_speed;
|
||||||
@@ -464,8 +453,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
float overlap = std::min(1 - (curr.distance+artificial_distance_to_curled_lines) * width_inv, 1 - (next.distance+artificial_distance_to_curled_lines) * width_inv);
|
float overlap = std::min(1 - (curr.distance+artificial_distance_to_curled_lines) * width_inv, 1 - (next.distance+artificial_distance_to_curled_lines) * width_inv);
|
||||||
|
|
||||||
processed_points.push_back({ scaled(curr.position), extrusion_speed, overlap });
|
processed_points.push_back({Point3(scaled(curr.position)), extrusion_speed, overlap});
|
||||||
}
|
}
|
||||||
return processed_points;
|
return processed_points;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -271,6 +271,7 @@ class Linef3
|
|||||||
public:
|
public:
|
||||||
Linef3() : a(Vec3d::Zero()), b(Vec3d::Zero()) {}
|
Linef3() : a(Vec3d::Zero()), b(Vec3d::Zero()) {}
|
||||||
Linef3(const Vec3d& _a, const Vec3d& _b) : a(_a), b(_b) {}
|
Linef3(const Vec3d& _a, const Vec3d& _b) : a(_a), b(_b) {}
|
||||||
|
Linef3(const Vec2d& _a, const Vec2d& _b, double z) : a(Vec3d(_a.x(), _a.y(), z)), b(Vec3d(_b.x(), _b.y(), z)) {}
|
||||||
|
|
||||||
Vec3d intersect_plane(double z) const;
|
Vec3d intersect_plane(double z) const;
|
||||||
void scale(double factor) { this->a *= factor; this->b *= factor; }
|
void scale(double factor) { this->a *= factor; this->b *= factor; }
|
||||||
@@ -311,6 +312,8 @@ public:
|
|||||||
using Scalar = Vec3d::Scalar;
|
using Scalar = Vec3d::Scalar;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using Linesf3 = std::vector<Linef3>;
|
||||||
|
|
||||||
BoundingBox get_extents(const Lines &lines);
|
BoundingBox get_extents(const Lines &lines);
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ public:
|
|||||||
Point3(int64_t x, int64_t y, int64_t z = 0) : Vec3crd(coord_t(x), coord_t(y), coord_t(z)) {}
|
Point3(int64_t x, int64_t y, int64_t z = 0) : Vec3crd(coord_t(x), coord_t(y), coord_t(z)) {}
|
||||||
Point3(double x, double y, double z = 0.0) : Vec3crd(coord_t(std::round(x)), coord_t(std::round(y)), coord_t(std::round(z))) {}
|
Point3(double x, double y, double z = 0.0) : Vec3crd(coord_t(std::round(x)), coord_t(std::round(y)), coord_t(std::round(z))) {}
|
||||||
Point3(const Point3 &rhs) { *this = rhs; }
|
Point3(const Point3 &rhs) { *this = rhs; }
|
||||||
explicit Point3(const Point &rhs, coord_t z = 0) : Vec3crd(rhs.x(), rhs.y(), z) {}
|
explicit Point3(const Vec2crd& vec2crd, coord_t z = 0) : Vec3crd(vec2crd.x(), vec2crd.y(), z) {}
|
||||||
explicit Point3(const Vec3crd &vec3crd) : Vec3crd(vec3crd) {}
|
explicit Point3(const Vec3crd &vec3crd) : Vec3crd(vec3crd) {}
|
||||||
// This constructor allows you to construct Point from Eigen expressions
|
// This constructor allows you to construct Point from Eigen expressions
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
|
|||||||
@@ -165,8 +165,8 @@ void estimate_malformations(LayerPtrs &layers, const Params ¶ms)
|
|||||||
flow_width,
|
flow_width,
|
||||||
params.bridge_distance);
|
params.bridge_distance);
|
||||||
for (size_t i = 0; i < annotated_points.size(); ++i) {
|
for (size_t i = 0; i < annotated_points.size(); ++i) {
|
||||||
const ExtendedPoint &a = i > 0 ? annotated_points[i - 1] : annotated_points[i];
|
const ExtendedPoint<2>& a = i > 0 ? annotated_points[i - 1] : annotated_points[i];
|
||||||
const ExtendedPoint &b = annotated_points[i];
|
const ExtendedPoint<2>& b = annotated_points[i];
|
||||||
ExtrusionLine line_out{a.position.cast<float>(), b.position.cast<float>(), float((a.position - b.position).norm()),
|
ExtrusionLine line_out{a.position.cast<float>(), b.position.cast<float>(), float((a.position - b.position).norm()),
|
||||||
extrusion};
|
extrusion};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user