mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-04 06:11:02 +00:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e11216af8 | ||
|
|
7a06d541e5 | ||
|
|
d381152d03 | ||
|
|
bf43b9ea7b | ||
|
|
0a30cfe6b0 | ||
|
|
5704fa348f |
+183
-61
@@ -140,6 +140,20 @@ using namespace nlohmann;
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/GuiColor.hpp"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
#include "libslic3r/BuildVolume.hpp"
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "libslic3r/Exception.hpp"
|
||||
#include "libslic3r/GCode/GCodeProcessor.hpp"
|
||||
#include "libslic3r/GCode/ToolOrdering.hpp"
|
||||
#include "libslic3r/ObjectID.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "libslic3r/ProjectTask.hpp"
|
||||
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/Jobs/SendJob.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#if __has_include(<X11/Xlib.h>)
|
||||
@@ -685,6 +699,162 @@ static void load_default_gcodes_to_config(DynamicPrintConfig& config, Preset::Ty
|
||||
}
|
||||
}
|
||||
|
||||
static int load_assemble_plate_list(std::string config_file, std::vector<assemble_plate_info_t> &assemble_plate_info_list)
|
||||
{
|
||||
int ret = 0;
|
||||
boost::filesystem::path directory_path(config_file);
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1% enter, file %2%")%__FUNCTION__ % config_file;
|
||||
if (!fs::exists(directory_path)) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("directory %1% not exist.")%config_file;
|
||||
return CLI_FILE_NOTFOUND;
|
||||
}
|
||||
|
||||
try {
|
||||
json root_json;
|
||||
boost::nowide::ifstream ifs(config_file);
|
||||
ifs >> root_json;
|
||||
ifs.close();
|
||||
|
||||
int plate_count = root_json[JSON_ASSEMPLE_PLATES].size();
|
||||
if ((plate_count <= 0) || (plate_count > MAX_PLATE_COUNT)) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< boost::format(": invalid plate count %1%")%plate_count;
|
||||
return CLI_CONFIG_FILE_ERROR;
|
||||
}
|
||||
assemble_plate_info_list.resize(plate_count);
|
||||
|
||||
for (int plate_index = 0; plate_index < plate_count; plate_index++)
|
||||
{
|
||||
assemble_plate_info_t &assemble_plate = assemble_plate_info_list[plate_index];
|
||||
const json& plate_json = root_json[JSON_ASSEMPLE_PLATES][plate_index];
|
||||
assemble_plate.plate_name = plate_json[JSON_ASSEMPLE_PLATE_NAME];
|
||||
assemble_plate.need_arrange = plate_json[JSON_ASSEMPLE_PLATE_NEED_ARRANGE];
|
||||
|
||||
if (plate_json.contains(JSON_ASSEMPLE_PLATE_PARAMS)) {
|
||||
assemble_plate.plate_params = plate_json[JSON_ASSEMPLE_PLATE_PARAMS].get<std::map<std::string, std::string>>();
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, has %2% plate params") % (plate_index + 1) % assemble_plate.plate_params.size();
|
||||
}
|
||||
|
||||
int object_count = plate_json[JSON_ASSEMPLE_OBJECTS].size();
|
||||
if (object_count <= 0) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< boost::format(": invalid object count %1% in plate %2%")%object_count %(plate_index+1);
|
||||
return CLI_CONFIG_FILE_ERROR;
|
||||
}
|
||||
|
||||
assemble_plate.assemble_obj_list.resize(object_count);
|
||||
for (int object_index = 0; object_index < object_count; object_index++)
|
||||
{
|
||||
assemble_object_info_t& assemble_object = assemble_plate.assemble_obj_list[object_index];
|
||||
const json& object_json = plate_json[JSON_ASSEMPLE_OBJECTS][object_index];
|
||||
|
||||
assemble_object.path = object_json[JSON_ASSEMPLE_OBJECT_PATH];
|
||||
assemble_object.count = object_json[JSON_ASSEMPLE_OBJECT_COUNT];
|
||||
|
||||
if (assemble_object.count <= 0) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": invalid object clone count %1% in plate %2% Object %3%") % assemble_object.count % (plate_index + 1) % assemble_object.path;
|
||||
return CLI_CONFIG_FILE_ERROR;
|
||||
}
|
||||
|
||||
assemble_object.filaments = object_json.at(JSON_ASSEMPLE_OBJECT_FILAMENTS).get<std::vector<int>>();
|
||||
if ((assemble_object.filaments.size() > 0) && (assemble_object.filaments.size() != assemble_object.count) && (assemble_object.filaments.size() != 1))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": object %1%'s filaments count %2% not equal to clone count %3%, also not equal to 1") % assemble_object.path % assemble_object.filaments.size() % assemble_object.count;
|
||||
return CLI_CONFIG_FILE_ERROR;
|
||||
}
|
||||
|
||||
if (object_json.contains(JSON_ASSEMPLE_OBJECT_ASSEMBLE_INDEX)) {
|
||||
assemble_object.assemble_index = object_json[JSON_ASSEMPLE_OBJECT_ASSEMBLE_INDEX].get<std::vector<int>>();
|
||||
if ((assemble_object.assemble_index.size() > 0) && (assemble_object.assemble_index.size() != assemble_object.count) && (assemble_object.assemble_index.size() != 1))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": object %1%'s assemble_index count %2% not equal to clone count %3%, also not equal to 1") % assemble_object.path % assemble_object.assemble_index.size() % assemble_object.count;
|
||||
return CLI_CONFIG_FILE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (object_json.contains(JSON_ASSEMPLE_OBJECT_POS_X)) {
|
||||
assemble_object.pos_x = object_json[JSON_ASSEMPLE_OBJECT_POS_X].get<std::vector<float>>();
|
||||
if ((assemble_object.pos_x.size() > 0) && (assemble_object.pos_x.size() != assemble_object.count) && (assemble_object.pos_x.size() != 1))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": object %1%'s pos_x count %2% not equal to clone count %3%, also not equal to 1") % assemble_object.path % assemble_object.pos_x.size() % assemble_object.count;
|
||||
return CLI_CONFIG_FILE_ERROR;
|
||||
}
|
||||
}
|
||||
if (object_json.contains(JSON_ASSEMPLE_OBJECT_POS_Y)) {
|
||||
assemble_object.pos_y = object_json[JSON_ASSEMPLE_OBJECT_POS_Y].get<std::vector<float>>();
|
||||
if ((assemble_object.pos_y.size() > 0) && (assemble_object.pos_y.size() != assemble_object.count) && (assemble_object.pos_y.size() != 1))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": object %1%'s pos_y count %2% not equal to clone count %3%, also not equal to 1") % assemble_object.path % assemble_object.pos_y.size() % assemble_object.count;
|
||||
return CLI_CONFIG_FILE_ERROR;
|
||||
}
|
||||
}
|
||||
if (object_json.contains(JSON_ASSEMPLE_OBJECT_POS_Z)) {
|
||||
assemble_object.pos_z = object_json[JSON_ASSEMPLE_OBJECT_POS_Z].get<std::vector<float>>();
|
||||
if ((assemble_object.pos_z.size() > 0) && (assemble_object.pos_z.size() != assemble_object.count) && (assemble_object.pos_z.size() != 1))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": object %1%'s pos_z count %2% not equal to clone count %3%, also not equal to 1") % assemble_object.path % assemble_object.pos_z.size() % assemble_object.count;
|
||||
return CLI_CONFIG_FILE_ERROR;
|
||||
}
|
||||
}
|
||||
if (object_json.contains(JSON_ASSEMPLE_OBJECT_PRINT_PARAMS)) {
|
||||
assemble_object.print_params = object_json[JSON_ASSEMPLE_OBJECT_PRINT_PARAMS].get<std::map<std::string, std::string>>();
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, object %2% has %3% print params") % (plate_index + 1) %assemble_object.path % assemble_object.print_params.size();
|
||||
}
|
||||
if (object_json.contains(JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES)) {
|
||||
json height_range_json = object_json[JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES];
|
||||
int range_count = height_range_json.size();
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, object %2% has %3% height ranges") % (plate_index + 1) %assemble_object.path % range_count;
|
||||
|
||||
assemble_object.height_ranges.resize(range_count);
|
||||
for (int range_index = 0; range_index < range_count; range_index++)
|
||||
{
|
||||
height_range_info_t& height_range = assemble_object.height_ranges[range_index];
|
||||
height_range.min_z = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_MIN_Z];
|
||||
height_range.max_z = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_MAX_Z];
|
||||
height_range.range_params = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_RANGE_PARAMS].get<std::map<std::string, std::string>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (plate_json.contains(JSON_ASSEMPLE_ASSEMBLE_PARAMS)) {
|
||||
json assemble_params_json = plate_json[JSON_ASSEMPLE_ASSEMBLE_PARAMS];
|
||||
int assemble_count = assemble_params_json.size();
|
||||
for (int i = 0; i < assemble_count; i++)
|
||||
{
|
||||
assembled_param_info_t assembled_param;
|
||||
int assemble_index = assemble_params_json[i][JSON_ASSEMPLE_OBJECT_ASSEMBLE_INDEX];
|
||||
if (assemble_params_json[i].contains(JSON_ASSEMPLE_OBJECT_PRINT_PARAMS)) {
|
||||
assembled_param.print_params = assemble_params_json[i][JSON_ASSEMPLE_OBJECT_PRINT_PARAMS].get<std::map<std::string, std::string>>();
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, assemble object %2% has %3% print params") % (plate_index + 1) %i % assembled_param.print_params.size();
|
||||
}
|
||||
if (assemble_params_json[i].contains(JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES)) {
|
||||
json height_range_json = assemble_params_json[i][JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES];
|
||||
int range_count = height_range_json.size();
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, assemble object %2% has %3% height ranges") % (plate_index + 1) %i % range_count;
|
||||
|
||||
assembled_param.height_ranges.resize(range_count);
|
||||
for (int range_index = 0; range_index < range_count; range_index++)
|
||||
{
|
||||
height_range_info_t& height_range = assembled_param.height_ranges[range_index];
|
||||
height_range.min_z = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_MIN_Z];
|
||||
height_range.max_z = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_MAX_Z];
|
||||
height_range.range_params = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_RANGE_PARAMS].get<std::map<std::string, std::string>>();
|
||||
}
|
||||
}
|
||||
assemble_plate.assembled_param_list.emplace(assemble_index, std::move(assembled_param));
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, has %2% plate params") % (plate_index + 1) % assemble_plate.plate_params.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(std::exception &err) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse file "<<config_file<<" got a generic exception, reason = " << err.what();
|
||||
ret = CLI_CONFIG_FILE_ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void merge_or_add_object(assemble_plate_info_t& assemble_plate_info, Model &model, int assemble_index, std::map<int, ModelObject*> &merged_objects, ModelObject *ori_object)
|
||||
{
|
||||
if (assemble_index > 0) {
|
||||
@@ -1750,14 +1920,6 @@ int CLI::run(int argc, char **argv)
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("current_printer_name %1%, current_process_name %2%")%current_printer_name %current_process_name;
|
||||
ConfigOptionStrings* option_strings = config.option<ConfigOptionStrings>("inherits_group");
|
||||
// One entry for the process, one per filament and one for the printer. A group of another
|
||||
// length still has the process first and the printer last; one too short for that is ignored.
|
||||
if (option_strings && option_strings->values.size() != current_filaments_name.size() + 2) {
|
||||
boost::nowide::cerr << "Warning: inherits_group has " << option_strings->values.size() << " entries, expected "
|
||||
<< current_filaments_name.size() + 2 << " for " << current_filaments_name.size() << " filaments" << std::endl;
|
||||
if (option_strings->values.size() < 2)
|
||||
option_strings = nullptr;
|
||||
}
|
||||
if (option_strings) {
|
||||
current_inherits_group = option_strings->values;
|
||||
size_t size = current_inherits_group.size();
|
||||
@@ -1779,11 +1941,14 @@ int CLI::run(int argc, char **argv)
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("inherits of process valid, current_process_system_name is %1%") %current_process_system_name;
|
||||
}
|
||||
|
||||
// A filament without an entry of its own counts as a system preset.
|
||||
current_filaments_system_name = current_filaments_name;
|
||||
for (size_t index = 1; index < size - 1 && index <= current_filaments_name.size(); index++) {
|
||||
if (!current_inherits_group[index].empty())
|
||||
current_filaments_system_name.resize(size - 2);
|
||||
for (int index = 1; index < (size - 1); index++) {
|
||||
if (current_inherits_group[index].empty()) {
|
||||
current_filaments_system_name[index-1] = current_filaments_name[index-1];
|
||||
}
|
||||
else {
|
||||
current_filaments_system_name[index-1] = current_inherits_group[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1916,12 +2081,7 @@ int CLI::run(int argc, char **argv)
|
||||
//parse the json and assemble object here
|
||||
Model model;
|
||||
|
||||
AssembleListResult list_result = load_assemble_plate_list(load_assemble_list, assemble_plate_info_list, MAX_PLATE_COUNT);
|
||||
int ret = CLI_SUCCESS;
|
||||
if (list_result == AssembleListResult::FileNotFound)
|
||||
ret = CLI_FILE_NOTFOUND;
|
||||
else if (list_result == AssembleListResult::ConfigError)
|
||||
ret = CLI_CONFIG_FILE_ERROR;
|
||||
int ret = load_assemble_plate_list(load_assemble_list, assemble_plate_info_list);
|
||||
if (ret) {
|
||||
record_exit_reson(outfile_dir, ret, 0, cli_errors[ret], sliced_info);
|
||||
flush_and_exit(ret);
|
||||
@@ -2677,37 +2837,6 @@ int CLI::run(int argc, char **argv)
|
||||
fetch_compatible_values = true;
|
||||
}
|
||||
|
||||
// Refresh every project filament no loaded filament replaces from its current system preset, as the GUI
|
||||
// does when it loads the project; the filament merge below keeps the keys the project lists as changed.
|
||||
// Entries stay in slot order, which the merge's variant bookkeeping relies on.
|
||||
std::vector<bool> load_filaments_refresh(load_filaments_config.size(), false);
|
||||
if (is_bbl_3mf && new_printer_name.empty()) {
|
||||
const ConfigOptionStrings *project_filament_ids = m_print_config.option<ConfigOptionStrings>("filament_ids");
|
||||
for (size_t index = 0; index < current_filaments_system_name.size(); index++) {
|
||||
const int slot = static_cast<int>(index) + 1;
|
||||
if (std::find(load_filaments_index.begin(), load_filaments_index.end(), slot) != load_filaments_index.end())
|
||||
continue;
|
||||
std::string system_name = current_filaments_system_name[index];
|
||||
if (system_name.empty())
|
||||
continue;
|
||||
PresetBundle::convert_filament_preset_name(current_printer_name, system_name);
|
||||
DynamicPrintConfig config;
|
||||
std::string error;
|
||||
if (!ensure_system_preset_resolver().resolve_system_preset(config, Preset::TYPE_FILAMENT, system_name, config_substitution_rule, error)) {
|
||||
BOOST_LOG_TRIVIAL(warning) << boost::format("CLI: system filament preset '%1%' not resolved (%2%); filament %3% keeps its values") % system_name % error % slot;
|
||||
continue;
|
||||
}
|
||||
const size_t at = std::upper_bound(load_filaments_index.begin(), load_filaments_index.end(), slot) - load_filaments_index.begin();
|
||||
load_filaments_id.insert(load_filaments_id.begin() + at,
|
||||
project_filament_ids != nullptr && index < project_filament_ids->size() ? project_filament_ids->values[index] : std::string());
|
||||
load_filaments_name.insert(load_filaments_name.begin() + at, system_name);
|
||||
load_filaments_config.insert(load_filaments_config.begin() + at, std::move(config));
|
||||
load_filaments_index.insert(load_filaments_index.begin() + at, slot);
|
||||
load_filaments_inherit.insert(load_filaments_inherit.begin() + at, system_name);
|
||||
load_filaments_refresh.insert(load_filaments_refresh.begin() + at, true);
|
||||
}
|
||||
}
|
||||
|
||||
//fetch upward_compatible_machine
|
||||
if (fetch_upward_values) {
|
||||
if (!current_printer_system_name.empty()) {
|
||||
@@ -3398,7 +3527,7 @@ int CLI::run(int argc, char **argv)
|
||||
}
|
||||
|
||||
//set the filament settings into print config
|
||||
if ((load_filament_count > 0) || (up_config_to_date) || !load_filaments_config.empty())
|
||||
if ((load_filament_count > 0) || (up_config_to_date))
|
||||
{
|
||||
//std::vector<int> filament_variant_count(filament_count, 1);
|
||||
std::vector<int> old_start_indice(filament_count, 0);
|
||||
@@ -3457,8 +3586,6 @@ int CLI::run(int argc, char **argv)
|
||||
for (int index = 0; index < load_filaments_config.size(); index++) {
|
||||
DynamicPrintConfig& config = load_filaments_config[index];
|
||||
int filament_index = load_filaments_index[index];
|
||||
// A filament given with --load-filaments replaces the slot; a refreshed one keeps the project's changed keys.
|
||||
const bool loaded = load_filament_count > 0 && !load_filaments_refresh[index];
|
||||
std::vector<std::string> different_keys;
|
||||
|
||||
//ORCA: diff before load_default_gcodes_to_config, the way the process and machine
|
||||
@@ -3468,12 +3595,12 @@ int CLI::run(int argc, char **argv)
|
||||
// compared" to "compared as empty against the parent" and land in the column
|
||||
// as an override the user never made.
|
||||
std::string filament_different_settings;
|
||||
if (loaded)
|
||||
if (load_filament_count > 0)
|
||||
filament_different_settings = cli_different_settings(config, load_filaments_inherit[index], Preset::TYPE_FILAMENT);
|
||||
|
||||
load_default_gcodes_to_config(config, Preset::TYPE_FILAMENT);
|
||||
|
||||
if (loaded) {
|
||||
if (load_filament_count > 0) {
|
||||
ConfigOptionStrings *opt_filament_settings = static_cast<ConfigOptionStrings *> (m_print_config.option("filament_settings_id", true));
|
||||
std::string& filament_name = load_filaments_name[index];
|
||||
ConfigOptionString* filament_name_setting = new ConfigOptionString(filament_name);
|
||||
@@ -3545,7 +3672,7 @@ int CLI::run(int argc, char **argv)
|
||||
flush_and_exit(CLI_CONFIG_FILE_ERROR);
|
||||
}
|
||||
|
||||
if (!loaded && !different_keys_set.empty())
|
||||
if ((load_filament_count == 0) && !different_keys_set.empty())
|
||||
{
|
||||
std::set<std::string>::iterator iter = different_keys_set.find(opt_key);
|
||||
if ( iter != different_keys_set.end()) {
|
||||
@@ -4735,11 +4862,6 @@ int CLI::run(int argc, char **argv)
|
||||
record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info);
|
||||
flush_and_exit(CLI_INVALID_PARAMS);
|
||||
}
|
||||
if (m_models.empty()) {
|
||||
boost::nowide::cerr << "Invalid params: --assemble needs at least one input model." << std::endl;
|
||||
record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info);
|
||||
flush_and_exit(CLI_INVALID_PARAMS);
|
||||
}
|
||||
Model m;
|
||||
ModelObject* new_object = m.add_object();
|
||||
new_object->name = _u8L("Assembly");
|
||||
@@ -5680,7 +5802,7 @@ int CLI::run(int argc, char **argv)
|
||||
float w = dynamic_cast<const ConfigOptionFloat *>(m_print_config.option("prime_tower_width"))->value;
|
||||
float a = dynamic_cast<const ConfigOptionFloat *>(m_print_config.option("wipe_tower_rotation_angle"))->value;
|
||||
float v = dynamic_cast<const ConfigOptionFloat *>(m_print_config.option("prime_volume"))->value;
|
||||
unsigned int filaments_cnt = (plate_data_src.size() >= static_cast<size_t>(plate_to_slice)) ? plate_data_src[plate_to_slice-1]->slice_filaments_info.size() : 0;
|
||||
unsigned int filaments_cnt = plate_data_src[plate_to_slice-1]->slice_filaments_info.size();
|
||||
if ((filaments_cnt == 0) || need_skip)
|
||||
{
|
||||
// slice filaments info invalid
|
||||
|
||||
+62
-2
@@ -5,14 +5,16 @@
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "libslic3r/Format/bbs_3mf.hpp"
|
||||
#include "libslic3r/GCode/ThumbnailData.hpp"
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/Format/AssembleList.hpp"
|
||||
|
||||
namespace Slic3r { class Preset; }
|
||||
namespace Slic3r { struct PlateBBoxData; }
|
||||
namespace Slic3r { struct ThumbnailData; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -27,6 +29,64 @@ namespace IO {
|
||||
};
|
||||
}
|
||||
|
||||
#define JSON_ASSEMPLE_PLATES "plates"
|
||||
#define JSON_ASSEMPLE_PLATE_PARAMS "plate_params"
|
||||
#define JSON_ASSEMPLE_PLATE_NAME "plate_name"
|
||||
#define JSON_ASSEMPLE_PLATE_NEED_ARRANGE "need_arrange"
|
||||
#define JSON_ASSEMPLE_OBJECTS "objects"
|
||||
#define JSON_ASSEMPLE_OBJECT_PATH "path"
|
||||
#define JSON_ASSEMPLE_OBJECT_COUNT "count"
|
||||
#define JSON_ASSEMPLE_OBJECT_FILAMENTS "filaments"
|
||||
#define JSON_ASSEMPLE_OBJECT_POS_X "pos_x"
|
||||
#define JSON_ASSEMPLE_OBJECT_POS_Y "pos_y"
|
||||
#define JSON_ASSEMPLE_OBJECT_POS_Z "pos_z"
|
||||
#define JSON_ASSEMPLE_OBJECT_ASSEMBLE_INDEX "assemble_index"
|
||||
#define JSON_ASSEMPLE_OBJECT_PRINT_PARAMS "print_params"
|
||||
#define JSON_ASSEMPLE_ASSEMBLE_PARAMS "assembled_params"
|
||||
|
||||
|
||||
#define JSON_ASSEMPLE_OBJECT_MIN_Z "min_z"
|
||||
#define JSON_ASSEMPLE_OBJECT_MAX_Z "max_z"
|
||||
#define JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES "height_ranges"
|
||||
#define JSON_ASSEMPLE_OBJECT_RANGE_PARAMS "range_params"
|
||||
|
||||
typedef struct _height_range_info {
|
||||
float min_z;
|
||||
float max_z;
|
||||
|
||||
std::map<std::string, std::string> range_params;
|
||||
}height_range_info_t;
|
||||
|
||||
typedef struct _assembled_param_info {
|
||||
std::map<std::string, std::string> print_params;
|
||||
std::vector<height_range_info_t> height_ranges;
|
||||
}assembled_param_info_t;
|
||||
|
||||
typedef struct _assemble_object_info {
|
||||
std::string path;
|
||||
int count;
|
||||
|
||||
std::vector<int> filaments;
|
||||
std::vector<int> assemble_index;
|
||||
std::vector<float> pos_x;
|
||||
std::vector<float> pos_y;
|
||||
std::vector<float> pos_z;
|
||||
std::map<std::string, std::string> print_params;
|
||||
std::vector<height_range_info_t> height_ranges;
|
||||
}assemble_object_info_t;
|
||||
|
||||
typedef struct _assemble_plate_info {
|
||||
std::string plate_name;
|
||||
bool need_arrange {false};
|
||||
int filaments_count {0};
|
||||
|
||||
std::map<std::string, std::string> plate_params;
|
||||
std::vector<assemble_object_info_t> assemble_obj_list;
|
||||
std::vector<ModelObject *> loaded_obj_list;
|
||||
std::map<int, assembled_param_info_t> assembled_param_list;
|
||||
}assemble_plate_info_t;
|
||||
|
||||
|
||||
typedef struct _printer_plate_info {
|
||||
std::string printer_name;
|
||||
int printable_width{0};
|
||||
|
||||
@@ -57,6 +57,10 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
#include "libslic3r/Format/STEP.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
using namespace Slic3r;
|
||||
namespace po = boost::program_options;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
@@ -358,7 +358,7 @@ namespace AABBTreeLines {
|
||||
return dist;
|
||||
}
|
||||
|
||||
std::vector<size_t> all_lines_in_radius(const Vec<LineType::Dim, Scalar>& point, Floating radius) const
|
||||
std::vector<size_t> all_lines_in_radius(const Vec<LineType::Dim, Scalar>& point, Floating radius)
|
||||
{
|
||||
return AABBTreeLines::all_lines_in_radius(this->lines, this->tree, point.template cast<Floating>(), radius * radius);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace Algorithm {
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "libslic3r/Arachne/SkeletalTrapezoidationJoint.hpp"
|
||||
#include "libslic3r/Arachne/utils/ExtrusionJunction.hpp"
|
||||
#include "libslic3r/Arachne/utils/ExtrusionLine.hpp"
|
||||
#include "libslic3r/Arachne/SkeletalTrapezoidationGraph.hpp"
|
||||
#include "libslic3r/Arachne/utils/PolygonsSegmentIndex.hpp"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#include "libslic3r/EdgeGrid.hpp"
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include "utils/HalfEdgeGraph.hpp"
|
||||
#include "utils/PolygonsSegmentIndex.hpp"
|
||||
#include "utils/ExtrusionJunction.hpp"
|
||||
#include "utils/ExtrusionLine.hpp"
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include "BeadingStrategy/BeadingStrategyFactory.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "utils/ExtrusionLine.hpp"
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Arachne/utils/ExtrusionJunction.hpp"
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include "libslic3r/ExtrusionEntity.hpp"
|
||||
#include "libslic3r/Line.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
|
||||
@@ -19,9 +19,7 @@
|
||||
#include "ExtrusionJunction.hpp"
|
||||
#include "../../Polyline.hpp"
|
||||
#include "../../Polygon.hpp"
|
||||
#include "../../BoundingBox.hpp"
|
||||
#include "../../ExtrusionEntity.hpp"
|
||||
#include "../../Flow.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Point.hpp"
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
#include "SparsePointGrid.hpp"
|
||||
#include "PolygonsPointIndex.hpp"
|
||||
#include "../../Polygon.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <libnest2d/utils/rotcalipers.hpp>
|
||||
|
||||
#include <numeric>
|
||||
#include <ClipperUtils.hpp>
|
||||
|
||||
#include <boost/geometry/index/rtree.hpp>
|
||||
#include <utility>
|
||||
@@ -45,6 +44,7 @@
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/multiprecision/integer.hpp>
|
||||
#include <boost/rational.hpp>
|
||||
#include "MultiMaterialSegmentation.hpp"
|
||||
|
||||
namespace libnest2d {
|
||||
#if !defined(_MSC_VER) && defined(__SIZEOF_INT128__) && !defined(__APPLE__)
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "Config.hpp"
|
||||
#include "ExtrusionEntityCollection.hpp"
|
||||
#include "MultiMaterialSegmentation.hpp"
|
||||
#include "SurfaceCollection.hpp"
|
||||
#include "TriangleMesh.hpp"
|
||||
|
||||
#ifndef NDEBUG
|
||||
// #define BRIM_DEBUG_TO_SVG
|
||||
|
||||
@@ -91,6 +91,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "libslic3r/Color.hpp"
|
||||
#include "libslic3r/TriangleMesh.hpp"
|
||||
|
||||
class Geom2d_TrimmedCurve;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
class Geom_TrimmedCurve;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
// Single source of truth for the weld tolerance the viewport and the kernel share.
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "libslic3r/Point.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
// hand-rolled SketchConstraints: full constraint set, real DoF counting, and
|
||||
// over-constrained (bad-constraint) detection. Solves on a fixed 2D XY workplane.
|
||||
|
||||
#include "libslic3r/CAD/SketchEngine.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace Slic3r { enum class SketchPointRole; }
|
||||
namespace Slic3r { struct SketchEntity; }
|
||||
namespace Slic3r { struct SketchEntityConstraintDef; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
struct SketchSolveResult {
|
||||
|
||||
@@ -202,8 +202,6 @@ set(lisbslic3r_sources
|
||||
Format/3mf.hpp
|
||||
Format/AMF.cpp
|
||||
Format/AMF.hpp
|
||||
Format/AssembleList.cpp
|
||||
Format/AssembleList.hpp
|
||||
Format/DRC.cpp
|
||||
Format/DRC.hpp
|
||||
Format/bbs_3mf.cpp
|
||||
|
||||
@@ -5,10 +5,8 @@
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <math.h>
|
||||
#include "Geometry.hpp"
|
||||
#include "Point.hpp"
|
||||
#include "Line.hpp"
|
||||
#include "Polygon.hpp"
|
||||
#include "libslic3r.h"
|
||||
|
||||
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
#define slic3r_Circle_hpp_
|
||||
|
||||
#include "Point.hpp"
|
||||
#include "Line.hpp"
|
||||
#include "libslic3r.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace Slic3r { class Line; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
constexpr double ZERO_TOLERANCE = 0.000005;
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "ClipperUtils.hpp"
|
||||
#include "BoundingBox.hpp"
|
||||
#include "ExPolygon.hpp"
|
||||
#include "Geometry.hpp"
|
||||
#include "Point.hpp"
|
||||
#include "Polygon.hpp"
|
||||
#include "Polyline.hpp"
|
||||
@@ -24,6 +23,7 @@
|
||||
#include <clipper2/clipper.h>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "ExtrusionEntity.hpp"
|
||||
|
||||
// #define CLIPPER_UTILS_DEBUG
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <clipper2/clipper2_z.hpp>
|
||||
#include <cstddef>
|
||||
#include "Point.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace ClipperZUtils {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <libslic3r/ClipperUtils.hpp>
|
||||
#include <libslic3r/Point.hpp>
|
||||
#include <libslic3r/ExPolygon.hpp>
|
||||
#include "Polygon.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -871,6 +871,19 @@ ConfigSubstitutions ConfigBase::load_from_json(const std::string &file, ForwardC
|
||||
return std::move(substitutions_ctxt.substitutions);
|
||||
}
|
||||
|
||||
// Case-insensitive compare of a JSON key against a fixed ASCII one, without
|
||||
// boost::iequals, whose std::locale() takes a lock the whole process shares in the
|
||||
// MSVC runtime.
|
||||
static bool ascii_iequals(const std::string &key, const char *literal)
|
||||
{
|
||||
auto lower = [](char c) { return (c >= 'A' && c <= 'Z') ? char(c - 'A' + 'a') : c; };
|
||||
size_t i = 0;
|
||||
for (; i < key.size() && literal[i] != '\0'; ++ i)
|
||||
if (lower(key[i]) != lower(literal[i]))
|
||||
return false;
|
||||
return i == key.size() && literal[i] == '\0';
|
||||
}
|
||||
|
||||
int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContext& substitution_context, bool load_inherits_to_config, std::map<std::string, std::string>& key_values, std::string& reason)
|
||||
{
|
||||
json j;
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <math.h>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include "Config.hpp"
|
||||
#include "Polyline.hpp"
|
||||
#include "PrintConfig.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
#include "CustomGCode.hpp"
|
||||
#include "Config.hpp"
|
||||
#include "GCode.hpp"
|
||||
#include "GCodeWriter.hpp"
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
#include <vector>
|
||||
#include <admesh/stl.h> // indexed_triangle_set
|
||||
#include "ExPolygon.hpp"
|
||||
#include "Emboss.hpp" // IProjection
|
||||
|
||||
namespace Slic3r::Emboss { class IProject3d; }
|
||||
namespace Slic3r::Emboss { class IProjection; }
|
||||
|
||||
namespace Slic3r{
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <optional>
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
#include "BoundingBox.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "ElephantFootCompensation.hpp"
|
||||
#include "Flow.hpp"
|
||||
#include "Geometry.hpp"
|
||||
#include "SVG.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -19,6 +18,7 @@
|
||||
#include <utility>
|
||||
#include <math.h>
|
||||
#include <limits>
|
||||
#include "ExtrusionEntity.hpp"
|
||||
|
||||
// #define CONTOUR_DISTANCE_DEBUG_SVG
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef slic3r_ElephantFootCompensation_hpp_
|
||||
#define slic3r_ElephantFootCompensation_hpp_
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "ExPolygon.hpp"
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "BoundingBox.hpp"
|
||||
#include "ExPolygon.hpp"
|
||||
#include "Exception.hpp"
|
||||
#include "Geometry/MedialAxis.hpp"
|
||||
#include "Point.hpp"
|
||||
#include "MultiPoint.hpp"
|
||||
@@ -8,7 +7,6 @@
|
||||
#include "Line.hpp"
|
||||
#include "ClipperUtils.hpp"
|
||||
#include "Polyline.hpp"
|
||||
#include "SVG.hpp"
|
||||
#include "libslic3r.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include "Polygon.hpp"
|
||||
using namespace Slic3r;
|
||||
|
||||
// IMPROVE: use one dimensional vector for polygons offset with searching by std::lower_bound
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include "Config.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define slic3r_Extruder_hpp_
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "Point.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "ExtrusionEntityCollection.hpp"
|
||||
#include "ExPolygon.hpp"
|
||||
#include "ClipperUtils.hpp"
|
||||
#include "Extruder.hpp"
|
||||
#include "Flow.hpp"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
@@ -21,6 +20,7 @@
|
||||
#include <string_view>
|
||||
#include "Utils.hpp"
|
||||
#include "libslic3r.h"
|
||||
#include "ArcFitter.hpp"
|
||||
|
||||
#define L(s) (s)
|
||||
|
||||
|
||||
@@ -175,23 +175,6 @@ private:
|
||||
bool is_reverse{true};
|
||||
};
|
||||
|
||||
// Calls `f` for every ExtrusionPath in `entity`, descending into collections, loops and multi-paths.
|
||||
template<typename F> void for_each_extrusion_path(const ExtrusionEntity &entity, F &&f)
|
||||
{
|
||||
if (auto *collection = dynamic_cast<const ExtrusionEntityCollection *>(&entity)) {
|
||||
for (const ExtrusionEntity *child : collection->entities)
|
||||
for_each_extrusion_path(*child, f);
|
||||
} else if (auto *loop = dynamic_cast<const ExtrusionLoop *>(&entity)) {
|
||||
for (const ExtrusionPath &path : loop->paths)
|
||||
f(path);
|
||||
} else if (auto *multi_path = dynamic_cast<const ExtrusionMultiPath *>(&entity)) {
|
||||
for (const ExtrusionPath &path : multi_path->paths)
|
||||
f(path);
|
||||
} else if (auto *path = dynamic_cast<const ExtrusionPath *>(&entity)) {
|
||||
f(*path);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "ExtrusionEntity.hpp"
|
||||
#include "libslic3r.h"
|
||||
#include "ExtrusionSimulator.hpp"
|
||||
#include "Polyline.hpp"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define slic3r_ExtrusionSimulator_hpp_
|
||||
|
||||
#include "Point.hpp"
|
||||
#include "libslic3r.h"
|
||||
#include "ExtrusionEntity.hpp"
|
||||
#include "BoundingBox.hpp"
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "BoundingBox.hpp"
|
||||
#include "TriangleMesh.hpp"
|
||||
#include "SLA/IndexedMesh.hpp"
|
||||
#include "Model.hpp"
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <unordered_set>
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
#include "libslic3r/Arachne/utils/ExtrusionJunction.hpp"
|
||||
#include "libslic3r/Arachne/utils/ExtrusionLine.hpp"
|
||||
#include "libslic3r/PerimeterGenerator.hpp"
|
||||
#include <cstddef>
|
||||
|
||||
namespace Slic3r { class PerimeterGenerator; }
|
||||
namespace Slic3r { struct FuzzySkinConfig; }
|
||||
namespace Slic3r::Arachne { struct ExtrusionLine; }
|
||||
|
||||
namespace Slic3r::Feature::FuzzySkin {
|
||||
|
||||
void fuzzy_polyline(Points& poly, bool closed, coordf_t slice_z, const FuzzySkinConfig& cfg);
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include <algorithm>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/Print.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "libslic3r/SurfaceCollection.hpp"
|
||||
|
||||
namespace std {
|
||||
template<> struct hash<Slic3r::GridPoint3>
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "libslic3r/Print.hpp"
|
||||
#include "VoxelUtils.hpp"
|
||||
#include <functional>
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include "libslic3r/MultiMaterialSegmentation.hpp"
|
||||
|
||||
namespace Slic3r { class PrintObject; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
#include "libslic3r/Geometry.hpp"
|
||||
#include "libslic3r/Fill/FillRectilinear.hpp"
|
||||
#include "libslic3r/Surface.hpp"
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
@@ -41,6 +41,13 @@
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
#include "libslic3r.h"
|
||||
#include "libslic3r/ExtrusionEntityCollection.hpp"
|
||||
#include "libslic3r/MultiMaterialSegmentation.hpp"
|
||||
#include "libslic3r/Slicing.hpp"
|
||||
#include "libslic3r/SurfaceCollection.hpp"
|
||||
|
||||
namespace Slic3r::FillAdaptive { struct Octree; }
|
||||
namespace Slic3r::FillLightning { class Generator; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
#include <utility>
|
||||
#include "Fill3DHoneycomb.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
|
||||
namespace Slic3r { class Point; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class Fill3DHoneycomb : public Fill
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
#include <boost/geometry/geometries/point.hpp>
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
#include <boost/geometry/index/rtree.hpp>
|
||||
#include "libslic3r/Fill/FillAdaptive.hpp"
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
#include "libslic3r/SurfaceCollection.hpp"
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "libslic3r/Line.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Flow.hpp"
|
||||
// #define INFILL_DEBUG_OUTPUT
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -24,10 +24,11 @@
|
||||
#include "../PrintConfig.hpp"
|
||||
#include "../Flow.hpp"
|
||||
#include "../ExtrusionEntity.hpp"
|
||||
#include "../ExtrusionEntityCollection.hpp"
|
||||
#include "../ShortestPath.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
|
||||
namespace Slic3r { class ExtrusionEntityCollection; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <libslic3r/ShortestPath.hpp>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "libslic3r/ExtrusionEntity.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "FillBase.hpp"
|
||||
#include <utility>
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
|
||||
namespace Slic3r { class Point; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class FillConcentric : public Fill
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
#include <libslic3r/ShortestPath.hpp>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include "libslic3r/Flow.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
|
||||
namespace Slic3r { class Surface; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include "libslic3r/ExtrusionEntity.hpp"
|
||||
#include "FillBase.hpp"
|
||||
|
||||
namespace Slic3r { class Surface; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class FillConcentricInternal : public Fill
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "../libslic3r.h"
|
||||
#include "../Point.hpp"
|
||||
#include "../Polygon.hpp"
|
||||
#include "../Polyline.hpp"
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../ShortestPath.hpp"
|
||||
#include "../Surface.hpp"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
@@ -13,6 +11,7 @@
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
#include "FillCrossHatch.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "../libslic3r.h"
|
||||
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "FillBase.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
|
||||
namespace Slic3r { class Point; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class FillCrossHatch : public Fill
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../MarchingSquares.hpp"
|
||||
#include "../ShortestPath.hpp"
|
||||
#include "../Surface.hpp"
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
@@ -18,6 +16,7 @@
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
#include "FillGyroid.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Marching-squares scalar field for the optimized gyroid branch.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#ifndef slic3r_FillGyroid_hpp_
|
||||
#define slic3r_FillGyroid_hpp_
|
||||
|
||||
#include "../libslic3r.h"
|
||||
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "FillBase.hpp"
|
||||
#include <utility>
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
|
||||
namespace Slic3r { class Point; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class FillGyroid : public Fill
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../ShortestPath.hpp"
|
||||
#include "../Surface.hpp"
|
||||
|
||||
#include "libslic3r/Fill/FillBase.hpp"
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
@@ -14,6 +12,7 @@
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
#include "FillHoneycomb.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../Print.hpp"
|
||||
#include "../ShortestPath.hpp"
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "libslic3r/Fill/Lightning/Layer.hpp"
|
||||
#include "FillBase.hpp"
|
||||
@@ -13,6 +12,7 @@
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include "libslic3r/Fill/FillLightning.hpp"
|
||||
|
||||
namespace Slic3r::FillLightning {
|
||||
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
|
||||
namespace Slic3r { class Point; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class PrintObject;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../ExPolygon.hpp"
|
||||
#include "../ShortestPath.hpp"
|
||||
#include "../Surface.hpp"
|
||||
#include "libslic3r/Fill/FillBase.hpp"
|
||||
#include <utility>
|
||||
#include "libslic3r/Point.hpp"
|
||||
@@ -15,6 +14,8 @@
|
||||
#include <cstdlib>
|
||||
|
||||
#include "FillLine.hpp"
|
||||
#include "libslic3r/ExtrusionEntity.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../ShortestPath.hpp"
|
||||
#include "../Surface.hpp"
|
||||
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include "libslic3r/Fill/FillBase.hpp"
|
||||
@@ -18,6 +17,7 @@
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include "FillPlanePath.hpp"
|
||||
#include "libslic3r/Config.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "../Geometry.hpp"
|
||||
#include "../Surface.hpp"
|
||||
#include "../ShortestPath.hpp"
|
||||
#include "../VariableWidth.hpp"
|
||||
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include "libslic3r/Fill/FillBase.hpp"
|
||||
|
||||
@@ -12,10 +12,11 @@
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "libslic3r/Flow.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
|
||||
namespace Slic3r { class Flow; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class PrintRegionConfig;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../ExPolygon.hpp"
|
||||
#include "../Surface.hpp"
|
||||
#include "../VariableWidth.hpp"
|
||||
#include "Arachne/WallToolPaths.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
@@ -22,6 +20,9 @@
|
||||
#include <math.h>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "libslic3r/Arachne/utils/ExtrusionJunction.hpp"
|
||||
#include "libslic3r/ExtrusionEntity.hpp"
|
||||
#include "libslic3r/Line.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "FillBase.hpp"
|
||||
#include <utility>
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
|
||||
namespace Slic3r { class Point; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class FillSpiralInset : public Fill
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "FillBase.hpp"
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
|
||||
namespace marchsq {
|
||||
using namespace Slic3r;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "FillBase.hpp"
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/MultiMaterialSegmentation.hpp"
|
||||
#include "libslic3r/SurfaceCollection.hpp"
|
||||
|
||||
/* Possible future tasks/optimizations,etc.:
|
||||
* - Improve connecting heuristic to favor connecting to shorter trees
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#include "../../ClipperUtils.hpp"
|
||||
#include "../../Geometry.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include "SVG.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Line.hpp"
|
||||
|
||||
//#define LIGHTNING_TREE_NODE_DEBUG_OUTPUT
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "Flow.hpp"
|
||||
#include "Exception.hpp"
|
||||
#include "Config.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "Print.hpp"
|
||||
#include "libslic3r.h"
|
||||
#include <cmath>
|
||||
@@ -10,6 +9,7 @@
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <string>
|
||||
#include <math.h>
|
||||
#include "PrintConfig.hpp"
|
||||
|
||||
// Mark string for localization and translate.
|
||||
#define L(s) Slic3r::I18N::translate(s)
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <math.h>
|
||||
#include "FlushVolPredictor.hpp"
|
||||
#include "slic3r/Utils/ColorSpaceConvert.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "FlushVolCalc.hpp"
|
||||
|
||||
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
#include "../Model.hpp"
|
||||
#include "../Utils.hpp"
|
||||
#include "../LocalesUtils.hpp"
|
||||
#include "../GCode.hpp"
|
||||
#include "../Geometry.hpp"
|
||||
#include "../GCode/ThumbnailData.hpp"
|
||||
#include "../Semver.hpp"
|
||||
#include "../Time.hpp"
|
||||
|
||||
#include "../I18N.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
|
||||
@@ -12,17 +12,10 @@
|
||||
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
|
||||
#include "../libslic3r.h"
|
||||
#include "../Exception.hpp"
|
||||
#include "../Model.hpp"
|
||||
#include "../GCode.hpp"
|
||||
#include "../PrintConfig.hpp"
|
||||
#include "../Utils.hpp"
|
||||
#include "../I18N.hpp"
|
||||
#include "../Geometry.hpp"
|
||||
#include "../CustomGCode.hpp"
|
||||
#include "../LocalesUtils.hpp"
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/TriangleMesh.hpp"
|
||||
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
#include "AssembleList.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
#define JSON_ASSEMPLE_PLATES "plates"
|
||||
#define JSON_ASSEMPLE_PLATE_PARAMS "plate_params"
|
||||
#define JSON_ASSEMPLE_PLATE_NAME "plate_name"
|
||||
#define JSON_ASSEMPLE_PLATE_NEED_ARRANGE "need_arrange"
|
||||
#define JSON_ASSEMPLE_OBJECTS "objects"
|
||||
#define JSON_ASSEMPLE_OBJECT_PATH "path"
|
||||
#define JSON_ASSEMPLE_OBJECT_COUNT "count"
|
||||
#define JSON_ASSEMPLE_OBJECT_FILAMENTS "filaments"
|
||||
#define JSON_ASSEMPLE_OBJECT_POS_X "pos_x"
|
||||
#define JSON_ASSEMPLE_OBJECT_POS_Y "pos_y"
|
||||
#define JSON_ASSEMPLE_OBJECT_POS_Z "pos_z"
|
||||
#define JSON_ASSEMPLE_OBJECT_ASSEMBLE_INDEX "assemble_index"
|
||||
#define JSON_ASSEMPLE_OBJECT_PRINT_PARAMS "print_params"
|
||||
#define JSON_ASSEMPLE_ASSEMBLE_PARAMS "assembled_params"
|
||||
|
||||
|
||||
#define JSON_ASSEMPLE_OBJECT_MIN_Z "min_z"
|
||||
#define JSON_ASSEMPLE_OBJECT_MAX_Z "max_z"
|
||||
#define JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES "height_ranges"
|
||||
#define JSON_ASSEMPLE_OBJECT_RANGE_PARAMS "range_params"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
AssembleListResult load_assemble_plate_list(const std::string &config_file, std::vector<assemble_plate_info_t> &assemble_plate_info_list, int max_plate_count)
|
||||
{
|
||||
AssembleListResult ret = AssembleListResult::Success;
|
||||
boost::filesystem::path directory_path(config_file);
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1% enter, file %2%")%__FUNCTION__ % config_file;
|
||||
if (!boost::filesystem::exists(directory_path)) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("directory %1% not exist.")%config_file;
|
||||
return AssembleListResult::FileNotFound;
|
||||
}
|
||||
|
||||
try {
|
||||
json root_json;
|
||||
boost::nowide::ifstream ifs(config_file);
|
||||
ifs >> root_json;
|
||||
ifs.close();
|
||||
|
||||
int plate_count = root_json[JSON_ASSEMPLE_PLATES].size();
|
||||
if ((plate_count <= 0) || (plate_count > max_plate_count)) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< boost::format(": invalid plate count %1%")%plate_count;
|
||||
return AssembleListResult::ConfigError;
|
||||
}
|
||||
assemble_plate_info_list.resize(plate_count);
|
||||
|
||||
for (int plate_index = 0; plate_index < plate_count; plate_index++)
|
||||
{
|
||||
assemble_plate_info_t &assemble_plate = assemble_plate_info_list[plate_index];
|
||||
const json& plate_json = root_json[JSON_ASSEMPLE_PLATES][plate_index];
|
||||
assemble_plate.plate_name = plate_json[JSON_ASSEMPLE_PLATE_NAME];
|
||||
assemble_plate.need_arrange = plate_json[JSON_ASSEMPLE_PLATE_NEED_ARRANGE];
|
||||
|
||||
if (plate_json.contains(JSON_ASSEMPLE_PLATE_PARAMS)) {
|
||||
assemble_plate.plate_params = plate_json[JSON_ASSEMPLE_PLATE_PARAMS].get<std::map<std::string, std::string>>();
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, has %2% plate params") % (plate_index + 1) % assemble_plate.plate_params.size();
|
||||
}
|
||||
|
||||
int object_count = plate_json[JSON_ASSEMPLE_OBJECTS].size();
|
||||
if (object_count <= 0) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< boost::format(": invalid object count %1% in plate %2%")%object_count %(plate_index+1);
|
||||
return AssembleListResult::ConfigError;
|
||||
}
|
||||
|
||||
assemble_plate.assemble_obj_list.resize(object_count);
|
||||
for (int object_index = 0; object_index < object_count; object_index++)
|
||||
{
|
||||
assemble_object_info_t& assemble_object = assemble_plate.assemble_obj_list[object_index];
|
||||
const json& object_json = plate_json[JSON_ASSEMPLE_OBJECTS][object_index];
|
||||
|
||||
assemble_object.path = object_json[JSON_ASSEMPLE_OBJECT_PATH];
|
||||
assemble_object.count = object_json[JSON_ASSEMPLE_OBJECT_COUNT];
|
||||
|
||||
if (assemble_object.count <= 0) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": invalid object clone count %1% in plate %2% Object %3%") % assemble_object.count % (plate_index + 1) % assemble_object.path;
|
||||
return AssembleListResult::ConfigError;
|
||||
}
|
||||
|
||||
assemble_object.filaments = object_json.at(JSON_ASSEMPLE_OBJECT_FILAMENTS).get<std::vector<int>>();
|
||||
if (assemble_object.filaments.empty())
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": object %1%'s filaments list is empty") % assemble_object.path;
|
||||
return AssembleListResult::ConfigError;
|
||||
}
|
||||
if ((assemble_object.filaments.size() != assemble_object.count) && (assemble_object.filaments.size() != 1))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": object %1%'s filaments count %2% not equal to clone count %3%, also not equal to 1") % assemble_object.path % assemble_object.filaments.size() % assemble_object.count;
|
||||
return AssembleListResult::ConfigError;
|
||||
}
|
||||
// 0 keeps the default filament, as it does for --load-filament-ids.
|
||||
if (std::any_of(assemble_object.filaments.begin(), assemble_object.filaments.end(), [](int id) { return id < 0; }))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": object %1% has a negative filament id") % assemble_object.path;
|
||||
return AssembleListResult::ConfigError;
|
||||
}
|
||||
|
||||
if (object_json.contains(JSON_ASSEMPLE_OBJECT_ASSEMBLE_INDEX)) {
|
||||
assemble_object.assemble_index = object_json[JSON_ASSEMPLE_OBJECT_ASSEMBLE_INDEX].get<std::vector<int>>();
|
||||
if ((assemble_object.assemble_index.size() > 0) && (assemble_object.assemble_index.size() != assemble_object.count) && (assemble_object.assemble_index.size() != 1))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": object %1%'s assemble_index count %2% not equal to clone count %3%, also not equal to 1") % assemble_object.path % assemble_object.assemble_index.size() % assemble_object.count;
|
||||
return AssembleListResult::ConfigError;
|
||||
}
|
||||
}
|
||||
|
||||
if (object_json.contains(JSON_ASSEMPLE_OBJECT_POS_X)) {
|
||||
assemble_object.pos_x = object_json[JSON_ASSEMPLE_OBJECT_POS_X].get<std::vector<float>>();
|
||||
if ((assemble_object.pos_x.size() > 0) && (assemble_object.pos_x.size() != assemble_object.count) && (assemble_object.pos_x.size() != 1))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": object %1%'s pos_x count %2% not equal to clone count %3%, also not equal to 1") % assemble_object.path % assemble_object.pos_x.size() % assemble_object.count;
|
||||
return AssembleListResult::ConfigError;
|
||||
}
|
||||
}
|
||||
if (object_json.contains(JSON_ASSEMPLE_OBJECT_POS_Y)) {
|
||||
assemble_object.pos_y = object_json[JSON_ASSEMPLE_OBJECT_POS_Y].get<std::vector<float>>();
|
||||
if ((assemble_object.pos_y.size() > 0) && (assemble_object.pos_y.size() != assemble_object.count) && (assemble_object.pos_y.size() != 1))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": object %1%'s pos_y count %2% not equal to clone count %3%, also not equal to 1") % assemble_object.path % assemble_object.pos_y.size() % assemble_object.count;
|
||||
return AssembleListResult::ConfigError;
|
||||
}
|
||||
}
|
||||
if (object_json.contains(JSON_ASSEMPLE_OBJECT_POS_Z)) {
|
||||
assemble_object.pos_z = object_json[JSON_ASSEMPLE_OBJECT_POS_Z].get<std::vector<float>>();
|
||||
if ((assemble_object.pos_z.size() > 0) && (assemble_object.pos_z.size() != assemble_object.count) && (assemble_object.pos_z.size() != 1))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": object %1%'s pos_z count %2% not equal to clone count %3%, also not equal to 1") % assemble_object.path % assemble_object.pos_z.size() % assemble_object.count;
|
||||
return AssembleListResult::ConfigError;
|
||||
}
|
||||
}
|
||||
if (object_json.contains(JSON_ASSEMPLE_OBJECT_PRINT_PARAMS)) {
|
||||
assemble_object.print_params = object_json[JSON_ASSEMPLE_OBJECT_PRINT_PARAMS].get<std::map<std::string, std::string>>();
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, object %2% has %3% print params") % (plate_index + 1) %assemble_object.path % assemble_object.print_params.size();
|
||||
}
|
||||
if (object_json.contains(JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES)) {
|
||||
json height_range_json = object_json[JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES];
|
||||
int range_count = height_range_json.size();
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, object %2% has %3% height ranges") % (plate_index + 1) %assemble_object.path % range_count;
|
||||
|
||||
assemble_object.height_ranges.resize(range_count);
|
||||
for (int range_index = 0; range_index < range_count; range_index++)
|
||||
{
|
||||
height_range_info_t& height_range = assemble_object.height_ranges[range_index];
|
||||
height_range.min_z = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_MIN_Z];
|
||||
height_range.max_z = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_MAX_Z];
|
||||
height_range.range_params = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_RANGE_PARAMS].get<std::map<std::string, std::string>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (plate_json.contains(JSON_ASSEMPLE_ASSEMBLE_PARAMS)) {
|
||||
json assemble_params_json = plate_json[JSON_ASSEMPLE_ASSEMBLE_PARAMS];
|
||||
int assemble_count = assemble_params_json.size();
|
||||
for (int i = 0; i < assemble_count; i++)
|
||||
{
|
||||
assembled_param_info_t assembled_param;
|
||||
int assemble_index = assemble_params_json[i][JSON_ASSEMPLE_OBJECT_ASSEMBLE_INDEX];
|
||||
if (assemble_params_json[i].contains(JSON_ASSEMPLE_OBJECT_PRINT_PARAMS)) {
|
||||
assembled_param.print_params = assemble_params_json[i][JSON_ASSEMPLE_OBJECT_PRINT_PARAMS].get<std::map<std::string, std::string>>();
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, assemble object %2% has %3% print params") % (plate_index + 1) %i % assembled_param.print_params.size();
|
||||
}
|
||||
if (assemble_params_json[i].contains(JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES)) {
|
||||
json height_range_json = assemble_params_json[i][JSON_ASSEMPLE_OBJECT_HEIGHT_RANGES];
|
||||
int range_count = height_range_json.size();
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, assemble object %2% has %3% height ranges") % (plate_index + 1) %i % range_count;
|
||||
|
||||
assembled_param.height_ranges.resize(range_count);
|
||||
for (int range_index = 0; range_index < range_count; range_index++)
|
||||
{
|
||||
height_range_info_t& height_range = assembled_param.height_ranges[range_index];
|
||||
height_range.min_z = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_MIN_Z];
|
||||
height_range.max_z = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_MAX_Z];
|
||||
height_range.range_params = height_range_json[range_index][JSON_ASSEMPLE_OBJECT_RANGE_PARAMS].get<std::map<std::string, std::string>>();
|
||||
}
|
||||
}
|
||||
assemble_plate.assembled_param_list.emplace(assemble_index, std::move(assembled_param));
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, has %2% plate params") % (plate_index + 1) % assemble_plate.plate_params.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(std::exception &err) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse file "<<config_file<<" got a generic exception, reason = " << err.what();
|
||||
ret = AssembleListResult::ConfigError;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
@@ -1,60 +0,0 @@
|
||||
#ifndef slic3r_Format_AssembleList_hpp_
|
||||
#define slic3r_Format_AssembleList_hpp_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class ModelObject;
|
||||
|
||||
typedef struct _height_range_info {
|
||||
float min_z;
|
||||
float max_z;
|
||||
|
||||
std::map<std::string, std::string> range_params;
|
||||
}height_range_info_t;
|
||||
|
||||
typedef struct _assembled_param_info {
|
||||
std::map<std::string, std::string> print_params;
|
||||
std::vector<height_range_info_t> height_ranges;
|
||||
}assembled_param_info_t;
|
||||
|
||||
typedef struct _assemble_object_info {
|
||||
std::string path;
|
||||
int count;
|
||||
|
||||
std::vector<int> filaments;
|
||||
std::vector<int> assemble_index;
|
||||
std::vector<float> pos_x;
|
||||
std::vector<float> pos_y;
|
||||
std::vector<float> pos_z;
|
||||
std::map<std::string, std::string> print_params;
|
||||
std::vector<height_range_info_t> height_ranges;
|
||||
}assemble_object_info_t;
|
||||
|
||||
typedef struct _assemble_plate_info {
|
||||
std::string plate_name;
|
||||
bool need_arrange {false};
|
||||
int filaments_count {0};
|
||||
|
||||
std::map<std::string, std::string> plate_params;
|
||||
std::vector<assemble_object_info_t> assemble_obj_list;
|
||||
std::vector<ModelObject *> loaded_obj_list;
|
||||
std::map<int, assembled_param_info_t> assembled_param_list;
|
||||
}assemble_plate_info_t;
|
||||
|
||||
enum class AssembleListResult {
|
||||
Success,
|
||||
FileNotFound,
|
||||
// Malformed JSON, a missing required field, or a value that fails validation.
|
||||
ConfigError
|
||||
};
|
||||
|
||||
// Read the JSON assemble list used by the CLI's --load-assemble-list into one entry per plate.
|
||||
AssembleListResult load_assemble_plate_list(const std::string &config_file, std::vector<assemble_plate_info_t> &assemble_plate_info_list, int max_plate_count);
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif /* slic3r_Format_AssembleList_hpp_ */
|
||||
@@ -1,4 +1,3 @@
|
||||
#include "../libslic3r.h"
|
||||
#include "../Model.hpp"
|
||||
#include "../TriangleMesh.hpp"
|
||||
#include "../TexturePainting.hpp"
|
||||
@@ -32,6 +31,7 @@
|
||||
|
||||
//Translation
|
||||
#include "I18N.hpp"
|
||||
#include "libslic3r/Format/OBJ.hpp"
|
||||
#define _L(s) Slic3r::I18N::translate(s)
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "SL1.hpp"
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "GCode/ThumbnailData.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
@@ -35,7 +34,6 @@
|
||||
#include "libslic3r/SlicesToTriangleMesh.hpp"
|
||||
#include "libslic3r/MarchingSquares.hpp"
|
||||
#include "libslic3r/ClipperUtils.hpp"
|
||||
#include "libslic3r/MTUtils.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "libslic3r/SLA/RasterBase.hpp"
|
||||
#include "libslic3r/miniz_extension.hpp"
|
||||
@@ -50,6 +48,7 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <string_view>
|
||||
#include "libslic3r/SLA/Pad.hpp"
|
||||
|
||||
namespace marchsq {
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include "../libslic3r.h"
|
||||
#include "../Model.hpp"
|
||||
#include "../TriangleMesh.hpp"
|
||||
#include "libslic3r/Exception.hpp"
|
||||
@@ -60,6 +59,8 @@
|
||||
#include "BRepTools.hxx"
|
||||
#include <IMeshTools_Parameters.hxx>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -104,7 +103,7 @@ public:
|
||||
MESH_SUCCESS,
|
||||
MESH_ERROR
|
||||
};
|
||||
Step(fs::path path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr);
|
||||
Step(boost::filesystem::path path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr);
|
||||
Step(std::string path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr);
|
||||
~Step();
|
||||
Step_Status load();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include "../libslic3r.h"
|
||||
#include "../Model.hpp"
|
||||
#include "../TriangleMesh.hpp"
|
||||
|
||||
@@ -7,6 +6,7 @@
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include "libslic3r/Format/STL.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define DIR_SEPARATOR '\\'
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "../Geometry.hpp"
|
||||
#include "../GCode/ThumbnailData.hpp"
|
||||
#include "../Semver.hpp"
|
||||
#include "../Time.hpp"
|
||||
|
||||
#include "../I18N.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
@@ -113,6 +112,8 @@ namespace pt = boost::property_tree;
|
||||
#include "NSVGUtils.hpp"
|
||||
|
||||
#include <fast_float/fast_float.h>
|
||||
#include "libslic3r/Format/bbs_3mf.hpp"
|
||||
#include "libslic3r/ProjectTask.hpp"
|
||||
|
||||
// Slightly faster than sprintf("%.9g"), but there is an issue with the karma floating point formatter,
|
||||
// https://github.com/boostorg/spirit/pull/586
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "TopoDS.hxx"
|
||||
#include "BRepExtrema_SelfIntersection.hxx"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
const double STEP_TRANS_CHORD_ERROR = 0.005;
|
||||
|
||||
+84
-124
@@ -120,7 +120,6 @@
|
||||
|
||||
#include <Shiny/Shiny.h>
|
||||
|
||||
#include "miniz_extension.hpp"
|
||||
|
||||
using namespace std::literals::string_view_literals;
|
||||
|
||||
@@ -132,6 +131,16 @@ using namespace std::literals::string_view_literals;
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include "AABBTreeLines.hpp"
|
||||
#include "Extruder.hpp"
|
||||
#include "ExtrusionEntityCollection.hpp"
|
||||
#include "FilamentMixer.hpp"
|
||||
#include "Format/STEP.hpp"
|
||||
#include "Model.hpp"
|
||||
#include "MultiNozzleUtils.hpp"
|
||||
#include "Slicing.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -806,13 +815,13 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
GCodeReader parser;
|
||||
parser.parse_buffer(gcode, [&changes](GCodeReader &parser, const GCodeReader::GCodeLine &line) {
|
||||
const std::string_view cmd = line.cmd();
|
||||
if (ascii_iequals(cmd, "M204") || ascii_iequals(cmd, "M201") ||
|
||||
ascii_iequals(cmd, "M202"))
|
||||
if (boost::iequals(cmd, "M204") || boost::iequals(cmd, "M201") ||
|
||||
boost::iequals(cmd, "M202"))
|
||||
changes.acceleration = true;
|
||||
else if ((ascii_iequals(cmd, "M205") || ascii_iequals(cmd, "M207") || ascii_iequals(cmd, "M566")) &&
|
||||
else if ((boost::iequals(cmd, "M205") || boost::iequals(cmd, "M207") || boost::iequals(cmd, "M566")) &&
|
||||
custom_gcode_line_has_xy_parameter(line.raw()))
|
||||
changes.jerk = true;
|
||||
else if (ascii_iequals(cmd, "SET_VELOCITY_LIMIT")) {
|
||||
else if (boost::iequals(cmd, "SET_VELOCITY_LIMIT")) {
|
||||
changes.acceleration |= boost::icontains(line.raw(), "ACCEL=");
|
||||
changes.jerk |= boost::icontains(line.raw(), "SQUARE_CORNER_VELOCITY=");
|
||||
}
|
||||
@@ -4404,75 +4413,6 @@ size_t GCode::get_nozzle_config_index(int filament_id) const
|
||||
return get_extruder_id(filament_id);
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct PrecomputedLayer
|
||||
{
|
||||
size_t index{size_t(-1)}; // size_t(-1) for the empty layer after the last
|
||||
std::vector<PrecomputedOverhangLayer> overhang_layers;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
template<typename BoolsOption> static bool any_enabled(const BoolsOption &option)
|
||||
{
|
||||
return std::any_of(option.values.begin(), option.values.end(), [](unsigned char enabled) { return enabled != 0; });
|
||||
}
|
||||
|
||||
// Whether process_layer() prepares the overhang estimator for `layer`.
|
||||
template<typename OverhangSpeed>
|
||||
static bool prepares_overhang_estimator(const Layer &layer, bool overhang_fan, OverhangSpeed overhang_speed)
|
||||
{
|
||||
const LayerRegionPtrs ®ions = layer.regions();
|
||||
return std::any_of(regions.begin(), regions.end(), [overhang_fan, &overhang_speed](const LayerRegion *region) {
|
||||
return region->has_extrusions() && (overhang_fan || overhang_speed(*region));
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<PrecomputedOverhangLayer> precompute_overhang_layers(const std::vector<GCode::LayerToPrint> &layers, bool overhang_fan)
|
||||
{
|
||||
// Any filament may print the layer, so a region's overhang speed counts if it is enabled for any.
|
||||
auto overhang_speed = [](const LayerRegion ®ion) { return any_enabled(region.region().config().enable_overhang_speed); };
|
||||
std::vector<PrecomputedOverhangLayer> out;
|
||||
for (const GCode::LayerToPrint &layer : layers)
|
||||
if (layer.object_layer != nullptr && layer.object_layer->lower_layer != nullptr &&
|
||||
prepares_overhang_estimator(*layer.object_layer, overhang_fan, overhang_speed)) {
|
||||
const LayerRegionPtrs ®ions = layer.object_layer->regions();
|
||||
const bool curled_lines = std::any_of(regions.begin(), regions.end(), [](const LayerRegion *region) {
|
||||
return any_enabled(region->region().config().slowdown_for_curled_perimeters);
|
||||
});
|
||||
out.push_back(precompute_overhang_layer(layer.original_object, *layer.object_layer, curled_lines));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Hands out the index of each layer to process_layers(), then computes the layers' overhang data in parallel.
|
||||
template<typename LayersAt>
|
||||
static auto precomputed_layers_source(size_t &next_index, size_t layer_count, bool nop_layer, bool overhang_fan, LayersAt layers_at)
|
||||
{
|
||||
return tbb::make_filter<void, PrecomputedLayer>(slic3r_tbb_filtermode::serial_in_order,
|
||||
[&next_index, layer_count, nop_layer](tbb::flow_control &fc) -> PrecomputedLayer {
|
||||
if (next_index < layer_count)
|
||||
return {next_index++};
|
||||
// The pressure equalizer returns one layer back, so it gets an empty layer after the last.
|
||||
if (next_index == layer_count + (nop_layer ? 1 : 0))
|
||||
fc.stop();
|
||||
else
|
||||
++next_index;
|
||||
return {};
|
||||
}) &
|
||||
tbb::make_filter<PrecomputedLayer, PrecomputedLayer>(slic3r_tbb_filtermode::parallel,
|
||||
[layers_at, overhang_fan](PrecomputedLayer layer) -> PrecomputedLayer {
|
||||
if (layer.index != size_t(-1))
|
||||
layer.overhang_layers = precompute_overhang_layers(layers_at(layer.index), overhang_fan);
|
||||
return layer;
|
||||
});
|
||||
}
|
||||
|
||||
// Whether the overhang fan can switch on for any filament.
|
||||
static bool overhang_fan_enabled(const PrintConfig &config, bool cooling_markers)
|
||||
{
|
||||
return cooling_markers && any_enabled(config.enable_overhang_bridge_fan);
|
||||
}
|
||||
|
||||
// Process all layers of all objects (non-sequential mode) with a parallel pipeline:
|
||||
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
|
||||
// and export G-code into file.
|
||||
@@ -4485,23 +4425,29 @@ void GCode::process_layers(
|
||||
{
|
||||
// The pipeline is variable: The vase mode filter is optional.
|
||||
size_t layer_to_print_idx = 0;
|
||||
const auto source = precomputed_layers_source(layer_to_print_idx, layers_to_print.size(), m_pressure_equalizer != nullptr,
|
||||
overhang_fan_enabled(print.config(), m_enable_cooling_markers),
|
||||
[&layers_to_print](size_t index) -> const std::vector<LayerToPrint> & { return layers_to_print[index].second; });
|
||||
const auto generator = tbb::make_filter<PrecomputedLayer, LayerResult>(slic3r_tbb_filtermode::serial_in_order,
|
||||
[this, &print, &tool_ordering, &print_object_instances_ordering, &layers_to_print](PrecomputedLayer precomputed) -> LayerResult {
|
||||
if (precomputed.index == size_t(-1))
|
||||
return LayerResult::make_nop_layer_result();
|
||||
const std::pair<coordf_t, std::vector<LayerToPrint>>& layer = layers_to_print[precomputed.index];
|
||||
const LayerTools& layer_tools = tool_ordering.tools_for_layer(layer.first);
|
||||
print.set_status(80, Slic3r::format(_(L("Generating G-code: layer %1%")), std::to_string(precomputed.index + 1)));
|
||||
if (m_wipe_tower && layer_tools.has_wipe_tower)
|
||||
m_wipe_tower->next_layer();
|
||||
//BBS
|
||||
check_placeholder_parser_failed();
|
||||
print.throw_if_canceled();
|
||||
m_extrusion_quality_estimator.set_precomputed_layers(std::move(precomputed.overhang_layers));
|
||||
return this->process_layer(print, layer.second, layer_tools, &layer == &layers_to_print.back(), &print_object_instances_ordering, tool_ordering.get_most_used_extruder(), size_t(-1));
|
||||
const auto generator = tbb::make_filter<void, LayerResult>(slic3r_tbb_filtermode::serial_in_order,
|
||||
[this, &print, &tool_ordering, &print_object_instances_ordering, &layers_to_print, &layer_to_print_idx](tbb::flow_control& fc) -> LayerResult {
|
||||
if (layer_to_print_idx >= layers_to_print.size()) {
|
||||
if (layer_to_print_idx == layers_to_print.size() + (m_pressure_equalizer ? 1 : 0)) {
|
||||
fc.stop();
|
||||
return {};
|
||||
} else {
|
||||
// Pressure equalizer need insert empty input. Because it returns one layer back.
|
||||
// Insert NOP (no operation) layer;
|
||||
++layer_to_print_idx;
|
||||
return LayerResult::make_nop_layer_result();
|
||||
}
|
||||
} else {
|
||||
const std::pair<coordf_t, std::vector<LayerToPrint>>& layer = layers_to_print[layer_to_print_idx++];
|
||||
const LayerTools& layer_tools = tool_ordering.tools_for_layer(layer.first);
|
||||
print.set_status(80, Slic3r::format(_(L("Generating G-code: layer %1%")), std::to_string(layer_to_print_idx)));
|
||||
if (m_wipe_tower && layer_tools.has_wipe_tower)
|
||||
m_wipe_tower->next_layer();
|
||||
//BBS
|
||||
check_placeholder_parser_failed();
|
||||
print.throw_if_canceled();
|
||||
return this->process_layer(print, layer.second, layer_tools, &layer == &layers_to_print.back(), &print_object_instances_ordering, tool_ordering.get_most_used_extruder(), size_t(-1));
|
||||
}
|
||||
});
|
||||
if (m_spiral_vase) {
|
||||
float nozzle_diameter = EXTRUDER_CONFIG(nozzle_diameter);
|
||||
@@ -4559,15 +4505,13 @@ void GCode::process_layers(
|
||||
|
||||
// The pipeline elements are joined using const references, thus no copying is performed.
|
||||
if (m_spiral_vase && m_pressure_equalizer)
|
||||
tbb::parallel_pipeline(12, source & generator & spiral_mode & pressure_equalizer & cooling & fan_mover & output);
|
||||
tbb::parallel_pipeline(12, generator & spiral_mode & pressure_equalizer & cooling & fan_mover & output);
|
||||
else if (m_spiral_vase)
|
||||
tbb::parallel_pipeline(12, source & generator & spiral_mode & cooling & fan_mover & output);
|
||||
tbb::parallel_pipeline(12, generator & spiral_mode & cooling & fan_mover & output);
|
||||
else if (m_pressure_equalizer)
|
||||
tbb::parallel_pipeline(12, source & generator & pressure_equalizer & cooling & fan_mover & pa_processor_filter & output);
|
||||
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & fan_mover & pa_processor_filter & output);
|
||||
else
|
||||
tbb::parallel_pipeline(12, source & generator & cooling & fan_mover & pa_processor_filter & output);
|
||||
// The estimator's precomputed data points into this print's layers.
|
||||
m_extrusion_quality_estimator.set_precomputed_layers({});
|
||||
tbb::parallel_pipeline(12, generator & cooling & fan_mover & pa_processor_filter & output);
|
||||
|
||||
}
|
||||
|
||||
@@ -4585,20 +4529,26 @@ void GCode::process_layers(
|
||||
{
|
||||
// The pipeline is variable: The vase mode filter is optional.
|
||||
size_t layer_to_print_idx = 0;
|
||||
const auto source = precomputed_layers_source(layer_to_print_idx, layers_to_print.size(), m_pressure_equalizer != nullptr,
|
||||
overhang_fan_enabled(print.config(), m_enable_cooling_markers),
|
||||
[&layers_to_print](size_t index) { return std::vector<LayerToPrint>{layers_to_print[index]}; });
|
||||
const auto generator = tbb::make_filter<PrecomputedLayer, LayerResult>(slic3r_tbb_filtermode::serial_in_order,
|
||||
[this, &print, &tool_ordering, &layers_to_print, single_object_idx, prime_extruder](PrecomputedLayer precomputed) -> LayerResult {
|
||||
if (precomputed.index == size_t(-1))
|
||||
return LayerResult::make_nop_layer_result();
|
||||
LayerToPrint &layer = layers_to_print[precomputed.index];
|
||||
print.set_status(80, Slic3r::format(_(L("Generating G-code: layer %1%")), std::to_string(precomputed.index + 1)));
|
||||
//BBS
|
||||
check_placeholder_parser_failed();
|
||||
print.throw_if_canceled();
|
||||
m_extrusion_quality_estimator.set_precomputed_layers(std::move(precomputed.overhang_layers));
|
||||
return this->process_layer(print, { std::move(layer) }, tool_ordering.tools_for_layer(layer.print_z()), &layer == &layers_to_print.back(), nullptr, tool_ordering.get_most_used_extruder(), single_object_idx, prime_extruder);
|
||||
const auto generator = tbb::make_filter<void, LayerResult>(slic3r_tbb_filtermode::serial_in_order,
|
||||
[this, &print, &tool_ordering, &layers_to_print, &layer_to_print_idx, single_object_idx, prime_extruder](tbb::flow_control& fc) -> LayerResult {
|
||||
if (layer_to_print_idx >= layers_to_print.size()) {
|
||||
if (layer_to_print_idx == layers_to_print.size() + (m_pressure_equalizer ? 1 : 0)) {
|
||||
fc.stop();
|
||||
return {};
|
||||
} else {
|
||||
// Pressure equalizer need insert empty input. Because it returns one layer back.
|
||||
// Insert NOP (no operation) layer;
|
||||
++layer_to_print_idx;
|
||||
return LayerResult::make_nop_layer_result();
|
||||
}
|
||||
} else {
|
||||
LayerToPrint &layer = layers_to_print[layer_to_print_idx ++];
|
||||
print.set_status(80, Slic3r::format(_(L("Generating G-code: layer %1%")), std::to_string(layer_to_print_idx)));
|
||||
//BBS
|
||||
check_placeholder_parser_failed();
|
||||
print.throw_if_canceled();
|
||||
return this->process_layer(print, { std::move(layer) }, tool_ordering.tools_for_layer(layer.print_z()), &layer == &layers_to_print.back(), nullptr, tool_ordering.get_most_used_extruder(), single_object_idx, prime_extruder);
|
||||
}
|
||||
});
|
||||
if (m_spiral_vase) {
|
||||
float nozzle_diameter = EXTRUDER_CONFIG(nozzle_diameter);
|
||||
@@ -4653,15 +4603,13 @@ void GCode::process_layers(
|
||||
|
||||
// The pipeline elements are joined using const references, thus no copying is performed.
|
||||
if (m_spiral_vase && m_pressure_equalizer)
|
||||
tbb::parallel_pipeline(12, source & generator & spiral_mode & pressure_equalizer & cooling & fan_mover & output);
|
||||
tbb::parallel_pipeline(12, generator & spiral_mode & pressure_equalizer & cooling & fan_mover & output);
|
||||
else if (m_spiral_vase)
|
||||
tbb::parallel_pipeline(12, source & generator & spiral_mode & cooling & fan_mover & output);
|
||||
tbb::parallel_pipeline(12, generator & spiral_mode & cooling & fan_mover & output);
|
||||
else if (m_pressure_equalizer)
|
||||
tbb::parallel_pipeline(12, source & generator & pressure_equalizer & cooling & fan_mover & pa_processor_filter & output);
|
||||
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & fan_mover & pa_processor_filter & output);
|
||||
else
|
||||
tbb::parallel_pipeline(12, source & generator & cooling & fan_mover & pa_processor_filter & output);
|
||||
// The estimator's precomputed data points into this print's layers.
|
||||
m_extrusion_quality_estimator.set_precomputed_layers({});
|
||||
tbb::parallel_pipeline(12, generator & cooling & fan_mover & pa_processor_filter & output);
|
||||
}
|
||||
|
||||
std::string GCode::placeholder_parser_process(const std::string &name, const std::string &templ, unsigned int current_filament_id, const DynamicConfig *config_override)
|
||||
@@ -6021,13 +5969,25 @@ LayerResult GCode::process_layer(
|
||||
return next_extruder;
|
||||
};
|
||||
|
||||
const bool overhang_fan = overhang_fan_enabled(m_config, m_enable_cooling_markers);
|
||||
auto overhang_speed = [this](const LayerRegion ®ion) {
|
||||
return bool(region.region().config().enable_overhang_speed.get_at(get_nozzle_config_index(m_writer.filament()->id())));
|
||||
};
|
||||
for (const auto &layer_to_print : layers)
|
||||
if (layer_to_print.object_layer && prepares_overhang_estimator(*layer_to_print.object_layer, overhang_fan, overhang_speed))
|
||||
m_extrusion_quality_estimator.prepare_for_new_layer(layer_to_print.original_object, layer_to_print.object_layer);
|
||||
for (const auto &layer_to_print : layers) {
|
||||
if (layer_to_print.object_layer) {
|
||||
const auto& regions = layer_to_print.object_layer->regions();
|
||||
const bool has_extrusions = std::any_of(regions.begin(), regions.end(), [](const LayerRegion* r) {
|
||||
return r->has_extrusions();
|
||||
});
|
||||
const bool enable_overhang_speed = std::any_of(regions.begin(), regions.end(), [this](const LayerRegion* r) {
|
||||
return r->has_extrusions() && r->region().config().enable_overhang_speed.get_at(get_nozzle_config_index(m_writer.filament()->id()));
|
||||
});
|
||||
const bool enable_overhang_fan = m_enable_cooling_markers && has_extrusions &&
|
||||
std::any_of(m_config.enable_overhang_bridge_fan.values.begin(),
|
||||
m_config.enable_overhang_bridge_fan.values.end(),
|
||||
[](unsigned char value) { return value != 0; });
|
||||
if (enable_overhang_speed || enable_overhang_fan) {
|
||||
m_extrusion_quality_estimator.prepare_for_new_layer(layer_to_print.original_object,
|
||||
layer_to_print.object_layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Group extrusions by an extruder, then by an object, an island and a region.
|
||||
std::map<unsigned int, std::vector<ObjectByExtruder>> by_extruder;
|
||||
|
||||
@@ -4,10 +4,8 @@
|
||||
#include "ExtrusionEntity.hpp"
|
||||
#include "Polygon.hpp"
|
||||
#include "Config.hpp"
|
||||
#include "ExtrusionEntityCollection.hpp"
|
||||
#include "Print.hpp"
|
||||
#include "libslic3r.h"
|
||||
#include "ExPolygon.hpp"
|
||||
#include "GCodeWriter.hpp"
|
||||
#include "Layer.hpp"
|
||||
#include "Point.hpp"
|
||||
@@ -22,7 +20,6 @@
|
||||
#include "GCode/WipeTower.hpp"
|
||||
#include "GCode/SeamPlacer.hpp"
|
||||
#include "GCode/GCodeProcessor.hpp"
|
||||
#include "EdgeGrid.hpp"
|
||||
#include "GCode/ThumbnailData.hpp"
|
||||
#include "libslic3r/ObjectID.hpp"
|
||||
#include "GCode/ExtrusionProcessor.hpp"
|
||||
@@ -47,6 +44,10 @@
|
||||
#include <cfloat>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "BoundingBox.hpp"
|
||||
#include "Polyline.hpp"
|
||||
|
||||
namespace Slic3r { class ExtrusionEntityCollection; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -864,10 +865,6 @@ private:
|
||||
|
||||
std::vector<const PrintInstance*> sort_object_instances_by_model_order(const Print& print, bool init_order = false);
|
||||
|
||||
// The overhang data ExtrusionQualityEstimator needs for the object layers in `layers`, computed ahead of the generator;
|
||||
// `overhang_fan` says whether the overhang fan can switch on for any filament.
|
||||
std::vector<PrecomputedOverhangLayer> precompute_overhang_layers(const std::vector<GCode::LayerToPrint> &layers, bool overhang_fan);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include <cmath>
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include "libslic3r/GCode/AdaptivePAProcessor.hpp"
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/GCodeWriter.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -41,9 +45,6 @@ AdaptivePAProcessor::AdaptivePAProcessor(GCode &gcodegen)
|
||||
m_pa_change_pattern(R"(; PA_CHANGE:T(\d+) MM3MM:([0-9]*\.[0-9]+) ACCEL:(\d+) BR:(\d+) RC:(\d+) OV:(\d+))"),
|
||||
m_g1_f_pattern(R"(G1 F([0-9]+))")
|
||||
{
|
||||
const size_t indices = std::max(m_config.adaptive_pressure_advance.size(), m_config.enable_pressure_advance.size());
|
||||
for (size_t i = 0; i < indices && !m_enabled; ++i)
|
||||
m_enabled = m_config.adaptive_pressure_advance.get_at(i) && m_config.enable_pressure_advance.get_at(i);
|
||||
}
|
||||
|
||||
// Method to get the interpolator for a specific filament config index.
|
||||
@@ -69,12 +70,6 @@ AdaptivePAInterpolator* AdaptivePAProcessor::getInterpolator(unsigned int config
|
||||
* @return A string containing the processed G-code with adaptive pressure advance applied.
|
||||
*/
|
||||
std::string AdaptivePAProcessor::process_layer(std::string &&gcode) {
|
||||
// Without PA_CHANGE tags the loop below would only terminate the layer's last line.
|
||||
if (!m_enabled && gcode.find("; PA_CHANGE") == std::string::npos) {
|
||||
if (!gcode.empty() && gcode.back() != '\n')
|
||||
gcode += '\n';
|
||||
return std::move(gcode);
|
||||
}
|
||||
std::istringstream stream(gcode);
|
||||
std::string line;
|
||||
std::ostringstream output;
|
||||
|
||||
@@ -78,7 +78,6 @@ private:
|
||||
double m_next_feedrate; ///< First feed rate (speed) for the upcomming island.
|
||||
double m_current_feedrate; ///< Current, latest feedrate.
|
||||
int m_last_config_index; ///< Filament config index of the last PA_CHANGE tag.
|
||||
bool m_enabled{false}; ///< Whether any filament config index has both PA and adaptive PA on, the only ones that emit PA_CHANGE tags.
|
||||
|
||||
std::regex m_pa_change_pattern; ///< Regular expression to detect PA_CHANGE pattern.
|
||||
std::regex m_g1_f_pattern; ///< Regular expression to detect G1 F pattern.
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "../ExPolygon.hpp"
|
||||
#include "../Geometry.hpp"
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../SVG.hpp"
|
||||
#include "libslic3r/Line.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Point.hpp"
|
||||
@@ -31,6 +30,11 @@
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "libslic3r/GCode/AvoidCrossingPerimeters.hpp"
|
||||
#include "libslic3r/Extruder.hpp"
|
||||
#include "libslic3r/GCodeWriter.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "libslic3r/SurfaceCollection.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#ifndef slic3r_AvoidCrossingPerimeters_hpp_
|
||||
#define slic3r_AvoidCrossingPerimeters_hpp_
|
||||
|
||||
#include "../libslic3r.h"
|
||||
#include "../ExPolygon.hpp"
|
||||
#include "../EdgeGrid.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include <vector>
|
||||
#include "libslic3r/MultiMaterialSegmentation.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <atomic>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "libslic3r/Model.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
#ifndef slic3r_ConflictChecker_hpp_
|
||||
#define slic3r_ConflictChecker_hpp_
|
||||
|
||||
#include "../Utils.hpp"
|
||||
#include "../Model.hpp"
|
||||
#include "../Print.hpp"
|
||||
#include "../Layer.hpp"
|
||||
#include "libslic3r/Line.hpp"
|
||||
#include "libslic3r/ExtrusionEntity.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Polyline.hpp"
|
||||
#include "libslic3r/ExtrusionEntityCollection.hpp"
|
||||
#include "libslic3r/GCode/GCodeProcessor.hpp"
|
||||
|
||||
#include <queue>
|
||||
@@ -20,6 +17,8 @@
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
namespace Slic3r { class ExtrusionEntityCollection; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
struct LineWithID
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "../GCode.hpp"
|
||||
#include "../LocalesUtils.hpp"
|
||||
#include "libslic3r/Extruder.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
@@ -30,6 +29,10 @@
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include "libslic3r/GCode/CoolingBuffer.hpp"
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/GCodeWriter.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -409,13 +412,13 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
||||
if (*c == 0 || *c == ';')
|
||||
break;
|
||||
|
||||
assert(is_decimal_separator_point()); // for atof
|
||||
//BBS: Parse the axis.
|
||||
size_t axis = (*c >= 'X' && *c <= 'Z') ? (*c - 'X') :
|
||||
(*c == 'E') ? 3 : (*c == 'F') ? 4 :
|
||||
(*c == 'I') ? 5 : (*c == 'J') ? 6 : size_t(-1);
|
||||
if (axis != size_t(-1)) {
|
||||
++ c;
|
||||
new_pos[axis] = float(atof_decimal_point(std::string_view(c, sline.data() + sline.size() - c)));
|
||||
new_pos[axis] = float(atof(++c));
|
||||
if (axis == 4) {
|
||||
// Convert mm/min to mm/sec.
|
||||
new_pos[4] /= 60.f;
|
||||
@@ -551,9 +554,10 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
||||
line.type = CoolingLine::TYPE_G4;
|
||||
size_t pos_S = sline.find('S', 3);
|
||||
size_t pos_P = sline.find('P', 3);
|
||||
assert(is_decimal_separator_point()); // for atof
|
||||
line.time = line.time_max = float(
|
||||
(pos_S > 0) ? atof_decimal_point(sline.c_str() + pos_S + 1) :
|
||||
(pos_P > 0) ? atof_decimal_point(sline.c_str() + pos_P + 1) * 0.001 : 0.);
|
||||
(pos_S > 0) ? atof(sline.c_str() + pos_S + 1) :
|
||||
(pos_P > 0) ? atof(sline.c_str() + pos_P + 1) * 0.001 : 0.);
|
||||
} else if (boost::starts_with(sline, ";_FORCE_RESUME_FAN_SPEED")) {
|
||||
line.type = CoolingLine::TYPE_FORCE_RESUME_FAN;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef slic3r_CoolingBuffer_hpp_
|
||||
#define slic3r_CoolingBuffer_hpp_
|
||||
|
||||
#include "../libslic3r.h"
|
||||
#include "../Point.hpp"
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
@@ -39,14 +38,7 @@ template<int Dim> struct ExtendedPoint
|
||||
float curvature;
|
||||
};
|
||||
|
||||
// A KNOWN_DISTANCES functor that knows no distances, so every input point is queried.
|
||||
struct NoKnownDistances
|
||||
{
|
||||
template<typename P> const double *operator()(const P &) const { return nullptr; }
|
||||
};
|
||||
|
||||
template<bool SCALED_INPUT, bool ADD_INTERSECTIONS, bool PREV_LAYER_BOUNDARY_OFFSET, bool SIGNED_DISTANCE, bool CURVATURE = true,
|
||||
typename POINTS, typename L, typename KNOWN_DISTANCES = NoKnownDistances>
|
||||
template<bool SCALED_INPUT, bool ADD_INTERSECTIONS, bool PREV_LAYER_BOUNDARY_OFFSET, bool SIGNED_DISTANCE, typename POINTS, typename L>
|
||||
std::vector<ExtendedPoint<L::Dim>> estimate_points_properties(const POINTS& input_points,
|
||||
const AABBTreeLines::LinesDistancer<L>& unscaled_prev_layer,
|
||||
float flow_width,
|
||||
@@ -57,9 +49,7 @@ std::vector<ExtendedPoint<L::Dim>> estimate_points_properties(const POINTS&
|
||||
const std::function<float(float)>& distance_to_speed = {},
|
||||
// Overlap (1 - distance / flow_width) at or below which the overhang
|
||||
// fan switches on; negative when the fan does not depend on overlap.
|
||||
float fan_overlap_threshold = -1.0f,
|
||||
// Returns an input point's signed distance if already known, else nullptr.
|
||||
const KNOWN_DISTANCES& known_distance = KNOWN_DISTANCES{})
|
||||
float fan_overlap_threshold = -1.0f)
|
||||
{
|
||||
bool looped = input_points.front() == input_points.back();
|
||||
std::function<size_t(size_t,size_t)> get_prev_index = [](size_t idx, size_t count) {
|
||||
@@ -104,26 +94,21 @@ std::vector<ExtendedPoint<L::Dim>> estimate_points_properties(const POINTS&
|
||||
float boundary_offset = PREV_LAYER_BOUNDARY_OFFSET ? 0.5 * flow_width : 0.0f;
|
||||
auto maybe_unscale = [](const P& p) -> Vec { return SCALED_INPUT ? unscaled(p) : p.template cast<double>(); };
|
||||
|
||||
using Distance = typename AABBTreeLines::LinesDistancer<L>::Floating;
|
||||
auto input_distance = [&unscaled_prev_layer, &known_distance](const P &input, const Vec &position) -> Distance {
|
||||
if (const double *known = known_distance(input))
|
||||
return Distance(*known);
|
||||
auto [distance, nearest_line, x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(
|
||||
position.template cast<AABBScalar>());
|
||||
return distance;
|
||||
};
|
||||
|
||||
std::vector<ExtendedPoint<L::Dim>> points;
|
||||
points.reserve(input_points.size() * (ADD_INTERSECTIONS ? 1.5 : 1));
|
||||
|
||||
{
|
||||
ExtendedPoint<L::Dim> start_point{maybe_unscale(input_points.front())};
|
||||
start_point.distance = input_distance(input_points.front(), start_point.position) + boundary_offset;
|
||||
auto [distance, nearest_line, x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(
|
||||
start_point.position.template cast<AABBScalar>());
|
||||
start_point.distance = distance + boundary_offset;
|
||||
points.push_back(start_point);
|
||||
}
|
||||
for (size_t i = 1; i < input_points.size(); i++) {
|
||||
ExtendedPoint<L::Dim> next_point{maybe_unscale(input_points[i])};
|
||||
next_point.distance = input_distance(input_points[i], next_point.position) + boundary_offset;
|
||||
auto [distance, nearest_line,
|
||||
x] = unscaled_prev_layer.template distance_from_lines_extra<SIGNED_DISTANCE>(next_point.position.template cast<AABBScalar>());
|
||||
next_point.distance = distance + boundary_offset;
|
||||
|
||||
// Intersection handling
|
||||
if (ADD_INTERSECTIONS &&
|
||||
@@ -364,9 +349,6 @@ std::vector<ExtendedPoint<L::Dim>> estimate_points_properties(const POINTS&
|
||||
points = std::move(new_points);
|
||||
}
|
||||
|
||||
if constexpr (!CURVATURE)
|
||||
return points;
|
||||
|
||||
// Curvature calculation
|
||||
float accumulated_distance = 0;
|
||||
std::vector<float> distances_for_curvature(points.size());
|
||||
@@ -435,49 +417,6 @@ std::vector<ExtendedPoint<L::Dim>> estimate_points_properties(const POINTS&
|
||||
return points;
|
||||
}
|
||||
|
||||
struct Point3Hash
|
||||
{
|
||||
size_t operator()(const Vec3crd &pt) const noexcept { return size_t(((89 * 31 + int64_t(pt.x())) * 31 + pt.y()) * 31 + pt.z()); }
|
||||
};
|
||||
|
||||
// The trees of the layer below an object layer, and the signed distances from the layer's perimeter and bridge
|
||||
// vertices to that layer's outline, computed for ExtrusionQualityEstimator ahead of the G-code generator.
|
||||
struct PrecomputedOverhangLayer
|
||||
{
|
||||
const PrintObject *object{nullptr};
|
||||
const Layer *layer{nullptr};
|
||||
std::shared_ptr<const AABBTreeLines::LinesDistancer<Linef3>> lower_boundaries;
|
||||
std::shared_ptr<const AABBTreeLines::LinesDistancer<CurledLine>> lower_curled_lines;
|
||||
std::unordered_map<Point3, double, Point3Hash> distances;
|
||||
};
|
||||
|
||||
// `layer` must have a layer below it; leave out `curled_lines` only when no region of `layer` slows down for curled
|
||||
// perimeters.
|
||||
inline PrecomputedOverhangLayer precompute_overhang_layer(const PrintObject *object, const Layer &layer, bool curled_lines = true)
|
||||
{
|
||||
PrecomputedOverhangLayer out{object, &layer,
|
||||
std::make_shared<const AABBTreeLines::LinesDistancer<Linef3>>(to_unscaled_linesf3(layer.lower_layer->lslices)),
|
||||
curled_lines ? std::make_shared<const AABBTreeLines::LinesDistancer<CurledLine>>(layer.lower_layer->curled_lines) :
|
||||
nullptr,
|
||||
{}};
|
||||
const AABBTreeLines::LinesDistancer<Linef3> &lower = *out.lower_boundaries;
|
||||
auto add_path = [&out, &lower](const ExtrusionPath &path) {
|
||||
if (!is_bridge(path.role()) && !is_perimeter(path.role()))
|
||||
return;
|
||||
for (const Point3 &point : path.polyline.points)
|
||||
if (auto [it, inserted] = out.distances.try_emplace(point, 0.); inserted) {
|
||||
const Eigen::Matrix<double, 3, 1, Eigen::DontAlign> position = unscaled(point);
|
||||
auto [distance, nearest_line, x] = lower.distance_from_lines_extra<true>(position.cast<double>());
|
||||
it->second = distance;
|
||||
}
|
||||
};
|
||||
for (const LayerRegion *region : layer.regions()) {
|
||||
for_each_extrusion_path(region->perimeters, add_path);
|
||||
for_each_extrusion_path(region->fills, add_path);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct ProcessedPoint
|
||||
{
|
||||
Point3 p;
|
||||
@@ -487,53 +426,23 @@ struct ProcessedPoint
|
||||
|
||||
class ExtrusionQualityEstimator
|
||||
{
|
||||
using Boundaries = AABBTreeLines::LinesDistancer<Linef3>;
|
||||
using CurledLines = AABBTreeLines::LinesDistancer<CurledLine>;
|
||||
std::unordered_map<const PrintObject*, std::shared_ptr<const Boundaries>> prev_layer_boundaries;
|
||||
std::unordered_map<const PrintObject*, std::shared_ptr<const CurledLines>> prev_curled_extrusions;
|
||||
// The layers the trees above are built from, and the layers prepared last.
|
||||
std::unordered_map<const PrintObject*, const Layer*> prev_layer_sources;
|
||||
std::unordered_map<const PrintObject*, const Layer*> last_prepared_layers;
|
||||
std::vector<PrecomputedOverhangLayer> precomputed_layers;
|
||||
const PrintObject *current_object;
|
||||
|
||||
const PrecomputedOverhangLayer *precomputed_for(const PrintObject *object) const
|
||||
{
|
||||
auto it = std::find_if(precomputed_layers.begin(), precomputed_layers.end(),
|
||||
[object](const PrecomputedOverhangLayer &layer) { return layer.object == object; });
|
||||
return it == precomputed_layers.end() ? nullptr : &*it;
|
||||
}
|
||||
|
||||
template<typename T> static const T &or_empty(const std::shared_ptr<const T> &tree)
|
||||
{
|
||||
static const T empty;
|
||||
return tree ? *tree : empty;
|
||||
}
|
||||
std::unordered_map<const PrintObject*, AABBTreeLines::LinesDistancer<Linef3>> prev_layer_boundaries;
|
||||
std::unordered_map<const PrintObject*, AABBTreeLines::LinesDistancer<Linef3>> next_layer_boundaries;
|
||||
std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<CurledLine>> prev_curled_extrusions;
|
||||
std::unordered_map<const PrintObject *, AABBTreeLines::LinesDistancer<CurledLine>> next_curled_extrusions;
|
||||
const PrintObject *current_object;
|
||||
|
||||
public:
|
||||
void set_current_object(const PrintObject *object) { current_object = object; }
|
||||
|
||||
// Takes the data computed ahead for the layer about to be generated, replacing the previous layer's.
|
||||
void set_precomputed_layers(std::vector<PrecomputedOverhangLayer> &&layers) { precomputed_layers = std::move(layers); }
|
||||
|
||||
// Measures the layer against the layer prepared before it.
|
||||
void prepare_for_new_layer(const PrintObject * obj, const Layer *layer)
|
||||
{
|
||||
if (layer == nullptr) return;
|
||||
const PrintObject *object = obj;
|
||||
const Layer *prev = std::exchange(last_prepared_layers[object], layer);
|
||||
prev_layer_sources[object] = prev;
|
||||
const PrecomputedOverhangLayer *precomputed = precomputed_for(object);
|
||||
if (prev == nullptr) {
|
||||
prev_layer_boundaries[object] = nullptr;
|
||||
prev_curled_extrusions[object] = nullptr;
|
||||
} else if (precomputed != nullptr && precomputed->layer == layer && layer->lower_layer == prev) {
|
||||
prev_layer_boundaries[object] = precomputed->lower_boundaries;
|
||||
prev_curled_extrusions[object] = precomputed->lower_curled_lines;
|
||||
} else {
|
||||
prev_layer_boundaries[object] = std::make_shared<const Boundaries>(to_unscaled_linesf3(prev->lslices));
|
||||
prev_curled_extrusions[object] = std::make_shared<const CurledLines>(prev->curled_lines);
|
||||
}
|
||||
prev_layer_boundaries[object] = next_layer_boundaries[object];
|
||||
next_layer_boundaries[object] = AABBTreeLines::LinesDistancer<Linef3>{to_unscaled_linesf3(layer->lslices)};
|
||||
prev_curled_extrusions[object] = next_curled_extrusions[object];
|
||||
next_curled_extrusions[object] = AABBTreeLines::LinesDistancer<CurledLine>{layer->curled_lines};
|
||||
}
|
||||
|
||||
std::vector<ProcessedPoint> estimate_extrusion_quality(const ExtrusionPath &path,
|
||||
@@ -617,24 +526,9 @@ public:
|
||||
return std::min(calculate_speed(distance), original_speed);
|
||||
};
|
||||
|
||||
// Precomputed distances hold only if they were measured against the layer prev_layer_boundaries is built from.
|
||||
const std::unordered_map<Point3, double, Point3Hash> *known = nullptr;
|
||||
if (const PrecomputedOverhangLayer *precomputed = precomputed_for(current_object);
|
||||
precomputed != nullptr && precomputed->layer->lower_layer == prev_layer_sources[current_object])
|
||||
known = &precomputed->distances;
|
||||
const Boundaries &prev_boundaries = or_empty(prev_layer_boundaries[current_object]);
|
||||
const CurledLines &prev_curled = or_empty(prev_curled_extrusions[current_object]);
|
||||
auto known_distance = [known](const Point3 &point) -> const double * {
|
||||
if (known == nullptr)
|
||||
return nullptr;
|
||||
auto it = known->find(point);
|
||||
return it == known->end() ? nullptr : &it->second;
|
||||
};
|
||||
|
||||
std::vector<ExtendedPoint<3>> extended_points =
|
||||
estimate_points_properties<true, true, true, true, false>(path.polyline.points, prev_boundaries, path.width, -1,
|
||||
smallest_distance_with_lower_speed, effective_speed, fan_overlap_threshold,
|
||||
known_distance);
|
||||
estimate_points_properties<true, true, true, true>(path.polyline.points, prev_layer_boundaries[current_object], path.width, -1,
|
||||
smallest_distance_with_lower_speed, effective_speed, fan_overlap_threshold);
|
||||
const auto width_inv = 1.0f / path.width;
|
||||
std::vector<ProcessedPoint> processed_points;
|
||||
processed_points.reserve(extended_points.size());
|
||||
@@ -648,7 +542,7 @@ public:
|
||||
const double dist_limit = 10.0 * path.width;
|
||||
{
|
||||
Vec3d middle = 0.5 * (curr.position + next.position);
|
||||
auto line_indices = prev_curled.all_lines_in_radius(Point::new_scale(middle),
|
||||
auto line_indices = prev_curled_extrusions[current_object].all_lines_in_radius(Point::new_scale(middle),
|
||||
scale_(dist_limit));
|
||||
if (!line_indices.empty()) {
|
||||
double len = (next.position - curr.position).norm();
|
||||
@@ -669,7 +563,7 @@ public:
|
||||
|
||||
double projected_lengths_sum = 0;
|
||||
for (size_t idx : line_indices) {
|
||||
const CurledLine& line = prev_curled.get_line(idx);
|
||||
const CurledLine& line = prev_curled_extrusions[current_object].get_line(idx);
|
||||
Lines inside = intersection_ln({{line.a, line.b}}, {box_of_influence});
|
||||
if (inside.empty())
|
||||
continue;
|
||||
@@ -682,7 +576,7 @@ public:
|
||||
}
|
||||
|
||||
for (size_t idx : line_indices) {
|
||||
const CurledLine &line = prev_curled.get_line(idx);
|
||||
const CurledLine &line = prev_curled_extrusions[current_object].get_line(idx);
|
||||
float distance_from_curled = unscaled(line_alg::distance_to(line, Point::new_scale(middle)));
|
||||
float dist = path.width * (1.0 - (distance_from_curled / dist_limit)) *
|
||||
(1.0 - (distance_from_curled / dist_limit)) *
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/GCodeWriter.hpp"
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -2,11 +2,8 @@
|
||||
#define slic3r_GCode_FanMover_hpp_
|
||||
|
||||
|
||||
#include "../libslic3r.h"
|
||||
#include "../PrintConfig.hpp"
|
||||
#include "../ExtrusionEntity.hpp"
|
||||
|
||||
#include "../Point.hpp"
|
||||
#include "../GCodeReader.hpp"
|
||||
#include "../GCodeWriter.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user