mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-01 15:22:21 +00:00
ENH: Use the real prime tower model after slicing.
1. set wipe tower real height 2. fix wipe tower small arc error 3. add rib_width constraint to ensure that the rib wall of the wipetower are attached to the infill. jira: STUDIO-10540 Change-Id: Idfdc809f0236121d98587ac2a09a2ebbf5caf945 (cherry picked from commit 3a7dcfd23249571224a4d538c55907a0a5c6154d)
This commit is contained in:
@@ -642,9 +642,9 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
// We want to rotate and shift all extrusions (gcode postprocessing) and starting and ending position
|
||||
float alpha = m_wipe_tower_rotation / 180.f * float(M_PI);
|
||||
|
||||
auto transform_wt_pt = [&alpha, this](const Vec2f& pt,bool rib_offset=true) -> Vec2f {
|
||||
auto transform_wt_pt = [&alpha, this](const Vec2f& pt) -> Vec2f {
|
||||
Vec2f out = Eigen::Rotation2Df(alpha) * pt;
|
||||
out += m_wipe_tower_pos + (rib_offset? m_rib_offset:Vec2f(0.f,0.f));
|
||||
out += m_wipe_tower_pos + m_rib_offset;
|
||||
return out;
|
||||
};
|
||||
|
||||
@@ -877,7 +877,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
avoid_bbx = scaled(m_wipe_tower_bbx);
|
||||
Polygon avoid_points = avoid_bbx.polygon();
|
||||
for (auto& p : avoid_points.points) {
|
||||
Vec2f pp = transform_wt_pt(unscale(p).cast<float>(),false);
|
||||
Vec2f pp = transform_wt_pt(unscale(p).cast<float>());
|
||||
p = wipe_tower_point_to_object_point(gcodegen, pp + plate_origin_2d);
|
||||
}
|
||||
avoid_bbx = BoundingBox(avoid_points.points);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "GCodeProcessor.hpp"
|
||||
#include "BoundingBox.hpp"
|
||||
#include "LocalesUtils.hpp"
|
||||
#include "Triangulation.hpp"
|
||||
|
||||
|
||||
namespace Slic3r
|
||||
@@ -18,7 +19,9 @@ bool flat_ironing = true; // Whether to ena
|
||||
static constexpr float flat_iron_area = 4.f;
|
||||
constexpr float flat_iron_speed = 10.f * 60.f;
|
||||
static const double wipe_tower_wall_infill_overlap = 0.0;
|
||||
static constexpr double WIPE_TOWER_RESOLUTION = 0.0375;
|
||||
static constexpr double WIPE_TOWER_RESOLUTION = 0.1;
|
||||
#define WT_SIMPLIFY_TOLERANCE_SCALED (0.001 / SCALING_FACTOR)
|
||||
static constexpr int arc_fit_size = 20;
|
||||
#define SCALED_WIPE_TOWER_RESOLUTION (WIPE_TOWER_RESOLUTION / SCALING_FACTOR)
|
||||
inline float align_round(float value, float base)
|
||||
{
|
||||
@@ -98,7 +101,7 @@ static Polygon chamfer_polygon(Polygon &polygon, double chamfer_dis = 2., double
|
||||
return res;
|
||||
}
|
||||
|
||||
static Polygon rounding_polygon(Polygon &polygon, double rounding = 2., double angle_tol = 30. / 180. * PI)
|
||||
Polygon WipeTower::rounding_polygon(Polygon &polygon, double rounding /*= 2.*/, double angle_tol/* = 30. / 180. * PI*/)
|
||||
{
|
||||
if (polygon.points.size() < 3) return polygon;
|
||||
Polygon res;
|
||||
@@ -140,8 +143,7 @@ static Polygon rounding_polygon(Polygon &polygon, double rounding = 2., double a
|
||||
Vec2d center = b + dir * dis;
|
||||
double radius = (left - center).norm();
|
||||
ArcSegment arc(scaled(center), scaled(radius), scaled(left), scaled(right), is_ccw ? ArcDirection::Arc_Dir_CCW : ArcDirection::Arc_Dir_CW);
|
||||
float sample_angle = 5.f / 180.f * PI;
|
||||
int n = std::ceil(abs(arc.angle_radians) / sample_angle);
|
||||
int n = arc_fit_size;
|
||||
//std::cout << "start " << arc.start_point[0] << " " << arc.start_point[1] << std::endl;
|
||||
//std::cout << "end " << arc.end_point[0] << " " << arc.end_point[1] << std::endl;
|
||||
//std::cout << "start angle " << arc.polar_start_theta << " end angle " << arc.polar_end_theta << std::endl;
|
||||
@@ -162,6 +164,7 @@ static Polygon rounding_polygon(Polygon &polygon, double rounding = 2., double a
|
||||
} else
|
||||
res.points.push_back(polygon.points[i]);
|
||||
}
|
||||
res.remove_duplicate_points();
|
||||
res.points.shrink_to_fit();
|
||||
return res;
|
||||
}
|
||||
@@ -198,8 +201,7 @@ static Polygon rounding_rectangle(Polygon &polygon, double rounding = 2., double
|
||||
Vec2d center = b;
|
||||
double radius = real_rounding_dis;
|
||||
ArcSegment arc(scaled(center), scaled(radius), scaled(left), scaled(right), is_ccw ? ArcDirection::Arc_Dir_CCW : ArcDirection::Arc_Dir_CW);
|
||||
float sample_angle = 5.f / 180.f * PI;
|
||||
int n = std::ceil(abs(arc.angle_radians) / sample_angle);
|
||||
int n = arc_fit_size;
|
||||
// std::cout << "start " << arc.start_point[0] << " " << arc.start_point[1] << std::endl;
|
||||
// std::cout << "end " << arc.end_point[0] << " " << arc.end_point[1] << std::endl;
|
||||
// std::cout << "start angle " << arc.polar_start_theta << " end angle " << arc.polar_end_theta << std::endl;
|
||||
@@ -724,9 +726,7 @@ public:
|
||||
width += m_layer_height * float(1. - M_PI / 4.);
|
||||
if (m_extrusions.empty() || m_extrusions.back().pos != rotated_current_pos) m_extrusions.emplace_back(WipeTower::Extrusion(rotated_current_pos, 0, m_current_tool));
|
||||
{
|
||||
|
||||
float sample_angle = 5.f / 180.f * PI;
|
||||
int n = std::ceil(abs(arc.angle_radians) / sample_angle);
|
||||
int n = arc_fit_size;
|
||||
for (int j = 0; j < n; j++) {
|
||||
float cur_angle = arc.polar_start_theta + (float) j / n * arc.angle_radians;
|
||||
if (cur_angle > 2 * PI)
|
||||
@@ -899,6 +899,7 @@ public:
|
||||
WipeTowerWriter &polygon(const Polygon &wall_polygon, const float f = 0.f)
|
||||
{
|
||||
Polyline pl = to_polyline(wall_polygon);
|
||||
pl.simplify(WT_SIMPLIFY_TOLERANCE_SCALED);
|
||||
pl.simplify_by_fitting_arc(SCALED_WIPE_TOWER_RESOLUTION);
|
||||
|
||||
auto get_closet_idx = [this](std::vector<Segment> &corners) -> int {
|
||||
@@ -1371,6 +1372,122 @@ float WipeTower::get_auto_brim_by_height(float max_height) {
|
||||
return 8.f;
|
||||
}
|
||||
|
||||
Vec2f WipeTower::move_box_inside_box(const BoundingBox &box1, const BoundingBox &box2,int scaled_offset)
|
||||
{
|
||||
Vec2f res{0, 0};
|
||||
if (box1.size()[0] >= box2.size()[0]- 2*scaled_offset || box1.size()[1] >= box2.size()[1]-2*scaled_offset) return res;
|
||||
|
||||
if (box1.max[0] > box2.max[0] - scaled_offset) {
|
||||
res[0] = unscaled<float>((box2.max[0] - scaled_offset) - box1.max[0]);
|
||||
}
|
||||
else if (box1.min[0] < box2.min[0] + scaled_offset) {
|
||||
res[0] = unscaled<float>((box2.min[0] + scaled_offset) - box1.min[0]);
|
||||
}
|
||||
|
||||
if (box1.max[1] > box2.max[1] - scaled_offset) {
|
||||
res[1] = unscaled<float>((box2.max[1] - scaled_offset) - box1.max[1]);
|
||||
}
|
||||
else if (box1.min[1] < box2.min[1] + scaled_offset) {
|
||||
res[1] = unscaled<float>((box2.min[1] + scaled_offset) - box1.min[1]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Polygon WipeTower::rib_section(float width, float depth, float rib_length, float rib_width,bool fillet_wall)
|
||||
{
|
||||
Polygon res;
|
||||
res.points.resize(16);
|
||||
float theta = std::atan(width / depth);
|
||||
float costheta = std::cos(theta);
|
||||
float sintheta = std::sin(theta);
|
||||
float w = rib_width / 2.f;
|
||||
float diag = std::sqrt(width * width + depth * depth);
|
||||
float l = (rib_length - diag) / 2;
|
||||
Vec2f diag_dir1 = Vec2f{width, depth}.normalized();
|
||||
Vec2f diag_dir1_perp{-diag_dir1[1], diag_dir1[0]};
|
||||
Vec2f diag_dir2 = Vec2f{-width, depth}.normalized();
|
||||
Vec2f diag_dir2_perp{-diag_dir2[1], diag_dir2[0]};
|
||||
std::vector<Vec2f> p{{0, 0}, {width, 0}, {width, depth}, {0, depth}};
|
||||
Polyline p_render;
|
||||
for (auto &x : p) p_render.points.push_back(scaled(x));
|
||||
res.points[0] = scaled(Vec2f{p[0].x(), p[0].y() + w / sintheta});
|
||||
res.points[1] = scaled(Vec2f{p[0] - diag_dir1 * l + diag_dir1_perp * w});
|
||||
res.points[2] = scaled(Vec2f{p[0] - diag_dir1 * l - diag_dir1_perp * w});
|
||||
res.points[3] = scaled(Vec2f{p[0].x() + w / costheta, p[0].y()});
|
||||
|
||||
res.points[4] = scaled(Vec2f{p[1].x() - w / costheta, p[1].y()});
|
||||
res.points[5] = scaled(Vec2f{p[1] - diag_dir2 * l + diag_dir2_perp * w});
|
||||
res.points[6] = scaled(Vec2f{p[1] - diag_dir2 * l - diag_dir2_perp * w});
|
||||
res.points[7] = scaled(Vec2f{p[1].x(), p[1].y() + w / sintheta});
|
||||
|
||||
res.points[8] = scaled(Vec2f{p[2].x(), p[2].y() - w / sintheta});
|
||||
res.points[9] = scaled(Vec2f{p[2] + diag_dir1 * l - diag_dir1_perp * w});
|
||||
res.points[10] = scaled(Vec2f{p[2] + diag_dir1 * l + diag_dir1_perp * w});
|
||||
res.points[11] = scaled(Vec2f{p[2].x() - w / costheta, p[2].y()});
|
||||
|
||||
res.points[12] = scaled(Vec2f{p[3].x() + w / costheta, p[3].y()});
|
||||
res.points[13] = scaled(Vec2f{p[3] + diag_dir2 * l - diag_dir2_perp * w});
|
||||
res.points[14] = scaled(Vec2f{p[3] + diag_dir2 * l + diag_dir2_perp * w});
|
||||
res.points[15] = scaled(Vec2f{p[3].x(), p[3].y() - w / sintheta});
|
||||
res.remove_duplicate_points();
|
||||
if (fillet_wall) { res = rounding_polygon(res); }
|
||||
res.points.shrink_to_fit();
|
||||
return res;
|
||||
}
|
||||
|
||||
TriangleMesh WipeTower::its_make_rib_tower(float width, float depth, float height, float rib_length, float rib_width, bool fillet_wall)
|
||||
{
|
||||
TriangleMesh res;
|
||||
Polygon bottom = rib_section(width, depth, rib_length, rib_width, fillet_wall);
|
||||
Polygon top = rib_section(width, depth, std::sqrt(width * width + depth * depth), rib_width, fillet_wall);
|
||||
if (fillet_wall)
|
||||
assert(bottom.points.size() == top.points.size());
|
||||
int offset = bottom.points.size();
|
||||
res.its.vertices.reserve(offset * 2);
|
||||
auto faces_bottom = Triangulation::triangulate(bottom);
|
||||
auto faces_top = Triangulation::triangulate(top);
|
||||
res.its.indices.reserve(offset * 2 + faces_bottom.size() + faces_top.size());
|
||||
for (auto &t : faces_bottom) res.its.indices.push_back({t[1], t[0], t[2]});
|
||||
for (auto &t : faces_top) res.its.indices.push_back({t[0] + offset, t[1] + offset, t[2] + offset});
|
||||
|
||||
for (int i = 0; i < bottom.size(); i++) res.its.vertices.push_back({unscaled<float>(bottom[i][0]), unscaled<float>(bottom[i][1]), 0});
|
||||
for (int i = 0; i < top.size(); i++) res.its.vertices.push_back({unscaled<float>(top[i][0]), unscaled<float>(top[i][1]), height});
|
||||
|
||||
for (int i = 0; i < offset; i++) {
|
||||
int a = i;
|
||||
int b = (i + 1) % offset;
|
||||
int c = i + offset;
|
||||
int d = b + offset;
|
||||
res.its.indices.push_back({a, b, c});
|
||||
res.its.indices.push_back({d, c, b});
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
TriangleMesh WipeTower::its_make_rib_brim(const Polygon& brim, float layer_height) {
|
||||
TriangleMesh res;
|
||||
int offset = brim.size();
|
||||
res.its.vertices.reserve(brim.size() * 2);
|
||||
auto faces= Triangulation::triangulate(brim);
|
||||
res.its.indices.reserve(brim.size() * 2 + 2 * faces.size());
|
||||
for (auto &t : faces) res.its.indices.push_back({t[1], t[0], t[2]});
|
||||
for (auto &t : faces) res.its.indices.push_back({t[0] + offset, t[1] + offset, t[2] + offset});
|
||||
|
||||
for (int i = 0; i < brim.size(); i++) res.its.vertices.push_back({unscaled<float>(brim[i][0]), unscaled<float>(brim[i][1]), 0});
|
||||
for (int i = 0; i < brim.size(); i++) res.its.vertices.push_back({unscaled<float>(brim[i][0]), unscaled<float>(brim[i][1]), layer_height});
|
||||
|
||||
for (int i = 0; i < offset; i++) {
|
||||
int a = i;
|
||||
int b = (i + 1) % offset;
|
||||
int c = i + offset;
|
||||
int d = b + offset;
|
||||
res.its.indices.push_back({a, b, c});
|
||||
res.its.indices.push_back({d, c, b});
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
WipeTower::WipeTower(const PrintConfig& config, int plate_idx, Vec3d plate_origin, size_t initial_tool, const float wipe_tower_height) :
|
||||
m_semm(config.single_extruder_multi_material.value),
|
||||
m_wipe_tower_pos(config.wipe_tower_x.get_at(plate_idx), config.wipe_tower_y.get_at(plate_idx)),
|
||||
@@ -3634,6 +3751,8 @@ void WipeTower::plan_tower_new()
|
||||
update_all_layer_depth(max_depth);
|
||||
m_rib_length = std::max({m_rib_length, sqrt(m_wipe_tower_depth * m_wipe_tower_depth + m_wipe_tower_width * m_wipe_tower_width)});
|
||||
m_rib_length += m_extra_rib_length;
|
||||
m_rib_length = std::max(0.f, m_rib_length);
|
||||
m_rib_width = std::min(m_rib_width, std::min(m_wipe_tower_depth, m_wipe_tower_width) / 2.f); // Ensure that the rib wall of the wipetower are attached to the infill.
|
||||
|
||||
}
|
||||
|
||||
@@ -3698,7 +3817,7 @@ void WipeTower::generate_new(std::vector<std::vector<WipeTower::ToolChangeResult
|
||||
if (m_plan.empty())
|
||||
return;
|
||||
//m_extra_spacing = 1.f;
|
||||
|
||||
m_wipe_tower_height = m_plan.back().z;//real wipe_tower_height
|
||||
plan_tower_new();
|
||||
|
||||
m_layer_info = m_plan.begin();
|
||||
|
||||
@@ -28,7 +28,11 @@ public:
|
||||
static const std::map<float, float> min_depth_per_height;
|
||||
static float get_limit_depth_by_height(float max_height);
|
||||
static float get_auto_brim_by_height(float max_height);
|
||||
|
||||
static TriangleMesh its_make_rib_tower(float width, float depth, float height, float rib_length, float rib_width, bool fillet_wall);
|
||||
static TriangleMesh its_make_rib_brim(const Polygon& brim, float layer_height);
|
||||
static Polygon rib_section(float width, float depth, float rib_length, float rib_width, bool fillet_wall);
|
||||
static Vec2f move_box_inside_box(const BoundingBox &box1, const BoundingBox &box2, int offset = 0);
|
||||
static Polygon rounding_polygon(Polygon &polygon, double rounding = 2., double angle_tol = 30. / 180. * PI);
|
||||
struct Extrusion
|
||||
{
|
||||
Extrusion(const Vec2f &pos, float width, unsigned int tool) : pos(pos), width(width), tool(tool) {}
|
||||
@@ -192,20 +196,16 @@ public:
|
||||
if (m_outer_wall.empty()) return BoundingBoxf({Vec2d(0,0)});
|
||||
BoundingBox box = get_extents(m_outer_wall.begin()->second);
|
||||
BoundingBoxf res = BoundingBoxf(unscale(box.min), unscale(box.max));
|
||||
res.translate(m_rib_offset.cast<double>());
|
||||
return res;
|
||||
}
|
||||
std::map<float, Polylines> get_outer_wall() const
|
||||
{
|
||||
std::map<float, Polylines> res = m_outer_wall;
|
||||
Point trans = scaled(m_rib_offset);
|
||||
for (auto &[h,polylines] : res)
|
||||
for (auto &polyline : polylines)
|
||||
polyline.translate(trans.x(), trans.y());
|
||||
return res;
|
||||
return m_outer_wall;
|
||||
}
|
||||
float get_height() const { return m_wipe_tower_height; }
|
||||
float get_layer_height() const { return m_layer_height; }
|
||||
float get_rib_length() const { return m_rib_length; }
|
||||
float get_rib_width() const { return m_rib_width; }
|
||||
|
||||
void set_last_layer_extruder_fill(bool extruder_fill) {
|
||||
if (!m_plan.empty()) {
|
||||
|
||||
@@ -977,13 +977,20 @@ static StringObjectException layered_print_cleareance_valid(const Print &print,
|
||||
|
||||
Polygons convex_hulls_temp;
|
||||
if (print.has_wipe_tower()) {
|
||||
Polygon wipe_tower_convex_hull;
|
||||
wipe_tower_convex_hull.points.emplace_back(scale_(x), scale_(y));
|
||||
wipe_tower_convex_hull.points.emplace_back(scale_(x + width), scale_(y));
|
||||
wipe_tower_convex_hull.points.emplace_back(scale_(x + width), scale_(y + depth));
|
||||
wipe_tower_convex_hull.points.emplace_back(scale_(x), scale_(y + depth));
|
||||
wipe_tower_convex_hull.rotate(a);
|
||||
convex_hulls_temp.push_back(wipe_tower_convex_hull);
|
||||
if (!print.is_step_done(psWipeTower)) {
|
||||
Polygon wipe_tower_convex_hull;
|
||||
wipe_tower_convex_hull.points.emplace_back(scale_(x), scale_(y));
|
||||
wipe_tower_convex_hull.points.emplace_back(scale_(x + width), scale_(y));
|
||||
wipe_tower_convex_hull.points.emplace_back(scale_(x + width), scale_(y + depth));
|
||||
wipe_tower_convex_hull.points.emplace_back(scale_(x), scale_(y + depth));
|
||||
wipe_tower_convex_hull.rotate(a);
|
||||
convex_hulls_temp.push_back(wipe_tower_convex_hull);
|
||||
} else {
|
||||
//here, wipe_tower_polygon is not always convex.
|
||||
Polygon wipe_tower_polygon = print.wipe_tower_data().wipe_tower_mesh_data->bottom;
|
||||
wipe_tower_polygon.translate(Point(scale_(x), scale_(y)));
|
||||
convex_hulls_temp.push_back(wipe_tower_polygon);
|
||||
}
|
||||
}
|
||||
if (!intersection(convex_hulls_other, convex_hulls_temp).empty()) {
|
||||
if (warning) {
|
||||
@@ -2569,7 +2576,7 @@ Points Print::first_layer_wipe_tower_corners(bool check_wipe_tower_existance) co
|
||||
{
|
||||
double width = m_wipe_tower_data.bbx.max.x() - m_wipe_tower_data.bbx.min.x();
|
||||
double depth = m_wipe_tower_data.bbx.max.y() -m_wipe_tower_data.bbx.min.y();
|
||||
Vec2d pt0 = m_wipe_tower_data.bbx.min;
|
||||
Vec2d pt0 = m_wipe_tower_data.bbx.min + m_wipe_tower_data.rib_offset.cast<double>();
|
||||
|
||||
// First the corners.
|
||||
std::vector<Vec2d> pts = { pt0,
|
||||
@@ -2874,8 +2881,8 @@ const WipeTowerData &Print::wipe_tower_data(size_t filaments_cnt) const
|
||||
}
|
||||
const_cast<Print *>(this)->m_wipe_tower_data.brim_width = m_config.prime_tower_brim_width;
|
||||
}
|
||||
if (m_config.prime_tower_brim_width < 0) const_cast<Print *>(this)->m_wipe_tower_data.brim_width = WipeTower::get_auto_brim_by_height(max_height);
|
||||
}
|
||||
if (m_config.prime_tower_brim_width < 0 ) const_cast<Print *>(this)->m_wipe_tower_data.brim_width = WipeTower::get_auto_brim_by_height(max_height);
|
||||
return m_wipe_tower_data;
|
||||
}
|
||||
|
||||
@@ -3058,10 +3065,13 @@ void Print::_make_wipe_tower()
|
||||
|
||||
m_wipe_tower_data.used_filament = wipe_tower.get_used_filament();
|
||||
m_wipe_tower_data.number_of_toolchanges = wipe_tower.get_number_of_toolchanges();
|
||||
m_wipe_tower_data.construct_mesh(wipe_tower.width(), wipe_tower.get_depth(), wipe_tower.get_height(), wipe_tower.get_brim_width(), config().prime_tower_rib_wall.value,
|
||||
wipe_tower.get_rib_width(), wipe_tower.get_rib_length(), config().prime_tower_fillet_wall.value);
|
||||
const Vec3d origin = this->get_plate_origin();
|
||||
m_fake_wipe_tower.set_fake_extrusion_data(wipe_tower.position(), wipe_tower.width(), wipe_tower.get_height(),
|
||||
wipe_tower.get_layer_height(), m_wipe_tower_data.depth, m_wipe_tower_data.brim_width,
|
||||
{scale_(origin.x()), scale_(origin.y())});
|
||||
m_fake_wipe_tower.rib_offset = wipe_tower.get_rib_offset();
|
||||
m_fake_wipe_tower.set_fake_extrusion_data(wipe_tower.position() + m_fake_wipe_tower.rib_offset, wipe_tower.width(), wipe_tower.get_height(), wipe_tower.get_layer_height(),
|
||||
m_wipe_tower_data.depth,
|
||||
m_wipe_tower_data.brim_width, {scale_(origin.x()), scale_(origin.y())});
|
||||
m_fake_wipe_tower.outer_wall = wipe_tower.get_outer_wall();
|
||||
} else {
|
||||
// Get wiping matrix to get number of extruders and convert vector<double> to vector<float>:
|
||||
@@ -4667,6 +4677,25 @@ ExtrusionLayers FakeWipeTower::getTrueExtrusionLayersFromWipeTower() const
|
||||
}
|
||||
return wtels;
|
||||
}
|
||||
|
||||
void WipeTowerData::construct_mesh(float width, float depth, float height, float brim_width, bool is_rib_wipe_tower, float rib_width, float rib_length,bool fillet_wall)
|
||||
{
|
||||
wipe_tower_mesh_data = WipeTowerMeshData{};
|
||||
float first_layer_height=0.08; //brim height
|
||||
if (!is_rib_wipe_tower) {
|
||||
wipe_tower_mesh_data->real_wipe_tower_mesh = make_cube(width, depth, height);
|
||||
wipe_tower_mesh_data->real_brim_mesh = make_cube(width + 2 * brim_width, depth + 2 * brim_width, first_layer_height);
|
||||
wipe_tower_mesh_data->real_brim_mesh.translate({-brim_width, -brim_width, 0});
|
||||
wipe_tower_mesh_data->bottom = {scaled(Vec2f{-brim_width, -brim_width}), scaled(Vec2f{width + brim_width, 0}), scaled(Vec2f{width + brim_width, depth + brim_width}),
|
||||
scaled(Vec2f{0, depth})};
|
||||
} else {
|
||||
wipe_tower_mesh_data->real_wipe_tower_mesh = WipeTower::its_make_rib_tower(width, depth, height, rib_length, rib_width, fillet_wall);
|
||||
wipe_tower_mesh_data->bottom = WipeTower::rib_section(width, depth, rib_length, rib_width, fillet_wall);
|
||||
wipe_tower_mesh_data->bottom = offset(wipe_tower_mesh_data->bottom, scaled(brim_width)).front();
|
||||
wipe_tower_mesh_data->real_brim_mesh = WipeTower::its_make_rib_brim(wipe_tower_mesh_data->bottom, first_layer_height);
|
||||
wipe_tower_mesh_data->real_wipe_tower_mesh.translate(Vec3f(rib_offset[0], rib_offset[1],0));
|
||||
wipe_tower_mesh_data->real_brim_mesh.translate(Vec3f(rib_offset[0], rib_offset[1], 0));
|
||||
wipe_tower_mesh_data->bottom.translate(scaled(Vec2f(rib_offset[0], rib_offset[1])));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
@@ -594,13 +594,14 @@ struct FakeWipeTower
|
||||
Vec2f pos;
|
||||
float width;
|
||||
float height;
|
||||
float layer_height;
|
||||
float layer_height;// Due to variable layer height, this parameter may be not right.
|
||||
float depth;
|
||||
std::vector<std::pair<float, float>> z_and_depth_pairs;
|
||||
float brim_width;
|
||||
float rotation_angle;
|
||||
float cone_angle;
|
||||
Vec2d plate_origin;
|
||||
Vec2f rib_offset{0.f,0.f};
|
||||
std::map<float , Polylines> outer_wall; //wipe tower's true outer wall and brim
|
||||
|
||||
void set_fake_extrusion_data(Vec2f p, float w, float h, float lh, float d, float bd, Vec2d o)
|
||||
@@ -627,7 +628,7 @@ struct FakeWipeTower
|
||||
plate_origin = o;
|
||||
}
|
||||
|
||||
void set_pos(Vec2f p) { pos = p; }
|
||||
void set_pos(Vec2f p) { pos = p+rib_offset; }
|
||||
void set_pos_and_rotation(const Vec2f& p, float rotation) { pos = p; rotation_angle = rotation; }
|
||||
|
||||
std::vector<ExtrusionPaths> getFakeExtrusionPathsFromWipeTower() const
|
||||
@@ -736,6 +737,12 @@ struct FakeWipeTower
|
||||
|
||||
struct WipeTowerData
|
||||
{
|
||||
struct WipeTowerMeshData
|
||||
{
|
||||
Polygon bottom;
|
||||
TriangleMesh real_wipe_tower_mesh;
|
||||
TriangleMesh real_brim_mesh;
|
||||
};
|
||||
// Following section will be consumed by the GCodeGenerator.
|
||||
// Tool ordering of a non-sequential print has to be known to calculate the wipe tower.
|
||||
// Cache it here, so it does not need to be recalculated during the G-code generation.
|
||||
@@ -752,9 +759,9 @@ struct WipeTowerData
|
||||
std::vector<std::pair<float, float>> z_and_depth_pairs;
|
||||
float brim_width;
|
||||
float height;
|
||||
BoundingBoxf bbx;
|
||||
BoundingBoxf bbx;//including brim
|
||||
Vec2f rib_offset;
|
||||
|
||||
std::optional<WipeTowerMeshData> wipe_tower_mesh_data;//added rib_offset
|
||||
void clear() {
|
||||
priming.reset(nullptr);
|
||||
tool_changes.clear();
|
||||
@@ -763,7 +770,9 @@ struct WipeTowerData
|
||||
number_of_toolchanges = -1;
|
||||
depth = 0.f;
|
||||
brim_width = 0.f;
|
||||
wipe_tower_mesh_data = std::nullopt;
|
||||
}
|
||||
void construct_mesh(float width, float depth, float height, float brim_width, bool is_rib_wipe_tower, float rib_width, float rib_length, bool fillet_wall);
|
||||
|
||||
private:
|
||||
// Only allow the WipeTowerData to be instantiated internally by Print,
|
||||
|
||||
Reference in New Issue
Block a user