Conflict checker: detection of the wipe tower when it narrows towards the top
This commit is contained in:
parent
15eb860a31
commit
46678c27b5
@ -210,11 +210,11 @@ ConflictResultOpt ConflictChecker::find_inter_of_lines_in_diff_objs(PrintObjectP
|
|||||||
|
|
||||||
LinesBucketQueue conflictQueue;
|
LinesBucketQueue conflictQueue;
|
||||||
if (wtdptr.has_value()) { // wipe tower at 0 by default
|
if (wtdptr.has_value()) { // wipe tower at 0 by default
|
||||||
auto wtpaths = (*wtdptr)->getFakeExtrusionPathsFromWipeTower();
|
std::vector<ExtrusionPaths> wtpaths = (*wtdptr)->getFakeExtrusionPathsFromWipeTower();
|
||||||
conflictQueue.emplace_back_bucket(std::move(wtpaths), *wtdptr, Points{Point((*wtdptr)->plate_origin)});
|
conflictQueue.emplace_back_bucket(std::move(wtpaths), *wtdptr, Points{Point((*wtdptr)->plate_origin)});
|
||||||
}
|
}
|
||||||
for (PrintObject *obj : objs) {
|
for (PrintObject *obj : objs) {
|
||||||
auto layers = getAllLayersExtrusionPathsFromObject(obj);
|
std::pair<std::vector<ExtrusionPaths>, std::vector<ExtrusionPaths>> layers = getAllLayersExtrusionPathsFromObject(obj);
|
||||||
|
|
||||||
Points instances_shifts;
|
Points instances_shifts;
|
||||||
for (const PrintInstance& inst : obj->instances())
|
for (const PrintInstance& inst : obj->instances())
|
||||||
|
@ -1563,4 +1563,19 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<std::pair<float, float>> WipeTower::get_z_and_depth_pairs() const
|
||||||
|
{
|
||||||
|
std::vector<std::pair<float, float>> out = {{0.f, m_wipe_tower_depth}};
|
||||||
|
for (const WipeTowerInfo& wti : m_plan) {
|
||||||
|
assert(wti.depth < wti.depth + WT_EPSILON);
|
||||||
|
if (wti.depth < out.back().second - WT_EPSILON)
|
||||||
|
out.emplace_back(wti.z, wti.depth);
|
||||||
|
}
|
||||||
|
if (out.back().first < m_wipe_tower_height - WT_EPSILON)
|
||||||
|
out.emplace_back(m_wipe_tower_height, 0.f);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -143,6 +143,7 @@ public:
|
|||||||
void generate(std::vector<std::vector<ToolChangeResult>> &result);
|
void generate(std::vector<std::vector<ToolChangeResult>> &result);
|
||||||
|
|
||||||
float get_depth() const { return m_wipe_tower_depth; }
|
float get_depth() const { return m_wipe_tower_depth; }
|
||||||
|
std::vector<std::pair<float, float>> get_z_and_depth_pairs() const;
|
||||||
float get_brim_width() const { return m_wipe_tower_brim_width_real; }
|
float get_brim_width() const { return m_wipe_tower_brim_width_real; }
|
||||||
float get_wipe_tower_height() const { return m_wipe_tower_height; }
|
float get_wipe_tower_height() const { return m_wipe_tower_height; }
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
#include <boost/regex.hpp>
|
#include <boost/regex.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
template class PrintState<PrintStep, psCount>;
|
template class PrintState<PrintStep, psCount>;
|
||||||
@ -1502,6 +1501,7 @@ void Print::_make_wipe_tower()
|
|||||||
m_wipe_tower_data.tool_changes.reserve(m_wipe_tower_data.tool_ordering.layer_tools().size());
|
m_wipe_tower_data.tool_changes.reserve(m_wipe_tower_data.tool_ordering.layer_tools().size());
|
||||||
wipe_tower.generate(m_wipe_tower_data.tool_changes);
|
wipe_tower.generate(m_wipe_tower_data.tool_changes);
|
||||||
m_wipe_tower_data.depth = wipe_tower.get_depth();
|
m_wipe_tower_data.depth = wipe_tower.get_depth();
|
||||||
|
m_wipe_tower_data.z_and_depth_pairs = wipe_tower.get_z_and_depth_pairs();
|
||||||
m_wipe_tower_data.brim_width = wipe_tower.get_brim_width();
|
m_wipe_tower_data.brim_width = wipe_tower.get_brim_width();
|
||||||
m_wipe_tower_data.height = wipe_tower.get_wipe_tower_height();
|
m_wipe_tower_data.height = wipe_tower.get_wipe_tower_height();
|
||||||
|
|
||||||
@ -1528,7 +1528,7 @@ void Print::_make_wipe_tower()
|
|||||||
m_wipe_tower_data.number_of_toolchanges = wipe_tower.get_number_of_toolchanges();
|
m_wipe_tower_data.number_of_toolchanges = wipe_tower.get_number_of_toolchanges();
|
||||||
const Vec3d origin = Vec3d::Zero();
|
const Vec3d origin = Vec3d::Zero();
|
||||||
m_fake_wipe_tower.set_fake_extrusion_data(wipe_tower.position(), wipe_tower.width(), wipe_tower.get_wipe_tower_height(), config().first_layer_height, m_wipe_tower_data.depth,
|
m_fake_wipe_tower.set_fake_extrusion_data(wipe_tower.position(), wipe_tower.width(), wipe_tower.get_wipe_tower_height(), config().first_layer_height, m_wipe_tower_data.depth,
|
||||||
m_wipe_tower_data.brim_width, config().wipe_tower_rotation_angle, {scale_(origin.x()), scale_(origin.y())});
|
m_wipe_tower_data.z_and_depth_pairs, m_wipe_tower_data.brim_width, config().wipe_tower_rotation_angle, {scale_(origin.x()), scale_(origin.y())});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1597,4 +1597,57 @@ std::string PrintStatistics::finalize_output_path(const std::string &path_in) co
|
|||||||
return final_path;
|
return final_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<ExtrusionPaths> FakeWipeTower::getFakeExtrusionPathsFromWipeTower() const
|
||||||
|
{
|
||||||
|
float h = height;
|
||||||
|
float lh = layer_height;
|
||||||
|
int d = scale_(depth);
|
||||||
|
int w = scale_(width);
|
||||||
|
int bd = scale_(brim_width);
|
||||||
|
Point minCorner = { -bd, -bd };
|
||||||
|
Point maxCorner = { minCorner.x() + w + bd, minCorner.y() + d + bd };
|
||||||
|
|
||||||
|
std::vector<ExtrusionPaths> paths;
|
||||||
|
for (float hh = 0.f; hh < h; hh += lh) {
|
||||||
|
|
||||||
|
if (hh != 0.f) {
|
||||||
|
// The wipe tower may be getting smaller. Find the depth for this layer.
|
||||||
|
size_t i = 0;
|
||||||
|
for (i=0; i<z_and_depth_pairs.size()-1; ++i)
|
||||||
|
if (hh >= z_and_depth_pairs[i].first && hh < z_and_depth_pairs[i+1].first)
|
||||||
|
break;
|
||||||
|
d = scale_(z_and_depth_pairs[i].second);
|
||||||
|
minCorner = {0.f, -d/2 + scale_(z_and_depth_pairs.front().second/2.f)};
|
||||||
|
maxCorner = { minCorner.x() + w, minCorner.y() + d };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExtrusionPath path(ExtrusionRole::WipeTower, 0.0, 0.0, lh);
|
||||||
|
path.polyline = { minCorner, {maxCorner.x(), minCorner.y()}, maxCorner, {minCorner.x(), maxCorner.y()}, minCorner };
|
||||||
|
paths.push_back({ path });
|
||||||
|
|
||||||
|
// We added the border, now add several parallel lines so we can detect an object that is fully inside the tower.
|
||||||
|
// For now, simply use fixed spacing of 3mm.
|
||||||
|
for (coord_t y=minCorner.y()+scale_(3.); y<maxCorner.y(); y+=scale_(3.)) {
|
||||||
|
path.polyline = { {minCorner.x(), y}, {maxCorner.x(), y} };
|
||||||
|
paths.back().push_back(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hh == 0.f) {
|
||||||
|
minCorner = minCorner + Point(bd, bd);
|
||||||
|
maxCorner = maxCorner - Point(bd, bd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate and translate the tower into the final position.
|
||||||
|
for (ExtrusionPaths& ps : paths) {
|
||||||
|
for (ExtrusionPath& p : ps) {
|
||||||
|
p.polyline.rotate(Geometry::deg2rad(rotation_angle));
|
||||||
|
p.polyline.translate(scale_(pos.x()), scale_(pos.y()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -426,17 +426,19 @@ struct FakeWipeTower
|
|||||||
float height;
|
float height;
|
||||||
float layer_height;
|
float layer_height;
|
||||||
float depth;
|
float depth;
|
||||||
|
std::vector<std::pair<float, float>> z_and_depth_pairs;
|
||||||
float brim_width;
|
float brim_width;
|
||||||
float rotation_angle;
|
float rotation_angle;
|
||||||
Vec2d plate_origin;
|
Vec2d plate_origin;
|
||||||
|
|
||||||
void set_fake_extrusion_data(const Vec2f& p, float w, float h, float lh, float d, float bd, float ra, const Vec2d& o)
|
void set_fake_extrusion_data(const Vec2f& p, float w, float h, float lh, float d, const std::vector<std::pair<float, float>>& zad, float bd, float ra, const Vec2d& o)
|
||||||
{
|
{
|
||||||
pos = p;
|
pos = p;
|
||||||
width = w;
|
width = w;
|
||||||
height = h;
|
height = h;
|
||||||
layer_height = lh;
|
layer_height = lh;
|
||||||
depth = d;
|
depth = d;
|
||||||
|
z_and_depth_pairs = zad;
|
||||||
brim_width = bd;
|
brim_width = bd;
|
||||||
rotation_angle = ra;
|
rotation_angle = ra;
|
||||||
plate_origin = o;
|
plate_origin = o;
|
||||||
@ -444,45 +446,7 @@ struct FakeWipeTower
|
|||||||
|
|
||||||
void set_pos_and_rotation(const Vec2f& p, float rotation) { pos = p; rotation_angle = rotation; }
|
void set_pos_and_rotation(const Vec2f& p, float rotation) { pos = p; rotation_angle = rotation; }
|
||||||
|
|
||||||
std::vector<ExtrusionPaths> getFakeExtrusionPathsFromWipeTower() const
|
std::vector<ExtrusionPaths> getFakeExtrusionPathsFromWipeTower() const;
|
||||||
{
|
|
||||||
float h = height;
|
|
||||||
float lh = layer_height;
|
|
||||||
int d = scale_(depth);
|
|
||||||
int w = scale_(width);
|
|
||||||
int bd = scale_(brim_width);
|
|
||||||
Point minCorner = { -bd, -bd };
|
|
||||||
Point maxCorner = { minCorner.x() + w + bd, minCorner.y() + d + bd };
|
|
||||||
|
|
||||||
std::vector<ExtrusionPaths> paths;
|
|
||||||
for (float hh = 0.f; hh < h; hh += lh) {
|
|
||||||
ExtrusionPath path(ExtrusionRole::WipeTower, 0.0, 0.0, lh);
|
|
||||||
path.polyline = { minCorner, {maxCorner.x(), minCorner.y()}, maxCorner, {minCorner.x(), maxCorner.y()}, minCorner };
|
|
||||||
paths.push_back({ path });
|
|
||||||
|
|
||||||
// We added the border, now add several parallel lines so we can detect an object that is fully inside the tower.
|
|
||||||
// For now, simply use fixed spacing of 3mm.
|
|
||||||
for (coord_t y=minCorner.y()+scale_(3.); y<maxCorner.y(); y+=scale_(3.)) {
|
|
||||||
path.polyline = { {minCorner.x(), y}, {maxCorner.x(), y} };
|
|
||||||
paths.push_back({ path });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hh == 0.f) {
|
|
||||||
minCorner = minCorner + Point(bd, bd);
|
|
||||||
maxCorner = maxCorner - Point(bd, bd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rotate and translate the tower into the final position.
|
|
||||||
for (ExtrusionPaths& ps : paths) {
|
|
||||||
for (ExtrusionPath& p : ps) {
|
|
||||||
p.polyline.rotate(Geometry::deg2rad(rotation_angle));
|
|
||||||
p.polyline.translate(scale_(pos.x()), scale_(pos.y()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return paths;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WipeTowerData
|
struct WipeTowerData
|
||||||
@ -500,6 +464,7 @@ struct WipeTowerData
|
|||||||
|
|
||||||
// Depth of the wipe tower to pass to GLCanvas3D for exact bounding box:
|
// Depth of the wipe tower to pass to GLCanvas3D for exact bounding box:
|
||||||
float depth;
|
float depth;
|
||||||
|
std::vector<std::pair<float, float>> z_and_depth_pairs;
|
||||||
float brim_width;
|
float brim_width;
|
||||||
float height;
|
float height;
|
||||||
|
|
||||||
|
@ -480,11 +480,11 @@ int GLVolumeCollection::load_object_volume(
|
|||||||
|
|
||||||
#if ENABLE_OPENGL_ES
|
#if ENABLE_OPENGL_ES
|
||||||
int GLVolumeCollection::load_wipe_tower_preview(
|
int GLVolumeCollection::load_wipe_tower_preview(
|
||||||
float pos_x, float pos_y, float width, float depth, float height, float cone_angle,
|
float pos_x, float pos_y, float width, float depth, const std::vector<std::pair<float, float>>& z_and_depth_pairs, float height, float cone_angle,
|
||||||
float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh)
|
float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh)
|
||||||
#else
|
#else
|
||||||
int GLVolumeCollection::load_wipe_tower_preview(
|
int GLVolumeCollection::load_wipe_tower_preview(
|
||||||
float pos_x, float pos_y, float width, float depth, float height, float cone_angle,
|
float pos_x, float pos_y, float width, float depth, const std::vector<std::pair<float, float>>& z_and_depth_pairs, float height, float cone_angle,
|
||||||
float rotation_angle, bool size_unknown, float brim_width)
|
float rotation_angle, bool size_unknown, float brim_width)
|
||||||
#endif // ENABLE_OPENGL_ES
|
#endif // ENABLE_OPENGL_ES
|
||||||
{
|
{
|
||||||
@ -534,8 +534,13 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
|||||||
|
|
||||||
mesh.scale(Vec3f(width / (n * min_width), 1.f, height)); // Scaling to proper width
|
mesh.scale(Vec3f(width / (n * min_width), 1.f, height)); // Scaling to proper width
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
mesh = make_cube(width, depth, height);
|
for (size_t i=1; i<z_and_depth_pairs.size(); ++i) {
|
||||||
|
TriangleMesh m = make_cube(width, z_and_depth_pairs[i-1].second, z_and_depth_pairs[i].first-z_and_depth_pairs[i-1].first);
|
||||||
|
m.translate(0.f, -z_and_depth_pairs[i-1].second/2.f + z_and_depth_pairs[0].second/2.f, z_and_depth_pairs[i-1].first);
|
||||||
|
mesh.merge(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We'll make another mesh to show the brim (fixed layer height):
|
// We'll make another mesh to show the brim (fixed layer height):
|
||||||
TriangleMesh brim_mesh = make_cube(width + 2.f * brim_width, depth + 2.f * brim_width, 0.2f);
|
TriangleMesh brim_mesh = make_cube(width + 2.f * brim_width, depth + 2.f * brim_width, 0.2f);
|
||||||
|
@ -396,10 +396,10 @@ public:
|
|||||||
|
|
||||||
#if ENABLE_OPENGL_ES
|
#if ENABLE_OPENGL_ES
|
||||||
int load_wipe_tower_preview(
|
int load_wipe_tower_preview(
|
||||||
float pos_x, float pos_y, float width, float depth, float height, float cone_angle, float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh = nullptr);
|
float pos_x, float pos_y, float width, float depth, const std::vector<std::pair<float, float>>& z_and_depth_pairs, float height, float cone_angle, float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh = nullptr);
|
||||||
#else
|
#else
|
||||||
int load_wipe_tower_preview(
|
int load_wipe_tower_preview(
|
||||||
float pos_x, float pos_y, float width, float depth, float height, float cone_angle, float rotation_angle, bool size_unknown, float brim_width);
|
float pos_x, float pos_y, float width, float depth, const std::vector<std::pair<float, float>>& z_and_depth_pairs, float height, float cone_angle, float rotation_angle, bool size_unknown, float brim_width);
|
||||||
#endif // ENABLE_OPENGL_ES
|
#endif // ENABLE_OPENGL_ES
|
||||||
|
|
||||||
// Load SLA auxiliary GLVolumes (for support trees or pad).
|
// Load SLA auxiliary GLVolumes (for support trees or pad).
|
||||||
|
@ -2260,9 +2260,10 @@ void GCodeViewer::load_shells(const Print& print)
|
|||||||
if (extruders_count > 1 && config.wipe_tower && !config.complete_objects) {
|
if (extruders_count > 1 && config.wipe_tower && !config.complete_objects) {
|
||||||
const WipeTowerData& wipe_tower_data = print.wipe_tower_data(extruders_count);
|
const WipeTowerData& wipe_tower_data = print.wipe_tower_data(extruders_count);
|
||||||
const float depth = wipe_tower_data.depth;
|
const float depth = wipe_tower_data.depth;
|
||||||
|
const std::vector<std::pair<float, float>> z_and_depth_pairs = print.wipe_tower_data(extruders_count).z_and_depth_pairs;
|
||||||
const float brim_width = wipe_tower_data.brim_width;
|
const float brim_width = wipe_tower_data.brim_width;
|
||||||
if (depth != 0.)
|
if (depth != 0.)
|
||||||
m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_cone_angle, config.wipe_tower_rotation_angle,
|
m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, z_and_depth_pairs, max_z, config.wipe_tower_cone_angle, config.wipe_tower_rotation_angle,
|
||||||
!print.is_step_done(psWipeTower), brim_width);
|
!print.is_step_done(psWipeTower), brim_width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2554,6 +2554,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||||||
|
|
||||||
const Print *print = m_process->fff_print();
|
const Print *print = m_process->fff_print();
|
||||||
const float depth = print->wipe_tower_data(extruders_count).depth;
|
const float depth = print->wipe_tower_data(extruders_count).depth;
|
||||||
|
const std::vector<std::pair<float, float>> z_and_depth_pairs = print->wipe_tower_data(extruders_count).z_and_depth_pairs;
|
||||||
const float height_real = print->wipe_tower_data(extruders_count).height; // -1.f = unknown
|
const float height_real = print->wipe_tower_data(extruders_count).height; // -1.f = unknown
|
||||||
|
|
||||||
// Height of a print (Show at least a slab).
|
// Height of a print (Show at least a slab).
|
||||||
@ -2562,11 +2563,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||||||
if (depth != 0.) {
|
if (depth != 0.) {
|
||||||
#if ENABLE_OPENGL_ES
|
#if ENABLE_OPENGL_ES
|
||||||
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
|
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
|
||||||
x, y, w, depth, (float)height, ca, a, !print->is_step_done(psWipeTower),
|
x, y, w, depth, z_and_depth_pairs, (float)height, ca, a, !print->is_step_done(psWipeTower),
|
||||||
bw, &m_wipe_tower_mesh);
|
bw, &m_wipe_tower_mesh);
|
||||||
#else
|
#else
|
||||||
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
|
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
|
||||||
x, y, w, depth, (float)height, ca, a, !print->is_step_done(psWipeTower),
|
x, y, w, depth, z_and_depth_pairs, (float)height, ca, a, !print->is_step_done(psWipeTower),
|
||||||
bw);
|
bw);
|
||||||
#endif // ENABLE_OPENGL_ES
|
#endif // ENABLE_OPENGL_ES
|
||||||
if (volume_idx_wipe_tower_old != -1)
|
if (volume_idx_wipe_tower_old != -1)
|
||||||
|
Loading…
Reference in New Issue
Block a user