mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-14 00:52:04 +00:00
ENH: add PPS-CF/PPA-CF detection for multi-extruder printer
jira: STUDIO-9660 Change-Id: I1df024e178b8561569b493888d6057d8f96aea3c (cherry picked from commit b68a7b3bd6ad5c980885fbaed3c635ae1a424f73)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Bambulab",
|
||||
"url": "http://www.bambulab.com/Parameters/vendor/BBL.json",
|
||||
"version": "02.00.00.12",
|
||||
"version": "02.00.00.15",
|
||||
"force_update": "0",
|
||||
"description": "the initial version of BBL configurations",
|
||||
"machine_model_list": [
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
"25x0,350x0,350x320,25x320"
|
||||
],
|
||||
"machine_load_filament_time": "24",
|
||||
"unprintable_filament_types" : [
|
||||
"TPU",
|
||||
"PPS-CF,PPA-CF"
|
||||
],
|
||||
"machine_max_acceleration_x": [
|
||||
"16000",
|
||||
"16000",
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
],
|
||||
"extruder_printable_area": [],
|
||||
"extruder_printable_height": [],
|
||||
"unprintable_filament_types" : [""],
|
||||
"extruder_type": [
|
||||
"Direct Drive"
|
||||
],
|
||||
|
||||
@@ -46,6 +46,10 @@
|
||||
"320",
|
||||
"325"
|
||||
],
|
||||
"unprintable_filament_types" : [
|
||||
"",
|
||||
""
|
||||
],
|
||||
"extruder_type": [
|
||||
"Direct Drive",
|
||||
"Direct Drive"
|
||||
|
||||
@@ -55,6 +55,26 @@ bool LayerTools::is_extruder_order(unsigned int a, unsigned int b) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool check_filament_printable_after_group(const std::vector<unsigned int> &used_filaments, const std::vector<int> &filament_maps, const PrintConfig *print_config)
|
||||
{
|
||||
for (unsigned int filament_id : used_filaments) {
|
||||
std::string filament_type = print_config->filament_type.get_at(filament_id);
|
||||
for (size_t idx = 0; idx < print_config->unprintable_filament_types.values.size(); ++idx) {
|
||||
if (filament_maps[filament_id] == idx) {
|
||||
std::vector<std::string> limit_types = split_string(print_config->unprintable_filament_types.get_at(idx), ',');
|
||||
auto iter = std::find(limit_types.begin(), limit_types.end(), filament_type);
|
||||
if (iter != limit_types.end()) {
|
||||
std::string error_msg;
|
||||
std::string extruder_name = idx == 0 ? "left" : "right";
|
||||
error_msg = "Grouping error: " + filament_type + " can not be placed in the " + extruder_name + " extruder";
|
||||
throw Slic3r::RuntimeError(error_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return a zero based extruder from the region, or extruder_override if overriden.
|
||||
unsigned int LayerTools::wall_filament(const PrintRegion ®ion) const
|
||||
{
|
||||
@@ -1046,6 +1066,14 @@ std::vector<int> ToolOrdering::get_recommended_filament_maps(const std::vector<s
|
||||
fg.get_custom_seq = get_custom_seq;
|
||||
ret = fg.calc_filament_group();
|
||||
}
|
||||
|
||||
// todo: need calculated based on already grouped filaments
|
||||
// PPS-CF/PPA-CF can only be placed on the left extruder
|
||||
for (unsigned int filament_id : used_filaments) {
|
||||
if (print_config.filament_type.get_at(filament_id) == "PPS-CF" || print_config.filament_type.get_at(filament_id) == "PPA-CF") {
|
||||
ret[filament_id] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1129,6 +1157,8 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first
|
||||
}
|
||||
std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value - 1; });
|
||||
|
||||
check_filament_printable_after_group(used_filaments, filament_maps, print_config);
|
||||
|
||||
if (!check_tpu_group(used_filaments, filament_maps, print_config)) {
|
||||
if (map_mode == FilamentMapMode::fmmManual) {
|
||||
throw Slic3r::RuntimeError(std::string("Manual grouping error: TPU can only be placed in a nozzle alone."));
|
||||
|
||||
@@ -897,7 +897,7 @@ static std::vector<std::string> s_Preset_printer_options {
|
||||
"single_extruder_multi_material", "manual_filament_change", "machine_start_gcode", "machine_end_gcode", "before_layer_change_gcode", "printing_by_object_gcode", "layer_change_gcode", "time_lapse_gcode", "change_filament_gcode", "change_extrusion_role_gcode",
|
||||
"printer_model", "printer_variant", "printer_extruder_id", "printer_extruder_variant", "extruder_variant_list", "default_nozzle_volume_type",
|
||||
"printable_height", "extruder_printable_height", "extruder_clearance_radius", "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
|
||||
"nozzle_height",
|
||||
"nozzle_height", "unprintable_filament_types",
|
||||
"default_print_profile", "inherits",
|
||||
"silent_mode",
|
||||
"scan_first_layer", "machine_load_filament_time", "machine_unload_filament_time", "machine_tool_change_time", "time_cost", "machine_pause_gcode", "template_custom_gcode",
|
||||
|
||||
@@ -671,6 +671,12 @@ void PrintConfigDef::init_common_params()
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable{});
|
||||
|
||||
def = this->add("unprintable_filament_types", coStrings);
|
||||
def->label = L("Unprintable filament type");
|
||||
def->tooltip = L("Unprintable filament type");
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionStrings{""});
|
||||
|
||||
def = this->add("preferred_orientation", coFloat);
|
||||
def->label = L("Preferred orientation");
|
||||
def->tooltip = L("Automatically orient stls on the Z-axis upon initial import.");
|
||||
|
||||
@@ -1349,6 +1349,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
||||
((ConfigOptionPoints, bed_exclude_area))
|
||||
((ConfigOptionPoints, head_wrap_detect_zone))
|
||||
// BBS
|
||||
((ConfigOptionStrings, unprintable_filament_types))
|
||||
((ConfigOptionString, bed_custom_texture))
|
||||
((ConfigOptionString, bed_custom_model))
|
||||
((ConfigOptionEnum<BedType>, curr_bed_type))
|
||||
|
||||
@@ -180,6 +180,7 @@ extern size_t get_utf8_sequence_length(const char *seq, size_t size);
|
||||
extern local_encoded_string encode_path(const char *src);
|
||||
extern std::string decode_path(const char *src);
|
||||
extern std::string normalize_utf8_nfc(const char *src);
|
||||
extern std::vector<std::string> split_string(const std::string &str, char delimiter);
|
||||
|
||||
// Safely rename a file even if the target exists.
|
||||
// On Windows, the file explorer (or anti-virus or whatever else) often locks the file
|
||||
|
||||
@@ -1126,6 +1126,18 @@ std::string normalize_utf8_nfc(const char *src)
|
||||
return boost::locale::normalize(src, boost::locale::norm_nfc, locale_utf8);
|
||||
}
|
||||
|
||||
std::vector<std::string> split_string(const std::string &str, char delimiter)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
std::stringstream ss(str);
|
||||
std::string substr;
|
||||
|
||||
while (std::getline(ss, substr, delimiter)) {
|
||||
result.push_back(substr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace PerlUtils {
|
||||
// Get a file name including the extension.
|
||||
std::string path_to_filename(const char *src) { return boost::filesystem::path(src).filename().string(); }
|
||||
|
||||
@@ -285,9 +285,23 @@ PrinterArch get_printer_arch_by_str(std::string arch_str)
|
||||
|
||||
void check_filaments_for_vt_slot(const std::string &tag_vendor, const std::string &tag_type, int ams_id, bool &in_blacklist, std::string &ac, std::string &info)
|
||||
{
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
MachineObject *obj = dev->get_selected_machine();
|
||||
if (obj == nullptr)
|
||||
return;
|
||||
|
||||
if (tag_type == "TPU" && ams_id != VIRTUAL_TRAY_MAIN_ID) {
|
||||
wxString extruder_name = _L("left");
|
||||
if (obj->is_main_extruder_on_left()) {
|
||||
extruder_name = _L("right");
|
||||
}
|
||||
wxString info_str = wxString::Format(_L("TPU is not supported by %s extruder for this printer."), extruder_name);
|
||||
|
||||
ac = "prohibition";
|
||||
info = wxString(_L("TPU is not supported by deputy extruder.")).ToUTF8().data();
|
||||
info = info_str.ToUTF8().data();
|
||||
in_blacklist = true;
|
||||
}
|
||||
}
|
||||
@@ -7080,7 +7094,6 @@ void DeviceManager::load_last_machine()
|
||||
json DeviceManager::filaments_blacklist = json::object();
|
||||
|
||||
|
||||
|
||||
std::string DeviceManager::parse_printer_type(std::string type_str)
|
||||
{
|
||||
return get_value_from_config<std::string>(type_str, "printer_type");
|
||||
@@ -7243,8 +7256,54 @@ bool DeviceManager::is_virtual_slot(int ams_id)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceManager::check_filaments_printable(const std::string &tag_vendor, const std::string &tag_type, int ams_id, bool &in_blacklist, std::string &ac, std::string &info)
|
||||
{
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MachineObject *obj = dev->get_selected_machine();
|
||||
if (obj == nullptr || !obj->is_multi_extruders()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Preset *printer_preset = GUI::get_printer_preset(obj);
|
||||
if (!printer_preset)
|
||||
return true;
|
||||
|
||||
ConfigOptionStrings *unprintable_filament_types_op = dynamic_cast<ConfigOptionStrings *>(printer_preset->config.option("unprintable_filament_types"));
|
||||
if (!unprintable_filament_types_op)
|
||||
return true;
|
||||
|
||||
ConfigOptionInts *physical_extruder_map_op = dynamic_cast<ConfigOptionInts *>(printer_preset->config.option("physical_extruder_map"));
|
||||
if (!physical_extruder_map_op)
|
||||
return true;
|
||||
|
||||
std::vector<int> physical_extruder_maps = physical_extruder_map_op->values;
|
||||
for (size_t idx = 0; idx < unprintable_filament_types_op->values.size(); ++idx) {
|
||||
if (physical_extruder_maps[idx] == obj->get_extruder_id_by_ams_id(std::to_string(ams_id))) {
|
||||
std::vector<std::string> filament_types = split_string(unprintable_filament_types_op->values.at(idx), ',');
|
||||
auto iter = std::find(filament_types.begin(), filament_types.end(), tag_type);
|
||||
if (iter != filament_types.end()) {
|
||||
wxString extruder_name = idx == 0 ? _L("left") : _L("right");
|
||||
ac = "prohibition";
|
||||
info = (wxString::Format(_L("%s is not supported by %s extruder."), tag_type, extruder_name)).ToUTF8().data();
|
||||
in_blacklist = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceManager::check_filaments_in_blacklist(std::string tag_vendor, std::string tag_type, int ams_id, bool& in_blacklist, std::string& ac, std::string& info)
|
||||
{
|
||||
if (!check_filaments_printable(tag_vendor, tag_type, ams_id, in_blacklist, ac, info)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (DeviceManager::is_virtual_slot(ams_id)) {
|
||||
check_filaments_for_vt_slot(tag_vendor, tag_type, ams_id, in_blacklist, ac, info);
|
||||
return;
|
||||
|
||||
@@ -1302,6 +1302,7 @@ public:
|
||||
static bool key_field_only;
|
||||
static json function_table;
|
||||
static json filaments_blacklist;
|
||||
static json filaments_printable_blacklist;
|
||||
|
||||
template<typename T>
|
||||
static T get_value_from_config(std::string type_str, std::string item){
|
||||
@@ -1337,6 +1338,7 @@ public:
|
||||
static std::vector<std::string> get_resolution_supported(std::string type_str);
|
||||
static std::vector<std::string> get_compatible_machine(std::string type_str);
|
||||
static void check_filaments_in_blacklist(std::string tag_vendor, std::string tag_type, int ams_id, bool &in_blacklist, std::string &ac, std::string &info);
|
||||
static bool check_filaments_printable(const std::string &tag_vendor, const std::string &tag_type, int ams_id, bool &in_blacklist, std::string &ac, std::string &info);
|
||||
static boost::bimaps::bimap<std::string, std::string> get_all_model_id_with_name();
|
||||
static std::string load_gcode(std::string type_str, std::string gcode_file);
|
||||
static bool is_virtual_slot(int ams_id);
|
||||
|
||||
@@ -118,6 +118,8 @@ std::string object_limited_text = _u8L("An object is laid on the left/right extr
|
||||
std::string object_clashed_text = _u8L("An object is laid over the boundary of plate or exceeds the height limit.\n"
|
||||
"Please solve the problem by moving it totally on or off the plate, and confirming that the height is within the build volume.");
|
||||
|
||||
wxString filament_printable_error_msg;
|
||||
|
||||
GLCanvas3D::LayersEditing::~LayersEditing()
|
||||
{
|
||||
if (m_z_texture_id != 0) {
|
||||
@@ -2922,6 +2924,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
bool tpu_valid = cur_plate->check_tpu_printable_status(wxGetApp().preset_bundle->full_config(), wxGetApp().preset_bundle->get_used_tpu_filaments(cur_plate->get_extruders(true)));
|
||||
_set_warning_notification(EWarning::TPUPrintableError, !tpu_valid);
|
||||
|
||||
bool filament_printable = cur_plate->check_filament_printable(wxGetApp().preset_bundle->full_config(), filament_printable_error_msg);
|
||||
_set_warning_notification(EWarning::FilamentPrintableError, !filament_printable);
|
||||
|
||||
bool model_fits = contained_min_one && !m_model->objects.empty() && !partlyOut && object_results.filaments.empty() && tpu_valid;
|
||||
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, model_fits));
|
||||
ppl.get_curr_plate()->update_slice_ready_status(model_fits);
|
||||
@@ -2932,6 +2937,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
_set_warning_notification(EWarning::ObjectLimited, false);
|
||||
//_set_warning_notification(EWarning::SlaSupportsOutside, false);
|
||||
_set_warning_notification(EWarning::TPUPrintableError, false);
|
||||
_set_warning_notification(EWarning::FilamentPrintableError, false);
|
||||
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false));
|
||||
}
|
||||
}
|
||||
@@ -9834,6 +9840,11 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
|
||||
error = ErrorType::SLICING_ERROR;
|
||||
break;
|
||||
}
|
||||
case EWarning::FilamentPrintableError: {
|
||||
text = filament_printable_error_msg.ToUTF8();
|
||||
error = ErrorType::SLICING_ERROR;
|
||||
break;
|
||||
}
|
||||
case EWarning::MultiExtruderPrintableError: {
|
||||
for (auto error_iter = m_gcode_viewer.m_gcode_check_result.print_area_error_infos.begin(); error_iter != m_gcode_viewer.m_gcode_check_result.print_area_error_infos.end(); ++error_iter) {
|
||||
if (error_iter != m_gcode_viewer.m_gcode_check_result.print_area_error_infos.begin()) {
|
||||
@@ -9990,10 +10001,18 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
|
||||
notification_manager.close_slicing_serious_warning_notification(text);
|
||||
break;
|
||||
case SLICING_ERROR:
|
||||
if (state)
|
||||
notification_manager.push_slicing_error_notification(text, conflictObj ? std::vector<ModelObject const*>{conflictObj} : std::vector<ModelObject const*>{});
|
||||
else
|
||||
notification_manager.close_slicing_error_notification(text);
|
||||
if (warning == EWarning::FilamentPrintableError) {
|
||||
if (state)
|
||||
notification_manager.push_slicing_customize_error_notification(NotificationType::BBLFilamentPrintableError, NotificationManager::NotificationLevel::ErrorNotificationLevel, text);
|
||||
else
|
||||
notification_manager.close_slicing_customize_error_notification(NotificationType::BBLFilamentPrintableError, NotificationManager::NotificationLevel::ErrorNotificationLevel);
|
||||
}
|
||||
else {
|
||||
if (state)
|
||||
notification_manager.push_slicing_error_notification(text, conflictObj ? std::vector<ModelObject const*>{conflictObj} : std::vector<ModelObject const*>{});
|
||||
else
|
||||
notification_manager.close_slicing_error_notification(text);
|
||||
}
|
||||
break;
|
||||
case SLICING_LIMIT_ERROR:
|
||||
if (state)
|
||||
|
||||
@@ -385,6 +385,7 @@ class GLCanvas3D
|
||||
GCodeConflict,
|
||||
ToolHeightOutside,
|
||||
TPUPrintableError,
|
||||
FilamentPrintableError,
|
||||
MultiExtruderPrintableError, // after slice
|
||||
MultiExtruderHeightOutside, // after slice
|
||||
FilamentUnPrintableOnFirstLayer
|
||||
|
||||
@@ -152,6 +152,7 @@ enum class NotificationType
|
||||
BBLPreviewOnlyMode,
|
||||
BBLPrinterConfigUpdateAvailable,
|
||||
BBLUserPresetExceedLimit,
|
||||
BBLFilamentPrintableError,
|
||||
BBLSliceLimitError,
|
||||
BBLSliceMultiExtruderHeightOutside,
|
||||
NotificationTypeCount
|
||||
|
||||
@@ -1727,6 +1727,29 @@ std::vector<int> PartPlate::get_used_filaments()
|
||||
return std::vector(used_extruders_set.begin(), used_extruders_set.end());
|
||||
}
|
||||
|
||||
bool PartPlate::check_filament_printable(const DynamicPrintConfig &config, wxString& error_message)
|
||||
{
|
||||
error_message.clear();
|
||||
std::vector<int> used_filaments = get_extruders(true); // 1 base
|
||||
if (!used_filaments.empty()) {
|
||||
for (auto filament_idx : used_filaments) {
|
||||
int filament_id = filament_idx - 1;
|
||||
std::string filament_type = config.option<ConfigOptionStrings>("filament_type")->values.at(filament_id);
|
||||
std::vector<int> filament_map = get_real_filament_maps(config);
|
||||
int extruder_idx = filament_map[filament_id] - 1;
|
||||
std::string filament_types_str = config.option<ConfigOptionStrings>("unprintable_filament_types")->values.at(extruder_idx);
|
||||
std::vector<string> filament_types = split_string(filament_types_str, ',');
|
||||
auto iter = std::find(filament_types.begin(), filament_types.end(), filament_type);
|
||||
if (iter != filament_types.end()) {
|
||||
wxString extruder_name = extruder_idx == 0 ? _L("left") : _L("right");
|
||||
error_message = wxString::Format(_L("Filament %s cannot be placed in the %s extruder for printing."), filament_type, extruder_name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PartPlate::check_tpu_printable_status(const DynamicPrintConfig & config, const std::vector<int> &tpu_filaments)
|
||||
{
|
||||
bool tpu_valid = true;
|
||||
|
||||
@@ -331,6 +331,7 @@ public:
|
||||
// get used filaments from gcode result, 1 based idx
|
||||
std::vector<int> get_used_filaments();
|
||||
int get_physical_extruder_by_filament_id(const DynamicConfig& g_config, int idx) const;
|
||||
bool check_filament_printable(const DynamicPrintConfig & config, wxString& error_message);
|
||||
bool check_tpu_printable_status(const DynamicPrintConfig & config, const std::vector<int> &tpu_filaments);
|
||||
|
||||
/* instance related operations*/
|
||||
|
||||
Reference in New Issue
Block a user