ENH: reopen confilctchecker with adpative height.

and fix conflict checking when the wipe tower's brim fully encloses the model

jira: STUDIO-10237, STUDIO-10296
Change-Id: I6e2a6640c06ddb6b3af700c9048fa26434411631
This commit is contained in:
jiangkai.zhao 2025-02-17 11:47:41 +08:00 committed by lane.wei
parent 939b405c35
commit b36c41e514
5 changed files with 61 additions and 39 deletions

View File

@ -228,16 +228,15 @@ ConflictResultOpt ConflictChecker::find_inter_of_lines_in_diff_objs(PrintObjectP
if (wtdptr.has_value()) { // wipe tower at 0 by default if (wtdptr.has_value()) { // wipe tower at 0 by default
//auto wtpaths = wtdptr.value()->getFakeExtrusionPathsFromWipeTower(); //auto wtpaths = wtdptr.value()->getFakeExtrusionPathsFromWipeTower();
auto wtpaths = wtdptr.value()->getTrueExtrusionPathsFromWipeTower(); ExtrusionLayers wtels = wtdptr.value()->getTrueExtrusionLayersFromWipeTower();
ExtrusionLayers wtels; //wtels.type = ExtrusionLayersType::WIPE_TOWER;
wtels.type = ExtrusionLayersType::WIPE_TOWER; //for (int i = 0; i < wtpaths.size(); ++i) { // assume that wipe tower always has same height
for (int i = 0; i < wtpaths.size(); ++i) { // assume that wipe tower always has same height // ExtrusionLayer el;
ExtrusionLayer el; // el.paths = wtpaths[i];
el.paths = wtpaths[i]; // el.bottom_z = wtpaths[i].front().height * (float) i;
el.bottom_z = wtpaths[i].front().height * (float) i; // el.layer = nullptr;
el.layer = nullptr; // wtels.push_back(el);
wtels.push_back(el); //}
}
conflictQueue.emplace_back_bucket(std::move(wtels), wtdptr.value(), {wtdptr.value()->plate_origin.x(), wtdptr.value()->plate_origin.y()}); conflictQueue.emplace_back_bucket(std::move(wtels), wtdptr.value(), {wtdptr.value()->plate_origin.x(), wtdptr.value()->plate_origin.y()});
} }
for (PrintObject *obj : objs) { for (PrintObject *obj : objs) {

View File

@ -2971,7 +2971,8 @@ WipeTower::ToolChangeResult WipeTower::finish_layer_new(bool extrude_perimeter,
//} //}
Polygon outer_wall; Polygon outer_wall;
outer_wall = generate_support_wall_new(writer, wt_box, feedrate, first_layer, m_use_rib_wall, extrude_perimeter, m_use_gap_wall); outer_wall = generate_support_wall_new(writer, wt_box, feedrate, first_layer, m_use_rib_wall, extrude_perimeter, m_use_gap_wall);
if (extrude_perimeter)
m_outer_wall[m_z_pos].push_back(to_polyline(outer_wall));
// brim chamfer // brim chamfer
float spacing = m_perimeter_width - m_layer_height * float(1. - M_PI_4); float spacing = m_perimeter_width - m_layer_height * float(1. - M_PI_4);
// How many perimeters shall the brim have? // How many perimeters shall the brim have?
@ -2994,6 +2995,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer_new(bool extrude_perimeter,
for (size_t i = 0; i < loops_num; ++i) { for (size_t i = 0; i < loops_num; ++i) {
outer_wall = offset(outer_wall, scaled(spacing)).front(); outer_wall = offset(outer_wall, scaled(spacing)).front();
writer.polygon(outer_wall, feedrate); writer.polygon(outer_wall, feedrate);
m_outer_wall[m_z_pos].push_back(to_polyline(outer_wall));
} }
/*for (size_t i = 0; i < loops_num; ++i) { /*for (size_t i = 0; i < loops_num; ++i) {
@ -3012,10 +3014,6 @@ WipeTower::ToolChangeResult WipeTower::finish_layer_new(bool extrude_perimeter,
if (extrude_perimeter || loops_num > 0) { if (extrude_perimeter || loops_num > 0) {
writer.add_wipe_path(outer_wall, m_filpar[m_current_tool].wipe_dist); writer.add_wipe_path(outer_wall, m_filpar[m_current_tool].wipe_dist);
if (!extrude_perimeter)
m_outer_wall.back() = to_polyline(outer_wall);
else
m_outer_wall.push_back(to_polyline(outer_wall));
} }
else { else {
// Now prepare future wipe. box contains rectangle that was extruded last (ccw). // Now prepare future wipe. box contains rectangle that was extruded last (ccw).
@ -3723,7 +3721,6 @@ void WipeTower::generate_new(std::vector<std::vector<WipeTower::ToolChangeResult
int wall_filament = get_wall_filament_for_all_layer(); int wall_filament = get_wall_filament_for_all_layer();
std::vector<WipeTower::ToolChangeResult> layer_result; std::vector<WipeTower::ToolChangeResult> layer_result;
m_outer_wall.reserve(m_plan.size());
int index = 0; int index = 0;
std::unordered_set<int> solid_blocks_id;// The contact surface of different bonded materials is solid. std::unordered_set<int> solid_blocks_id;// The contact surface of different bonded materials is solid.
for (auto layer : m_plan) { for (auto layer : m_plan) {
@ -4061,7 +4058,7 @@ WipeTower::ToolChangeResult WipeTower::only_generate_out_wall(bool is_new_mode)
//else //else
// writer.rectangle(wt_box, feedrate); // writer.rectangle(wt_box, feedrate);
outer_wall = generate_support_wall_new(writer, wt_box, feedrate, first_layer, m_use_rib_wall, true, m_use_gap_wall); outer_wall = generate_support_wall_new(writer, wt_box, feedrate, first_layer, m_use_rib_wall, true, m_use_gap_wall);
m_outer_wall.push_back( to_polyline(outer_wall)); m_outer_wall[m_z_pos].push_back(to_polyline(outer_wall));
// Now prepare future wipe. box contains rectangle that was extruded last (ccw). // Now prepare future wipe. box contains rectangle that was extruded last (ccw).
// Vec2f target = (writer.pos() == wt_box.ld ? wt_box.rd : (writer.pos() == wt_box.rd ? wt_box.ru : (writer.pos() == wt_box.ru ? wt_box.lu : wt_box.ld))); // Vec2f target = (writer.pos() == wt_box.ld ? wt_box.rd : (writer.pos() == wt_box.rd ? wt_box.ru : (writer.pos() == wt_box.ru ? wt_box.lu : wt_box.ld)));

View File

@ -188,17 +188,18 @@ public:
float get_depth() const { return m_wipe_tower_depth; } float get_depth() const { return m_wipe_tower_depth; }
float get_brim_width() const { return m_wipe_tower_brim_width_real; } float get_brim_width() const { return m_wipe_tower_brim_width_real; }
BoundingBoxf get_bbx() const { BoundingBoxf get_bbx() const {
BoundingBox box = get_extents(m_outer_wall.front()); BoundingBox box = get_extents(m_outer_wall.begin()->second);
BoundingBoxf res = BoundingBoxf(unscale(box.min), unscale(box.max)); BoundingBoxf res = BoundingBoxf(unscale(box.min), unscale(box.max));
res.translate(m_rib_offset.cast<double>()); res.translate(m_rib_offset.cast<double>());
return res; return res;
} }
Polylines get_outer_wall() const { std::map<float, Polylines> get_outer_wall() const
Polylines res = m_outer_wall; {
std::map<float, Polylines> res = m_outer_wall;
Point trans = scaled(m_rib_offset); Point trans = scaled(m_rib_offset);
for (auto &polyline : res) for (auto &[h,polylines] : res)
for (auto &p : polyline.points) for (auto &polyline : polylines)
p += trans; polyline.translate(trans.x(), trans.y());
return res; return res;
} }
float get_height() const { return m_wipe_tower_height; } float get_height() const { return m_wipe_tower_height; }
@ -481,7 +482,7 @@ private:
float m_extra_spacing = 1.f; float m_extra_spacing = 1.f;
float m_tpu_fixed_spacing = 2; float m_tpu_fixed_spacing = 2;
std::vector<Vec2f> m_wall_skip_points; std::vector<Vec2f> m_wall_skip_points;
std::vector<Polyline> m_outer_wall; std::map<float,Polylines> m_outer_wall;
bool is_first_layer() const { return size_t(m_layer_info - m_plan.begin()) == m_first_layer_idx; } bool is_first_layer() const { return size_t(m_layer_info - m_plan.begin()) == m_first_layer_idx; }
// Calculates length of extrusion line to extrude given volume // Calculates length of extrusion line to extrude given volume

View File

@ -2024,8 +2024,7 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
break; break;
} }
} }
// TODO adaptive layer height won't work with conflict checker because m_fake_wipe_tower's path is generated using fixed layer height if(!m_no_check /*&& !has_adaptive_layer_height*/)
if(!m_no_check && !has_adaptive_layer_height)
{ {
using Clock = std::chrono::high_resolution_clock; using Clock = std::chrono::high_resolution_clock;
auto startTime = Clock::now(); auto startTime = Clock::now();
@ -4098,4 +4097,40 @@ Point PrintInstance::shift_without_plate_offset() const
return shift - Point(scaled(plate_offset.x()), scaled(plate_offset.y())); return shift - Point(scaled(plate_offset.x()), scaled(plate_offset.y()));
} }
ExtrusionLayers FakeWipeTower::getTrueExtrusionLayersFromWipeTower() const
{
ExtrusionLayers wtels;
wtels.type = ExtrusionLayersType::WIPE_TOWER;
std::vector<float> layer_heights;
layer_heights.reserve(outer_wall.size());
auto pre = outer_wall.begin();
for (auto it = outer_wall.begin(); it != outer_wall.end(); ++it) {
if (it == outer_wall.begin())
layer_heights.push_back(it->first);
else {
layer_heights.push_back(it->first - pre->first);
++pre;
}
}
Point trans = {scale_(pos.x()), scale_(pos.y())};
for (auto it = outer_wall.begin(); it != outer_wall.end(); ++it) {
int index = std::distance(outer_wall.begin(), it);
ExtrusionLayer el;
ExtrusionPaths paths;
paths.reserve(it->second.size());
for (auto &polyline : it->second) {
ExtrusionPath path(ExtrusionRole::erWipeTower, 0.0, 0.0, layer_heights[index]);
path.polyline = polyline;
for (auto &p : path.polyline.points) p += trans;
paths.push_back(path);
}
el.paths = std::move(paths);
el.bottom_z = it->first - layer_heights[index];
el.layer = nullptr;
wtels.push_back(el);
}
return wtels;
}
} // namespace Slic3r } // namespace Slic3r

View File

@ -36,6 +36,7 @@ class SupportLayer;
// BBS // BBS
class TreeSupportData; class TreeSupportData;
class TreeSupport; class TreeSupport;
class ExtrusionLayers;
#define MARGIN_HEIGHT 1.5 #define MARGIN_HEIGHT 1.5
#define MAX_OUTER_NOZZLE_RADIUS 4 #define MAX_OUTER_NOZZLE_RADIUS 4
@ -621,7 +622,7 @@ struct FakeWipeTower
float depth; float depth;
float brim_width; float brim_width;
Vec2d plate_origin; Vec2d plate_origin;
Polylines outer_wall; //wipe tower's true outer wall 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) void set_fake_extrusion_data(Vec2f p, float w, float h, float lh, float d, float bd, Vec2d o)
{ {
@ -661,18 +662,7 @@ struct FakeWipeTower
return paths; return paths;
} }
std::vector<ExtrusionPaths> getTrueExtrusionPathsFromWipeTower() const ExtrusionLayers getTrueExtrusionLayersFromWipeTower() const;
{
std::vector<ExtrusionPaths> paths;
Point trans = {scale_(pos.x()), scale_(pos.y())};
for (auto &polyline : outer_wall) {
ExtrusionPath path(ExtrusionRole::erWipeTower, 0.0, 0.0, layer_height);
path.polyline.points.reserve( polyline.points.size());
for (auto &p : polyline.points) path.polyline.points.push_back(p + trans);
paths.push_back({path});
}
return paths;
}
}; };
struct WipeTowerData struct WipeTowerData