Skip to content

Commit

Permalink
Support upload g-code to third-party printers
Browse files Browse the repository at this point in the history
* wip

* fix cmake warning

* add UI and config options for Moonraker connection

* wip: copy whole print host UI from PS

* add more needed options

* wip 2

* fix string issue on Mac

* wip3

* fix cmake warning

* working
need tweaks

* cleanup

* support thumbnail

* fix DNS resolving issue in Windows

* code clean up
  • Loading branch information
SoftFever authored Aug 20, 2022
1 parent 82127a9 commit 488b1cd
Show file tree
Hide file tree
Showing 51 changed files with 5,000 additions and 17 deletions.
22 changes: 22 additions & 0 deletions resources/images/add.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions resources/images/add_copies.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions resources/images/browse.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 6 additions & 4 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include "libslic3r.h"
#include "LocalesUtils.hpp"
#include "libslic3r/format.hpp"

#include "Time.hpp"
#include <algorithm>
#include <cstdlib>
#include <chrono>
Expand Down Expand Up @@ -1352,9 +1352,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
}

//BBS: add plate id into thumbnail render logic
//DoExport::export_thumbnails_to_file(thumbnail_cb, print.get_plate_index(), THUMBNAIL_SIZE,
// [&file](const char* sz) { file.write(sz); },
// [&print]() { print.throw_if_canceled(); });
file.write_format("; hack-fix: write fake slicer info here so that Moonraker will extract thumbs.\n");
file.write_format("; %s\n\n",std::string(std::string("generated by PrusaSlicer " SLIC3R_VERSION " on " ) + Slic3r::Utils::utc_timestamp()).c_str());
DoExport::export_thumbnails_to_file(thumbnail_cb, print.get_plate_index(), { Vec2d(300, 300) },
[&file](const char* sz) { file.write(sz); },
[&print]() { print.throw_if_canceled(); });


// Write some terse information on the slicing parameters.
Expand Down
36 changes: 35 additions & 1 deletion src/libslic3r/Preset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,13 @@ static std::vector<std::string> s_Preset_printer_options {
"silent_mode",
// BBS
"scan_first_layer", "machine_load_filament_time", "machine_unload_filament_time", "machine_pause_gcode",
"nozzle_type", "auxiliary_fan", "nozzle_volume"
"nozzle_type", "auxiliary_fan", "nozzle_volume",
//SoftFever
"connection_moonraker_url","connection_port", "host_type", "print_host", "printhost_apikey",
"printhost_cafile","printhost_port","printhost_authorization_type",
"printhost_user",
"printhost_password",
"printhost_ssl_ignore_revoke"
};

static std::vector<std::string> s_Preset_sla_print_options {
Expand Down Expand Up @@ -2189,6 +2195,21 @@ void add_correct_opts_to_diff(const std::string &opt_key, t_config_option_keys&
}
}

// template<class T>
// void add_correct_opt_to_diff(const std::string &opt_key, t_config_option_keys& vec, const ConfigBase &other, const ConfigBase &this_c)
// {
// const T* opt_init = static_cast<const T*>(other.option(opt_key));
// const T* opt_cur = static_cast<const T*>(this_c.option(opt_key));
// int opt_init_max_id = opt_init->values.size() - 1;
// for (int i = 0; i < int(opt_cur->values.size()); i++)
// {
// int init_id = i <= opt_init_max_id ? i : 0;
// if (opt_cur->values[i] != opt_init->values[init_id])
// vec.emplace_back(opt_key + "#" + std::to_string(i));
// }
// }


// Use deep_diff to correct return of changed options, considering individual options for each extruder.
inline t_config_option_keys deep_diff(const ConfigBase &config_this, const ConfigBase &config_other)
{
Expand All @@ -2212,6 +2233,7 @@ inline t_config_option_keys deep_diff(const ConfigBase &config_this, const Confi
case coBools: add_correct_opts_to_diff<ConfigOptionBools >(opt_key, diff, config_other, config_this); break;
case coFloats: add_correct_opts_to_diff<ConfigOptionFloats >(opt_key, diff, config_other, config_this); break;
case coStrings: add_correct_opts_to_diff<ConfigOptionStrings >(opt_key, diff, config_other, config_this); break;
// case coString: add_correct_opts_to_diff<ConfigOptionString >(opt_key, diff, config_other, config_this); break;
case coPercents:add_correct_opts_to_diff<ConfigOptionPercents >(opt_key, diff, config_other, config_this); break;
case coPoints: add_correct_opts_to_diff<ConfigOptionPoints >(opt_key, diff, config_other, config_this); break;
// BBS
Expand Down Expand Up @@ -2519,6 +2541,16 @@ static std::vector<std::string> s_PhysicalPrinter_opts {
"preset_name", // temporary option to compatibility with older Slicer
"preset_names",
"printer_technology",
"host_type",
"print_host",
"printhost_apikey",
"printhost_cafile",
"printhost_port",
"printhost_authorization_type",
// HTTP digest authentization (RFC 2617)
"printhost_user",
"printhost_password",
"printhost_ssl_ignore_revoke"
};

const std::vector<std::string>& PhysicalPrinter::printer_options()
Expand Down Expand Up @@ -2682,6 +2714,8 @@ void PhysicalPrinterCollection::load_printers(
// see https://github.com/prusa3d/PrusaSlicer/issues/732
boost::filesystem::path dir = boost::filesystem::absolute(boost::filesystem::path(dir_path) / subdir).make_preferred();
m_dir_path = dir.string();
if(!boost::filesystem::exists(dir))
return;
std::string errors_cummulative;
// Store the loaded printers into a new vector, otherwise the binary search for already existing presets would be broken.
std::deque<PhysicalPrinter> printers_loaded;
Expand Down
8 changes: 5 additions & 3 deletions src/libslic3r/PresetBundle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1245,8 +1245,10 @@ DynamicPrintConfig PresetBundle::full_config() const
DynamicPrintConfig PresetBundle::full_config_secure() const
{
DynamicPrintConfig config = this->full_config();
//BBS example: config.erase("print_host");
return config;
//FIXME legacy, the keys should not be there after conversion to a Physical Printer profile.
config.erase("print_host");
config.erase("printhost_apikey");
config.erase("printhost_cafile"); return config;
}

const std::set<std::string> ignore_settings_list ={
Expand Down Expand Up @@ -3231,4 +3233,4 @@ void PresetBundle::set_default_suppressed(bool default_suppressed)
printers.set_default_suppressed(default_suppressed);
}

} // namespace Slic3r
} // namespace Slic3r
134 changes: 134 additions & 0 deletions src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ static t_config_enum_values s_keys_map_PrinterTechnology {
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PrinterTechnology)

static t_config_enum_values s_keys_map_PrintHostType {
{ "prusalink", htPrusaLink },
{ "octoprint", htOctoPrint },
{ "duet", htDuet },
{ "flashair", htFlashAir },
{ "astrobox", htAstroBox },
{ "repetier", htRepetier },
{ "mks", htMKS }
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PrintHostType)

static t_config_enum_values s_keys_map_AuthorizationType {
{ "key", atKeyPassword },
{ "user", atUserPassword }
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(AuthorizationType)

static t_config_enum_values s_keys_map_GCodeFlavor {
{ "marlin", gcfMarlinLegacy },
{ "reprap", gcfRepRapSprinter },
Expand Down Expand Up @@ -257,6 +274,7 @@ void PrintConfigDef::init_common_params()

def = this->add("printable_area", coPoints);
def->label = L("Printable area");

//BBS
def->mode = comDevelop;
def->set_default_value(new ConfigOptionPoints{ Vec2d(0, 0), Vec2d(200, 0), Vec2d(200, 200), Vec2d(0, 200) });
Expand Down Expand Up @@ -304,6 +322,98 @@ void PrintConfigDef::init_common_params()
def->mode = comDevelop;
def->set_default_value(new ConfigOptionStrings());

//SoftFever
def = this->add("connection_moonraker_url", coString);
def->label = L("Moonraker URL");
//def->tooltip = L("Names of presets related to the physical printer");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionString("http://"));

def = this->add("connection_port", coString);
def->label = L("Connection port");
//def->tooltip = L("Names of presets related to the physical printer");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionString("7125"));



def = this->add("print_host", coString);
def->label = L("Hostname, IP or URL");
def->tooltip = L("Slic3r can upload G-code files to a printer host. This field should contain "
"the hostname, IP address or URL of the printer host instance. "
"Print host behind HAProxy with basic auth enabled can be accessed by putting the user name and password into the URL "
"in the following format: https://username:password@your-octopi-address/");
def->mode = comAdvanced;
def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionString(""));

def = this->add("printhost_apikey", coString);
def->label = L("API Key / Password");
def->tooltip = L("Slic3r can upload G-code files to a printer host. This field should contain "
"the API Key or the password required for authentication.");
def->mode = comAdvanced;
def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionString(""));

def = this->add("printhost_port", coString);
def->label = L("Printer");
def->tooltip = L("Name of the printer");
def->gui_type = ConfigOptionDef::GUIType::select_open;
def->mode = comAdvanced;
def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionString(""));

def = this->add("printhost_cafile", coString);
def->label = L("HTTPS CA File");
def->tooltip = L("Custom CA certificate file can be specified for HTTPS OctoPrint connections, in crt/pem format. "
"If left blank, the default OS CA certificate repository is used.");
def->mode = comAdvanced;
def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionString(""));

// Options used by physical printers

def = this->add("printhost_user", coString);
def->label = L("User");
// def->tooltip = L("");
def->mode = comAdvanced;
def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionString(""));

def = this->add("printhost_password", coString);
def->label = L("Password");
// def->tooltip = L("");
def->mode = comAdvanced;
def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionString(""));

// Only available on Windows.
def = this->add("printhost_ssl_ignore_revoke", coBool);
def->label = L("Ignore HTTPS certificate revocation checks");
def->tooltip = L("Ignore HTTPS certificate revocation checks in case of missing or offline distribution points. "
"One may want to enable this option for self signed certificates if connection fails.");
def->mode = comAdvanced;
def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionBool(false));

def = this->add("preset_names", coStrings);
def->label = L("Printer preset names");
def->tooltip = L("Names of presets related to the physical printer");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionStrings());

def = this->add("printhost_authorization_type", coEnum);
def->label = L("Authorization Type");
// def->tooltip = L("");
def->enum_keys_map = &ConfigOptionEnum<AuthorizationType>::get_enum_values();
def->enum_values.push_back("key");
def->enum_values.push_back("user");
def->enum_labels.push_back(L("API key"));
def->enum_labels.push_back(L("HTTP digest"));
def->mode = comAdvanced;
def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionEnum<AuthorizationType>(atKeyPassword));

// temporary workaround for compatibility with older Slicer
{
def = this->add("preset_name", coString);
Expand Down Expand Up @@ -1624,6 +1734,30 @@ void PrintConfigDef::init_fff_params()
def->mode = comDevelop;
def->set_default_value(new ConfigOptionFloats { 0.4 });

def = this->add("host_type", coEnum);
def->label = L("Host Type");
def->tooltip = L("Slic3r can upload G-code files to a printer host. This field must contain "
"the kind of the host.");
def->enum_keys_map = &ConfigOptionEnum<PrintHostType>::get_enum_values();
def->enum_values.push_back("prusalink");
def->enum_values.push_back("octoprint");
def->enum_values.push_back("duet");
def->enum_values.push_back("flashair");
def->enum_values.push_back("astrobox");
def->enum_values.push_back("repetier");
def->enum_values.push_back("mks");
def->enum_labels.push_back("PrusaLink");
def->enum_labels.push_back("OctoPrint");
def->enum_labels.push_back("Duet");
def->enum_labels.push_back("FlashAir");
def->enum_labels.push_back("AstroBox");
def->enum_labels.push_back("Repetier");
def->enum_labels.push_back("MKS");
def->mode = comAdvanced;
def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionEnum<PrintHostType>(htOctoPrint));


def = this->add("nozzle_volume", coFloat);
def->label = L("Nozzle volume");
def->tooltip = L("Volume of nozzle between the cutter and the end of nozzle");
Expand Down
15 changes: 15 additions & 0 deletions src/libslic3r/PrintConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ enum class FuzzySkinType {
All,
};

enum PrintHostType {
htPrusaLink, htOctoPrint, htDuet, htFlashAir, htAstroBox, htRepetier, htMKS
};

enum AuthorizationType {
atKeyPassword, atUserPassword
};

#define HAS_LIGHTNING_INFILL 0

enum InfillPattern : int {
Expand Down Expand Up @@ -236,6 +244,9 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(BedType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(DraftShield)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(ForwardCompatibilitySubstitutionRule)

CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PrintHostType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(AuthorizationType)

#undef CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS

// Defines each and every confiuration option of Slic3r, including the properties of the GUI dialogs.
Expand Down Expand Up @@ -755,6 +766,10 @@ PRINT_CONFIG_CLASS_DEFINE(
//BBS
((ConfigOptionEnum<NozzleType>, nozzle_type))
((ConfigOptionBool, auxiliary_fan))
//SoftFever
((ConfigOptionString, connection_moonraker_url))
((ConfigOptionString, connection_port))

)

// This object is mapped to Perl as Slic3r::Config::Print.
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1106,7 +1106,7 @@ std::string string_printf(const char *format, ...)

std::string header_slic3r_generated()
{
return std::string(SLIC3R_APP_NAME " " SLIC3R_VERSION);
return std::string(SLIC3R_APP_NAME "-SoftFever" " " SLIC3R_VERSION);
}

std::string header_gcodeviewer_generated()
Expand Down
2 changes: 1 addition & 1 deletion src/minilzo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
project(minilzo)
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 3.0)

add_library(minilzo INTERFACE)

Expand Down
2 changes: 1 addition & 1 deletion src/qhull/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ endif()
else(Qhull_FOUND)

project(qhull)
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 3.1)

# Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, qhull-warn.pri
set(qhull_VERSION2 "2015.2 2016/01/18") # not used, See global.c, global_r.c, rbox.c, rbox_r.c
Expand Down
Loading

0 comments on commit 488b1cd

Please sign in to comment.