mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 08:05:58 +08:00
Serialize parameters from json var to config opt format
improved config options filtering changed outgoing json for upload to connect
This commit is contained in:
parent
a627c4c64e
commit
eb7f27c83d
@ -3828,9 +3828,7 @@ namespace {
|
||||
const Preset* find_preset_by_nozzle_and_options(
|
||||
const PrinterPresetCollection& collection
|
||||
, const std::string& model_id
|
||||
, const std::string& nozzle
|
||||
, const std::map<std::string
|
||||
, std::string>& options)
|
||||
, std::map<std::string, std::vector<std::string>>& options)
|
||||
{
|
||||
// find all matching presets when repo prefix is ommited
|
||||
std::vector<const Preset*> results;
|
||||
@ -3854,33 +3852,39 @@ const Preset* find_preset_by_nozzle_and_options(
|
||||
|
||||
if (!preset.is_system || printer_model != model_id)
|
||||
continue;
|
||||
// nozzle diameter
|
||||
if (!nozzle.empty() && preset.config.has("nozzle_diameter")) {
|
||||
double nozzle_diameter = static_cast<const ConfigOptionFloats*>(preset.config.option("nozzle_diameter"))->values[0];
|
||||
std::string nozzle_diameter_serialized = into_u8(double_to_string(nozzle_diameter));
|
||||
if (size_t pos = nozzle_diameter_serialized.find(",") != std::string::npos) {
|
||||
nozzle_diameter_serialized.replace(pos, 1, 1, '.');
|
||||
}
|
||||
if (nozzle != nozzle_diameter_serialized) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// other options
|
||||
// options (including nozzle_diameter)
|
||||
bool failed = false;
|
||||
for (const auto& opt : options) {
|
||||
if (!preset.config.has(opt.first)) {
|
||||
failed = true;
|
||||
break;
|
||||
assert(preset.config.has(opt.first));
|
||||
// We compare only first value now, but options contains data for all (some might be empty tho)
|
||||
std::string opt_val;
|
||||
if (preset.config.option(opt.first)->is_scalar()) {
|
||||
opt_val = preset.config.option(opt.first)->serialize();
|
||||
} else {
|
||||
switch (preset.config.option(opt.first)->type()) {
|
||||
case coInts: opt_val = std::to_string(static_cast<const ConfigOptionInts*>(preset.config.option(opt.first))->values[0]); break;
|
||||
case coFloats:
|
||||
opt_val = into_u8(double_to_string(static_cast<const ConfigOptionFloats*>(preset.config.option(opt.first))->values[0]));
|
||||
if (size_t pos = opt_val.find(",") != std::string::npos)
|
||||
opt_val.replace(pos, 1, 1, '.');
|
||||
break;
|
||||
case coStrings: opt_val = static_cast<const ConfigOptionStrings*>(preset.config.option(opt.first))->values[0]; break;
|
||||
case coBools: opt_val = static_cast<const ConfigOptionBools*>(preset.config.option(opt.first))->values[0] ? "1" : "0"; break;
|
||||
default:
|
||||
assert(true);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (preset.config.option(opt.first)->serialize() != opt.second) {
|
||||
|
||||
if (opt_val != opt.second[0])
|
||||
{
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (failed) {
|
||||
continue;
|
||||
if (!failed) {
|
||||
results.push_back(&preset);
|
||||
}
|
||||
results.push_back(&preset);
|
||||
}
|
||||
// find visible without prefix
|
||||
for (const Preset *preset : results) {
|
||||
@ -3924,12 +3928,23 @@ bool GUI_App::select_printer_from_connect(const std::string& msg)
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to select printer from Connect. Printer_model is empty.";
|
||||
return false;
|
||||
}
|
||||
std::string nozzle = UserAccountUtils::get_nozzle_from_json(ptree);
|
||||
std::map<std::string, std::string> config_options_to_match;
|
||||
std::map<std::string, std::vector<std::string>> config_options_to_match;
|
||||
UserAccountUtils::fill_config_options_from_json(ptree, config_options_to_match);
|
||||
BOOST_LOG_TRIVIAL(info) << "Select printer from Connect. Model: " << model_name << "nozzle: " << nozzle;
|
||||
// prevent not having nozzle diameter
|
||||
if (config_options_to_match.find("nozzle_diameter") == config_options_to_match.end()) {
|
||||
std::string diameter = UserAccountUtils::get_keyword_from_json(ptree, msg, "nozzle_diameter");
|
||||
if (!diameter.empty())
|
||||
config_options_to_match["nozzle_diameter"] = {diameter};
|
||||
}
|
||||
// log
|
||||
BOOST_LOG_TRIVIAL(info) << "Select printer from Connect. Model: " << model_name;
|
||||
for(const auto& pair :config_options_to_match) {
|
||||
std::string out;
|
||||
for(const std::string& val :pair.second) { out += val + ",";}
|
||||
BOOST_LOG_TRIVIAL(info) << pair.first << ": " << out;
|
||||
}
|
||||
// select printer
|
||||
const Preset* printer_preset = find_preset_by_nozzle_and_options(preset_bundle->printers, model_name, nozzle, config_options_to_match);
|
||||
const Preset* printer_preset = find_preset_by_nozzle_and_options(preset_bundle->printers, model_name, config_options_to_match);
|
||||
bool is_installed = printer_preset && select_printer_preset(printer_preset);
|
||||
// notification
|
||||
std::string out = printer_preset ?
|
||||
@ -4031,6 +4046,9 @@ void GUI_App::select_filament_from_connect(const std::string& msg)
|
||||
size_t extruder_count = preset_bundle->extruders_filaments.size();
|
||||
if (extruder_count != materials.size()) {
|
||||
BOOST_LOG_TRIVIAL(error) << format("Failed to select filament from Connect. Selected printer has %1% extruders while data from Connect contains %2% materials.", extruder_count, materials.size());
|
||||
plater()->get_notification_manager()->close_notification_of_type(NotificationType::SelectFilamentFromConnect);
|
||||
// TRN: Notification text.
|
||||
plater()->get_notification_manager()->push_notification(NotificationType::SelectFilamentFromConnect, NotificationManager::NotificationLevel::ImportantNotificationLevel, _u8L("Failed to select filament from Connect."));
|
||||
return;
|
||||
}
|
||||
std::string notification_text;
|
||||
@ -4065,7 +4083,6 @@ void GUI_App::handle_connect_request_printer_select_inner(const std::string & ms
|
||||
BOOST_LOG_TRIVIAL(debug) << "Handling web request: " << msg;
|
||||
// return to plater
|
||||
this->mainframe->select_tab(size_t(0));
|
||||
|
||||
if (!select_printer_from_connect(msg)) {
|
||||
// If printer was not selected, do not select filament.
|
||||
return;
|
||||
|
@ -11,7 +11,7 @@ namespace pt = boost::property_tree;
|
||||
namespace Slic3r { namespace GUI { namespace UserAccountUtils {
|
||||
|
||||
namespace {
|
||||
std::string parse_tree_for_param(const pt::ptree &tree, const std::string ¶m) {
|
||||
std::string parse_tree_for_param(const pt::ptree& tree, const std::string& param) {
|
||||
for (const auto §ion : tree) {
|
||||
if (section.first == param) {
|
||||
return section.second.data();
|
||||
@ -24,8 +24,7 @@ std::string parse_tree_for_param(const pt::ptree &tree, const std::string ¶m
|
||||
}
|
||||
|
||||
void parse_tree_for_param_vector(
|
||||
const pt::ptree &tree, const std::string ¶m, std::vector<std::string> &results
|
||||
) {
|
||||
const pt::ptree &tree, const std::string& param, std::vector<std::string>& results) {
|
||||
for (const auto §ion : tree) {
|
||||
if (section.first == param) {
|
||||
results.emplace_back(section.second.data());
|
||||
@ -35,7 +34,7 @@ void parse_tree_for_param_vector(
|
||||
}
|
||||
}
|
||||
|
||||
pt::ptree parse_tree_for_subtree(const pt::ptree &tree, const std::string ¶m) {
|
||||
pt::ptree parse_tree_for_subtree(const pt::ptree& tree, const std::string& param) {
|
||||
for (const auto §ion : tree) {
|
||||
if (section.first == param) {
|
||||
return section.second;
|
||||
@ -47,7 +46,7 @@ pt::ptree parse_tree_for_subtree(const pt::ptree &tree, const std::string ¶m
|
||||
return pt::ptree();
|
||||
}
|
||||
|
||||
void json_to_ptree(boost::property_tree::ptree &ptree, const std::string &json) {
|
||||
void json_to_ptree(boost::property_tree::ptree& ptree, const std::string& json) {
|
||||
try {
|
||||
std::stringstream ss(json);
|
||||
pt::read_json(ss, ptree);
|
||||
@ -59,7 +58,7 @@ void json_to_ptree(boost::property_tree::ptree &ptree, const std::string &json)
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string get_nozzle_from_json(boost::property_tree::ptree &ptree) {
|
||||
std::string get_nozzle_from_json(boost::property_tree::ptree& ptree) {
|
||||
assert(!ptree.empty());
|
||||
|
||||
std::string out = parse_tree_for_param(ptree, "nozzle_diameter");
|
||||
@ -74,7 +73,7 @@ std::string get_nozzle_from_json(boost::property_tree::ptree &ptree) {
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string get_keyword_from_json(boost::property_tree::ptree &ptree, const std::string &json, const std::string &keyword )
|
||||
std::string get_keyword_from_json(boost::property_tree::ptree& ptree, const std::string& json, const std::string& keyword )
|
||||
{
|
||||
if (ptree.empty()) {
|
||||
json_to_ptree(ptree, json);
|
||||
@ -83,7 +82,7 @@ std::string get_keyword_from_json(boost::property_tree::ptree &ptree, const std:
|
||||
return parse_tree_for_param(ptree, keyword);
|
||||
}
|
||||
|
||||
void fill_supported_printer_models_from_json(boost::property_tree::ptree &ptree, std::vector<std::string> &result)
|
||||
void fill_supported_printer_models_from_json(boost::property_tree::ptree& ptree, std::vector<std::string>& result)
|
||||
{
|
||||
assert(!ptree.empty());
|
||||
std::string printer_model = parse_tree_for_param(ptree, "printer_model");
|
||||
@ -102,16 +101,87 @@ void fill_supported_printer_models_from_json(boost::property_tree::ptree &ptree,
|
||||
}
|
||||
}
|
||||
|
||||
void fill_config_options_from_json(boost::property_tree::ptree& ptree, std::map<std::string, std::string>& result)
|
||||
namespace {
|
||||
std::string json_var_to_opt_string(const std::string& json_var)
|
||||
{
|
||||
if (json_var == "true")
|
||||
return "1";
|
||||
if (json_var == "false")
|
||||
return "0";
|
||||
return json_var;
|
||||
}
|
||||
}
|
||||
|
||||
void fill_config_options_from_json(boost::property_tree::ptree& ptree, std::map<std::string, std::vector<std::string>>& result)
|
||||
{
|
||||
assert(!ptree.empty());
|
||||
pt::ptree subtree = parse_tree_for_subtree(ptree, "printerConfig");
|
||||
for (const auto &item : subtree) {
|
||||
result[item.first] = item.second.data();
|
||||
/*
|
||||
"slot": {
|
||||
"active": 3,
|
||||
"slots": {
|
||||
"1": {
|
||||
"material": "PETG",
|
||||
"temp": 32.0,
|
||||
"fan_hotend": 0.0,
|
||||
"fan_print": 0.0,
|
||||
"nozzle_diameter": 3.2, // float
|
||||
"high_flow": true, // boolean
|
||||
"high_temperature": false, // boolean
|
||||
"hardened": true, // boolean
|
||||
},
|
||||
"3": {
|
||||
"material": "ASA",
|
||||
"temp": 35.0,
|
||||
"fan_hotend": 0.0,
|
||||
"fan_print": 0.0,
|
||||
"nozzle_diameter": 3.2, // float
|
||||
"high_flow": true, // boolean
|
||||
"high_temperature": false, // boolean
|
||||
"hardened": true, // boolean
|
||||
},
|
||||
}
|
||||
}
|
||||
*/
|
||||
const std::map<std::string, std::string> parameters = {
|
||||
// first name from connect, second config option
|
||||
{"nozzle_diameter","nozzle_diameter"},
|
||||
{"high_flow","nozzle_high_flow"},
|
||||
//{"",""}
|
||||
};
|
||||
pt::ptree slots = parse_tree_for_subtree(parse_tree_for_subtree(ptree, "slot"), "slots");
|
||||
for (const auto &subtree : slots) {
|
||||
size_t slot_id;
|
||||
try {
|
||||
slot_id = boost::lexical_cast<size_t>(subtree.first);
|
||||
} catch (const boost::bad_lexical_cast&) {
|
||||
continue;
|
||||
}
|
||||
for (const auto &item : subtree.second) {
|
||||
if (parameters.find(item.first) == parameters.end()) {
|
||||
continue;
|
||||
}
|
||||
std::string config_name = parameters.at(item.first);
|
||||
// resolve value
|
||||
std::string val;
|
||||
if (item.second.size() > 0) {
|
||||
for (const auto &subitem : item.second) {
|
||||
if (!val.empty()) {
|
||||
val += ",";
|
||||
}
|
||||
val += json_var_to_opt_string(subitem.second.data());
|
||||
}
|
||||
} else {
|
||||
val = json_var_to_opt_string(item.second.data());
|
||||
}
|
||||
// insert value
|
||||
while (result[config_name].size() < slot_id)
|
||||
result[config_name].emplace_back();
|
||||
result[config_name][slot_id - 1] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fill_material_from_json(const std::string &json, std::vector<std::string> &result)
|
||||
void fill_material_from_json(const std::string& json, std::vector<std::string>& result)
|
||||
{
|
||||
pt::ptree ptree;
|
||||
json_to_ptree(ptree, json);
|
||||
@ -178,10 +248,26 @@ void fill_material_from_json(const std::string &json, std::vector<std::string> &
|
||||
return;
|
||||
}
|
||||
// search "slot" subtree for all "material"s
|
||||
parse_tree_for_param_vector(slot_subtree, "material", result);
|
||||
// this parses "slots" with respect to numbers of slots and adds empty string to missing numbers
|
||||
// if only filled should be used. Use: parse_tree_for_param_vector(slot_subtree, "material", result);
|
||||
pt::ptree slots = parse_tree_for_subtree(slot_subtree, "slots");
|
||||
assert(!slots.empty());
|
||||
for (const auto &subtree : slots) {
|
||||
size_t slot_id;
|
||||
try {
|
||||
slot_id = boost::lexical_cast<size_t>(subtree.first);
|
||||
} catch (const boost::bad_lexical_cast&) {
|
||||
continue;
|
||||
}
|
||||
std::string val = parse_tree_for_param(subtree.second, "material");
|
||||
// add empty for missing id
|
||||
while (result.size() < slot_id)
|
||||
result.emplace_back();
|
||||
result[slot_id - 1] = val;
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_print_data_from_json(const std::string &json, const std::string &keyword) {
|
||||
std::string get_print_data_from_json(const std::string& json, const std::string& keyword) {
|
||||
// copy subtree string f.e.
|
||||
// { "<keyword>": {"param1": "something", "filename":"abcd.gcode", "param3":true},
|
||||
// "something_else" : 0 } into: {"param1": "something", "filename":"%1%", "param3":true,
|
||||
|
@ -15,7 +15,7 @@ std::string get_keyword_from_json(boost::property_tree::ptree& ptree, const std:
|
||||
// Only ptree is passed since these functions are called on places that already has the ptree from get_keyword_from_json call
|
||||
std::string get_nozzle_from_json(boost::property_tree::ptree &ptree);
|
||||
void fill_supported_printer_models_from_json(boost::property_tree::ptree& ptree, std::vector<std::string>& result);
|
||||
void fill_config_options_from_json(boost::property_tree::ptree& ptree, std::map<std::string, std::string>& result);
|
||||
void fill_config_options_from_json(boost::property_tree::ptree& ptree, std::map<std::string,std::vector<std::string>>& result);
|
||||
|
||||
// Since fill_material_from_json is called only from one place where ptree doesnt need to be shared, it is not always read from json.
|
||||
void fill_material_from_json(const std::string& json, std::vector<std::string>& result);
|
||||
|
@ -1288,8 +1288,10 @@ void PrinterPickWebViewDialog::request_compatible_printers_FFF() {
|
||||
nozzle_diameter_serialized.Replace(L",", L".");
|
||||
// Sending only first filament type for now. This should change to array of values
|
||||
const std::string filament_type_serialized = full_config.option("filament_type")->serialize();
|
||||
std::string printer_model_serialized = full_config.option("printer_model")->serialize();
|
||||
const std::string nozzle_high_flow_serialized = static_cast<const ConfigOptionBools *>(full_config.option("nozzle_high_flow"))->values[0] ? "1" : "0";
|
||||
const std::string filament_abrasive_serialized = static_cast<const ConfigOptionBools *>(full_config.option("filament_abrasive"))->values[0] ? "1" : "0";
|
||||
|
||||
std::string printer_model_serialized = full_config.option("printer_model")->serialize();
|
||||
std::string vendor_repo_prefix;
|
||||
if (selected_printer.vendor) {
|
||||
vendor_repo_prefix = selected_printer.vendor->repo_prefix;
|
||||
@ -1311,19 +1313,13 @@ void PrinterPickWebViewDialog::request_compatible_printers_FFF() {
|
||||
"{"
|
||||
"\"printerUuid\": \"%4%\", "
|
||||
"\"printerModel\": \"%3%\", "
|
||||
"\"nozzleDiameter\": %2%, "
|
||||
"\"nozzle_diameter\": %2%, "
|
||||
"\"material\": \"%1%\", "
|
||||
"\"filename\": \"%5%\", "
|
||||
"\"fullConfig\": {"
|
||||
, filament_type_serialized, nozzle_diameter_serialized, printer_model_serialized, uuid, filename);
|
||||
|
||||
for (auto it = full_config.cbegin(); it != full_config.cend(); ++it) {
|
||||
std::string value = full_config.option(it->first)->serialize();
|
||||
boost::algorithm::replace_all(value, "\"", "\\\"");
|
||||
request += it == full_config.cbegin() ? "" : ",";
|
||||
request += GUI::format("\"%1%\": \"%2%\"", it->first, value);
|
||||
}
|
||||
request += "}}";
|
||||
"\"filament_abrasive\": \"%6%\","
|
||||
"\"nozzle_high_flow\": \"%7%\""
|
||||
"}"
|
||||
, filament_type_serialized, nozzle_diameter_serialized, printer_model_serialized, uuid, filename, nozzle_high_flow_serialized, filament_abrasive_serialized);
|
||||
|
||||
wxString script = GUI::format_wxstr("window._prusaConnect_v1.requestCompatiblePrinter(%1%)", request);
|
||||
run_script(script);
|
||||
|
Loading…
x
Reference in New Issue
Block a user