mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-31 06:42:07 +00:00
ENH: Add gcode check for multi_extruder
jira: none Change-Id: Iebc43e608c4509eb62b280af2d401fa9e0e089ba (cherry picked from commit c75c10e312b8d0bd5404d92db88c95a9e6186bc1)
This commit is contained in:
@@ -1627,6 +1627,19 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
||||
break;
|
||||
}
|
||||
}
|
||||
// check gcode is valid in multi_extruder printabele area
|
||||
int extruder_size = m_print->config().nozzle_diameter.values.size();
|
||||
if (extruder_size > 1) {
|
||||
std::vector<Vec2d> printable_area = m_print->get_printable_area();
|
||||
Polygon printable_poly = Polygon::new_scale(printable_area);
|
||||
std::vector<std::vector<Vec2d>> extruder_printable_areas = m_print->get_extruder_printable_area();
|
||||
std::vector<Polygons> extruder_unprintable_polys;
|
||||
for (const auto &e_printable_area : extruder_printable_areas) {
|
||||
Polygons ploys = diff(printable_poly, Polygon::new_scale(e_printable_area));
|
||||
extruder_unprintable_polys.emplace_back(ploys);
|
||||
}
|
||||
m_processor.check_multi_extruder_gcode_valid(extruder_unprintable_polys, m_print->get_filament_maps());
|
||||
}
|
||||
|
||||
m_processor.finalize(true);
|
||||
// DoExport::update_print_estimated_times_stats(m_processor, print->m_print_statistics);
|
||||
|
||||
@@ -698,6 +698,59 @@ GCodeProcessor::GCodeProcessor()
|
||||
m_time_processor.machines[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Stealth)].line_m73_stop_mask = "M73 D%s\n";
|
||||
}
|
||||
|
||||
bool GCodeProcessor::check_multi_extruder_gcode_valid(const std::vector<Polygons> &unprintable_areas, const std::vector<int> &filament_map)
|
||||
{
|
||||
m_result.gcode_check_result.reset();
|
||||
|
||||
auto to_2d = [](const Vec3d &pos) -> Point {
|
||||
Point ps(scale_(pos.x()), scale_(pos.y()));
|
||||
return ps;
|
||||
};
|
||||
|
||||
std::map<int, Points> gcode_path_pos;
|
||||
for (const GCodeProcessorResult::MoveVertex &move : m_result.moves) {
|
||||
if (move.type == EMoveType::Extrude/* || move.type == EMoveType::Travel*/) {
|
||||
if (move.is_arc_move_with_interpolation_points()) {
|
||||
for (int i = 0; i < move.interpolation_points.size(); i++) {
|
||||
gcode_path_pos[int(move.extruder_id)].emplace_back(to_2d(move.interpolation_points[i].cast<double>()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
gcode_path_pos[int(move.extruder_id)].emplace_back(to_2d(move.position.cast<double>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool valid = true;
|
||||
for (auto iter = gcode_path_pos.begin(); iter != gcode_path_pos.end(); ++iter) {
|
||||
int extruder_id = filament_map[iter->first] - 1;
|
||||
Polygon path_poly(iter->second);
|
||||
BoundingBox bbox = path_poly.bounding_box();
|
||||
|
||||
// Simplified use bounding_box, Accurate calculation is not efficient
|
||||
for (const Polygon &poly : unprintable_areas[extruder_id]) {
|
||||
if (poly.bounding_box().overlap(bbox)) {
|
||||
m_result.gcode_check_result.error_code = 1;
|
||||
m_result.gcode_check_result.error_infos[extruder_id].push_back(iter->first);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Accurate calculation is not efficient
|
||||
for (const Polygon& poly : unprintable_areas[extruder_id]) {
|
||||
if (poly.overlaps({path_poly})) {
|
||||
m_result.gcode_check_result.error_code = 1;
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
void GCodeProcessor::apply_config(const PrintConfig& config)
|
||||
{
|
||||
m_parser.apply_config(config);
|
||||
|
||||
@@ -133,9 +133,21 @@ class Print;
|
||||
|
||||
using ConflictResultOpt = std::optional<ConflictResult>;
|
||||
|
||||
struct GCodeCheckResult
|
||||
{
|
||||
int error_code = 0; // 0 means succeed
|
||||
std::map<int, std::vector<int>> error_infos; // extruder_id to filament_ids
|
||||
|
||||
void reset() {
|
||||
error_code = 0;
|
||||
error_infos.clear();
|
||||
}
|
||||
};
|
||||
|
||||
struct GCodeProcessorResult
|
||||
{
|
||||
ConflictResultOpt conflict_result;
|
||||
GCodeCheckResult gcode_check_result;
|
||||
BedMatchResult bed_match_result;
|
||||
|
||||
struct SettingsIds
|
||||
@@ -260,6 +272,7 @@ class Print;
|
||||
spiral_vase_layers = other.spiral_vase_layers;
|
||||
warnings = other.warnings;
|
||||
bed_type = other.bed_type;
|
||||
gcode_check_result = other.gcode_check_result;
|
||||
bed_match_result = other.bed_match_result;
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
time = other.time;
|
||||
@@ -776,6 +789,8 @@ class Print;
|
||||
public:
|
||||
GCodeProcessor();
|
||||
|
||||
// check whether the gcode path meets the filament_map grouping requirements
|
||||
bool check_multi_extruder_gcode_valid(const std::vector<Polygons> &unprintable_areas, const std::vector<int>& filament_map);
|
||||
void apply_config(const PrintConfig& config);
|
||||
void set_print(Print* print) { m_print = print; }
|
||||
void enable_stealth_time_estimator(bool enabled);
|
||||
|
||||
@@ -2651,6 +2651,16 @@ FilamentMapMode Print::get_filament_map_mode() const
|
||||
return m_config.filament_map_mode;
|
||||
}
|
||||
|
||||
std::vector<Vec2d> Print::get_printable_area()
|
||||
{
|
||||
return m_config.printable_area.values;
|
||||
}
|
||||
|
||||
std::vector<std::vector<Vec2d>> Print::get_extruder_printable_area()
|
||||
{
|
||||
return m_config.extruder_printable_area.values;
|
||||
}
|
||||
|
||||
size_t Print::get_extruder_id(unsigned int filament_id) const
|
||||
{
|
||||
std::vector<int> filament_map = get_filament_maps();
|
||||
|
||||
@@ -956,7 +956,6 @@ public:
|
||||
// get the group label of filament
|
||||
size_t get_extruder_id(unsigned int filament_id) const;
|
||||
|
||||
// 1 based ids
|
||||
const std::vector<std::vector<int>>& get_unprintable_filament_ids() const { return m_unprintable_filament_ids; }
|
||||
void set_unprintable_filament_ids(const std::vector<std::vector<int>> &filament_ids) { m_unprintable_filament_ids = filament_ids; }
|
||||
|
||||
@@ -1099,6 +1098,8 @@ private:
|
||||
FakeWipeTower m_fake_wipe_tower;
|
||||
bool m_has_auto_filament_map_result{false};
|
||||
|
||||
std::vector<std::vector<int>> m_unprintable_filament_ids;
|
||||
|
||||
//SoftFever: calibration
|
||||
Calib_Params m_calib_params;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user