ENH: support to set bed type for each plate

Signed-off-by: yifan.wu <yifan.wu@bambulab.com>
Change-Id: I654743ce8b49057587545c3acfe0b78504242d46
This commit is contained in:
yifan.wu 2022-10-25 21:57:07 +08:00 committed by Lane.Wei
parent c61fd447c9
commit e363966f9b
8 changed files with 81 additions and 8 deletions

View file

@ -235,6 +235,7 @@ static constexpr const char* FIRST_TRIANGLE_ID_ATTR = "firstid";
static constexpr const char* LAST_TRIANGLE_ID_ATTR = "lastid"; static constexpr const char* LAST_TRIANGLE_ID_ATTR = "lastid";
static constexpr const char* SUBTYPE_ATTR = "subtype"; static constexpr const char* SUBTYPE_ATTR = "subtype";
static constexpr const char* LOCK_ATTR = "locked"; static constexpr const char* LOCK_ATTR = "locked";
static constexpr const char* BED_TYPE_ATTR = "bed_type";
static constexpr const char* GCODE_FILE_ATTR = "gcode_file"; static constexpr const char* GCODE_FILE_ATTR = "gcode_file";
static constexpr const char* THUMBNAIL_FILE_ATTR = "thumbnail_file"; static constexpr const char* THUMBNAIL_FILE_ATTR = "thumbnail_file";
static constexpr const char* PATTERN_FILE_ATTR = "pattern_file"; static constexpr const char* PATTERN_FILE_ATTR = "pattern_file";
@ -3131,6 +3132,12 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
{ {
std::istringstream(value) >> std::boolalpha >> m_curr_plater->locked; std::istringstream(value) >> std::boolalpha >> m_curr_plater->locked;
} }
else if (key == BED_TYPE_ATTR)
{
BedType bed_type = BedType::btPC;
ConfigOptionEnum<BedType>::from_string(value, bed_type);
m_curr_plater->config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(bed_type));
}
else if (key == GCODE_FILE_ATTR) else if (key == GCODE_FILE_ATTR)
{ {
m_curr_plater->gcode_file = value; m_curr_plater->gcode_file = value;
@ -5563,6 +5570,11 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
//plate index //plate index
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PLATERID_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->plate_index + 1 << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PLATERID_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->plate_index + 1 << "\"/>\n";
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << LOCK_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->locked<< "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << LOCK_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->locked<< "\"/>\n";
ConfigOption* bed_type_opt = plate_data->config.option("curr_bed_type");
t_config_enum_names bed_type_names = ConfigOptionEnum<BedType>::get_enum_names();
if (bed_type_opt != nullptr && bed_type_names.size() > bed_type_opt->getInt())
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << BED_TYPE_ATTR << "\" " << VALUE_ATTR << "=\"" << bed_type_names[bed_type_opt->getInt()] << "\"/>\n";
if (save_gcode) if (save_gcode)
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << GCODE_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << xml_escape(plate_data->gcode_file) << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << GCODE_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << xml_escape(plate_data->gcode_file) << "\"/>\n";
if (!plate_data->gcode_file.empty()) { if (!plate_data->gcode_file.empty()) {

View file

@ -67,6 +67,7 @@ struct PlateData
std::string gcode_prediction; std::string gcode_prediction;
std::string gcode_weight; std::string gcode_weight;
std::vector<FilamentInfo> slice_filaments_info; std::vector<FilamentInfo> slice_filaments_info;
DynamicPrintConfig config;
bool is_sliced_valid = false; bool is_sliced_valid = false;
bool toolpath_outside {false}; bool toolpath_outside {false};

View file

@ -564,7 +564,7 @@ void PrintConfigDef::init_fff_params()
def->max = 120; def->max = 120;
def->set_default_value(new ConfigOptionInts{45}); def->set_default_value(new ConfigOptionInts{45});
def = this->add("curr_bed_type", coEnums); def = this->add("curr_bed_type", coEnum);
def->label = L("Bed type"); def->label = L("Bed type");
def->tooltip = L("Bed types supported by the printer"); def->tooltip = L("Bed types supported by the printer");
def->mode = comSimple; def->mode = comSimple;

View file

@ -654,7 +654,10 @@ Print::ApplyStatus BackgroundSlicingProcess::apply(const Model &model, const Dyn
{ {
assert(m_print != nullptr); assert(m_print != nullptr);
assert(config.opt_enum<PrinterTechnology>("printer_technology") == m_print->technology()); assert(config.opt_enum<PrinterTechnology>("printer_technology") == m_print->technology());
Print::ApplyStatus invalidated = m_print->apply(model, config); // TODO: add partplate config
DynamicPrintConfig new_config = config;
new_config.apply(*m_current_plate->config());
Print::ApplyStatus invalidated = m_print->apply(model, new_config);
if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) != 0 && m_print->technology() == ptFFF && if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) != 0 && m_print->technology() == ptFFF &&
!m_fff_print->is_step_done(psGCodeExport)) { !m_fff_print->is_step_done(psGCodeExport)) {
// Some FFF status was invalidated, and the G-code was not exported yet. // Some FFF status was invalidated, and the G-code was not exported yet.

View file

@ -4036,11 +4036,18 @@ void ObjectList::select_items(const std::vector<ObjectVolumeID>& ov_ids)
void ObjectList::select_items(const wxDataViewItemArray& sels) void ObjectList::select_items(const wxDataViewItemArray& sels)
{ {
m_prevent_list_events = true; m_prevent_list_events = true;
m_last_selected_item = sels.empty() ? wxDataViewItem(nullptr) : sels.back(); m_last_selected_item = sels.empty() ? wxDataViewItem(nullptr) : sels.back();
UnselectAll(); UnselectAll();
if (!sels.empty()) {
SetSelections(sels); SetSelections(sels);
}
else {
int curr_plate_idx = wxGetApp().plater()->get_partplate_list().get_curr_plate_index();
on_plate_selected(curr_plate_idx);
}
part_selection_changed(); part_selection_changed();
m_prevent_list_events = false; m_prevent_list_events = false;

View file

@ -130,6 +130,33 @@ void PartPlate::init()
m_print = nullptr; m_print = nullptr;
} }
BedType PartPlate::get_bed_type()
{
std::string bed_type_key = "curr_bed_type";
if (m_config.has(bed_type_key))
return m_config.opt_enum<BedType>(bed_type_key);
if (m_plater) {
// In GUI mode
DynamicConfig& proj_cfg = wxGetApp().preset_bundle->project_config;
if (proj_cfg.has(bed_type_key))
return proj_cfg.opt_enum<BedType>(bed_type_key);
}
return BedType::btPC;
}
void PartPlate::set_bed_type(BedType bed_type)
{
m_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(bed_type));
}
void PartPlate::reset_bed_type()
{
m_config.erase("curr_bed_type");
}
bool PartPlate::valid_instance(int obj_id, int instance_id) bool PartPlate::valid_instance(int obj_id, int instance_id)
{ {
if ((obj_id >= 0) && (obj_id < m_model->objects.size())) if ((obj_id >= 0) && (obj_id < m_model->objects.size()))
@ -4015,6 +4042,7 @@ int PartPlateList::store_to_3mf_structure(PlateDataPtrs& plate_data_list, bool w
plate_data_item->locked = m_plate_list[i]->m_locked; plate_data_item->locked = m_plate_list[i]->m_locked;
plate_data_item->plate_index = m_plate_list[i]->m_plate_index; plate_data_item->plate_index = m_plate_list[i]->m_plate_index;
plate_data_item->plate_thumbnail.load_from(m_plate_list[i]->thumbnail_data); plate_data_item->plate_thumbnail.load_from(m_plate_list[i]->thumbnail_data);
plate_data_item->config.apply(*m_plate_list[i]->config());
if (m_plate_list[i]->obj_to_instance_set.size() > 0) if (m_plate_list[i]->obj_to_instance_set.size() > 0)
{ {
@ -4080,6 +4108,7 @@ int PartPlateList::load_from_3mf_structure(PlateDataPtrs& plate_data_list)
{ {
int index = create_plate(false); int index = create_plate(false);
m_plate_list[index]->m_locked = plate_data_list[i]->locked; m_plate_list[index]->m_locked = plate_data_list[i]->locked;
m_plate_list[index]->config()->apply(plate_data_list[i]->config);
if (plate_data_list[i]->plate_index != index) if (plate_data_list[i]->plate_index != index)
{ {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(":plate index %1% seems invalid, skip it")% plate_data_list[i]->plate_index; BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(":plate index %1% seems invalid, skip it")% plate_data_list[i]->plate_index;

View file

@ -142,6 +142,9 @@ private:
int m_hover_id; int m_hover_id;
bool m_selected; bool m_selected;
// BBS
DynamicPrintConfig m_config;
void init(); void init();
bool valid_instance(int obj_id, int instance_id); bool valid_instance(int obj_id, int instance_id);
void generate_print_polygon(ExPolygon &print_polygon); void generate_print_polygon(ExPolygon &print_polygon);
@ -200,6 +203,11 @@ public:
//clear alll the instances in plate //clear alll the instances in plate
void clear(bool clear_sliced_result = true); void clear(bool clear_sliced_result = true);
BedType get_bed_type();
void set_bed_type(BedType);
void reset_bed_type();
DynamicPrintConfig* config() { return &m_config; }
//static const int plate_x_offset = 20; //mm //static const int plate_x_offset = 20; //mm
//static const double plate_x_gap = 0.2; //static const double plate_x_gap = 0.2;
ThumbnailData thumbnail_data; ThumbnailData thumbnail_data;
@ -373,7 +381,7 @@ public:
std::vector<std::pair<int, int>> objects_and_instances; std::vector<std::pair<int, int>> objects_and_instances;
std::vector<std::pair<int, int>> instances_outside; std::vector<std::pair<int, int>> instances_outside;
ar(m_plate_index, m_print_index, m_origin, m_width, m_depth, m_height, m_locked, m_selected, m_ready_for_slice, m_slice_result_valid, m_printable, m_tmp_gcode_path, objects_and_instances, instances_outside); ar(m_plate_index, m_print_index, m_origin, m_width, m_depth, m_height, m_locked, m_selected, m_ready_for_slice, m_slice_result_valid, m_printable, m_tmp_gcode_path, objects_and_instances, instances_outside, m_config);
for (std::vector<std::pair<int, int>>::iterator it = objects_and_instances.begin(); it != objects_and_instances.end(); ++it) for (std::vector<std::pair<int, int>>::iterator it = objects_and_instances.begin(); it != objects_and_instances.end(); ++it)
obj_to_instance_set.insert(std::pair(it->first, it->second)); obj_to_instance_set.insert(std::pair(it->first, it->second));
@ -391,7 +399,7 @@ public:
for (std::set<std::pair<int, int>>::iterator it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); ++it) for (std::set<std::pair<int, int>>::iterator it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); ++it)
objects_and_instances.emplace_back(it->first, it->second); objects_and_instances.emplace_back(it->first, it->second);
ar(m_plate_index, m_print_index, m_origin, m_width, m_depth, m_height, m_locked, m_selected, m_ready_for_slice, m_slice_result_valid, m_printable, m_tmp_gcode_path, objects_and_instances, instances_outside); ar(m_plate_index, m_print_index, m_origin, m_width, m_depth, m_height, m_locked, m_selected, m_ready_for_slice, m_slice_result_valid, m_printable, m_tmp_gcode_path, objects_and_instances, instances_outside, m_config);
} }
/*template<class Archive> void serialize(Archive& ar) /*template<class Archive> void serialize(Archive& ar)
{ {

View file

@ -2527,7 +2527,7 @@ void Plater::setExtruderParams(std::map<size_t, Slic3r::ExtruderParams>& extPara
for (unsigned int i = 0; i != numExtruders; ++i) { for (unsigned int i = 0; i != numExtruders; ++i) {
std::string matName = ""; std::string matName = "";
// BBS // BBS
int bedTemp = 0; int bedTemp = 35;
double endTemp = 0.f; double endTemp = 0.f;
if (config.has("filament_type")) { if (config.has("filament_type")) {
matName = config.opt_string("filament_type", i); matName = config.opt_string("filament_type", i);
@ -2536,10 +2536,14 @@ void Plater::setExtruderParams(std::map<size_t, Slic3r::ExtruderParams>& extPara
endTemp = config.opt_int("nozzle_temperature", i); endTemp = config.opt_int("nozzle_temperature", i);
} }
// FIXME: curr_bed_type is now a plate config rather than a global config.
// Currently bed temp is not used for brim generation, so just comment it for now.
#if 0
if (config.has("curr_bed_type")) { if (config.has("curr_bed_type")) {
BedType curr_bed_type = config.opt_enum<BedType>("curr_bed_type"); BedType curr_bed_type = config.opt_enum<BedType>("curr_bed_type");
bedTemp = config.opt_int(get_bed_temp_key(curr_bed_type), i); bedTemp = config.opt_int(get_bed_temp_key(curr_bed_type), i);
} }
#endif
if (i == 0) extParas.insert({ i,{matName, bedTemp, endTemp} }); if (i == 0) extParas.insert({ i,{matName, bedTemp, endTemp} });
extParas.insert({ i + 1,{matName, bedTemp, endTemp} }); extParas.insert({ i + 1,{matName, bedTemp, endTemp} });
} }
@ -5146,6 +5150,7 @@ void Plater::priv::on_select_bed_type(wxCommandEvent &evt)
DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config; DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config;
const t_config_enum_values* keys_map = print_config_def.get("curr_bed_type")->enum_keys_map; const t_config_enum_values* keys_map = print_config_def.get("curr_bed_type")->enum_keys_map;
if (keys_map) { if (keys_map) {
BedType bed_type = btCount; BedType bed_type = btCount;
for (auto item : *keys_map) { for (auto item : *keys_map) {
@ -5155,6 +5160,11 @@ void Plater::priv::on_select_bed_type(wxCommandEvent &evt)
if (bed_type != btCount) { if (bed_type != btCount) {
config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(bed_type)); config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(bed_type));
// clear all plates' bed type config
for (int i = 0; i < partplate_list.get_plate_count(); i++)
partplate_list.get_plate(i)->reset_bed_type();
// update plater with new config // update plater with new config
q->on_config_change(wxGetApp().preset_bundle->full_config()); q->on_config_change(wxGetApp().preset_bundle->full_config());
@ -5781,7 +5791,7 @@ void Plater::priv::on_action_export_to_sdcard(SimpleEvent&)
void Plater::priv::on_plate_selected(SimpleEvent&) void Plater::priv::on_plate_selected(SimpleEvent&)
{ {
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received plate selected event\n" ; BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received plate selected event\n" ;
//sidebar->obj_list()->on_plate_selected(partplate_list.get_curr_plate_index()); sidebar->obj_list()->on_plate_selected(partplate_list.get_curr_plate_index());
} }
void Plater::priv::on_action_request_model_id(wxCommandEvent& evt) void Plater::priv::on_action_request_model_id(wxCommandEvent& evt)
@ -10084,6 +10094,9 @@ int Plater::select_plate(int plate_index, bool need_slice)
} }
} }
} }
p->on_plate_selected(SimpleEvent(EVT_GLCANVAS_PLATE_SELECT));
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, return %3%")%__LINE__ %plate_index %ret; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, return %3%")%__LINE__ %plate_index %ret;
return ret; return ret;
} }