Merge: Snapmaker Orca 2.1.2

This commit is contained in:
xiaoyeliu
2025-11-17 10:04:25 +08:00
parent 737948be1f
commit e89263e51a
1147 changed files with 668188 additions and 15290 deletions
+226 -4
View File
@@ -37,8 +37,9 @@ using namespace nlohmann;
namespace Slic3r {
static const std::string VERSION_CHECK_URL = "https://check-version.orcaslicer.com/latest";
static const std::string PROFILE_UPDATE_URL = "https://api.github.com/repos/OrcaSlicer/orcaslicer-profiles/releases/tags";
static const std::string VERSION_CHECK_URL_STABLE = "https://api.github.com/repos/Snapmaker/OrcaSlicer/releases/latest";
static const std::string VERSION_CHECK_URL = "https://api.github.com/repos/Snapmaker/OrcaSlicer/releases";
static const std::string PROFILE_UPDATE_URL = "https://api.github.com/repos/Snapmaker/Orca_Presets/releases/latest";
static const std::string MODELS_STR = "models";
const std::string AppConfig::SECTION_FILAMENTS = "filaments";
@@ -263,6 +264,9 @@ void AppConfig::set_defaults()
if(get("check_stable_update_only").empty()) {
set_bool("check_stable_update_only", false);
}
// SM prerelease does not update
set_bool("check_stable_update_only", true);
// Orca
if(get("show_splash_screen").empty()) {
@@ -522,6 +526,8 @@ std::string AppConfig::load()
#else
ifs >> j;
#endif
// SM orca
update_filament_names(j);
}
catch(nlohmann::detail::parse_error &err) {
#ifdef WIN32
@@ -669,6 +675,11 @@ std::string AppConfig::load()
}
}
}
// SM Orca
if (j.contains("devices")) {
m_device_list = j["devices"].get<std::vector<DeviceInfo>>();
}
} catch(std::exception err) {
BOOST_LOG_TRIVIAL(info) << format("parse app config \"%1%\", error: %2%", AppConfig::loading_path(), err.what());
@@ -785,6 +796,11 @@ void AppConfig::save()
continue;
}
for (const auto& kvp : category.second) {
// SM Orca
if (kvp.first == "use_new_connect") {
j[category.first][kvp.first] = false;
continue;
}
if (kvp.second == "true") {
j[category.first][kvp.first] = true;
continue;
@@ -820,6 +836,20 @@ void AppConfig::save()
for (const auto& preset : m_printer_settings) {
j["orca_presets"].push_back(preset.second);
}
j["devices"] = json::array();
for (size_t i = 0; i < m_device_list.size(); ++i) {
if (m_device_list[i].link_mode != "wan") {
j["devices"].push_back(m_device_list[i]);
}
}
// j["devices"] = m_device_list;
for (size_t i = 0; i < j["devices"].size(); ++i) {
j["devices"][i]["connected"] = false;
}
for (const auto& local_machine : m_local_machines) {
json m_json;
m_json["dev_name"] = local_machine.second.dev_name;
@@ -1382,10 +1412,10 @@ std::string AppConfig::config_path()
return path;
}
std::string AppConfig::version_check_url() const
std::string AppConfig::version_check_url(bool stable_only/* = false*/) const
{
auto from_settings = get("version_check_url");
return from_settings.empty() ? VERSION_CHECK_URL : from_settings;
return from_settings.empty() ? stable_only ? VERSION_CHECK_URL_STABLE : VERSION_CHECK_URL : from_settings;
}
std::string AppConfig::profile_update_url() const
@@ -1398,4 +1428,196 @@ bool AppConfig::exists()
return boost::filesystem::exists(config_path());
}
void AppConfig::save_device_info(const DeviceInfo& device)
{
// 检查是否已存在该设备
auto it = std::find_if(m_device_list.begin(), m_device_list.end(),
[&device](const DeviceInfo& d) { return d.dev_id == device.dev_id; });
if (it != m_device_list.end()) {
// 更新已存在的设备信息
*it = device;
} else {
// 添加新设备
m_device_list.push_back(device);
}
m_dirty = true;
}
void AppConfig::clear_device_info()
{
m_device_list.clear();
m_dirty = true;
}
void AppConfig::remove_device_info(const std::string& dev_id)
{
auto it = std::find_if(m_device_list.begin(), m_device_list.end(),
[&dev_id](const DeviceInfo& d) { return d.dev_id == dev_id; });
if (it != m_device_list.end()) {
m_device_list.erase(it);
m_dirty = true;
}
}
std::vector<DeviceInfo> AppConfig::get_devices() const
{
return m_device_list;
}
bool AppConfig::get_device_info(const std::string& dev_id, DeviceInfo& info) const
{
auto it = std::find_if(m_device_list.begin(), m_device_list.end(),
[&dev_id](const DeviceInfo& d) { return d.dev_id == dev_id; });
if (it != m_device_list.end()) {
info = *it;
return true;
}
return false;
}
void AppConfig::clear_filament_extruder_map()
{
filament_extruder_map.clear();
}
std::unordered_map<int, int>& AppConfig::get_filament_extruder_map_ref()
{
return filament_extruder_map;
}
const std::map<std::string, std::string> AppConfig::filament_name_map = {
// J1相关映射
{"PolyLite J1 PLA @0.2 nozzle", "PolyLite PLA @J1 0.2 nozzle"},
{"PolyLite J1 PLA", "PolyLite PLA @J1"},
{"PolyTerra J1 PLA @0.2 nozzle", "PolyTerra PLA @J1 0.2 nozzle"},
{"PolyTerra J1 PLA", "PolyTerra PLA @J1"},
{"Snapmaker J1 ABS @0.2 nozzle", "Snapmaker ABS @J1 0.2 nozzle"},
{"Snapmaker J1 ABS @0.8 nozzle", "Snapmaker ABS @J1 0.8 nozzle"},
{"Snapmaker J1 ABS", "Snapmaker ABS @J1"},
{"Snapmaker J1 ABS Benchy", "Snapmaker ABS Benchy @J1"},
{"Snapmaker J1 ASA @0.2 nozzle", "Snapmaker ASA @J1 0.2 nozzle"},
{"Snapmaker J1 ASA", "Snapmaker ASA @J1"},
{"Snapmaker J1 Breakaway Support", "Snapmaker Breakaway Support @J1"},
{"Snapmaker J1 PA-CF", "Snapmaker PA-CF @J1"},
{"Snapmaker J1 PET", "Snapmaker PET @J1"},
{"Snapmaker J1 PETG @0.2 nozzle", "Snapmaker PETG @J1 0.2 nozzle"},
{"Snapmaker J1 PETG @0.8 nozzle", "Snapmaker PETG @J1 0.8 nozzle"},
{"Snapmaker J1 PETG", "Snapmaker PETG @J1"},
{"Snapmaker J1 PETG-CF", "Snapmaker PETG-CF @J1"},
{"Snapmaker J1 PLA", "Snapmaker PLA @J1"},
{"Snapmaker J1 PLA Eco @0.2 nozzle", "Snapmaker PLA Eco @J1 0.2 nozzle"},
{"Snapmaker J1 PLA Eco @0.8 nozzle", "Snapmaker PLA Eco @J1 0.8 nozzle"},
{"Snapmaker J1 PLA Eco", "Snapmaker PLA Eco @J1"},
{"Snapmaker J1 PLA Matte @0.2 nozzle", "Snapmaker PLA Matte @J1 0.2 nozzle"},
{"Snapmaker J1 PLA Matte @0.8 nozzle", "Snapmaker PLA Matte @J1 0.8 nozzle"},
{"Snapmaker J1 PLA Matte", "Snapmaker PLA Matte @J1"},
{"Snapmaker J1 PLA Metal @0.2 nozzle", "Snapmaker PLA Metal @J1 0.2 nozzle"},
{"Snapmaker J1 PLA Metal", "Snapmaker PLA Metal @J1"},
{"Snapmaker J1 PLA Silk @0.2 nozzle", "Snapmaker PLA Silk @J1 0.2 nozzle"},
{"Snapmaker J1 PLA Silk", "Snapmaker PLA Silk @J1"},
{"Snapmaker J1 PLA-CF", "Snapmaker PLA-CF @J1"},
{"Snapmaker J1 PVA @0.2 nozzle", "Snapmaker PVA @J1 0.2 nozzle"},
{"Snapmaker J1 PVA", "Snapmaker PVA @J1"},
{"Snapmaker J1 TPE", "Snapmaker TPE @J1"},
{"Snapmaker J1 TPU", "Snapmaker TPU @J1"},
{"Snapmaker J1 TPU High-Flow", "Snapmaker TPU High-Flow @J1"},
// Dual相关映射
{"PolyLite Dual PLA @0.2 nozzle", "PolyLite PLA @Dual 0.2 nozzle"},
{"PolyLite Dual PLA", "PolyLite PLA @Dual"},
{"PolyTerra Dual PLA @0.2 nozzle", "PolyTerra PLA @Dual 0.2 nozzle"},
{"PolyTerra Dual PLA", "PolyTerra PLA @Dual"},
{"Snapmaker Dual ABS @0.2 nozzle", "Snapmaker ABS @Dual 0.2 nozzle"},
{"Snapmaker Dual ABS @0.8 nozzle", "Snapmaker ABS @Dual 0.8 nozzle"},
{"Snapmaker Dual ABS", "Snapmaker ABS @Dual"},
{"Snapmaker Dual ABS Benchy", "Snapmaker ABS Benchy @Dual"},
{"Snapmaker Dual ASA @0.2 nozzle", "Snapmaker ASA @Dual 0.2 nozzle"},
{"Snapmaker Dual ASA", "Snapmaker ASA @Dual"},
{"Snapmaker Dual PA-CF", "Snapmaker PA-CF @Dual"},
{"Snapmaker Dual PET @0.8 nozzle", "Snapmaker PET @Dual 0.8 nozzle"},
{"Snapmaker Dual PET", "Snapmaker PET @Dual"},
{"Snapmaker Dual PETG @0.2 nozzle", "Snapmaker PETG @Dual 0.2 nozzle"},
{"Snapmaker Dual PETG @0.8 nozzle", "Snapmaker PETG @Dual 0.8 nozzle"},
{"Snapmaker Dual PETG", "Snapmaker PETG @Dual"},
{"Snapmaker Dual PETG-CF", "Snapmaker PETG-CF @Dual"},
{"Snapmaker Dual PLA", "Snapmaker PLA @Dual"},
{"Snapmaker Dual PLA Eco @0.2 nozzle", "Snapmaker PLA Eco @Dual 0.2 nozzle"},
{"Snapmaker Dual PLA Eco @0.8 nozzle", "Snapmaker PLA Eco @Dual 0.8 nozzle"},
{"Snapmaker Dual PLA Eco", "Snapmaker PLA Eco @Dual"},
{"Snapmaker Dual PLA Matte @0.2 nozzle", "Snapmaker PLA Matte @Dual 0.2 nozzle"},
{"Snapmaker Dual PLA Matte @0.8 nozzle", "Snapmaker PLA Matte @Dual 0.8 nozzle"},
{"Snapmaker Dual PLA Matte", "Snapmaker PLA Matte @Dual"},
{"Snapmaker Dual PLA Metal @0.2 nozzle", "Snapmaker PLA Metal @Dual 0.2 nozzle"},
{"Snapmaker Dual PLA Metal", "Snapmaker PLA Metal @Dual"},
{"Snapmaker Dual PLA Silk @0.2 nozzle", "Snapmaker PLA Silk @Dual 0.2 nozzle"},
{"Snapmaker Dual PLA Silk", "Snapmaker PLA Silk @Dual"},
{"Snapmaker Dual PLA-CF @0.8 nozzle", "Snapmaker PLA-CF @Dual 0.8 nozzle"},
{"Snapmaker Dual PLA-CF", "Snapmaker PLA-CF @Dual"},
{"Snapmaker Dual PVA @0.2 nozzle", "Snapmaker PVA @Dual 0.2 nozzle"},
{"Snapmaker Dual PVA", "Snapmaker PVA @Dual"},
{"Snapmaker Dual TPE", "Snapmaker TPE @Dual"},
{"Snapmaker Dual TPU", "Snapmaker TPU @Dual"},
{"Snapmaker Dual TPU High-Flow", "Snapmaker TPU High-Flow @Dual"}};
void AppConfig::update_filament_names(json& j)
{
bool need_save = false;
// 更新 filaments 数组中的耗材名称
if (j.contains("filaments") && j["filaments"].is_array()) {
auto& filaments = j["filaments"];
for (auto& filament : filaments) {
if (filament.is_string()) {
std::string old_name = filament.get<std::string>();
auto it = filament_name_map.find(old_name);
if (it != filament_name_map.end()) {
filament = it->second;
need_save = true;
}
}
}
}
// 更新 orca_presets 中的耗材名称
if (j.contains("orca_presets") && j["orca_presets"].is_array()) {
auto& presets = j["orca_presets"];
for (auto& preset : presets) {
// 更新主要耗材字段
if (preset.contains("filament")) {
std::string old_name = preset["filament"].get<std::string>();
auto it = filament_name_map.find(old_name);
if (it != filament_name_map.end()) {
preset["filament"] = it->second;
need_save = true;
}
}
// 更新 filament_XX 字段
for (int i = 1; ; i++) {
std::string key = std::string("filament_") + (i < 10 ? "0" : "") + std::to_string(i);
if (!preset.contains(key)) {
break;
}
std::string old_name = preset[key].get<std::string>();
auto it = filament_name_map.find(old_name);
if (it != filament_name_map.end()) {
preset[key] = it->second;
need_save = true;
}
}
}
}
//// 如果有更新,保存文件
//if (need_save) {
// std::string conf_path = (fs::path(Slic3r::data_dir()) / "Snapmaker_Orca.conf").string();
// boost::nowide::ofstream ofs(conf_path);
// ofs << std::setw(4) << j << std::endl;
//}
}
}; // namespace Slic3r
+51 -1
View File
@@ -30,6 +30,35 @@ using namespace nlohmann;
namespace Slic3r {
struct DeviceInfo {
std::string ip;
std::string dev_id;
std::string dev_name;
std::string model_name;
std::string preset_name; // 关联的打印机预设名称
bool connected;
std::string img;
std::vector<std::string> nozzle_sizes;
std::string sn;
int protocol;
std::string api_key;
std::string user;
std::string password;
std::string ca;
std::string cert;
std::string key;
std::string clientId;
int port;
std::string link_mode;
std::string userid;
std::string id;
// 用于JSON序列化
NLOHMANN_DEFINE_TYPE_INTRUSIVE(DeviceInfo, ip, dev_id, dev_name, model_name, preset_name, connected, img, nozzle_sizes, sn, protocol,api_key,
user, password, ca, cert, key, clientId, port, link_mode, userid, id)
};
// Connected LAN mode BambuLab printer
struct BBLocalMachine
@@ -294,7 +323,7 @@ public:
// Get the Slic3r version check url.
// This returns a hardcoded string unless it is overriden by "version_check_url" in the ini file.
std::string version_check_url() const;
std::string version_check_url(bool stable_only = false) const;
// Get the Orca profile update url.
std::string profile_update_url() const;
@@ -339,10 +368,22 @@ public:
bool get_mouse_device_invert_roll(const std::string& name, bool& invert) const
{ return get_3dmouse_device_numeric_value(name, "invert_roll", invert); }
void update_filament_names(json& j);
static const std::string SECTION_FILAMENTS;
static const std::string SECTION_MATERIALS;
static const std::string SECTION_EMBOSS_STYLE;
// 添加设备相关的方法
void save_device_info(const DeviceInfo& device);
void remove_device_info(const std::string& dev_id);
std::vector<DeviceInfo> get_devices() const;
bool get_device_info(const std::string& dev_id, DeviceInfo& info) const;
void clear_device_info();
void clear_filament_extruder_map();
std::unordered_map<int, int>& get_filament_extruder_map_ref();
private:
template<typename T>
bool get_3dmouse_device_numeric_value(const std::string &device_name, const char *parameter_name, T &out) const
@@ -383,6 +424,15 @@ private:
std::vector<PrinterCaliInfo> m_printer_cali_infos;
std::map<std::string, BBLocalMachine> m_local_machines;
// 添加耗材名称映射表
static const std::map<std::string, std::string> filament_name_map;
// 添加设备信息存储
std::vector<DeviceInfo> m_device_list;
// 耗材喷嘴映射表
std::unordered_map<int, int> filament_extruder_map;
};
} // namespace Slic3r
-1
View File
@@ -14,7 +14,6 @@ BuildVolume::BuildVolume(const std::vector<Vec2d> &printable_area, const double
assert(printable_height >= 0);
m_polygon = Polygon::new_scale(printable_area);
assert(m_polygon.is_counter_clockwise());
// Calcuate various metrics of the input polygon.
m_convex_hull = Geometry::convex_hull(m_polygon.points);
+62 -7
View File
@@ -1276,16 +1276,16 @@ ConfigSubstitutions ConfigBase::load_from_gcode_file(const std::string &file, Fo
// Read a 64k block from the end of the G-code.
boost::nowide::ifstream ifs(file);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": before parse_file %1%") % file.c_str();
// Look for Slic3r or OrcaSlicer header.
// Look for Slic3r or Snapmaker_Orca header.
// Look for the header across the whole file as the G-code may have been extended at the start by a post-processing script or the user.
//BBS
bool has_delimiters = true;
{
//BBS
std::string bambuslicer_gcode_header = "; OrcaSlicer";
std::string bambuslicer_gcode_header = "; Snapmaker_Orca";
std::string orcaslicer_gcode_header = std::string("; generated by ");
orcaslicer_gcode_header += SLIC3R_APP_NAME;
std::string Snapmaker_Orca_gcode_header = std::string("; generated by ");
Snapmaker_Orca_gcode_header += SLIC3R_APP_NAME;
std::string header;
bool header_found = false;
@@ -1297,7 +1297,7 @@ ConfigSubstitutions ConfigBase::load_from_gcode_file(const std::string &file, Fo
line_c = skip_whitespaces(line_c);
// BBS
if (strncmp(bambuslicer_gcode_header.c_str(), line_c, strlen(bambuslicer_gcode_header.c_str())) == 0 ||
strncmp(orcaslicer_gcode_header.c_str(), line_c, strlen(orcaslicer_gcode_header.c_str())) == 0) {
strncmp(Snapmaker_Orca_gcode_header.c_str(), line_c, strlen(Snapmaker_Orca_gcode_header.c_str())) == 0) {
header_found = true;
break;
}
@@ -1324,11 +1324,66 @@ ConfigSubstitutions ConfigBase::load_from_gcode_file(const std::string &file, Fo
bool begin_found = false;
bool end_found = false;
std::string line;
while (std::getline(ifs, line))
if (line.rfind("; CONFIG_BLOCK_START",0)==0) {
int thumbnail_id = 0;
while (std::getline(ifs, line)) {
// 找到缩略图开始标记
if (line.find("; THUMBNAIL_BLOCK_START") != std::string::npos) {
std::string thumb_content = "";
int width = 0;
int height = 0;
int data_size = 0;
// 跳过空行
std::getline(ifs, line);
std::getline(ifs, line);
// 读取缩略图信息行
std::getline(ifs, line);
if (line.find("; thumbnail begin") != std::string::npos) {
// 解析宽度、高度和数据大小
// 格式: "; thumbnail begin 48x48 1144"
sscanf(line.c_str(), "; thumbnail begin %dx%d %d", &width, &height, &data_size);
// 读取Base64编码的数据
std::string base64_data;
while (std::getline(ifs, line)) {
if (line.find("; thumbnail end") != std::string::npos) {
break;
}
// 移除行首的 "; "
if (line.substr(0, 2) == "; ") {
base64_data += line.substr(2);
}
}
thumb_content = base64_data;
this->set_deserialize("thumb" + std::to_string(thumbnail_id++), thumb_content, substitutions_ctxt);
}
// 读取到块结束标记
while (std::getline(ifs, line)) {
if (line.find("; THUMBNAIL_BLOCK_END") != std::string::npos) {
break;
}
}
/*if (thumbnail_id == 2)
break;*/
}
}
ifs.clear(); // 清除可能的 EOF 标志
ifs.seekg(0);
while (std::getline(ifs, line)) {
if (line.rfind("; CONFIG_BLOCK_START", 0) == 0) {
begin_found = true;
break;
}
}
if (!begin_found) {
//BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << format("Configuration block closing tag \"; CONFIG_BLOCK_START\" not found when reading %1%", file);
throw Slic3r::RuntimeError(format("Config tag \"; CONFIG_BLOCK_START\" not found"));
+2 -2
View File
@@ -231,8 +231,8 @@ class ConfigOptionDef;
struct ConfigOptionDeleter { void operator()(ConfigOption* p); };
using ConfigOptionUniquePtr = std::unique_ptr<ConfigOption, ConfigOptionDeleter>;
// When parsing a configuration value, if the old_value is not understood by this OrcaSlicer version,
// it is being substituted with some default value that this OrcaSlicer could work with.
// When parsing a configuration value, if the old_value is not understood by this Snapmaker_Orca version,
// it is being substituted with some default value that this Snapmaker_Orca could work with.
// This structure serves to inform the user about the substitutions having been done during file import.
struct ConfigSubstitution {
const ConfigOptionDef *opt_def { nullptr };
+16 -16
View File
@@ -1729,7 +1729,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
// Orca: skip version check
bool dont_load_config = !m_load_config;
// if (m_bambuslicer_generator_version) {
// Semver app_version = *(Semver::parse(SoftFever_VERSION));
// Semver app_version = *(Semver::parse(Snapmaker_VERSION));
// Semver file_version = *m_bambuslicer_generator_version;
// if (file_version.maj() != app_version.maj())
// dont_load_config = true;
@@ -1858,7 +1858,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
lock.close();
if (!m_is_bbl_3mf) {
// if the 3mf was not produced by OrcaSlicer and there is more than one instance,
// if the 3mf was not produced by Snapmaker_Orca and there is more than one instance,
// split the object in as many objects as instances
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", found 3mf from other vendor, split as instance");
for (const IdToModelObjectMap::value_type& object : m_objects) {
@@ -2094,7 +2094,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
extruder_id = extruder_opt->getInt();
if (extruder_id == 0 || extruder_id > max_filament_id)
mo->config.set_key_value("extruder", new ConfigOptionInt(1));
mo->config.set_key_value("extruder", new ConfigOptionInt(0));
if (mo->volumes.size() == 1) {
mo->volumes[0]->config.erase("extruder");
@@ -2108,7 +2108,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
if (vol_extruder_opt->getInt() == 0)
mv->config.erase("extruder");
else if (vol_extruder_opt->getInt() > max_filament_id)
mv->config.set_key_value("extruder", new ConfigOptionInt(1));
mv->config.set_key_value("extruder", new ConfigOptionInt(0));
}
}
}
@@ -3328,7 +3328,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
}
if (!m_is_bbl_3mf) {
// if the 3mf was not produced by OrcaSlicer and there is only one object,
// if the 3mf was not produced by Snapmaker_Orca and there is only one object,
// set the object name to match the filename
if (m_model->objects.size() == 1)
m_model->objects.front()->name = m_name;
@@ -3728,12 +3728,12 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
}*/
} else if (m_curr_metadata_name == BBL_APPLICATION_TAG) {
// Generator application of the 3MF.
// SLIC3R_APP_KEY - SoftFever_VERSION
// SLIC3R_APP_KEY - Snapmaker_VERSION
if (boost::starts_with(m_curr_characters, "BambuStudio-")) {
m_is_bbl_3mf = true;
m_bambuslicer_generator_version = Semver::parse(m_curr_characters.substr(12));
}
else if (boost::starts_with(m_curr_characters, "OrcaSlicer-")) {
else if (boost::starts_with(m_curr_characters, "Snapmaker_Orca-")) {
m_is_bbl_3mf = true;
m_bambuslicer_generator_version = Semver::parse(m_curr_characters.substr(11));
}
@@ -3741,15 +3741,15 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
/*} else if (m_curr_metadata_name == BBS_FDM_SUPPORTS_PAINTING_VERSION) {
m_fdm_supports_painting_version = (unsigned int) atoi(m_curr_characters.c_str());
check_painting_version(m_fdm_supports_painting_version, FDM_SUPPORTS_PAINTING_VERSION,
_(L("The selected 3MF contains FDM supports painted object using a newer version of OrcaSlicer and is not compatible.")));
_(L("The selected 3MF contains FDM supports painted object using a newer version of Snapmaker_Orca and is not compatible.")));
} else if (m_curr_metadata_name == BBS_SEAM_PAINTING_VERSION) {
m_seam_painting_version = (unsigned int) atoi(m_curr_characters.c_str());
check_painting_version(m_seam_painting_version, SEAM_PAINTING_VERSION,
_(L("The selected 3MF contains seam painted object using a newer version of OrcaSlicer and is not compatible.")));
_(L("The selected 3MF contains seam painted object using a newer version of Snapmaker_Orca and is not compatible.")));
} else if (m_curr_metadata_name == BBS_MM_PAINTING_VERSION) {
m_mm_painting_version = (unsigned int) atoi(m_curr_characters.c_str());
check_painting_version(m_mm_painting_version, MM_PAINTING_VERSION,
_(L("The selected 3MF contains multi-material painted object using a newer version of OrcaSlicer and is not compatible.")));*/
_(L("The selected 3MF contains multi-material painted object using a newer version of Snapmaker_Orca and is not compatible.")));*/
} else if (m_curr_metadata_name == BBL_MODEL_ID_TAG) {
m_model_id = xml_unescape(m_curr_characters);
} else if (m_curr_metadata_name == BBL_MODEL_NAME_TAG) {
@@ -4908,7 +4908,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
TriangleMesh triangle_mesh(std::move(its), volume_data.mesh_stats);
if (!m_is_bbl_3mf) {
// if the 3mf was not produced by OrcaSlicer and there is only one instance,
// if the 3mf was not produced by Snapmaker_Orca and there is only one instance,
// bake the transformation into the geometry to allow the reload from disk command
// to work properly
if (object.instances.size() == 1) {
@@ -5791,7 +5791,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
}
// Adds content types file ("[Content_Types].xml";).
// The content of this file is the same for each OrcaSlicer 3mf.
// The content of this file is the same for each Snapmaker_Orca 3mf.
if (!_add_content_types_file_to_archive(archive)) {
return false;
}
@@ -6174,7 +6174,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
}
// Adds relationships file ("_rels/.rels").
// The content of this file is the same for each OrcaSlicer 3mf.
// The content of this file is the same for each Snapmaker_Orca 3mf.
// The relationshis file contains a reference to the geometry file "3D/3dmodel.model", the name was chosen to be compatible with CURA.
if (!_add_relationships_file_to_archive(archive, {}, {}, {}, temp_data, export_plate_idx)) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", _add_relationships_file_to_archive failed\n");
@@ -6538,7 +6538,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
metadata_item_map[BBL_CREATION_DATE_TAG] = "";
metadata_item_map[BBL_MODIFICATION_TAG] = "";
//SoftFever: write BambuStudio tag to keep it compatible
metadata_item_map[BBL_APPLICATION_TAG] = (boost::format("%1%-%2%") % "BambuStudio" % SoftFever_VERSION).str();
metadata_item_map[BBL_APPLICATION_TAG] = (boost::format("%1%-%2%") % "BambuStudio" % Snapmaker_VERSION).str();
}
metadata_item_map[BBS_3MF_VERSION] = std::to_string(VERSION_BBS_3MF);
@@ -7420,7 +7420,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
{
const std::string& temp_path = model.get_backup_path();
std::string temp_file = temp_path + std::string("/") + "_temp_1.config";
config.save_to_json(temp_file, std::string("project_settings"), std::string("project"), std::string(SoftFever_VERSION));
config.save_to_json(temp_file, std::string("project_settings"), std::string("project"), std::string(Snapmaker_VERSION));
return _add_file_to_archive(archive, BBS_PROJECT_CONFIG_FILE, temp_file);
}
@@ -7798,7 +7798,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
// save slice header for debug
stream << " <" << SLICE_HEADER_TAG << ">\n";
stream << " <" << SLICE_HEADER_ITEM_TAG << " " << KEY_ATTR << "=\"" << "X-BBL-Client-Type" << "\" " << VALUE_ATTR << "=\"" << "slicer" << "\"/>\n";
stream << " <" << SLICE_HEADER_ITEM_TAG << " " << KEY_ATTR << "=\"" << "X-BBL-Client-Version" << "\" " << VALUE_ATTR << "=\"" << convert_to_full_version(SoftFever_VERSION) << "\"/>\n";
stream << " <" << SLICE_HEADER_ITEM_TAG << " " << KEY_ATTR << "=\"" << "X-BBL-Client-Version" << "\" " << VALUE_ATTR << "=\"" << convert_to_full_version(Snapmaker_VERSION) << "\"/>\n";
stream << " </" << SLICE_HEADER_TAG << ">\n";
for (unsigned int i = 0; i < (unsigned int)plate_data_list.size(); ++i)
+50 -9
View File
@@ -281,7 +281,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
std::string OozePrevention::post_toolchange(GCode& gcodegen)
{
return (gcodegen.config().standby_temperature_delta.value != 0) ?
gcodegen.writer().set_temperature(this->_get_temp(gcodegen), true, gcodegen.writer().extruder()->id()) :
gcodegen.writer().set_temperature(this->_get_temp(gcodegen), gcodegen.config().tool_change_temprature_wait, gcodegen.writer().extruder()->id()) :
std::string();
}
@@ -723,6 +723,12 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
float wipe_tower_rotation = tcr.priming ? 0.f : alpha;
Vec2f plate_origin_2d(m_plate_origin(0), m_plate_origin(1));
// For Snapmaker Artision
gcodegen.m_next_wipe_x = 0;
gcodegen.m_next_wipe_y = 0;
auto transformed_pos = Eigen::Rotation2Df(wipe_tower_rotation) * tcr.start_pos + wipe_tower_offset;
gcodegen.m_next_wipe_x = transformed_pos(0);
gcodegen.m_next_wipe_y = transformed_pos(1);
std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation);
@@ -741,13 +747,21 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
gcodegen.config().filament_multitool_ramming.get_at(tcr.initial_tool));
const bool should_travel_to_tower = !tcr.priming && (tcr.force_travel // wipe tower says so
|| !needs_toolchange // this is just finishing the tower with no toolchange
|| will_go_down // Make sure to move to prime tower before moving down
|| is_ramming);
if (should_travel_to_tower || gcodegen.m_need_change_layer_lift_z) {
// FIXME: It would be better if the wipe tower set the force_travel flag for all toolchanges,
// then we could simplify the condition and make it more readable.
gcode += gcodegen.retract();
auto type = ZHopType(gcodegen.m_config.z_hop_types.get_at(gcodegen.m_writer.extruder()->id()));
if (type == ZHopType::zhtAuto) {
type = ZHopType::zhtSpiral;
}
auto lift_type = gcodegen.to_lift_type(type);
if (gcodegen.m_config.z_hop_when_prime.get_at(gcodegen.m_writer.extruder()->id())) {
gcode += gcodegen.retract(false, false, lift_type);
}
gcodegen.m_avoid_crossing_perimeters.use_external_mp_once();
gcode += gcodegen.travel_to(wipe_tower_point_to_object_point(gcodegen, start_pos + plate_origin_2d), erMixed, "Travel to a Wipe Tower");
gcode += gcodegen.unretract();
@@ -839,6 +853,8 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
Vec2f transformed_pos = trans_pos(pos);
Vec2f old_pos(-1000.1f, -1000.1f);
bool isFirstTransform = true;
while (gcode_str) {
std::getline(gcode_str, line); // we read the gcode line by line
@@ -3206,16 +3222,29 @@ void GCode::_print_first_layer_extruder_temperatures(GCodeOutputStream &file, Pr
file.write(m_writer.set_temperature(temp, wait, first_printing_extruder_id));
} else {
// Set temperatures of all the printing extruders.
bool is_active = true;
int target_temp = -1;
int target_tool = -1;
for (unsigned int tool_id : print.extruders()) {
is_active = true;
int temp = print.config().nozzle_temperature_initial_layer.get_at(tool_id);
if (m_ooze_prevention.enable && tool_id != first_printing_extruder_id) {
if (print.config().ooze_prevention.value && tool_id != first_printing_extruder_id) {
is_active = false;
if (print.config().idle_temperature.get_at(tool_id) == 0)
temp += print.config().standby_temperature_delta.value;
else
temp = print.config().idle_temperature.get_at(tool_id);
}
if (temp > 0)
file.write(m_writer.set_temperature(temp, wait, tool_id));
if (temp > 0) {
if (is_active) {
target_temp = temp;
target_tool = tool_id;
}else
file.write(m_writer.set_temperature(temp, wait, tool_id));
}
}
if (target_temp != -1 && target_tool != -1) {
file.write(m_writer.set_temperature(target_temp, wait, target_tool));
}
}
}
@@ -6343,9 +6372,17 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li
(the extruder might be already retracted fully or partially). We call these
methods even if we performed wipe, since this will ensure the entire retraction
length is honored in case wipe path was too short. */
if ((!this->on_first_layer() || this->config().bottom_surface_pattern != InfillPattern::ipHilbertCurve) &&
(role != erTopSolidInfill || this->config().top_surface_pattern != InfillPattern::ipHilbertCurve))
gcode += toolchange ? m_writer.retract_for_toolchange() : m_writer.retract();
// Snapmaker U1
std::string printer_model = this->m_curr_print->m_config.printer_model.value;
if (printer_model == "Snapmaker U1" && toolchange) {
gcode += "M400\n";
}
if ((!this->on_first_layer() || this->config().bottom_surface_pattern != InfillPattern::ipHilbertCurve) &&
(role != erTopSolidInfill || this->config().top_surface_pattern != InfillPattern::ipHilbertCurve)){
gcode += toolchange ? m_writer.retract_for_toolchange() : m_writer.retract();
}
gcode += m_writer.reset_e();
// Orca: check if should + can lift (roughly from SuperSlicer)
@@ -6546,6 +6583,10 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z, bool b
dyn_config.set_key_value(key_value, new ConfigOptionFloat(0.f));
}
// For Snapmaker Artisian
dyn_config.set_key_value("next_wipe_x", new ConfigOptionFloat(m_next_wipe_x));
dyn_config.set_key_value("next_wipe_y", new ConfigOptionFloat(m_next_wipe_y));
// Process the custom change_filament_gcode.
const std::string& change_filament_gcode = m_config.change_filament_gcode.value;
std::string toolchange_gcode_parsed;
+4
View File
@@ -544,6 +544,10 @@ private:
float m_last_layer_z{ 0.0f };
float m_max_layer_z{ 0.0f };
float m_last_width{ 0.0f };
// SM_Orca
float m_next_wipe_x {0.0f};
float m_next_wipe_y {0.0f};
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
double m_last_mm3_per_mm;
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
@@ -1,5 +1,5 @@
// AdaptivePAInterpolator.cpp
// OrcaSlicer
// Snapmaker_Orca
//
// Implementation file for the AdaptivePAInterpolator class, providing methods to parse data and perform PA interpolation.
@@ -1,5 +1,5 @@
// AdaptivePAInterpolator.hpp
// OrcaSlicer
// Snapmaker_Orca
//
// Header file for the AdaptivePAInterpolator class, responsible for interpolating pressure advance (PA) values based on flow rate and acceleration using PCHIP interpolation.
+1 -1
View File
@@ -1,5 +1,5 @@
// AdaptivePAProcessor.cpp
// OrcaSlicer
// Snapmaker_Orca
//
// Implementation of the AdaptivePAProcessor class, responsible for processing G-code layers with adaptive pressure advance.
+1 -1
View File
@@ -1,5 +1,5 @@
// AdaptivePAProcessor.hpp
// OrcaSlicer
// Snapmaker_Orca
//
// Header file for the AdaptivePAProcessor class, responsible for processing G-code layers for the purposes of applying adaptive pressure advance.
+15 -11
View File
@@ -616,12 +616,12 @@ void GCodeProcessorResult::reset() {
#endif // ENABLE_GCODE_VIEWER_STATISTICS
const std::vector<std::pair<GCodeProcessor::EProducer, std::string>> GCodeProcessor::Producers = {
//BBS: OrcaSlicer is also "bambu". Otherwise the time estimation didn't work.
//BBS: Snapmaker_Orca is also "bambu". Otherwise the time estimation didn't work.
//FIXME: Workaround and should be handled when do removing-bambu
{ EProducer::OrcaSlicer, SLIC3R_APP_NAME },
{ EProducer::OrcaSlicer, "generated by OrcaSlicer" },
{ EProducer::OrcaSlicer, "generated by BambuStudio" },
{ EProducer::OrcaSlicer, "BambuStudio" }
{ EProducer::Snapmaker_Orca, SLIC3R_APP_NAME },
{ EProducer::Snapmaker_Orca, "generated by Snapmaker_Orca" },
{ EProducer::Snapmaker_Orca, "generated by BambuStudio" },
{ EProducer::Snapmaker_Orca, "BambuStudio" }
//{ EProducer::Slic3rPE, "generated by Slic3r Bambu Edition" },
//{ EProducer::Slic3r, "generated by Slic3r" },
//{ EProducer::SuperSlicer, "generated by SuperSlicer" },
@@ -712,6 +712,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
// Orca:
m_is_XL_printer = is_XL_printer(config);
m_preheat_time = config.preheat_time;
m_delta_temperature = config.delta_temperature;
m_preheat_steps = config.preheat_steps;
// sanity check
if(m_preheat_steps < 1)
@@ -811,6 +812,8 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
{
m_current_config = config;
m_parser.apply_config(config);
//BBS
@@ -1191,6 +1194,7 @@ void GCodeProcessor::reset()
m_seams_count = 0;
m_preheat_time = 0.f;
m_delta_temperature = 0;
m_preheat_steps = 1;
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
@@ -1242,12 +1246,12 @@ void GCodeProcessor::process_file(const std::string& filename, std::function<voi
});
m_parser.reset();
// if the gcode was produced by OrcaSlicer,
// if the gcode was produced by Snapmaker_Orca,
// extract the config from it
if (m_producer == EProducer::OrcaSlicer || m_producer == EProducer::Slic3rPE || m_producer == EProducer::Slic3r) {
if (m_producer == EProducer::Snapmaker_Orca || m_producer == EProducer::Slic3rPE || m_producer == EProducer::Slic3r) {
DynamicPrintConfig config;
config.apply(FullPrintConfig::defaults());
// Silently substitute unknown values by new ones for loading configurations from OrcaSlicer's own G-code.
// Silently substitute unknown values by new ones for loading configurations from Snapmaker_Orca's own G-code.
// Showing substitution log or errors may make sense, but we are not really reading many values from the G-code config,
// thus a probability of incorrect substitution is low and the G-code viewer is a consumer-only anyways.
config.load_from_gcode_file(filename, ForwardCompatibilitySubstitutionRule::EnableSilent);
@@ -1959,7 +1963,7 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers
return;
}
if (!producers_enabled || m_producer == EProducer::OrcaSlicer) {
if (!producers_enabled || m_producer == EProducer::Snapmaker_Orca) {
// height tag
if (boost::starts_with(comment, reserved_tag(ETags::Height))) {
if (!parse_number(comment.substr(reserved_tag(ETags::Height).size()), m_forced_height))
@@ -2106,7 +2110,7 @@ bool GCodeProcessor::process_producers_tags(const std::string_view comment)
case EProducer::Slic3rPE:
case EProducer::Slic3r:
case EProducer::SuperSlicer:
case EProducer::OrcaSlicer: { return process_bambuslicer_tags(comment); }
case EProducer::Snapmaker_Orca: { return process_bambuslicer_tags(comment); }
case EProducer::Cura: { return process_cura_tags(comment); }
case EProducer::Simplify3D: { return process_simplify3d_tags(comment); }
case EProducer::CraftWare: { return process_craftware_tags(comment); }
@@ -4640,7 +4644,7 @@ void GCodeProcessor::run_post_process()
} else {
std::string comment = "preheat T" + std::to_string(tool_number) +
" time: " + std::to_string((int) std::round(time_diffs[0])) + "s";
return GCodeWriter::set_temperature(temperature, this->m_flavor, false, tool_number, comment);
return GCodeWriter::set_temperature(temperature + m_delta_temperature, this->m_flavor, false, tool_number, comment);
}
},
// line replacer
+7 -1
View File
@@ -731,6 +731,7 @@ class Print;
int m_seams_count;
bool m_single_extruder_multi_material;
float m_preheat_time;
int m_delta_temperature;
int m_preheat_steps;
bool m_disable_m73;
#if ENABLE_GCODE_VIEWER_STATISTICS
@@ -740,7 +741,7 @@ class Print;
enum class EProducer
{
Unknown,
OrcaSlicer,
Snapmaker_Orca,
Slic3rPE,
Slic3r,
SuperSlicer,
@@ -754,6 +755,8 @@ class Print;
static const std::vector<std::pair<GCodeProcessor::EProducer, std::string>> Producers;
EProducer m_producer;
DynamicConfig m_current_config;
TimeProcessor m_time_processor;
UsedFilaments m_used_filaments;
@@ -783,7 +786,10 @@ class Print;
const GCodeProcessorResult& get_result() const { return m_result; }
GCodeProcessorResult& result() { return m_result; }
GCodeProcessorResult&& extract_result() { return std::move(m_result); }
DynamicConfig& current_dynamic_config() { return m_current_config; }
GCodeReader& parser() { return m_parser; }
// Load a G-code into a stand-alone G-code viewer.
// throws CanceledException through print->throw_if_canceled() (sent by the caller as callback).
void process_file(const std::string& filename, std::function<void()> cancel_callback = nullptr);
@@ -1,5 +1,5 @@
// PchipInterpolatorHelper.cpp
// OrcaSlicer
// Snapmaker_Orca
//
// Implementation file for the PchipInterpolatorHelper class
@@ -1,5 +1,5 @@
// PchipInterpolatorHelper.hpp
// OrcaSlicer
// Snapmaker_Orca
//
// Header file for the PchipInterpolatorHelper class, responsible for performing Piecewise Cubic Hermite Interpolating Polynomial (PCHIP) interpolation on given data points.
+28
View File
@@ -246,6 +246,24 @@ ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extrude
this->mark_skirt_layers(object.print()->config(), max_layer_height);
}
bool ToolOrdering::insert_wipe_tower_extruder()
{
if(!m_print_config_ptr->enable_prime_tower)
return false;
// In case that wipe_tower_extruder is set to non-zero, we must make sure that the extruder will be in the list.
bool changed = false;
if (m_print_config_ptr->wipe_tower_filament != 0) {
for (LayerTools& lt : m_layer_tools) {
if (lt.wipe_tower_partitions > 0) {
lt.extruders.emplace_back(m_print_config_ptr->wipe_tower_filament - 1);
sort_remove_duplicates(lt.extruders);
changed = true;
}
}
}
return changed;
}
// For the use case when all objects are printed at once.
// (print->config().print_sequence == PrintSequence::ByObject is false).
ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool prime_multi_material)
@@ -312,6 +330,16 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool
this->fill_wipe_tower_partitions(print.config(), object_bottom_z, max_layer_height);
if (this->insert_wipe_tower_extruder()) {
// Now convert the 0-based list to 1-based again, because that is what reorder_extruder expects.
for (LayerTools& lt : m_layer_tools) {
for (auto& extruder : lt.extruders)
++extruder;
}
this->reorder_extruders(first_extruder);
this->fill_wipe_tower_partitions(print.config(), object_bottom_z, max_layer_height);
}
this->collect_extruder_statistics(prime_multi_material);
this->mark_skirt_layers(print.config(), max_layer_height);
+1
View File
@@ -194,6 +194,7 @@ private:
// BBS
void reorder_extruders(std::vector<unsigned int> tool_order_layer0);
void fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height);
bool insert_wipe_tower_extruder();
void mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height);
void collect_extruder_statistics(bool prime_multi_material);
void reorder_extruders_for_minimum_flush_volume();
+11 -10
View File
@@ -119,7 +119,7 @@ public:
WipeTowerWriter& set_initial_tool(size_t tool) { m_current_tool = tool; return *this; }
WipeTowerWriter& set_z(float z)
WipeTowerWriter& set_z(float z)
{ m_current_z = z; return *this; }
WipeTowerWriter& set_extrusion_flow(float flow)
@@ -238,7 +238,7 @@ public:
WipeTowerWriter& travel(float x, float y, float f = 0.f)
{ return extrude_explicit(x, y, 0.f, f); }
WipeTowerWriter& travel(const Vec2f &dest, float f = 0.f)
WipeTowerWriter& travel(const Vec2f &dest, float f = 0.f)
{ return extrude_explicit(dest.x(), dest.y(), 0.f, f); }
// Extrude a line from current position to x, y with the extrusion amount given by m_extrusion_flow.
@@ -249,7 +249,7 @@ public:
return extrude_explicit(x, y, std::sqrt(dx*dx+dy*dy) * m_extrusion_flow, f, true);
}
WipeTowerWriter& extrude(const Vec2f &dest, const float f = 0.f)
WipeTowerWriter& extrude(const Vec2f &dest, const float f = 0.f)
{ return extrude(dest.x(), dest.y(), f); }
WipeTowerWriter& rectangle(const Vec2f& ld,float width,float height,const float f = 0.f)
@@ -300,7 +300,7 @@ public:
do {
++i;
if (i == 4) i = 0;
if (need_change_flow) {
if (need_change_flow) {
if (i == 1) {
// using bridge flow in bridge area, and add notes for gcode-check when flow changed
set_extrusion_flow(wipe_tower->extrusion_flow(0.2));
@@ -359,7 +359,7 @@ public:
// Elevate the extruder head above the current print_z position.
WipeTowerWriter& z_hop(float hop, float f = 0.f)
{
{
m_gcode += std::string("G1") + set_format_Z(m_current_z + hop);
if (f != 0 && f != m_current_feedrate)
m_gcode += set_format_F(f);
@@ -368,7 +368,7 @@ public:
}
// Lower the extruder head back to the current print_z position.
WipeTowerWriter& z_hop_reset(float f = 0.f)
WipeTowerWriter& z_hop_reset(float f = 0.f)
{ return z_hop(0, f); }
// Move to x1, +y_increment,
@@ -456,14 +456,14 @@ public:
}
WipeTowerWriter& flush_planner_queue()
{
m_gcode += "G4 S0\n";
{
m_gcode += "G4 S0\n";
return *this;
}
// Reset internal extruder counter.
WipeTowerWriter& reset_extruder()
{
{
m_gcode += "G92 E0\n";
return *this;
}
@@ -674,7 +674,8 @@ void WipeTower::set_extruder(size_t idx, const PrintConfig& config)
m_filpar.push_back(FilamentParameters());
m_filpar[idx].material = config.filament_type.get_at(idx);
m_filpar[idx].is_soluble = config.filament_soluble.get_at(idx);
// m_filpar[idx].is_soluble = config.filament_soluble.get_at(idx);
m_filpar[idx].is_soluble = config.wipe_tower_filament == 0 ? config.filament_soluble.get_at(idx) : (idx != size_t(config.wipe_tower_filament - 1));
// BBS
m_filpar[idx].is_support = config.filament_is_support.get_at(idx);
m_filpar[idx].nozzle_temperature = config.nozzle_temperature.get_at(idx);
+77 -27
View File
@@ -565,7 +565,8 @@ public:
float line_width,
GCodeFlavor flavor,
const std::vector<WipeTower2::FilamentParameters>& filament_parameters,
bool enable_arc_fitting)
bool enable_arc_fitting,
const std::string& printer_model)
:
m_current_pos(std::numeric_limits<float>::max(), std::numeric_limits<float>::max()),
m_current_z(0.f),
@@ -574,8 +575,9 @@ public:
m_extrusion_flow(0.f),
m_preview_suppressed(false),
m_elapsed_time(0.f),
m_gcode_flavor(flavor), m_filpar(filament_parameters)
//m_enable_arc_fitting(enable_arc_fitting)
m_gcode_flavor(flavor),
m_filpar(filament_parameters),
m_printer_model(printer_model)
{
// ORCA: This class is only used by non BBL printers, so set the parameter appropriately.
// This fixes an issue where the wipe tower was using BBL tags resulting in statistics for purging in the purge tower not being displayed.
@@ -624,13 +626,28 @@ public:
WipeTowerWriter2& disable_linear_advance() {
if (m_gcode_flavor == gcfRepRapSprinter || m_gcode_flavor == gcfRepRapFirmware)
m_gcode += (std::string("M572 D") + std::to_string(m_current_tool) + " S0\n");
else if (m_gcode_flavor == gcfKlipper)
m_gcode += "SET_PRESSURE_ADVANCE ADVANCE=0\n";
else if (m_gcode_flavor == gcfKlipper){
// m_gcode += "SET_PRESSURE_ADVANCE ADVANCE=0\n"; // Snapmaker U1
}
else
m_gcode += "M900 K0\n";
return *this;
}
WipeTowerWriter2& disable_linear_advance_value(float value = 0.0) {
if (m_gcode_flavor == gcfRepRapSprinter || m_gcode_flavor == gcfRepRapFirmware)
m_gcode += (std::string("M572 D") + std::to_string(m_current_tool) + " S"+ std::to_string(value) + "\n");
else if (m_gcode_flavor == gcfKlipper) {
m_gcode += "SET_PRESSURE_ADVANCE ADVANCE=" + Slic3r::float_to_string_decimal_point(value, 4) + "\n"; // Snapmaker U1
}
else
m_gcode += "M900 K" + std::to_string(value) + "\n";
return *this;
}
WipeTowerWriter2& switch_filament_monitoring(bool enable) {
m_gcode += std::string("G4 S0\n") + "M591 " + (enable ? "R" : "S0") + "\n";
return *this;
@@ -896,16 +913,20 @@ public:
WipeTowerWriter2& speed_override_backup()
{
// This is only supported by Prusa at this point (https://github.com/prusa3d/PrusaSlicer/issues/3114)
if (m_gcode_flavor == gcfMarlinLegacy || m_gcode_flavor == gcfMarlinFirmware)
if (m_gcode_flavor == gcfMarlinLegacy || m_gcode_flavor == gcfMarlinFirmware || is_snapmaker_u1()) {
// u1 特殊处理
m_gcode += "M220 B\n";
}
return *this;
}
// Let the firmware restore the active speed override value.
WipeTowerWriter2& speed_override_restore()
{
if (m_gcode_flavor == gcfMarlinLegacy || m_gcode_flavor == gcfMarlinFirmware)
if (m_gcode_flavor == gcfMarlinLegacy || m_gcode_flavor == gcfMarlinFirmware || is_snapmaker_u1()) {
// u1 特殊处理
m_gcode += "M220 R\n";
}
return *this;
}
@@ -1151,6 +1172,13 @@ private:
GCodeFlavor m_gcode_flavor;
bool m_enable_arc_fitting = false;
const std::vector<WipeTower2::FilamentParameters>& m_filpar;
std::string m_printer_model;
// 判断是否是 Snapmaker U1 打印机
bool is_snapmaker_u1() const {
return boost::icontains(m_printer_model, "Snapmaker") &&
boost::icontains(m_printer_model, "U1");
}
std::string set_format_X(float x)
{
@@ -1240,7 +1268,11 @@ WipeTower2::WipeTower2(const PrintConfig& config, const PrintRegionConfig& defau
m_infill_speed(default_region_config.sparse_infill_speed),
m_perimeter_speed(default_region_config.inner_wall_speed),
m_current_tool(initial_tool),
wipe_volumes(wiping_matrix), m_wipe_tower_max_purge_speed(float(config.wipe_tower_max_purge_speed)),
wipe_volumes(wiping_matrix),
m_wipe_tower_max_purge_speed(float(config.wipe_tower_max_purge_speed)),
m_change_pressure(config.enable_change_pressure_when_wiping),
m_change_pressure_value(config.ramming_pressure_advance_value),
m_ramming_width_ratio(config.ramming_line_width_ratio),
m_enable_arc_fitting(config.enable_arc_fitting),
m_used_fillet(config.wipe_tower_fillet_wall),
m_rib_width(config.wipe_tower_rib_width),
@@ -1274,6 +1306,9 @@ WipeTower2::WipeTower2(const PrintConfig& config, const PrintRegionConfig& defau
m_is_mk4mmu3 = boost::icontains(config.printer_notes.value, "PRINTER_MODEL_MK4") && boost::icontains(config.printer_notes.value, "MMU");
// 保存打印机型号信息
m_printer_model = config.printer_model.value;
// Calculate where the priming lines should be - very naive test not detecting parallelograms etc.
const std::vector<Vec2d>& bed_points = config.printable_area.values;
BoundingBoxf bb(bed_points);
@@ -1305,7 +1340,8 @@ void WipeTower2::set_extruder(size_t idx, const PrintConfig& config)
m_filpar.push_back(FilamentParameters());
m_filpar[idx].material = config.filament_type.get_at(idx);
m_filpar[idx].is_soluble = config.filament_soluble.get_at(idx);
// m_filpar[idx].is_soluble = config.filament_soluble.get_at(idx);
m_filpar[idx].is_soluble = config.wipe_tower_filament == 0 ? config.filament_soluble.get_at(idx) : (idx != size_t(config.wipe_tower_filament - 1));
m_filpar[idx].temperature = config.nozzle_temperature.get_at(idx);
m_filpar[idx].first_layer_temperature = config.nozzle_temperature_initial_layer.get_at(idx);
m_filpar[idx].filament_minimal_purge_on_wipe_tower = config.filament_minimal_purge_on_wipe_tower.get_at(idx);
@@ -1351,7 +1387,7 @@ void WipeTower2::set_extruder(size_t idx, const PrintConfig& config)
float vol = config.filament_multitool_ramming_volume.get_at(idx);
float flow = config.filament_multitool_ramming_flow.get_at(idx);
m_filpar[idx].multitool_ramming = config.filament_multitool_ramming.get_at(idx) && vol > 0.f && flow > 0.f;
m_filpar[idx].ramming_line_width_multiplicator = 2.;
m_filpar[idx].ramming_line_width_multiplicator = m_ramming_width_ratio;
m_filpar[idx].ramming_step_multiplicator = 1.;
// Now the ramming speed vector. In this case it contains just one value (flow).
@@ -1405,7 +1441,7 @@ std::vector<WipeTower::ToolChangeResult> WipeTower2::prime(
for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) {
size_t old_tool = m_current_tool;
WipeTowerWriter2 writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar, m_enable_arc_fitting);
WipeTowerWriter2 writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar, m_enable_arc_fitting, m_printer_model);
writer.set_extrusion_flow(m_extrusion_flow)
.set_z(m_z_pos)
.set_initial_tool(m_current_tool);
@@ -1432,7 +1468,10 @@ std::vector<WipeTower::ToolChangeResult> WipeTower2::prime(
toolchange_Load(writer, cleaning_box); // Prime the tool.
if (idx_tool + 1 == tools.size()) {
// Last tool should not be unloaded, but it should be wiped enough to become of a pure color.
toolchange_Wipe(writer, cleaning_box, wipe_volumes[tools[idx_tool-1]][tool]);
if (idx_tool == 0)
toolchange_Wipe(writer, cleaning_box, wipe_volumes[tools[idx_tool]][tool]);
else
toolchange_Wipe(writer, cleaning_box, wipe_volumes[tools[idx_tool - 1]][tool]);
} else {
// Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
//writer.travel(writer.x(), writer.y() + m_perimeter_width, 7200);
@@ -1500,7 +1539,7 @@ WipeTower::ToolChangeResult WipeTower2::tool_change(size_t tool)
(tool != (unsigned int)(-1) ? wipe_area+m_depth_traversed-0.5f*m_perimeter_width
: m_wipe_tower_depth-m_perimeter_width));
WipeTowerWriter2 writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar, m_enable_arc_fitting);
WipeTowerWriter2 writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar, m_enable_arc_fitting, m_printer_model);
writer.set_extrusion_flow(m_extrusion_flow)
.set_z(m_z_pos)
.set_initial_tool(m_current_tool)
@@ -1590,8 +1629,12 @@ void WipeTower2::toolchange_Unload(
if (do_ramming) {
writer.travel(ramming_start_pos); // move to starting position
if (! m_is_mk4mmu3)
writer.disable_linear_advance();
if (!m_is_mk4mmu3) {
if (m_change_pressure) {
writer.disable_linear_advance_value(m_change_pressure_value);
}
}
if (cold_ramming)
writer.set_extruder_temp(old_temperature - 20);
}
@@ -1634,8 +1677,13 @@ void WipeTower2::toolchange_Unload(
}
bool is_over_tower_height = false;
if (m_plan.size() > 0 && m_num_layer_changes == m_plan.size()) {
is_over_tower_height = true;
}
// now the ramming itself:
while (do_ramming && i < m_filpar[m_current_tool].ramming_speed.size())
while (do_ramming && i < m_filpar[m_current_tool].ramming_speed.size() && !is_over_tower_height)
{
// The time step is different for SEMM ramming and the MM ramming. See comments in set_extruder() for details.
const float time_step = m_semm ? 0.25f : m_filpar[m_current_tool].multitool_ramming_time;
@@ -1705,8 +1753,12 @@ void WipeTower2::toolchange_Unload(
float speed_inc = (final_speed - initial_speed) / (2.f * number_of_cooling_moves - 1.f);
if (m_is_mk4mmu3)
writer.disable_linear_advance();
if (m_is_mk4mmu3) {
if (m_change_pressure) {
writer.disable_linear_advance_value(m_change_pressure_value);
}
}
writer.suppress_preview()
.travel(writer.x(), writer.y() + y_step);
@@ -1928,7 +1980,7 @@ WipeTower::ToolChangeResult WipeTower2::finish_layer()
size_t old_tool = m_current_tool;
WipeTowerWriter2 writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar, m_enable_arc_fitting);
WipeTowerWriter2 writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar, m_enable_arc_fitting, m_printer_model);
writer.set_extrusion_flow(m_extrusion_flow)
.set_z(m_z_pos)
.set_initial_tool(m_current_tool)
@@ -2216,14 +2268,12 @@ void WipeTower2::save_on_last_wipe()
int WipeTower2::first_toolchange_to_nonsoluble(
const std::vector<WipeTowerInfo::ToolChange>& tool_changes) const
{
// Orca: allow calculation of the required depth and wipe volume for soluable toolchanges as well
// NOTE: it's not clear if this is the right way, technically we should disable wipe tower if soluble filament is used as it
// will will make the wipe tower unstable. Need to revist this in the future.
return tool_changes.empty() ? -1 : 0;
//for (size_t idx=0; idx<tool_changes.size(); ++idx)
// if (! m_filpar[tool_changes[idx].new_tool].is_soluble)
// return idx;
//return -1;
// 使用 wipe_tower_filament 配置来决定哪个挤出机用于 wipe tower
for (size_t idx=0; idx<tool_changes.size(); ++idx) {
if (!m_filpar[tool_changes[idx].new_tool].is_soluble)
return idx;
}
return -1;
}
static WipeTower::ToolChangeResult merge_tcr(WipeTower::ToolChangeResult& first,
+4 -1
View File
@@ -175,10 +175,13 @@ private:
return m_filpar[0].filament_area; // all extruders are assumed to have the same filament diameter at this point
}
bool m_change_pressure = true;
float m_change_pressure_value = 0.0;
float m_ramming_width_ratio = 2.0;
bool m_semm = true; // Are we using a single extruder multimaterial printer?
bool m_enable_filament_ramming = true;
bool m_is_mk4mmu3 = false;
std::string m_printer_model; // Printer model name (e.g., "Snapmaker U1")
Vec2f m_wipe_tower_pos; // Left front corner of the wipe tower in mm.
float m_wipe_tower_width; // Width of the wipe tower.
float m_wipe_tower_depth = 0.f; // Depth of the wipe tower
+24 -6
View File
@@ -458,7 +458,7 @@ ModelObject* Model::add_object(const char *name, const char *path, const Triangl
new_volume->source.volume_idx = (int)new_object->volumes.size() - 1;
// BBS: set extruder id to 1
if (!new_object->config.has("extruder") || new_object->config.extruder() == 0)
new_object->config.set_key_value("extruder", new ConfigOptionInt(1));
new_object->config.set_key_value("extruder", new ConfigOptionInt(0));
new_object->invalidate_bounding_box();
return new_object;
}
@@ -476,7 +476,7 @@ ModelObject* Model::add_object(const char *name, const char *path, TriangleMesh
new_volume->source.volume_idx = (int)new_object->volumes.size() - 1;
// BBS: set default extruder id to 1
if (!new_object->config.has("extruder") || new_object->config.extruder() == 0)
new_object->config.set_key_value("extruder", new ConfigOptionInt(1));
new_object->config.set_key_value("extruder", new ConfigOptionInt(0));
new_object->invalidate_bounding_box();
return new_object;
}
@@ -487,7 +487,7 @@ ModelObject* Model::add_object(const ModelObject &other)
new_object->set_model(this);
// BBS: set default extruder id to 1
if (!new_object->config.has("extruder") || new_object->config.extruder() == 0)
new_object->config.set_key_value("extruder", new ConfigOptionInt(1));
new_object->config.set_key_value("extruder", new ConfigOptionInt(0));
this->objects.push_back(new_object);
// BBS: backup
if (need_backup) {
@@ -2424,7 +2424,7 @@ int ModelVolume::extruder_id() const
const ConfigOption *opt = this->config.option("extruder");
if ((opt == nullptr) || (opt->getInt() == 0))
opt = this->object->config.option("extruder");
extruder_id = (opt == nullptr) ? 1 : opt->getInt();
extruder_id = (opt == nullptr) ? 0 : opt->getInt();
}
return extruder_id;
}
@@ -2466,6 +2466,8 @@ std::vector<int> ModelVolume::get_extruders() const
int volume_extruder_id = this->extruder_id();
if (volume_extruder_id > 0)
volume_extruders.push_back(volume_extruder_id);
else if (volume_extruder_id == 0)
volume_extruders.push_back(volume_extruder_id + 1);
return volume_extruders;
}
@@ -2481,6 +2483,19 @@ void ModelVolume::update_extruder_count(size_t extruder_count)
}
}
void ModelVolume::update_extruder_count_when_delete_filament(size_t extruder_count, size_t filament_id, int replace_filament_id)
{
std::vector<int> used_extruders = get_extruders();
for (int extruder_id : used_extruders) {
if (extruder_id >= filament_id) {
mmu_segmentation_facets.set_enforcer_block_type_limit(*this, (EnforcerBlockerType) (extruder_count),
(EnforcerBlockerType) (filament_id),
(EnforcerBlockerType) (replace_filament_id));
break;
}
}
}
void ModelVolume::center_geometry_after_creation(bool update_source_offset)
{
Vec3d shift = this->mesh().bounding_box().center();
@@ -3375,10 +3390,13 @@ void FacetsAnnotation::get_facets(const ModelVolume& mv, std::vector<indexed_tri
selector.get_facets(facets_per_type);
}
void FacetsAnnotation::set_enforcer_block_type_limit(const ModelVolume& mv, EnforcerBlockerType max_type)
void FacetsAnnotation::set_enforcer_block_type_limit(const ModelVolume& mv,
EnforcerBlockerType max_type,
EnforcerBlockerType to_delete_filament,
EnforcerBlockerType replace_filament)
{
TriangleSelector selector(mv.mesh());
selector.deserialize(m_data, false, max_type);
selector.deserialize(m_data, false, max_type, to_delete_filament, replace_filament);
this->set(selector);
}
+5 -1
View File
@@ -734,7 +734,10 @@ public:
indexed_triangle_set get_facets(const ModelVolume& mv, EnforcerBlockerType type) const;
// BBS
void get_facets(const ModelVolume& mv, std::vector<indexed_triangle_set>& facets_per_type) const;
void set_enforcer_block_type_limit(const ModelVolume& mv, EnforcerBlockerType max_type);
void set_enforcer_block_type_limit(const ModelVolume& mv,
EnforcerBlockerType max_type,
EnforcerBlockerType to_delete_filament = EnforcerBlockerType::NONE,
EnforcerBlockerType replace_filament = EnforcerBlockerType::NONE);
indexed_triangle_set get_facets_strict(const ModelVolume& mv, EnforcerBlockerType type) const;
bool has_facets(const ModelVolume& mv, EnforcerBlockerType type) const;
bool empty() const { return m_data.triangles_to_split.empty(); }
@@ -915,6 +918,7 @@ public:
// BBS
std::vector<int> get_extruders() const;
void update_extruder_count(size_t extruder_count);
void update_extruder_count_when_delete_filament(size_t extruder_count, size_t filament_id, int replace_filament_id = -1);
// Split this volume, append the result to the object owning this volume.
// Return the number of volumes created from this one.
+1 -1
View File
@@ -69,7 +69,7 @@ namespace Slic3r {
PlaceholderParser::PlaceholderParser(const DynamicConfig *external_config) : m_external_config(external_config)
{
this->set("version", std::string(SoftFever_VERSION));
this->set("version", std::string(Snapmaker_VERSION));
this->apply_env_variables();
this->update_timestamp();
this->update_user_name();
+59 -16
View File
@@ -52,6 +52,31 @@ using boost::property_tree::ptree;
namespace Slic3r {
Semver get_min_version_from_json(std::string file_path)
{
try {
boost::nowide::ifstream ifs(file_path);
json j;
ifs >> j;
if (!j.count(BBL_JSON_KEY_MIN_VERSION)) {
return Semver();
}
std::string version_str = j.at(BBL_JSON_KEY_MIN_VERSION);
auto config_version = Semver::parse(version_str);
if (!config_version) {
return Semver();
} else {
return *config_version;
}
}
catch (nlohmann::detail::parse_error& err) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << file_path
<< " got a nlohmann::detail::parse_error, reason = " << err.what();
return Semver();
}
}
//BBS: add a function to load the version from xxx.json
Semver get_version_from_json(std::string file_path)
{
@@ -753,17 +778,10 @@ BedType Preset::get_default_bed_type(PresetBundle* preset_bundle)
{
if (config.has("default_bed_type") && !config.opt_string("default_bed_type").empty()) {
try {
std::string str_bed_type = config.opt_string("default_bed_type");
// Try parsing as integer first (legacy format)
int bed_type_value = atoi(str_bed_type.c_str());
if (bed_type_value > 0) {
std::string str_bed_type = config.opt_string("default_bed_type");
int bed_type_value = atoi(str_bed_type.c_str());
if (bed_type_value != 0)
return BedType(bed_type_value);
}
else {
BOOST_LOG_TRIVIAL(error) << "default_bed_type: invalid bed type: " << str_bed_type;
}
return BedType::btPEI;
} catch(...) {
;
@@ -775,6 +793,8 @@ BedType Preset::get_default_bed_type(PresetBundle* preset_bundle)
return BedType::btPC;
} else if (model_id == "C11") {
return BedType::btPEI;
} else if (model_id == "SM_U1") {
return BedType::btPTE;
}
return BedType::btPEI;
}
@@ -814,7 +834,7 @@ static std::vector<std::string> s_Preset_print_options {
"support_top_z_distance", "support_on_build_plate_only","support_critical_regions_only", "bridge_no_support", "thick_bridges", "thick_internal_bridges","dont_filter_internal_bridges","enable_extra_bridge_layer", "max_bridge_length", "print_sequence", "print_order", "support_remove_small_overhang",
"filename_format", "wall_filament", "support_bottom_z_distance",
"sparse_infill_filament", "solid_infill_filament", "support_filament", "support_interface_filament","support_interface_not_for_body",
"ooze_prevention", "standby_temperature_delta", "preheat_time","preheat_steps", "interface_shells", "line_width", "initial_layer_line_width", "inner_wall_line_width",
"ooze_prevention", "standby_temperature_delta", "preheat_time","delta_temperature","preheat_steps", "interface_shells", "line_width", "initial_layer_line_width", "inner_wall_line_width",
"outer_wall_line_width", "sparse_infill_line_width", "internal_solid_infill_line_width",
"skin_infill_line_width","skeleton_infill_line_width",
"top_surface_line_width", "support_line_width", "infill_wall_overlap","top_bottom_infill_wall_overlap", "bridge_flow", "internal_bridge_flow",
@@ -866,7 +886,7 @@ static std::vector<std::string> s_Preset_filament_options {
"activate_air_filtration","during_print_exhaust_fan_speed","complete_print_exhaust_fan_speed",
// Retract overrides
"filament_retraction_length", "filament_z_hop", "filament_z_hop_types", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_lift_enforce", "filament_retraction_speed", "filament_deretraction_speed", "filament_retract_restart_extra", "filament_retraction_minimum_travel",
"filament_retract_when_changing_layer", "filament_wipe", "filament_retract_before_wipe",
"filament_retract_when_changing_layer", "filament_wipe", "filament_retract_before_wipe", "filament_retract_length_toolchange", "filament_retract_restart_extra_toolchange",
// Profile compatibility
"filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits",
//BBS
@@ -902,8 +922,8 @@ static std::vector<std::string> s_Preset_printer_options {
"nozzle_height",
"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",
"nozzle_type", "nozzle_hrc","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_types", "travel_slope", "retract_lift_enforce","support_chamber_temp_control","support_air_filtration","printer_structure",
"scan_first_layer", "machine_load_filament_time", "machine_unload_filament_time", "machine_tool_change_time", "tool_change_temprature_wait", "time_cost", "machine_pause_gcode", "template_custom_gcode",
"nozzle_type", "nozzle_hrc","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_types", "z_hop_when_prime", "travel_slope", "retract_lift_enforce","support_chamber_temp_control","support_air_filtration","printer_structure",
"best_object_pos","head_wrap_detect_zone",
"host_type", "print_host", "printhost_apikey", "bbl_use_printhost",
"print_host_webui",
@@ -911,7 +931,7 @@ static std::vector<std::string> s_Preset_printer_options {
"printhost_user", "printhost_password", "printhost_ssl_ignore_revoke", "thumbnails", "thumbnails_format",
"use_firmware_retraction", "use_relative_e_distances", "printer_notes",
"cooling_tube_retraction",
"cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "purge_in_prime_tower", "enable_filament_ramming",
"cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "purge_in_prime_tower", "enable_filament_ramming", "ramming_line_width_ratio", "enable_change_pressure_when_wiping", "ramming_pressure_advance_value",
"z_offset",
"disable_m73", "preferred_orientation", "emit_machine_limits_to_gcode", "pellet_modded_printer", "support_multi_bed_types", "default_bed_type", "bed_mesh_min","bed_mesh_max","bed_mesh_probe_distance", "adaptive_bed_mesh_margin", "enable_long_retraction_when_cut","long_retractions_when_cut","retraction_distances_when_cut"
};
@@ -2615,6 +2635,17 @@ size_t PresetCollection::first_visible_idx() const
return first_visible;
}
std::vector<std::string> PresetCollection::diameters_of_selected_printer()
{
std::set<std::string> diameters;
auto printer_model = m_edited_preset.config.opt_string("printer_model");
for (auto &preset : m_presets) {
if (preset.config.opt_string("printer_model") == printer_model)
diameters.insert(preset.config.opt_string("printer_variant"));
}
return std::vector<std::string>{diameters.begin(), diameters.end()};
}
void PresetCollection::set_default_suppressed(bool default_suppressed)
{
if (m_default_suppressed != default_suppressed) {
@@ -2897,8 +2928,20 @@ std::vector<std::string> PresetCollection::merge_presets(PresetCollection &&othe
preset.vendor = &it->second;
}
m_presets.emplace(it, std::move(preset));
} else
} else {
std::string default_vendor = std::string(PresetBundle::SM_BUNDLE);
if (preset.vendor->name == default_vendor) {
if (preset.vendor != nullptr) {
// Re-assign a pointer to the vendor structure in the new PresetBundle.
auto it = new_vendors.find(preset.vendor->id);
assert(it != new_vendors.end());
preset.vendor = &it->second;
}
m_presets.emplace(it, std::move(preset));
}
duplicates.emplace_back(std::move(preset.name));
}
}
return duplicates;
}
+8
View File
@@ -16,6 +16,7 @@
#include "ProjectTask.hpp"
//BBS: change system directories
#define PRESET_WEB_DIR "web"
#define PRESET_SYSTEM_DIR "system"
#define PRESET_USER_DIR "user"
#define PRESET_FILAMENT_NAME "filament"
@@ -35,6 +36,7 @@
//BBS: add json support
#define BBL_JSON_KEY_MIN_VERSION "min_version"
#define BBL_JSON_KEY_VERSION "version"
#define BBL_JSON_KEY_IS_CUSTOM "is_custom_defined"
#define BBL_JSON_KEY_URL "url"
@@ -83,6 +85,9 @@ enum ConfigFileType
//BBS: add a function to load the version from xxx.json
extern Semver get_version_from_json(std::string file_path);
extern Semver get_min_version_from_json(std::string file_path);
//BBS: add a function to load the key-values from xxx.json
extern int get_values_from_json(std::string file_path, std::vector<std::string>& keys, std::map<std::string, std::string>& key_values);
@@ -612,6 +617,9 @@ public:
// Orca: find preset, if not found, keep searching in the renamed history. This is function should only be used when find
// system(parent) presets for custom preset.
Preset* find_preset2(const std::string& name, bool auto_match = true);
std::vector<std::string> diameters_of_selected_printer();
const Preset* find_preset2(const std::string& name, bool auto_match = true) const
{
return const_cast<PresetCollection*>(this)->find_preset2(name, auto_match);
+63 -8
View File
@@ -43,11 +43,11 @@ static std::vector<std::string> s_project_options {
"flush_multiplier",
};
//Orca: add custom as default
const char *PresetBundle::ORCA_DEFAULT_BUNDLE = "Custom";
const char *PresetBundle::ORCA_DEFAULT_PRINTER_MODEL = "MyKlipper 0.4 nozzle";
const char *PresetBundle::ORCA_DEFAULT_PRINTER_VARIANT = "0.4";
const char *PresetBundle::ORCA_DEFAULT_FILAMENT = "Generic PLA @System";
// SM_FEATURE: add Snapmaker machine as default
const char* PresetBundle::SM_BUNDLE = "Snapmaker";
const char* PresetBundle::SM_DEFAULT_PRINTER_MODEL = "Snapmaker U1(0.4 nozzle)";
const char* PresetBundle::SM_DEFAULT_PRINTER_VARIANT = "0.4";
const char* PresetBundle::SM_DEFAULT_FILAMENT = "Snapmaker PLA SnapSpeed";
const char *PresetBundle::ORCA_FILAMENT_LIBRARY = "OrcaFilamentLibrary";
PresetBundle::PresetBundle()
@@ -172,6 +172,7 @@ void PresetBundle::setup_directories()
data_dir / "ota",
data_dir / PRESET_SYSTEM_DIR,
data_dir / PRESET_USER_DIR,
data_dir / PRESET_WEB_DIR,
// Store the print/filament/printer presets at the same location as the upstream Slic3r.
//data_dir / PRESET_SYSTEM_DIR / PRESET_PRINT_NAME,
//data_dir / PRESET_SYSTEM_DIR / PRESET_FILAMENT_NAME,
@@ -368,7 +369,7 @@ bool PresetBundle::use_bbl_device_tab() {
bool PresetBundle::backup_user_folder() const
{
const std::string backup_folderpath = data_dir() + "/" + (boost::format("user_backup-v%1%") % SoftFever_VERSION).str();
const std::string backup_folderpath = data_dir() + "/" + (boost::format("user_backup-v%1%") % Snapmaker_VERSION).str();
// Check if backup file already exists
if (boost::filesystem::exists(boost::filesystem::path(backup_folderpath)))
@@ -1118,7 +1119,7 @@ void PresetBundle::remove_users_preset(AppConfig &config, std::map<std::string,
}
if (need_reset_printer_preset) {
std::string default_printer_model = ORCA_DEFAULT_PRINTER_MODEL;
std::string default_printer_model = SM_DEFAULT_PRINTER_MODEL;
std::string default_printer_name;
for (auto it = printers.begin(); it != printers.end(); it++) {
if (it->config.has("printer_model")) {
@@ -1833,6 +1834,29 @@ void PresetBundle::export_selections(AppConfig &config)
}
// BBS
void PresetBundle::update_num_filaments(unsigned int to_del_filament_id)
{
unsigned old_filament_count = this->filament_presets.size();
assert(to_del_flament_id < old_filament_count);
filament_presets.erase(filament_presets.begin() + to_del_filament_id);
ConfigOptionStrings* filament_color = project_config.option<ConfigOptionStrings>("filament_colour");
if (filament_color->values.size() > to_del_filament_id) {
filament_color->values.erase(filament_color->values.begin() + to_del_filament_id);
} else {
filament_color->values.resize(to_del_filament_id);
}
if (ams_multi_color_filment.size() > to_del_filament_id) {
ams_multi_color_filment.erase(ams_multi_color_filment.begin() + to_del_filament_id);
} else {
ams_multi_color_filment.resize(to_del_filament_id);
}
update_multi_material_filament_presets(to_del_filament_id);
}
void PresetBundle::set_num_filaments(unsigned int n, std::vector<std::string> new_colors) {
int old_filament_count = this->filament_presets.size();
if (n > old_filament_count && old_filament_count != 0)
@@ -2053,6 +2077,37 @@ bool PresetBundle::check_filament_temp_equation_by_printer_type_and_nozzle_for_m
return is_equation;
}
Preset *PresetBundle::get_similar_printer_preset(std::string printer_model, std::string printer_variant)
{
if (printer_model.empty())
printer_model = printers.get_selected_preset().config.opt_string("printer_model");
auto printer_variant_old = printers.get_selected_preset().config.opt_string("printer_variant");
std::map<std::string, Preset*> printer_presets;
for (auto &preset : printers.m_presets) {
if (printer_variant.empty() && !preset.is_system)
continue;
if (preset.config.opt_string("printer_model") == printer_model)
printer_presets.insert({preset.name, &preset});
}
if (printer_presets.empty())
return nullptr;
auto prefer_printer = printers.get_selected_preset().name;
if (!printer_variant.empty())
boost::replace_all(prefer_printer, printer_variant_old, printer_variant);
else if (auto n = prefer_printer.find(printer_variant_old); n != std::string::npos)
prefer_printer = printer_model + " " + printer_variant_old + prefer_printer.substr(n + printer_variant_old.length());
if (auto iter = printer_presets.find(prefer_printer); iter != printer_presets.end()) {
return iter->second;
}
if (printer_variant.empty())
printer_variant = printer_variant_old;
for (auto& preset : printer_presets) {
if (preset.second->config.opt_string("printer_variant") == printer_variant)
return preset.second;
}
return printer_presets.begin()->second;
}
//BBS: check whether this is the only edited filament
bool PresetBundle::is_the_only_edited_filament(unsigned int filament_index)
{
@@ -3156,7 +3211,7 @@ std::pair<PresetsConfigSubstitutions, size_t> PresetBundle::load_vendor_configs_
return std::make_pair(std::move(substitutions), presets_loaded);
}
void PresetBundle::update_multi_material_filament_presets()
void PresetBundle::update_multi_material_filament_presets(size_t to_delete_filament_id)
{
if (printers.get_edited_preset().printer_technology() != ptFFF)
return;
+14 -7
View File
@@ -113,8 +113,9 @@ public:
void export_selections(AppConfig &config);
// BBS
void set_num_filaments(unsigned int n, std::vector<std::string> new_colors);
void set_num_filaments(unsigned int n, std::string new_col = "");
void set_num_filaments(unsigned int n, std::vector<std::string> new_colors);
void update_num_filaments(unsigned int to_del_filament_id);
unsigned int sync_ams_list(unsigned int & unknowns);
//BBS: check whether this is the only edited filament
bool is_the_only_edited_filament(unsigned int filament_index);
@@ -135,6 +136,8 @@ public:
std::string & nozzle_temp_max,
std::string & preset_setting_id);
Preset * get_similar_printer_preset(std::string printer_model, std::string printer_variant);
PresetCollection prints;
PresetCollection sla_prints;
PresetCollection filaments;
@@ -149,6 +152,10 @@ public:
// BBS: ams
std::map<int, DynamicPrintConfig> filament_ams_list;
std::vector<std::vector<std::string>> ams_multi_color_filment;
// Snapmaker
std::map<int, std::pair<std::string, std::string>> machine_filaments;
// Calibrate
Preset const * calibrate_printer = nullptr;
std::set<Preset const *> calibrate_filaments;
@@ -241,7 +248,7 @@ public:
// Read out the number of extruders from an active printer preset,
// update size and content of filament_presets.
void update_multi_material_filament_presets();
void update_multi_material_filament_presets(size_t to_delete_filament_id = size_t(-1));
// Update the is_compatible flag of all print and filament presets depending on whether they are marked
// as compatible with the currently selected printer (and print in case of filament presets).
@@ -268,11 +275,11 @@ public:
std::pair<PresetsConfigSubstitutions, std::string> load_system_filaments_json(ForwardCompatibilitySubstitutionRule compatibility_rule);
VendorProfile get_custom_vendor_models() const;
//orca: add 'custom' as default
static const char *ORCA_DEFAULT_BUNDLE;
static const char *ORCA_DEFAULT_PRINTER_MODEL;
static const char *ORCA_DEFAULT_PRINTER_VARIANT;
static const char *ORCA_DEFAULT_FILAMENT;
// SM_FEATURE: add Snapmaker machine as default
static const char *SM_BUNDLE;
static const char* SM_DEFAULT_PRINTER_MODEL;
static const char* SM_DEFAULT_PRINTER_VARIANT;
static const char* SM_DEFAULT_FILAMENT;
static const char *ORCA_FILAMENT_LIBRARY;
+8
View File
@@ -164,6 +164,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
"slow_down_layer_time",
"standby_temperature_delta",
"preheat_time",
"delta_temperature",
"preheat_steps",
"machine_start_gcode",
"filament_start_gcode",
@@ -481,6 +482,13 @@ std::vector<unsigned int> Print::extruders(bool conside_custom_gcode) const
}
}
// The wipe tower extruder can also be set. When the wipe tower is enabled and it will be generated,
// append its extruder into the list too.
if (has_wipe_tower() && config().wipe_tower_filament != 0 && extruders.size() > 1) {
assert(config().wipe_tower_filament > 0 && config().wipe_tower_filament < int(config().nozzle_diameter.size()));
extruders.emplace_back(config().wipe_tower_filament - 1); // the config value is 1-based
}
sort_remove_duplicates(extruders);
return extruders;
}
+6 -1
View File
@@ -235,7 +235,12 @@ static t_config_option_keys print_config_diffs(
if (opt_new == nullptr)
//FIXME This may happen when executing some test cases.
continue;
const ConfigOption *opt_new_filament = std::binary_search(extruder_retract_keys.begin(), extruder_retract_keys.end(), opt_key) ? new_full_config.option(filament_prefix + opt_key) : nullptr;
auto iter = std::find(extruder_retract_keys.begin(), extruder_retract_keys.end(), opt_key);
// const ConfigOption *opt_new_filament = std::binary_search(extruder_retract_keys.begin(), extruder_retract_keys.end(), opt_key) ? new_full_config.option(filament_prefix + opt_key) : nullptr;
const ConfigOption* opt_new_filament = (iter == extruder_retract_keys.end()) ? nullptr :
new_full_config.option(filament_prefix + opt_key);
if (opt_new_filament != nullptr && ! opt_new_filament->is_nil()) {
// An extruder retract override is available at some of the filament presets.
bool overriden = opt_new->overriden_by(opt_new_filament);
+1 -1
View File
@@ -67,7 +67,7 @@ std::string PrintBase::output_filename(const std::string &format, const std::str
DynamicConfig cfg;
if (config_override != nullptr)
cfg = *config_override;
cfg.set_key_value("version", new ConfigOptionString(std::string(SoftFever_VERSION)));
cfg.set_key_value("version", new ConfigOptionString(std::string(Snapmaker_VERSION)));
PlaceholderParser::update_timestamp(cfg);
PlaceholderParser::update_user_name(cfg);
this->update_object_placeholders(cfg, default_ext);
+109 -39
View File
@@ -585,7 +585,7 @@ void PrintConfigDef::init_common_params()
def = this->add("print_host", coString);
def->label = L("Hostname, IP or URL");
def->tooltip = L("Orca Slicer can upload G-code files to a printer host. This field should contain "
def->tooltip = L("Snapmaker Orca 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/");
@@ -684,7 +684,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("reduce_crossing_wall", coBool);
def->label = L("Avoid crossing walls");
def->category = L("Quality");
def->tooltip = L("Detour to avoid traveling across walls, which may cause blobs on the surface.");
def->tooltip = L("Detour and avoid to travel across wall which may cause blob on surface");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));
@@ -1764,6 +1764,7 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back("4");
def->enum_labels.push_back("5");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionInt{0});
def = this->add("extruder_clearance_height_to_rod", coFloat);
def->label = L("Height to rod");
@@ -1817,7 +1818,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L(
"This option sets the max point for the allowed bed mesh area. Due to the probe's XY offset, most printers are unable to probe the "
"entire bed. To ensure the probe point does not go outside the bed area, the minimum and maximum points of the bed mesh should be "
"set appropriately. OrcaSlicer ensures that adaptive_bed_mesh_min/adaptive_bed_mesh_max values do not exceed these min/max "
"set appropriately. Snapmaker_Orca ensures that adaptive_bed_mesh_min/adaptive_bed_mesh_max values do not exceed these min/max "
"points. This information can usually be obtained from your printer manufacturer. The default setting is (99999, 99999), which "
"means there are no limits, thus allowing probing across the entire bed.");
def->sidetext = "mm"; // milimeters, don't need translation
@@ -2002,6 +2003,18 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionStrings{ "#F2754E" });
def = this->add("thumb0", coStrings);
def->label = L("small thumb");
def->tooltip = L("first small thumb");
def->mode = comSimple;
def->set_default_value(new ConfigOptionString{""});
def = this->add("thumb1", coStrings);
def->label = L("big thumb");
def->tooltip = L("first big thumb");
def->mode = comSimple;
def->set_default_value(new ConfigOptionString{""});
// PS
def = this->add("filament_notes", coStrings);
def->label = L("Filament notes");
@@ -2058,6 +2071,12 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat { 0. });
def = this->add("tool_change_temprature_wait", coBool);
def->label = L("Wait for the temperature when changing tools");
def->tooltip = L("It will use the M109 instead of M104 T[target] after changing tools if this is set to true");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(true));
def = this->add("filament_diameter", coFloats);
def->label = L("Diameter");
@@ -2201,7 +2220,7 @@ void PrintConfigDef::init_fff_params()
def->label = L("Minimal purge on wipe tower");
def->tooltip = L("After a tool change, the exact position of the newly loaded filament inside "
"the nozzle may not be known, and the filament pressure is likely not yet stable. "
"Before purging the print head into an infill or a sacrificial object, Orca Slicer will always prime "
"Before purging the print head into an infill or a sacrificial object, Snapmaker Orca will always prime "
"this amount of material into the wipe tower to produce successive infill or sacrificial object extrusions reliably.");
def->sidetext = u8"mm³"; // cubic milimeters, don't need translation
def->min = 0;
@@ -3889,7 +3908,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("host_type", coEnum);
def->label = L("Host Type");
def->tooltip = L("Orca Slicer can upload G-code files to a printer host. This field must contain "
def->tooltip = L("Snapmaker Orca 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");
@@ -4094,7 +4113,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("If you want to process the output G-code through custom scripts, "
"just list their absolute paths here. Separate multiple scripts with a semicolon. "
"Scripts will be passed the absolute path to the G-code file as the first argument, "
"and they can access the Orca Slicer config settings by reading environment variables.");
"and they can access the Snapmaker Orca config settings by reading environment variables.");
def->gui_flags = "serialized";
def->multiline = true;
def->full_width = true;
@@ -4240,7 +4259,7 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionFloats {18});
def = this->add("retract_length_toolchange", coFloats);
def->label = L("Length");
def->label = L("Retraction Length (Toolchange)");
//def->full_label = L("Retraction Length (Toolchange)");
def->full_label = "Retraction Length (Toolchange)";
//def->tooltip = L("When retraction is triggered before changing tool, filament is pulled back "
@@ -4292,6 +4311,11 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionEnumsGeneric{ ZHopType::zhtSlope });
def = this->add("z_hop_when_prime", coBools);
def->label = L("Z hop when moving to tower");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBools{true});
def = this->add("travel_slope", coFloats);
def->label = L("Traveling angle");
def->tooltip = L("Traveling angle for Slope and Spiral Z-hop type. Setting it to 90° results in Normal Lift.");
@@ -4774,6 +4798,18 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(30.0));
def = this->add("delta_temperature", coInt);
def->label = L("Preheat delta temperature");
def->tooltip = L("Allow user to set the Preheat temperature. If target temperature is 220 and Preheat delta temperature is -30, then "
"the preheat temperature will be 190");
def->sidetext = "∆°C";
def->min = -50;
def->max = 50;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionInt(0));
def = this->add("preheat_steps", coInt);
def->label = L("Preheat steps");
def->tooltip = L("Insert multiple preheat commands (e.g. M104.1). Only useful for Prusa XL. For other printers, please set it to 1.");
@@ -4828,6 +4864,24 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(true));
def = this->add("ramming_line_width_ratio", coFloat);
def->label = L("Ramming line width ratio");
def->tooltip = L(
"This is used to decide the line width of wipe tower when ramming, ramming line width = [this ratio] * extruder * 1.25");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(2.0));
def = this->add("enable_change_pressure_when_wiping", coBool);
def->label = L("Enable change pressure advance when wiping");
def->tooltip = L("If it's set to false, the pressure advance value will not be changed.");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(true));
def = this->add("ramming_pressure_advance_value", coFloat);
def->label = L("Pressure advance value when ramming");
def->tooltip = L("Set_Pressure_advance [this value] when ramming on wipe tower");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0.0));
def = this->add("wipe_tower_no_sparse_layers", coBool);
def->label = L("No sparse layers (beta)");
@@ -6030,7 +6084,9 @@ void PrintConfigDef::init_fff_params()
// percents
"retract_before_wipe",
"long_retractions_when_cut",
"retraction_distances_when_cut"
"retraction_distances_when_cut",
"retract_length_toolchange",
"retract_restart_extra_toolchange"
}) {
auto it_opt = options.find(opt_key);
assert(it_opt != options.end());
@@ -6076,7 +6132,7 @@ void PrintConfigDef::init_extruder_option_keys()
// ConfigOptionFloats, ConfigOptionPercents, ConfigOptionBools, ConfigOptionStrings
m_extruder_option_keys = {
"nozzle_diameter", "min_layer_height", "max_layer_height", "extruder_offset",
"retraction_length", "z_hop", "z_hop_types", "travel_slope", "retract_lift_above", "retract_lift_below", "retract_lift_enforce", "retraction_speed", "deretraction_speed",
"retraction_length", "z_hop", "z_hop_types", "z_hop_when_prime", "travel_slope", "retract_lift_above", "retract_lift_below", "retract_lift_enforce", "retraction_speed", "deretraction_speed",
"retract_before_wipe", "retract_restart_extra", "retraction_minimum_travel", "wipe", "wipe_distance",
"retract_when_changing_layer", "retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour",
"default_filament_profile","retraction_distances_when_cut","long_retractions_when_cut"
@@ -6099,7 +6155,10 @@ void PrintConfigDef::init_extruder_option_keys()
"wipe",
"wipe_distance",
"z_hop",
"z_hop_types"
"z_hop_types",
"z_hop_when_prime",
"retract_length_toolchange",
"retract_restart_extra_toolchange"
};
assert(std::is_sorted(m_extruder_retract_keys.begin(), m_extruder_retract_keys.end()));
}
@@ -6130,7 +6189,9 @@ void PrintConfigDef::init_filament_option_keys()
"wipe",
"wipe_distance",
"z_hop",
"z_hop_types"
"z_hop_types",
"retract_length_toolchange",
"retract_restart_extra_toolchange",
};
assert(std::is_sorted(m_filament_retract_keys.begin(), m_filament_retract_keys.end()));
}
@@ -6923,7 +6984,6 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
"extruder_type",
"internal_bridge_support_thickness","extruder_clearance_max_radius", "top_area_threshold", "reduce_wall_solid_infill","filament_load_time","filament_unload_time",
"smooth_coefficient", "overhang_totally_speed", "silent_mode",
"overhang_speed_classic",
};
if (ignore.find(opt_key) != ignore.end()) {
@@ -7056,6 +7116,14 @@ void DynamicPrintConfig::normalize_fdm(int used_filaments)
}
}
if (this->has("wipe_tower_filament")) {
// If invalid, replace with 0.
int extruder = this->opt<ConfigOptionInt>("wipe_tower_filament")->value;
int num_extruders = this->opt<ConfigOptionFloats>("nozzle_diameter")->size();
if (extruder < 0 || extruder > num_extruders)
this->option("wipe_tower_filament")->setInt(0);
}
if (!this->has("solid_infill_filament") && this->has("sparse_infill_filament"))
this->option("solid_infill_filament", true)->setInt(this->option("sparse_infill_filament")->getInt());
@@ -7894,8 +7962,8 @@ CLIMiscConfigDef::CLIMiscConfigDef()
def = this->add("config_compatibility", coEnum);
def->label = L("Forward-compatibility rule when loading configurations from config files and project files (3MF, AMF).");
def->tooltip = L("This version of OrcaSlicer may not understand configurations produced by the newest OrcaSlicer versions. "
"For example, newer OrcaSlicer may extend the list of supported firmware flavors. One may decide to "
def->tooltip = L("This version of Snapmaker_Orca may not understand configurations produced by the newest OrcaSlicer versions. "
"For example, newer may extend the list of supported firmware flavors. One may decide to "
"bail out or to substitute an unknown value with a default silently or verbosely.");
def->enum_keys_map = &ConfigOptionEnum<ForwardCompatibilitySubstitutionRule>::get_enum_values();
def->enum_values.push_back("disable");
@@ -7971,7 +8039,7 @@ CLIMiscConfigDef::CLIMiscConfigDef()
def = this->add("single_instance", coBool);
def->label = L("Single instance mode");
def->tooltip = L("If enabled, the command line arguments are sent to an existing instance of GUI OrcaSlicer, "
"or an existing OrcaSlicer window is activated. "
"or an existing Snapmaker_Orca window is activated. "
"Overrides the \"single_instance\" configuration value from application preferences.");*/
/*
@@ -8388,7 +8456,7 @@ static std::map<t_custom_gcode_key, t_config_option_keys> s_CustomGcodeSpecificP
"new_retract_length_toolchange", "old_filament_e_feedrate", "old_filament_temp", "old_retract_length",
"old_retract_length_toolchange", "relative_e_axis", "second_flush_volume", "toolchange_count", "toolchange_z",
"travel_point_1_x", "travel_point_1_y", "travel_point_2_x", "travel_point_2_y", "travel_point_3_x",
"travel_point_3_y", "x_after_toolchange", "y_after_toolchange", "z_after_toolchange"}},
"travel_point_3_y", "x_after_toolchange", "y_after_toolchange", "z_after_toolchange", "next_wipe_x", "next_wipe_y"}},
{"change_extrusion_role_gcode", {"layer_num", "layer_z", "extrusion_role", "last_extrusion_role"}},
{"printing_by_object_gcode", {}},
{"machine_pause_gcode", {}},
@@ -8430,29 +8498,31 @@ CustomGcodeSpecificConfigDef::CustomGcodeSpecificConfigDef()
new_def("relative_e_axis", coBool, "Relative e-axis", "Indicates if relative positioning is being used.");
new_def("toolchange_count", coInt, "Toolchange count", "The number of toolchanges throught the print.");
new_def("fan_speed", coNone, "", ""); //Option is no longer used and is zeroed by placeholder parser for compatability
new_def("old_retract_length", coFloat, "Old retract length", "The retraction length of the previous filament.");
new_def("new_retract_length", coFloat, "New retract length", "The retraction lenght of the new filament.");
new_def("old_retract_length_toolchange", coFloat, "Old retract length toolchange", "The toolchange retraction length of the previous filament.");
new_def("new_retract_length_toolchange", coFloat, "New retract length toolchange", "The toolchange retraction length of the new filament.");
new_def("old_filament_temp", coInt, "Old filament temp", "The old filament temp.");
new_def("new_filament_temp", coInt, "New filament temp", "The new filament temp.");
new_def("x_after_toolchange", coFloat, "X after toolchange", "The X pos after toolchange.");
new_def("y_after_toolchange", coFloat, "Y after toolchange", "The Y pos after toolchange.");
new_def("z_after_toolchange", coFloat, "Z after toolchange", "The Z pos after toolchange.");
new_def("first_flush_volume", coFloat, "First flush volume", "The first flush volume.");
new_def("second_flush_volume", coFloat, "Second flush volume", "The second flush volume.");
new_def("old_filament_e_feedrate", coInt, "Old filament e feedrate", "The old filament extruder feedrate.");
new_def("new_filament_e_feedrate", coInt, "New filament e feedrate", "The new filament extruder feedrate.");
new_def("travel_point_1_x", coFloat, "Travel point 1 X", "The travel point 1 X.");
new_def("travel_point_1_y", coFloat, "Travel point 1 Y", "The travel point 1 Y.");
new_def("travel_point_2_x", coFloat, "Travel point 2 X", "The travel point 2 X.");
new_def("travel_point_2_y", coFloat, "Travel point 2 Y", "The travel point 2 Y.");
new_def("travel_point_3_x", coFloat, "Travel point 3 X", "The travel point 3 X.");
new_def("travel_point_3_y", coFloat, "Travel point 3 Y", "The travel point 3 Y.");
new_def("flush_length_1", coFloat, "Flush Length 1", "The first flush length.");
new_def("flush_length_2", coFloat, "Flush Length 2", "The second flush length.");
new_def("flush_length_3", coFloat, "Flush Length 3", "The third flush length.");
new_def("flush_length_4", coFloat, "Flush Length 4", "The fourth flush length.");
new_def("old_retract_length", coFloat, "Old retract length", "The retraction length of the previous filament");
new_def("new_retract_length", coFloat, "New retract length", "The retraction lenght of the new filament");
new_def("old_retract_length_toolchange", coFloat, "Old retract length toolchange", "The toolchange retraction length of the previous filament");
new_def("new_retract_length_toolchange", coFloat, "New retract length toolchange", "The toolchange retraction length of the new filament");
new_def("old_filament_temp", coInt, "Old filament temp", "The old filament temp");
new_def("new_filament_temp", coInt, "New filament temp", "The new filament temp");
new_def("x_after_toolchange", coFloat, "X after toolchange", "The x pos after toolchange");
new_def("y_after_toolchange", coFloat, "Y after toolchange", "The y pos after toolchange");
new_def("z_after_toolchange", coFloat, "Z after toolchange", "The z pos after toolchange");
new_def("first_flush_volume", coFloat, "First flush volume", "The first flush volume");
new_def("second_flush_volume", coFloat, "Second flush volume", "The second flush volume");
new_def("old_filament_e_feedrate", coInt, "Old filament e feedrate", "The old filament extruder feedrate");
new_def("new_filament_e_feedrate", coInt, "New filament e feedrate", "The new filament extruder feedrate");
new_def("travel_point_1_x", coFloat, "Travel point 1 x", "The travel point 1 x");
new_def("travel_point_1_y", coFloat, "Travel point 1 y", "The travel point 1 y");
new_def("travel_point_2_x", coFloat, "Travel point 2 x", "The travel point 2 x");
new_def("travel_point_2_y", coFloat, "Travel point 2 y", "The travel point 2 y");
new_def("travel_point_3_x", coFloat, "Travel point 3 x", "The travel point 3 x");
new_def("travel_point_3_y", coFloat, "Travel point 3 y", "The travel point 3 y");
new_def("flush_length_1", coFloat, "Flush Length 1", "The first flush length");
new_def("flush_length_2", coFloat, "Flush Length 2", "The second flush length");
new_def("flush_length_3", coFloat, "Flush Length 3", "The third flush length");
new_def("flush_length_4", coFloat, "Flush Length 4", "The fourth flush length");
new_def("next_wipe_x", coFloat, "Next Wipe X", "For Snapmaker Artision, next x after toolchange");
new_def("next_wipe_y", coFloat, "Next Wipe Y", "For Snapmaker Artision, next y after toolchange");
// change_extrusion_role_gcode
std::string extrusion_role_types = "Possible Values:\n[\"Perimeter\", \"ExternalPerimeter\", "
+14 -1
View File
@@ -57,7 +57,7 @@ enum class NoiseType {
};
enum PrintHostType {
htPrusaLink, htPrusaConnect, htOctoPrint, htDuet, htFlashAir, htAstroBox, htRepetier, htMKS, htESP3D, htCrealityPrint, htObico, htFlashforge, htSimplyPrint, htElegooLink
htPrusaLink, htPrusaConnect, htOctoPrint, htDuet, htFlashAir, htAstroBox, htRepetier, htMKS, htESP3D, htCrealityPrint, htObico, htFlashforge, htSimplyPrint, htElegooLink, htMoonRaker_mqtt, htMoonRaker,
};
enum AuthorizationType {
@@ -337,6 +337,13 @@ enum ZHopType {
zhtCount
};
enum FilamentMapMode {
fmmAutoForFlush,
fmmAutoForMatch,
fmmManual,
fmmDefault
};
enum NozzleVolumeType {
nvtNormal = 0,
nvtBigTraffic,
@@ -1193,6 +1200,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionBools, long_retractions_when_cut))
((ConfigOptionFloats, z_hop))
// BBS
((ConfigOptionBools, z_hop_when_prime))
((ConfigOptionEnumsGeneric, z_hop_types))
((ConfigOptionFloats, travel_slope))
((ConfigOptionFloats, retract_lift_above))
@@ -1240,6 +1248,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloat, extra_loading_move))
((ConfigOptionFloat, machine_load_filament_time))
((ConfigOptionFloat, machine_tool_change_time))
((ConfigOptionBool, tool_change_temprature_wait))
((ConfigOptionFloat, machine_unload_filament_time))
((ConfigOptionFloats, filament_loading_speed))
((ConfigOptionFloats, filament_loading_speed_start))
@@ -1258,6 +1267,9 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloats, filament_stamping_distance))
((ConfigOptionBool, purge_in_prime_tower))
((ConfigOptionBool, enable_filament_ramming))
((ConfigOptionFloat, ramming_line_width_ratio))
((ConfigOptionBool, enable_change_pressure_when_wiping))
((ConfigOptionFloat, ramming_pressure_advance_value))
((ConfigOptionBool, support_multi_bed_types))
// Small Area Infill Flow Compensation
@@ -1358,6 +1370,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionFloat, spiral_starting_flow_ratio))
((ConfigOptionInt, standby_temperature_delta))
((ConfigOptionFloat, preheat_time))
((ConfigOptionInt, delta_temperature))
((ConfigOptionInt, preheat_steps))
((ConfigOptionInts, nozzle_temperature))
((ConfigOptionBools, wipe))
+34 -4
View File
@@ -1720,7 +1720,11 @@ TriangleSelector::TriangleSplittingData TriangleSelector::serialize() const {
return out.data;
}
void TriangleSelector::deserialize(const TriangleSplittingData& data, bool needs_reset, EnforcerBlockerType max_ebt)
void TriangleSelector::deserialize(const TriangleSplittingData& data,
bool needs_reset,
EnforcerBlockerType max_ebt,
EnforcerBlockerType to_delete_filament,
EnforcerBlockerType replace_filament)
{
if (needs_reset)
reset(); // dump any current state
@@ -1766,11 +1770,37 @@ void TriangleSelector::deserialize(const TriangleSplittingData& data, bool needs
int num_of_children = num_of_split_sides == 0 ? 0 : num_of_split_sides + 1;
bool is_split = num_of_children != 0;
// Only valid if not is_split. Value of the second nibble was subtracted by 3, so it is added back.
auto state = is_split ? EnforcerBlockerType::NONE : EnforcerBlockerType((code & 0b1100) == 0b1100 ? next_nibble() + 3 : code >> 2);
// auto state = is_split ? EnforcerBlockerType::NONE : EnforcerBlockerType((code & 0b1100) == 0b1100 ? next_nibble() + 3 : code >> 2);
auto state = EnforcerBlockerType::NONE;
//// BBS
//if (state > max_ebt)
// state = EnforcerBlockerType::NONE;
// BBS
if (state > max_ebt)
if (!is_split) {
if ((code & 0b1100) == 0b1100) {
int next_code = next_nibble();
int num = 0;
while (next_code == 0b1111) {
num++;
next_code = next_nibble();
}
state = EnforcerBlockerType(next_code + 15 * num + 3); // old:next_nibble() + 3;
} else {
state = EnforcerBlockerType(code >> 2);
}
}
if (state == to_delete_filament)
state = replace_filament;
else if (to_delete_filament != EnforcerBlockerType::NONE && state != EnforcerBlockerType::NONE) {
state = state > to_delete_filament ? EnforcerBlockerType((int) state - 1) : state;
}
if (state > max_ebt) {
assert(false);
state = EnforcerBlockerType::NONE;
}
// Only valid if is_split.
int special_side = code >> 2;
+4 -2
View File
@@ -357,8 +357,10 @@ public:
// Load serialized data. Assumes that correct mesh is loaded.
void deserialize(const TriangleSplittingData& data,
bool needs_reset = true,
EnforcerBlockerType max_ebt = EnforcerBlockerType::ExtruderMax);
bool needs_reset = true,
EnforcerBlockerType max_ebt = EnforcerBlockerType::ExtruderMax,
EnforcerBlockerType to_delete_filament = EnforcerBlockerType::NONE,
EnforcerBlockerType replace_filament = EnforcerBlockerType::NONE);
// Extract all used facet states from the given TriangleSplittingData.
static std::vector<EnforcerBlockerType> extract_used_facet_states(const TriangleSplittingData &data);
+1 -1
View File
@@ -217,7 +217,7 @@ extern bool is_shapes_dir(const std::string& dir);
extern bool is_json_file(const std::string& path);
// Orca: custom protocal support utils
inline bool is_orca_open(const std::string& url) { return boost::starts_with(url, "orcaslicer://open"); }
inline bool is_orca_open(const std::string& url) { return boost::starts_with(url, "Snapmaker_Orca://open"); }
inline bool is_prusaslicer_open(const std::string& url) { return boost::starts_with(url, "prusaslicer://open"); }
inline bool is_bambustudio_open(const std::string& url) { return boost::starts_with(url, "bambustudio://open") || boost::starts_with(url, "bambustudioopen://"); }
inline bool is_cura_open(const std::string& url) { return boost::starts_with(url, "cura://open"); }
+4 -4
View File
@@ -2,10 +2,10 @@
#define _libslic3r_h_
#include "libslic3r_version.h"
#define SLIC3R_APP_FULL_NAME "Orca Slicer"
#define GCODEVIEWER_APP_NAME "OrcaSlicer G-code Viewer"
#define GCODEVIEWER_APP_KEY "OrcaSlicerGcodeViewer"
#define GCODEVIEWER_BUILD_ID std::string("OrcaSlicer G-code Viewer-") + std::string(SLIC3R_VERSION) + std::string("-RC")
#define SLIC3R_APP_FULL_NAME "Snapmaker Orca"
#define GCODEVIEWER_APP_NAME "Snapmaker_Orca G-code Viewer"
#define GCODEVIEWER_APP_KEY "Snapmaker_OrcaGcodeViewer"
#define GCODEVIEWER_BUILD_ID std::string("Snapmaker_Orca G-code Viewer-") + std::string(SLIC3R_VERSION) + std::string("-RC")
// this needs to be included early for MSVC (listing it in Build.PL is not enough)
#include <memory>
+2 -1
View File
@@ -4,7 +4,8 @@
#define SLIC3R_APP_NAME "@SLIC3R_APP_NAME@"
#define SLIC3R_APP_KEY "@SLIC3R_APP_KEY@"
#define SLIC3R_VERSION "@SLIC3R_VERSION@"
#define SoftFever_VERSION "@SoftFever_VERSION@"
#define Snapmaker_VERSION "@Snapmaker_VERSION@"
#define MIN_FIRM_VER "@MIN_FIRM_VER@"
#ifndef GIT_COMMIT_HASH
#define GIT_COMMIT_HASH "0000000" // 0000000 means uninitialized
#endif
+3 -3
View File
@@ -337,7 +337,7 @@ void set_log_path_and_level(const std::string& file, unsigned int level)
}
#endif
//BBS log file at C:\\Users\\[yourname]\\AppData\\Roaming\\OrcaSlicer\\log\\[log_filename].log
//BBS log file at C:\\Users\\[yourname]\\AppData\\Roaming\\Snapmaker_Orca\\log\\[log_filename].log
auto log_folder = boost::filesystem::path(g_data_dir) / "log";
if (!boost::filesystem::exists(log_folder)) {
boost::filesystem::create_directory(log_folder);
@@ -1162,12 +1162,12 @@ std::string string_printf(const char *format, ...)
std::string header_slic3r_generated()
{
return std::string(SLIC3R_APP_NAME " " SoftFever_VERSION);
return std::string(SLIC3R_APP_NAME " " Snapmaker_VERSION);
}
std::string header_gcodeviewer_generated()
{
return std::string(GCODEVIEWER_APP_NAME " " SoftFever_VERSION);
return std::string(GCODEVIEWER_APP_NAME " " Snapmaker_VERSION);
}
unsigned get_current_pid()