OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
OrcaSlicer.cpp File Reference
#include <map>
#include <vector>
#include "libslic3r/PrintBase.hpp"
#include <boost/date_time/posix_time/posix_time_duration.hpp>
#include <cerrno>
#include <utility>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
#include "libslic3r/LocalesUtils.hpp"
#include <fstream>
#include <exception>
#include <set>
#include "libslic3r/Color.hpp"
#include "libslic3r/TriangleSelector.hpp"
#include <algorithm>
#include "libslic3r/Format/bbs_3mf.hpp"
#include "libslic3r/Format/AssembleList.hpp"
#include <cstdlib>
#include <stdlib.h>
#include <stdexcept>
#include "libslic3r/Point.hpp"
#include "libslic3r_version.h"
#include "libslic3r/Semver.hpp"
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/BoundingBox.hpp"
#include "libslic3r/CustomGCode.hpp"
#include <memory>
#include <sstream>
#include <iomanip>
#include <iterator>
#include "libslic3r/ClipperUtils.hpp"
#include "libslic3r/GCode/WipeTowerEstimate.hpp"
#include "slic3r/GUI/Gizmos/GLGizmoBase.hpp"
#include <functional>
#include "libslic3r/Arrange.hpp"
#include "libslic3r/Polygon.hpp"
#include "libslic3r/GCode/ThumbnailData.hpp"
#include "slic3r/GUI/3DScene.hpp"
#include "slic3r/GUI/GLShader.hpp"
#include <cassert>
#include <boost/filesystem/exception.hpp>
#include <signal.h>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <math.h>
#include <csignal>
#include <atomic>
#include <new>
#include <optional>
#include "nlohmann/json.hpp"
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp>
#include <boost/nowide/args.hpp>
#include <boost/nowide/cstdlib.hpp>
#include <boost/nowide/iostream.hpp>
#include <boost/nowide/fstream.hpp>
#include <boost/nowide/filesystem.hpp>
#include <boost/dll/runtime_symbol_info.hpp>
#include <boost/log/trivial.hpp>
#include "unix/fhs.hpp"
#include "libslic3r/libslic3r.h"
#include "libslic3r/Config.hpp"
#include "libslic3r/FilamentMixer.hpp"
#include "libslic3r/Preset.hpp"
#include "libslic3r/Geometry.hpp"
#include "libslic3r/GCode.hpp"
#include "libslic3r/MeshRepair.hpp"
#include "libslic3r/Model.hpp"
#include "libslic3r/ModelArrange.hpp"
#include "libslic3r/Platform.hpp"
#include "libslic3r/Print.hpp"
#include "libslic3r/SLAPrint.hpp"
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/Format/AMF.hpp"
#include "libslic3r/Format/3mf.hpp"
#include "libslic3r/Format/STL.hpp"
#include "libslic3r/Format/OBJ.hpp"
#include "libslic3r/Format/SL1.hpp"
#include "libslic3r/Utils.hpp"
#include "libslic3r/Time.hpp"
#include "libslic3r/Thread.hpp"
#include "libslic3r/BlacklistedLibraryCheck.hpp"
#include "libslic3r/FlushVolCalc.hpp"
#include "libslic3r/LayOnFace.hpp"
#include "libslic3r/Orient.hpp"
#include "libslic3r/PNGReadWrite.hpp"
#include "libslic3r/ObjColorUtils.hpp"
#include "OrcaSlicer.hpp"
#include <wx/filename.h>
#include <wx/stdpaths.h>
#include "slic3r/Utils/MeshInspect.hpp"
#include "slic3r/Utils/PaintCLI.hpp"
#include "slic3r/GUI/PartPlate.hpp"
#include "slic3r/GUI/BitmapCache.hpp"
#include "slic3r/GUI/OpenGLManager.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/Camera.hpp"
#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/GCodeStatistics.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"
#include <boost/nowide/convert.hpp>
#include <stdio.h>

Go to the source code of this file.

Classes

struct  _sliced_plate_info
struct  _sliced_info

Macros

#define MAX_CLONEABLE_SIZE   512
#define flush_and_exit(ret)
#define DIR_SEPARATOR   '/'

Typedefs

typedef struct _sliced_plate_info sliced_plate_info_t
typedef struct _sliced_info sliced_info_t

Functions

static Pointfs legacy_bed_exclude_area_points (const DynamicPrintConfig &config)
void default_status_callback (const PrintBase::SlicingStatus &slicing_status)
static PrinterTechnology get_printer_technology (const DynamicConfig &config)
static void cli_record_warning (sliced_info_t &sliced_info, const std::string &cls, nlohmann::json details=nlohmann::json::object())
void record_exit_reson (std::string outputdir, int code, int plate_id, std::string error_message, sliced_info_t &sliced_info, std::map< std::string, std::string > key_values=std::map< std::string, std::string >())
static int decode_png_to_thumbnail (std::string png_file, ThumbnailData &thumbnail_data)
static void glfw_callback (int error_code, const char *description)
static int load_key_values_from_json (const std::string &file, std::map< std::string, std::string > &key_values)
static void load_default_gcodes_to_config (DynamicPrintConfig &config, Preset::Type type)
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)
bool convert_obj_cluster_colors (std::vector< Slic3r::RGBA > &input_colors, std::vector< RGBA > &all_colours, int max_filament_count, std::vector< unsigned char > &output_filament_ids)
static int construct_assemble_list (std::vector< assemble_plate_info_t > &assemble_plate_info_list, Model &model, PlateDataPtrs &plate_list, std::vector< RGBA > &all_colours)
static void load_downward_settings_list_from_config (std::string config_file, std::string printer_name, std::string printer_model, std::vector< std::string > &downward_settings)
void attach_console_on_demand ()
int main (int argc, char **argv)

Variables

std::map< int, std::string > cli_errors
std::vector< PrintBase::SlicingStatus > g_slicing_warnings
const float bed3d_ax3s_default_stem_radius = 0.5f
const float bed3d_ax3s_default_stem_length = 25.0f
const float bed3d_ax3s_default_tip_radius = 2.5f * bed3d_ax3s_default_stem_radius
const float bed3d_ax3s_default_tip_length = 5.0f
static std::set< std::string > gcodes_key_set

Class Documentation

◆ _sliced_plate_info

struct _sliced_plate_info
Collaboration diagram for _sliced_plate_info:
Class Members
int plate_id {0}
size_t sliced_time {0}
size_t sliced_time_with_cache {0}
size_t triangle_count {0}
string warning_message

◆ _sliced_info

struct _sliced_info
Collaboration diagram for _sliced_info:
Class Members
vector< string > downward_machines
size_t export_time
float layer_height {0.f}
int plate_count {0}
int plate_to_slice {0}
size_t prepare_time
vector< sliced_plate_info_t > sliced_plates
float sparse_infill_density {0.f}
bool strict_mode {false}
vector< string > upward_machines
int wall_loops {0}
json warnings = nlohmann::json::array()

Macro Definition Documentation

◆ DIR_SEPARATOR

#define DIR_SEPARATOR   '/'

◆ flush_and_exit

#define flush_and_exit ( ret)
Value:
{ boost::nowide::cout << __FUNCTION__ << " found error, exit" << std::endl;\
boost::nowide::cout.flush();\
boost::nowide::cerr.flush();\
for (Model &model : m_models) {\
model.remove_backup_path_if_exist();\
}\
return(ret);}
Definition Model.hpp:1696
494#define flush_and_exit(ret) { boost::nowide::cout << __FUNCTION__ << " found error, exit" << std::endl;\
495 boost::nowide::cout.flush();\
496 boost::nowide::cerr.flush();\
497 for (Model &model : m_models) {\
498 model.remove_backup_path_if_exist();\
499 }\
500 return(ret);}

Referenced by Slic3r::CLI::run().

◆ MAX_CLONEABLE_SIZE

#define MAX_CLONEABLE_SIZE   512

Referenced by Slic3r::CLI::run().

Typedef Documentation

◆ sliced_info_t

typedef struct _sliced_info sliced_info_t

◆ sliced_plate_info_t

Function Documentation

◆ attach_console_on_demand()

void attach_console_on_demand ( )
8206 {
8207#ifdef _WIN32
8208 static bool console_attached = false;
8209
8210 if (!console_attached) {
8211 // Try attaching to the parent console first
8212 if (AttachConsole(ATTACH_PARENT_PROCESS)) {
8213 console_attached = true;
8214 } else if (GetLastError() == ERROR_ACCESS_DENIED) {
8215 // Already has a console (maybe attached by debugger)
8216 console_attached = true;
8217 } else {
8218 // No parent console found, try allocating a new one
8219 if (AllocConsole()) {
8220 console_attached = true;
8221 }
8222 }
8223
8224 if (console_attached) {
8225 FILE* fp = nullptr;
8226 // Redirect standard C streams to the console
8227 if (freopen_s(&fp, "CONOUT$", "w", stdout) == 0) {
8228 setvbuf(stdout, NULL, _IONBF, 0); // Optional: Disable buffering
8229 }
8230 if (freopen_s(&fp, "CONOUT$", "w", stderr) == 0) {
8231 setvbuf(stderr, NULL, _IONBF, 0); // Optional: Disable buffering
8232 }
8233 if (freopen_s(&fp, "CONIN$", "r", stdin) == 0) {
8234 // Input redirection successful
8235 }
8236 // Sync C++ streams with C streams after redirection
8237 std::ios::sync_with_stdio(true);
8238 // Clear potential error states from C++ streams
8239 std::cout.clear();
8240 std::cerr.clear();
8241 std::cin.clear();
8242 boost::nowide::cout.clear();
8243 boost::nowide::cerr.clear();
8244 boost::nowide::cin.clear();
8245 }
8246 }
8247#endif
8248}

Referenced by Slic3r::CLI::print_help().

Here is the caller graph for this function:

◆ cli_record_warning()

void cli_record_warning ( sliced_info_t & sliced_info,
const std::string & cls,
nlohmann::json details = nlohmann::json::object() )
static
513{
514 details["class"] = cls;
515 sliced_info.warnings.push_back(std::move(details));
516}
nlohmann::json warnings
Definition OrcaSlicer.cpp:266

References _sliced_info::warnings.

Referenced by Slic3r::CLI::run().

Here is the caller graph for this function:

◆ construct_assemble_list()

int construct_assemble_list ( std::vector< assemble_plate_info_t > & assemble_plate_info_list,
Model & model,
PlateDataPtrs & plate_list,
std::vector< RGBA > & all_colours )
static
806{
807 int ret = 0;
808 int plate_count = assemble_plate_info_list.size();
809 ConfigSubstitutionContext config_substitutions(ForwardCompatibilitySubstitutionRule::Enable);
810 Model temp_model;
811 const int max_filament_count = size_t(EnforcerBlockerType::ExtruderMax);
812
813 plate_list.resize(plate_count);
814 for (int index = 0; index < plate_count; index++)
815 {
816 //each plate has its dependent assemble list
817 std::map<int, ModelObject*> merged_objects;
818 std::set<int> used_filaments;
819 //std::map<ModelObject*, int> to_merge_objects;
820
821 assemble_plate_info_t& assemble_plate_info = assemble_plate_info_list[index];
822
823 int object_count = assemble_plate_info.assemble_obj_list.size();
824
825 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": Plate %1%, name %2%, obj count %3%, plate params count %4%") % (index + 1) %assemble_plate_info.plate_name %object_count %assemble_plate_info.plate_params.size();
826 PlateData* plate_data = new PlateData();
827 plate_list[index] = plate_data;
828 plate_data->plate_name = assemble_plate_info.plate_name;
829 plate_data->plate_index = index;
830
831 if (!assemble_plate_info.plate_params.empty())
832 {
833 for (auto plate_iter = assemble_plate_info.plate_params.begin(); plate_iter != assemble_plate_info.plate_params.end(); plate_iter++)
834 {
835 plate_data->config.set_deserialize(plate_iter->first, plate_iter->second, config_substitutions);
836 BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": Plate %1%, key %2%, value %3%") % (index + 1) % plate_iter->first % plate_iter->second;
837 }
838 }
839
840 //construct the object list
841 for (size_t obj_index = 0; obj_index < object_count; obj_index++)
842 {
843 assemble_object_info_t& assemble_object = assemble_plate_info.assemble_obj_list[obj_index];
844 std::string object_name;
845 std::string object_1_name;
846 ModelObject* object = nullptr;
847 TriangleMesh mesh;
848 bool skip_filament = false;
849
850 boost::filesystem::path object_path(assemble_object.path);
851 if (!fs::exists(object_path)) {
852 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": directory %1% not exist in plate %2%") % assemble_object.path % (index + 1);
853 return CLI_FILE_NOTFOUND;
854 }
855
856 const char* path_str = assemble_object.path.c_str();
857 const char* last_slash = strrchr(path_str, DIR_SEPARATOR);
858 object_name.assign((last_slash == nullptr) ? path_str : last_slash + 1);
859
860 if (boost::algorithm::iends_with(assemble_object.path, ".stl"))
861 {
862 if (!mesh.ReadSTLFile(path_str, true, nullptr)) {
863 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": failed to read stl file from %1%, plate index %2%, object index %3%") % assemble_object.path % (index+1) % (obj_index+1);
864 return CLI_DATA_FILE_ERROR;
865 }
866 if (mesh.empty()) {
867 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": found no mesh data from stl file %1%, plate index %2%, object index %3%") % assemble_object.path % (index + 1) % (obj_index + 1);
868 return CLI_DATA_FILE_ERROR;
869 }
870 object_name.erase(object_name.end() - 4, object_name.end());
871 object_1_name = object_name + "_1";
872 object = temp_model.add_object(object_1_name.c_str(), path_str, std::move(mesh));
873 if (!object) {
874 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": add_object %1% for stl failed, plate index %2%, object index %3%") % object_1_name % (index + 1) % (obj_index + 1);
875 return CLI_DATA_FILE_ERROR;
876 }
877 }
878 else if (boost::algorithm::iends_with(assemble_object.path, ".obj"))
879 {
880 std::string message;
881 ObjInfo obj_info;
882 bool result = load_obj(path_str, &mesh, obj_info, message);
883 if (!result) {
884 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": failed to read a valid mesh from obj file %1%, plate index %2%, object index %3%, error %4%") % assemble_object.path % (index + 1) % (obj_index + 1) % message;
885 return CLI_DATA_FILE_ERROR;
886 }
887 if (obj_info.lost_material_name != "") {
888 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": failed to read a valid mesh from obj file %1%, plate index %2%, object index %3%, mtl lost material: %4% ,please check mtl file") %
889 assemble_object.path % (index + 1) % (obj_index + 1) % obj_info.lost_material_name;
890 return CLI_DATA_FILE_ERROR;
891 }
892 if (obj_info.face_colors.size() > 0) {
893 auto temp0 = obj_info.face_colors.size();
894 auto temp1 = mesh.facets_count();
895 bool some_face_no_color = temp0 < temp1;
896 if (some_face_no_color) {
897 BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< boost::format(": failed to read a valid mesh from obj file %1%, plate index %2%, object index %3%, error:some_face_no_color,please check mtl file and obj file.") %
898 assemble_object.path % (index + 1) % (obj_index + 1);
899 return CLI_DATA_FILE_ERROR;
900 }
901 }
902 object_name.erase(object_name.end() - 4, object_name.end());
903 object_1_name = object_name + "_1";
904 //process colors
905 Model obj_temp_model;
906 ModelObject* temp_object = obj_temp_model.add_object(object_1_name.c_str(), path_str, std::move(mesh));
907 if (!temp_object) {
908 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": add_object %1% for obj failed, plate index %2%, object index %3%") % object_1_name % (index + 1) % (obj_index + 1);
909 return CLI_DATA_FILE_ERROR;
910 }
911
912 std::vector<unsigned char> output_filament_ids;
913 if (obj_info.vertex_colors.size() > 0) {
914 convert_obj_cluster_colors(obj_info.vertex_colors, all_colours, max_filament_count, output_filament_ids);
915 if (output_filament_ids.size() > 0) {
916 unsigned char first_extruder_id = output_filament_ids.front();
917 result = Model::obj_import_vertex_color_deal(output_filament_ids, first_extruder_id, & obj_temp_model);
918 }
919 skip_filament = true;
920 } else if (obj_info.face_colors.size() > 0 && obj_info.has_uv_png == false) { // mtl file
921 convert_obj_cluster_colors(obj_info.face_colors, all_colours, max_filament_count, output_filament_ids);
922 if (output_filament_ids.size() > 0) {
923 unsigned char first_extruder_id = output_filament_ids.front();
924 result = Model::obj_import_face_color_deal(output_filament_ids, first_extruder_id, & obj_temp_model);
925 }
926 skip_filament = true;
927 }
928 if (!result) {
929 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": failed to convert colors for %1%, plate index %2%, object index %3%, error %4%") % assemble_object.path % (index + 1) % (obj_index + 1) % message;
930 return CLI_DATA_FILE_ERROR;
931 }
932 object = temp_model.add_object(*temp_object);
933 if (!object) {
934 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": add_object %1% for stl failed, plate index %2%, object index %3%") % object_1_name % (index + 1) % (obj_index + 1);
935 return CLI_DATA_FILE_ERROR;
936 }
937 obj_temp_model.clear_objects();
938 obj_temp_model.clear_materials();
939 }
940 else {
941 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": unsupported file %1%, plate index %2%, object index %3%") % assemble_object.path % (index + 1) % (obj_index + 1);
942 return CLI_INVALID_PARAMS;
943 }
944
945 if (!skip_filament) {
946 object->config.set_key_value("extruder", new ConfigOptionInt(assemble_object.filaments[0]));
947 used_filaments.emplace(assemble_object.filaments[0]);
948 }
949 else {
950 assemble_object.filaments[0] = 0;
951 for (const ModelVolume* mv : object->volumes) {
952 std::vector<int> volume_extruders = mv->get_extruders();
953 used_filaments.insert(volume_extruders.begin(), volume_extruders.end());
954 }
955 }
956
957 if (!assemble_object.print_params.empty())
958 {
959 for (auto param_iter = assemble_object.print_params.begin(); param_iter != assemble_object.print_params.end(); param_iter++)
960 {
961 object->config.set_deserialize(param_iter->first, param_iter->second, config_substitutions);
962 BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, object %2% key %3%, value %4%") % (index + 1) % object_1_name % param_iter->first % param_iter->second;
963 }
964 }
965
966 if (!assemble_object.height_ranges.empty())
967 {
968 for (int range_index = 0; range_index < assemble_object.height_ranges.size(); range_index++)
969 {
970 height_range_info_t& range = assemble_object.height_ranges[range_index];
971 DynamicPrintConfig range_config;
972 for (auto range_config_iter = range.range_params.begin(); range_config_iter != range.range_params.end(); range_config_iter++)
973 {
974 range_config.set_deserialize(range_config_iter->first, range_config_iter->second, config_substitutions);
975 BOOST_LOG_TRIVIAL(debug) << boost::format("object %1%, height range %2% key %3%, value %4%") % object_1_name % range_index % range_config_iter->first % range_config_iter->second;
976 }
977 object->layer_config_ranges[{ range.min_z, range.max_z }].assign_config(std::move(range_config));
978 }
979 }
980
981 if (assemble_object.pos_x.empty())
982 assemble_object.pos_x.resize(1, 0.f);
983 if (assemble_object.pos_y.empty())
984 assemble_object.pos_y.resize(1, 0.f);
985 if (assemble_object.pos_z.empty())
986 assemble_object.pos_z.resize(1, 0.f);
987 if (assemble_object.assemble_index.empty())
988 assemble_object.assemble_index.resize(1, 0);
989
990 object->translate(assemble_object.pos_x[0], assemble_object.pos_y[0], assemble_object.pos_z[0]);
991 merge_or_add_object(assemble_plate_info, model, assemble_object.assemble_index[0], merged_objects, object);
992
993 BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": object %1%, name %2%, pos_x %3% pos_y %4%, pos_z %5%, filament %6%, assemble_index %7%")
994 %obj_index %object->name %assemble_object.pos_x[0] %assemble_object.pos_y[0] %assemble_object.pos_z[0] %assemble_object.filaments[0] %assemble_object.assemble_index[0];
995
996 for (size_t copy_index = 1; copy_index < assemble_object.count; copy_index++)
997 {
998 int array_index = copy_index;
999
1000 ModelObject* copy_obj = temp_model.add_object(*object);
1001 copy_obj->name = object_name + "_" + std::to_string(copy_index + 1);
1002
1003 if (copy_index >= assemble_object.pos_x.size())
1004 array_index = 0;
1005 copy_obj->translate(assemble_object.pos_x[array_index], assemble_object.pos_y[array_index], assemble_object.pos_z[array_index]);
1006
1007 if (copy_index < assemble_object.filaments.size())
1008 array_index = copy_index;
1009 else
1010 array_index = 0;
1011
1012 if (!skip_filament) {
1013 copy_obj->config.set_key_value("extruder", new ConfigOptionInt(assemble_object.filaments[array_index]));
1014 used_filaments.emplace(assemble_object.filaments[array_index]);
1015 }
1016 else {
1017 assemble_object.filaments[array_index] = 0;
1018 }
1019
1020 if (copy_index < assemble_object.assemble_index.size())
1021 array_index = copy_index;
1022 else
1023 array_index = 0;
1024 merge_or_add_object(assemble_plate_info, model, assemble_object.assemble_index[array_index], merged_objects, copy_obj);
1025
1026 BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": cloned object %1%, name %2%, pos_x %3% pos_y %4%, pos_z %5%")
1027 %copy_index %object->name %assemble_object.pos_x[array_index] %assemble_object.pos_y[array_index] %assemble_object.pos_z[array_index];
1028 }
1029 }
1030
1031 size_t assemble_count = merged_objects.size();
1032 if ((assemble_count > 0) && (assemble_plate_info.assembled_param_list.size() > 0))
1033 {
1034 for (auto& iter : merged_objects)
1035 {
1036 ModelObject* assemble_obj = iter.second;
1037 int assemble_index = iter.first;
1038
1039 auto assemble_iter = assemble_plate_info.assembled_param_list.find(assemble_index);
1040
1041 if (assemble_iter != assemble_plate_info.assembled_param_list.end())
1042 {
1043 assembled_param_info_t& assembled_param = assemble_iter->second;
1044 if (!assembled_param.print_params.empty())
1045 {
1046 for (auto param_iter = assembled_param.print_params.begin(); param_iter != assembled_param.print_params.end(); param_iter++)
1047 {
1048 assemble_obj->config.set_deserialize(param_iter->first, param_iter->second, config_substitutions);
1049 BOOST_LOG_TRIVIAL(debug) << boost::format("Plate %1%, assemble object %2% key %3%, value %4%") % (index + 1) % assemble_obj->name % param_iter->first % param_iter->second;
1050 }
1051 }
1052
1053 if (!assembled_param.height_ranges.empty())
1054 {
1055 for (int range_index = 0; range_index < assembled_param.height_ranges.size(); range_index++)
1056 {
1057 height_range_info_t& range = assembled_param.height_ranges[range_index];
1058 DynamicPrintConfig range_config;
1059 for (auto range_config_iter = range.range_params.begin(); range_config_iter != range.range_params.end(); range_config_iter++)
1060 {
1061 range_config.set_deserialize(range_config_iter->first, range_config_iter->second, config_substitutions);
1062 BOOST_LOG_TRIVIAL(debug) << boost::format("assenble object %1%, height range %2% key %3%, value %4%") % assemble_obj->name % range_index % range_config_iter->first % range_config_iter->second;
1063 }
1064 assemble_obj->layer_config_ranges[{ range.min_z, range.max_z }].assign_config(std::move(range_config));
1065 }
1066 }
1067 }
1068 }
1069 }
1070
1071 assemble_plate_info.filaments_count = used_filaments.size();
1072 assemble_plate_info.assemble_obj_list.clear();
1073 assemble_plate_info.assemble_obj_list.shrink_to_fit();
1074 assemble_plate_info.plate_params.clear();
1075
1076 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": Plate %1%, used filaments %2%") % (index + 1) % assemble_plate_info.filaments_count;
1077 }
1078
1079 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": has objects need to be merged, total plates %1%, total objects %2%") % plate_count % model.objects.size();
1080
1081 temp_model.clear_objects();
1082 temp_model.clear_materials();
1083 return ret;
1084}
#define DIR_SEPARATOR
Definition DRC.cpp:34
bool convert_obj_cluster_colors(std::vector< Slic3r::RGBA > &input_colors, std::vector< RGBA > &all_colours, int max_filament_count, std::vector< unsigned char > &output_filament_ids)
Definition OrcaSlicer.cpp:744
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)
Definition OrcaSlicer.cpp:714
void set_deserialize(const t_config_option_key &opt_key, const std::string &str, ConfigSubstitutionContext &config_substitutions, bool append=false)
Definition Config.cpp:614
Definition Config.hpp:1019
Definition PrintConfig.hpp:915
bool set_key_value(const std::string &opt_key, ConfigOption *opt)
Definition PrintConfig.hpp:2635
void set_deserialize(const t_config_option_key &opt_key, const std::string &str, ConfigSubstitutionContext &substitution_context, bool append=false)
Definition PrintConfig.hpp:2638
Definition Model.hpp:382
ModelConfigObject config
Definition Model.hpp:395
std::string name
Definition Model.hpp:384
void translate(const Vec3d &vector)
Definition Model.hpp:523
t_layer_config_ranges layer_config_ranges
Definition Model.hpp:397
ModelVolumePtrs volumes
Definition Model.hpp:393
Definition Model.hpp:832
std::vector< int > get_extruders() const
Definition Model.cpp:2713
static bool obj_import_face_color_deal(const std::vector< unsigned char > &face_filament_ids, const unsigned char &first_extruder_id, Model *model)
Definition Model.cpp:3426
void clear_materials()
Definition Model.cpp:776
ModelObjectPtrs objects
Definition Model.hpp:1702
static bool obj_import_vertex_color_deal(const std::vector< unsigned char > &vertex_filament_ids, const unsigned char &first_extruder_id, Model *model)
Definition Model.cpp:3306
ModelObject * add_object()
Definition Model.cpp:607
void clear_objects()
Definition Model.cpp:717
Definition TriangleMesh.hpp:94
bool empty() const
Definition TriangleMesh.hpp:146
bool ReadSTLFile(const char *input_file, bool repair=true, ImportstlProgressFn stlFn=nullptr, int custom_header_length=80)
Definition TriangleMesh.cpp:228
size_t facets_count() const
Definition TriangleMesh.hpp:145
#define CLI_FILE_NOTFOUND
Definition Utils.hpp:45
#define CLI_INVALID_PARAMS
Definition Utils.hpp:44
#define CLI_DATA_FILE_ERROR
Definition Utils.hpp:48
std::vector< height_range_info_t > height_ranges
Definition AssembleList.hpp:34
std::map< std::string, std::string > print_params
Definition AssembleList.hpp:33
std::vector< height_range_info_t > height_ranges
Definition AssembleList.hpp:21
std::string plate_name
Definition AssembleList.hpp:38
std::vector< RGBA > vertex_colors
Definition OBJ.hpp:20
std::vector< float > pos_z
Definition AssembleList.hpp:32
auto range(Cont &&cont)
Definition libslic3r.h:405
std::vector< float > pos_y
Definition AssembleList.hpp:31
bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo &obj_info, std::string &message, ObjParser::MtlData *out_mtl)
Definition OBJ.cpp:38
int filaments_count
Definition AssembleList.hpp:40
std::string path
Definition AssembleList.hpp:25
std::vector< int > assemble_index
Definition AssembleList.hpp:29
struct Slic3r::_assemble_plate_info assemble_plate_info_t
std::vector< assemble_object_info_t > assemble_obj_list
Definition AssembleList.hpp:43
struct Slic3r::_assemble_object_info assemble_object_info_t
struct Slic3r::_assembled_param_info assembled_param_info_t
int count
Definition AssembleList.hpp:26
std::map< int, assembled_param_info_t > assembled_param_list
Definition AssembleList.hpp:45
std::vector< RGBA > face_colors
Definition OBJ.hpp:21
std::vector< int > filaments
Definition AssembleList.hpp:28
bool has_uv_png
Definition OBJ.hpp:28
std::map< std::string, std::string > plate_params
Definition AssembleList.hpp:42
std::map< std::string, std::string > print_params
Definition AssembleList.hpp:20
std::string lost_material_name
Definition OBJ.hpp:23
struct Slic3r::_height_range_info height_range_info_t
std::vector< float > pos_x
Definition AssembleList.hpp:30
Definition OBJ.hpp:19
Definition Config.hpp:274
Definition bbs_3mf.hpp:78
std::string plate_name
Definition bbs_3mf.hpp:117
int plate_index
Definition bbs_3mf.hpp:96
DynamicPrintConfig config
Definition bbs_3mf.hpp:122

References Slic3r::Model::add_object(), Slic3r::_assemble_object_info::assemble_index, Slic3r::_assemble_plate_info::assemble_obj_list, Slic3r::_assemble_plate_info::assembled_param_list, Slic3r::Model::clear_materials(), Slic3r::Model::clear_objects(), CLI_DATA_FILE_ERROR, CLI_FILE_NOTFOUND, CLI_INVALID_PARAMS, Slic3r::ModelObject::config, Slic3r::PlateData::config, convert_obj_cluster_colors(), Slic3r::_assemble_object_info::count, DIR_SEPARATOR, Slic3r::TriangleMesh::empty(), Slic3r::Enable, Slic3r::ExtruderMax, Slic3r::ObjInfo::face_colors, Slic3r::TriangleMesh::facets_count(), Slic3r::_assemble_object_info::filaments, Slic3r::_assemble_plate_info::filaments_count, Slic3r::ModelVolume::get_extruders(), Slic3r::ObjInfo::has_uv_png, Slic3r::_assemble_object_info::height_ranges, Slic3r::_assembled_param_info::height_ranges, Slic3r::ModelObject::layer_config_ranges, Slic3r::load_obj(), Slic3r::ObjInfo::lost_material_name, merge_or_add_object(), Slic3r::ModelObject::name, Slic3r::Model::obj_import_face_color_deal(), Slic3r::Model::obj_import_vertex_color_deal(), Slic3r::Model::objects, Slic3r::_assemble_object_info::path, Slic3r::PlateData::plate_index, Slic3r::_assemble_plate_info::plate_name, Slic3r::PlateData::plate_name, Slic3r::_assemble_plate_info::plate_params, Slic3r::_assemble_object_info::pos_x, Slic3r::_assemble_object_info::pos_y, Slic3r::_assemble_object_info::pos_z, Slic3r::_assemble_object_info::print_params, Slic3r::_assembled_param_info::print_params, Slic3r::range(), Slic3r::TriangleMesh::ReadSTLFile(), Slic3r::ConfigBase::set_deserialize(), Slic3r::ModelConfig::set_deserialize(), Slic3r::ModelConfig::set_key_value(), Slic3r::ModelObject::translate(), Slic3r::ObjInfo::vertex_colors, and Slic3r::ModelObject::volumes.

Referenced by Slic3r::CLI::run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ convert_obj_cluster_colors()

bool convert_obj_cluster_colors ( std::vector< Slic3r::RGBA > & input_colors,
std::vector< RGBA > & all_colours,
int max_filament_count,
std::vector< unsigned char > & output_filament_ids )
745{
746 using namespace Slic3r::GUI;
747
748 BOOST_LOG_TRIVIAL(info) << boost::format("%1%:%2%, got original input obj colors %3%")%__FUNCTION__ %__LINE__ %input_colors.size();
749 if (input_colors.size() > 0) {
750 std::vector<Slic3r::RGBA> cluster_colors;
751 std::vector<int> cluster_labels;
752 char cluster_number = -1;
753
754 obj_color_deal_algo(input_colors, cluster_colors, cluster_labels, cluster_number, (int)EnforcerBlockerType::ExtruderMax);
755 std::vector<int> cluster_color_maps;
756
757 BOOST_LOG_TRIVIAL(info) << boost::format("%1%:%2%, after obj_color_deal_algo, cluster_colors size %3%, all_colours size %4%, max_filament_count=%5%")%__FUNCTION__ %__LINE__%cluster_colors.size() %all_colours.size() %max_filament_count;
758
759 cluster_color_maps.resize(cluster_colors.size(), 1);
760
761 int init_size = all_colours.size();
762
763 for (size_t i = 0; i < cluster_colors.size(); i++) {
764 if ((init_size + i + 1) <= max_filament_count) {
765 all_colours.push_back(cluster_colors[i]);
766 cluster_color_maps[i] = all_colours.size();
767 BOOST_LOG_TRIVIAL(info) << boost::format("%1%:%2%, cluster color index %3% RGBA {%4%,%5%,%6%,%7%} directly inserted, id %8%")
768 %__FUNCTION__ %__LINE__%(i+1) %cluster_colors[i][0] %cluster_colors[i][1] %cluster_colors[i][2] %cluster_colors[i][3] %cluster_color_maps[i] ;
769 }
770 else {
771 std::vector<ColorDistValue> color_dists;
772 color_dists.resize(max_filament_count);
773 for (size_t j = 0; j < max_filament_count; j++) {
774 color_dists[j].distance = calc_color_distance(cluster_colors[i], all_colours[j]);
775 color_dists[j].id = j + 1;
776 }
777 std::sort(color_dists.begin(), color_dists.end(), [](ColorDistValue &a, ColorDistValue &b) { return a.distance < b.distance; });
778 cluster_color_maps[i] = color_dists[0].id;
779 BOOST_LOG_TRIVIAL(info) << boost::format("%1%:%2%, cluster color index %3% RGBA {%4%,%5%,%6%,%7%} directly inserted, id %8%")
780 %__FUNCTION__ %__LINE__%(i+1) %cluster_colors[i][0] %cluster_colors[i][1] %cluster_colors[i][2] %cluster_colors[i][3] %cluster_color_maps[i] ;
781 }
782 }
783
784 //3.generate filament_ids
785 auto input_colors_size = input_colors.size();
786 output_filament_ids.resize(input_colors_size);
787 for (size_t i = 0; i < input_colors_size; i++) {
788 int label = cluster_labels[i];
789 output_filament_ids[i] = cluster_color_maps[label];
790 }
791
792 BOOST_LOG_TRIVIAL(info) << boost::format("%1%:%2%, all_colours size changes to %3%")%__FUNCTION__ %__LINE__%all_colours.size();
793
794 return true;
795 }
796
797 return false;
798}
Definition GuiColor.hpp:7
bool obj_color_deal_algo(std::vector< Slic3r::RGBA > &input_colors, std::vector< Slic3r::RGBA > &cluster_colors_from_algo, std::vector< int > &cluster_labels_from_algo, char &cluster_number, int max_cluster)
Definition ObjColorUtils.cpp:5
Definition Snapshot.cpp:54
float calc_color_distance(wxColour c1, wxColour c2)
Definition GuiColor.cpp:28
@ ExtruderMax
Definition TriangleSelector.hpp:66

References Slic3r::GUI::calc_color_distance(), Slic3r::ExtruderMax, and obj_color_deal_algo().

Referenced by construct_assemble_list().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ decode_png_to_thumbnail()

int decode_png_to_thumbnail ( std::string png_file,
ThumbnailData & thumbnail_data )
static
571{
572 if (!boost::filesystem::exists(png_file))
573 {
574 BOOST_LOG_TRIVIAL(error) << boost::format("can not find file %1%")%png_file;
575 return -1;
576 }
577
578 const std::size_t &size = boost::filesystem::file_size(png_file);
579 std::string png_buffer(size, '\0');
580 png_buffer.reserve(size);
581
582 boost::filesystem::ifstream ifs(png_file, std::ios::binary);
583 ifs.read(png_buffer.data(), png_buffer.size());
584 ifs.close();
585
587 Slic3r::png::ReadBuf rb{png_buffer.data(), png_buffer.size()};
588 BOOST_LOG_TRIVIAL(info) << boost::format("read png file %1%, size %2%")%png_file %size;
589
590 if ( !Slic3r::png::decode_colored_png(rb, img))
591 {
592 BOOST_LOG_TRIVIAL(error) << boost::format("decode png file %1% failed")%png_file;
593 return -2;
594 }
595
596 thumbnail_data.width = img.cols;
597 thumbnail_data.height = img.rows;
598 thumbnail_data.pixels = std::move(img.buf);
599
600 return 0;
601}
bool decode_colored_png(IStream &in_buf, ImageColorscale &out_img)
Definition PNGReadWrite.cpp:137
Definition PNGReadWrite.hpp:49
unsigned int height
Definition ThumbnailData.hpp:19
std::vector< unsigned char > pixels
Definition ThumbnailData.hpp:20
unsigned int width
Definition ThumbnailData.hpp:18
Definition PNGReadWrite.hpp:30
size_t rows
Definition PNGReadWrite.hpp:24
std::vector< PxT > buf
Definition PNGReadWrite.hpp:23
size_t cols
Definition PNGReadWrite.hpp:24

References Slic3r::png::Image< PxT >::buf, Slic3r::png::Image< PxT >::cols, Slic3r::png::decode_colored_png(), Slic3r::ThumbnailData::height, Slic3r::ThumbnailData::pixels, Slic3r::png::Image< PxT >::rows, and Slic3r::ThumbnailData::width.

Referenced by Slic3r::CLI::run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ default_status_callback()

void default_status_callback ( const PrintBase::SlicingStatus & slicing_status)
467{
468 if (slicing_status.warning_step != -1) {
469 g_slicing_warnings.push_back(slicing_status);
470 }
471 BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": percent=%1%, warning_step=%2%, message=%3%, message_type=%4%")%slicing_status.percent %slicing_status.warning_step %slicing_status.text %(int)(slicing_status.message_type);
472
473 return;
474}
std::vector< PrintBase::SlicingStatus > g_slicing_warnings
Definition OrcaSlicer.cpp:269
int percent
Definition PrintBase.hpp:459
std::string text
Definition PrintBase.hpp:460
PrintStateBase::SlicingNotificationType message_type
Definition PrintBase.hpp:479
int warning_step
Definition PrintBase.hpp:477

References g_slicing_warnings, Slic3r::PrintBase::SlicingStatus::message_type, Slic3r::PrintBase::SlicingStatus::percent, Slic3r::PrintBase::SlicingStatus::text, and Slic3r::PrintBase::SlicingStatus::warning_step.

Referenced by Slic3r::CLI::run().

Here is the caller graph for this function:

◆ get_printer_technology()

PrinterTechnology get_printer_technology ( const DynamicConfig & config)
static
478{
480 return (opt == nullptr) ? ptUnknown : opt->value;
481}
ConfigOption * option(const t_config_option_key &opt_key, bool create=false)
Definition Config.hpp:2768
Definition Config.hpp:2076
Definition BruteforceOptimizer.hpp:11
@ ptUnknown
Definition Config.hpp:235

References Slic3r::ConfigBase::option(), and Slic3r::ptUnknown.

Referenced by Slic3r::CLI::run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ glfw_callback()

void glfw_callback ( int error_code,
const char * description )
static
604{
605 BOOST_LOG_TRIVIAL(error) << "error_code " <<error_code <<", description: " <<description<< std::endl;
606}

Referenced by Slic3r::CLI::run().

Here is the caller graph for this function:

◆ legacy_bed_exclude_area_points()

Pointfs legacy_bed_exclude_area_points ( const DynamicPrintConfig & config)
static
188{
189 const ConfigOptionPoints *option = config.option<ConfigOptionPoints>("bed_exclude_area");
190 return option != nullptr ? option->values : Pointfs{};
191}
Definition Config.hpp:1575
std::vector< T > values
Definition Config.hpp:418
std::vector< Vec2d > Pointfs
Definition Point.hpp:77

References Slic3r::ConfigBase::option(), and Slic3r::ConfigOptionVector< T >::values.

Referenced by Slic3r::CLI::run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_default_gcodes_to_config()

void load_default_gcodes_to_config ( DynamicPrintConfig & config,
Preset::Type type )
static
654{
655 if (config.size() == 0) {
656 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< ", empty config, return directly";
657 return;
658 }
659 //add those empty gcodes by default
660 if (type == Preset::TYPE_PRINTER)
661 {
662 std::string change_filament_gcode = config.option<ConfigOptionString>("change_filament_gcode", true)->value;
663 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__<< ", change_filament_gcode: "<< change_filament_gcode;
664
665 ConfigOptionString* layer_change_gcode_opt = config.option<ConfigOptionString>("layer_change_gcode", true);
666 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__<< ", layer_change_gcode: "<<layer_change_gcode_opt->value;
667
668 ConfigOptionString* machine_end_gcode_opt = config.option<ConfigOptionString>("machine_end_gcode", true);
669 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__<< ", machine_end_gcode: "<<machine_end_gcode_opt->value;
670
671 ConfigOptionString* machine_pause_gcode_opt = config.option<ConfigOptionString>("machine_pause_gcode", true);
672 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__<< ", machine_pause_gcode: "<<machine_pause_gcode_opt->value;
673
674 ConfigOptionString* machine_start_gcode_opt = config.option<ConfigOptionString>("machine_start_gcode", true);
675 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__<< ", machine_start_gcode: "<<machine_start_gcode_opt->value;
676
677 ConfigOptionString* template_custom_gcode_opt = config.option<ConfigOptionString>("template_custom_gcode", true);
678 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__<< ", template_custom_gcode: "<<template_custom_gcode_opt->value;
679
680 ConfigOptionString* printing_by_object_gcode_opt = config.option<ConfigOptionString>("printing_by_object_gcode", true);
681 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__<< ", printing_by_object_gcode: "<<printing_by_object_gcode_opt->value;
682
683 ConfigOptionString* before_layer_change_gcode_opt = config.option<ConfigOptionString>("before_layer_change_gcode", true);
684 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__<< ", before_layer_change_gcode: "<<before_layer_change_gcode_opt->value;
685
686 ConfigOptionString* timeplase_gcode_opt = config.option<ConfigOptionString>("time_lapse_gcode", true);
687 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__<< ", time_lapse_gcode: "<<timeplase_gcode_opt->value;
688
689 ConfigOptionString *wrapping_detection_gcode_opt = config.option<ConfigOptionString>("wrapping_detection_gcode", true);
690 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << ", wrapping_detection_gcode: " << wrapping_detection_gcode_opt->value;
691 }
692 else if (type == Preset::TYPE_FILAMENT)
693 {
694 std::vector<std::string>& filament_start_gcodes = config.option<ConfigOptionStrings>("filament_start_gcode", true)->values;
695 if (filament_start_gcodes.empty()) {
696 filament_start_gcodes.resize(1, std::string());
697 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< ", set filament_start_gcodes to empty";
698 }
699 else {
700 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__<< ", filament_start_gcodes: "<<filament_start_gcodes[0];
701 }
702
703 std::vector<std::string>& filament_end_gcodes = config.option<ConfigOptionStrings>("filament_end_gcode", true)->values;
704 if (filament_end_gcodes.empty()) {
705 filament_end_gcodes.resize(1, std::string());
706 BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< ", set filament_end_gcode to empty";
707 }
708 else {
709 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__<< ", filament_end_gcode: "<<filament_end_gcodes[0];
710 }
711 }
712}
T value
Definition Config.hpp:329
Definition Config.hpp:1158
Definition Config.hpp:1190
size_t size() const
Definition Config.hpp:3082
@ TYPE_PRINTER
Definition Preset.hpp:250
@ TYPE_FILAMENT
Definition Preset.hpp:248
void trace(unsigned int level, const char *message)
Definition utils.cpp:247
zaa_minimize_perimeter_height change_filament_gcode((ConfigOptionString, change_extrusion_role_gcode))((ConfigOptionString

References Slic3r::change_filament_gcode(), Slic3r::ConfigBase::option(), Slic3r::DynamicConfig::size(), Slic3r::trace(), Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINTER, and Slic3r::ConfigOptionSingle< T >::value.

Referenced by Slic3r::CLI::run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_downward_settings_list_from_config()

void load_downward_settings_list_from_config ( std::string config_file,
std::string printer_name,
std::string printer_model,
std::vector< std::string > & downward_settings )
static
1087{
1088 std::map<std::string, std::string> printer_params;
1089
1090 boost::filesystem::path directory_path(config_file);
1091
1092 BOOST_LOG_TRIVIAL(info) << boost::format("%1%, will parse file %2% for printer mode %3%, printer name %4%")%__FUNCTION__ % config_file %printer_model %printer_name;
1093 if (!fs::exists(directory_path)) {
1094 BOOST_LOG_TRIVIAL(warning) << boost::format("file %1% not exist.")%config_file;
1095 }
1096 else {
1097 try {
1098 json root_json;
1099 boost::nowide::ifstream ifs(config_file);
1100 ifs >> root_json;
1101 ifs.close();
1102
1103 if (root_json.contains("printer")) {
1104 json printer_json = root_json["printer"];
1105 if (!printer_model.empty() && printer_json.contains(printer_model)) {
1106 json printer_model_json = printer_json[printer_model];
1107
1108 if (printer_model_json.contains("downward_check")) {
1109 json downward_check_json = printer_model_json["downward_check"];
1110 if (downward_check_json.contains(printer_name)) {
1111 downward_settings = downward_check_json[printer_name].get<std::vector<std::string>>();
1112 BOOST_LOG_TRIVIAL(info) << boost::format("got %1% downward settings of %2% in %3%")%downward_settings.size() %printer_name %config_file;
1113 }
1114 else {
1115 BOOST_LOG_TRIVIAL(info) << boost::format("can not find %1% in downward_check of %2% in %3%")%printer_name %printer_model %config_file;
1116 }
1117 }
1118 else {
1119 BOOST_LOG_TRIVIAL(info) << boost::format("can not find downward_check for %1% in %2%")%printer_model%config_file;
1120 }
1121 }
1122 else {
1123 BOOST_LOG_TRIVIAL(info) << boost::format("can not find printer_model %1% in %2%")%printer_model%config_file;
1124 }
1125 }
1126 else {
1127 BOOST_LOG_TRIVIAL(warning) << boost::format("can not find key printer in %1%")%config_file;
1128 }
1129 }
1130 catch (std::exception &err) {
1131 BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse file "<<config_file<<" got a generic exception, reason = " << err.what();
1132 }
1133 }
1134}
nlohmann::json json
Definition AssembleList.cpp:42

Referenced by Slic3r::CLI::run().

Here is the caller graph for this function:

◆ load_key_values_from_json()

int load_key_values_from_json ( const std::string & file,
std::map< std::string, std::string > & key_values )
static
614{
615 json j;
616 CNumericLocalesSetter locales_setter;
617
618 BOOST_LOG_TRIVIAL(debug) << __FUNCTION__<< ": begin to parse "<<file;
619 try {
620 boost::nowide::ifstream ifs(file);
621 ifs >> j;
622 ifs.close();
623
624 //parse the json elements
625 for (auto it = j.begin(); it != j.end(); it++) {
626 if (boost::iequals(it.key(),BBL_JSON_KEY_MODEL_ID)) {
627 key_values.emplace(BBL_JSON_KEY_MODEL_ID, it.value());
628 }
629 else if (boost::iequals(it.key(), BBL_JSON_KEY_NAME)) {
630 key_values.emplace(BBL_JSON_KEY_NAME, it.value());
631 }
632 }
633 }
634 catch (const std::ifstream::failure &err) {
635 BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse "<<file<<" got a ifstream error, reason = " << err.what();
636 return -1;
637 }
638 catch(nlohmann::detail::parse_error &err) {
639 BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse "<<file<<" got a nlohmann::detail::parse_error, reason = " << err.what();
640 return -2;
641 }
642 catch(std::exception &err) {
643 BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse "<<file<<" got a generic exception, reason = " << err.what();
644 return -3;
645 }
646 BOOST_LOG_TRIVIAL(debug) << __FUNCTION__<< ": finished parse, key_values size "<<key_values.size();
647 return 0;
648}
#define BBL_JSON_KEY_NAME
Definition Preset.hpp:58
#define BBL_JSON_KEY_MODEL_ID
Definition Preset.hpp:93
Definition LocalesUtils.hpp:19

References BBL_JSON_KEY_MODEL_ID, and BBL_JSON_KEY_NAME.

Referenced by Slic3r::CLI::run().

Here is the caller graph for this function:

◆ main()

int main ( int argc,
char ** argv )
8553{
8554#ifndef _WIN32
8555 // Ignore SIGPIPE so a write to a closed socket (e.g. a dropped printer
8556 // network connection) returns EPIPE to the caller instead of terminating
8557 // the whole process. Without this, losing the printer link kills
8558 // OrcaSlicer with SIGPIPE (exit 141) and produces no crash report.
8559 std::signal(SIGPIPE, SIG_IGN);
8560#endif
8561 return CLI().run(argc, argv);
8562}
Definition OrcaSlicer.hpp:60
int run(int argc, char **argv)
Definition OrcaSlicer.cpp:1149

References Slic3r::CLI::run().

Here is the call graph for this function:

◆ merge_or_add_object()

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 )
715{
716 if (assemble_index > 0) {
717 auto iter = merged_objects.find(assemble_index);
718 ModelObject* new_object = nullptr;
719 if (iter == merged_objects.end()) {
720 //create the object to merge
721 new_object = model.add_object();
722 new_object->name = "assemble_" + std::to_string(assemble_index);
723 merged_objects[assemble_index] = new_object;
724 assemble_plate_info.loaded_obj_list.emplace_back(new_object);
725 new_object->config.assign_config(ori_object->config.get());
726 }
727 else
728 new_object = iter->second;
729
730 for (auto volume : ori_object->volumes) {
731 ModelVolume* new_volume = new_object->add_volume(*volume);
732 // set extruder id
733 new_volume->config.set_key_value("extruder", new ConfigOptionInt(ori_object->config.extruder()));
734 }
735 BOOST_LOG_TRIVIAL(debug) << boost::format("assemble_index %1%, name %2%, merged to new model %3%") % assemble_index % ori_object->name % new_object->name;
736 }
737 else {
738 ModelObject* new_object = model.add_object(*ori_object);
739 assemble_plate_info.loaded_obj_list.emplace_back(new_object);
740 BOOST_LOG_TRIVIAL(debug) << boost::format("assemble_index %1%, name %2%, no need to merge, copy to new model") % assemble_index % ori_object->name;
741 }
742}
int extruder() const
Definition PrintConfig.hpp:2654
void assign_config(const ModelConfig &rhs)
Definition PrintConfig.hpp:2612
const DynamicPrintConfig & get() const
Definition PrintConfig.hpp:2645
ModelVolume * add_volume(const TriangleMesh &mesh, bool modify_to_center_geometry=true)
Definition Model.cpp:1389
ModelConfigObject config
Definition Model.hpp:904
std::vector< ModelObject * > loaded_obj_list
Definition AssembleList.hpp:44

References Slic3r::Model::add_object(), Slic3r::ModelObject::add_volume(), Slic3r::ModelConfig::assign_config(), Slic3r::ModelObject::config, Slic3r::ModelVolume::config, Slic3r::ModelConfig::extruder(), Slic3r::ModelConfig::get(), Slic3r::_assemble_plate_info::loaded_obj_list, Slic3r::ModelObject::name, Slic3r::ModelConfig::set_key_value(), and Slic3r::ModelObject::volumes.

Referenced by construct_assemble_list().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ record_exit_reson()

void record_exit_reson ( std::string outputdir,
int code,
int plate_id,
std::string error_message,
sliced_info_t & sliced_info,
std::map< std::string, std::string > key_values = std::map<std::string, std::string>() )
519{
520#if defined(__linux__) || defined(__LINUX__)
521 std::string result_file;
522
523 if (!outputdir.empty())
524 result_file = outputdir + "/result.json";
525 else
526 result_file = "result.json";
527
528 try {
529 json j;
530 //record the headers
531 if (sliced_info.downward_machines.size() > 0)
532 j["downward_compatible_machine"] = sliced_info.downward_machines;
533 if (sliced_info.upward_machines.size() > 0)
534 j["upward_compatible_machine"] = sliced_info.upward_machines;
535 j["plate_index"] = plate_id;
536 j["return_code"] = code;
537 j["error_string"] = error_message;
538 j["prepare_time"] = sliced_info.prepare_time;
539 j["export_time"] = sliced_info.export_time;
540 j["layer_height"] = sliced_info.layer_height;
541 j["wall_loops"] = sliced_info.wall_loops;
542 j["sparse_infill_density"] = sliced_info.sparse_infill_density;
543 for (size_t index = 0; index < sliced_info.sliced_plates.size(); index++)
544 {
545 json plate_json;
546 plate_json["id"] = sliced_info.sliced_plates[index].plate_id;
547 plate_json["sliced_time"] = sliced_info.sliced_plates[index].sliced_time;
548 plate_json["sliced_time_with_cache"] = sliced_info.sliced_plates[index].sliced_time_with_cache;
549 plate_json["triangle_count"] = sliced_info.sliced_plates[index].triangle_count;
550 plate_json["warning_message"] = sliced_info.sliced_plates[index].warning_message;
551 j["sliced_plates"].push_back(plate_json);
552 }
553 for (auto& iter: key_values)
554 j[iter.first] = iter.second;
555
556 j["warnings"] = sliced_info.warnings;
557 j["strict_mode"] = sliced_info.strict_mode;
558
559 boost::nowide::ofstream c;
560 c.open(result_file, std::ios::out | std::ios::trunc);
561 c << j.dump(1, '\t') << std::endl;
562 c.close();
563
564 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", saved config to %1%\n")%result_file;
565 }
566 catch (...) {}
567#endif
568}
int wall_loops
Definition OrcaSlicer.cpp:262
float sparse_infill_density
Definition OrcaSlicer.cpp:261
bool strict_mode
Definition OrcaSlicer.cpp:267
std::vector< std::string > downward_machines
Definition OrcaSlicer.cpp:264
std::vector< sliced_plate_info_t > sliced_plates
Definition OrcaSlicer.cpp:257
float layer_height
Definition OrcaSlicer.cpp:260
size_t export_time
Definition OrcaSlicer.cpp:259
std::vector< std::string > upward_machines
Definition OrcaSlicer.cpp:263
size_t prepare_time
Definition OrcaSlicer.cpp:258

References _sliced_info::downward_machines, _sliced_info::export_time, _sliced_info::layer_height, _sliced_info::prepare_time, _sliced_info::sliced_plates, _sliced_info::sparse_infill_density, _sliced_info::strict_mode, _sliced_info::upward_machines, _sliced_info::wall_loops, and _sliced_info::warnings.

Referenced by Slic3r::CLI::run().

Here is the caller graph for this function:

Variable Documentation

◆ bed3d_ax3s_default_stem_length

const float bed3d_ax3s_default_stem_length = 25.0f

◆ bed3d_ax3s_default_stem_radius

const float bed3d_ax3s_default_stem_radius = 0.5f

◆ bed3d_ax3s_default_tip_length

const float bed3d_ax3s_default_tip_length = 5.0f

◆ bed3d_ax3s_default_tip_radius

const float bed3d_ax3s_default_tip_radius = 2.5f * bed3d_ax3s_default_stem_radius

Referenced by Slic3r::CLI::run().

◆ cli_errors

std::map<int, std::string> cli_errors
193 {
194 {CLI_SUCCESS, "Success."},
195 {CLI_ENVIRONMENT_ERROR, "Failed setting up server environment."},
196 {CLI_INVALID_PARAMS, "Invalid parameters to the slicer."},
197 {CLI_FILE_NOTFOUND, "The input files to the slicer are not found."},
198 {CLI_FILELIST_INVALID_ORDER, "File list order to the slicer is invalid. Please make sure the 3mf in the first place."},
199 {CLI_CONFIG_FILE_ERROR, "The input preset file is invalid and can not be parsed."},
200 {CLI_DATA_FILE_ERROR, "The input model file to the slicer can not be parsed."},
201 {CLI_INVALID_PRINTER_TECH, "Unsupported printer technology (not FDM)."},
202 {CLI_UNSUPPORTED_OPERATION, "Unsupported CLI instruction."},
203 {CLI_COPY_OBJECTS_ERROR, "Failed copying objects."},
204 {CLI_SCALE_TO_FIT_ERROR, "Failed scaling an object to fit the plate."},
205 {CLI_EXPORT_STL_ERROR, "Failed exporting STL files."},
206 {CLI_EXPORT_OBJ_ERROR, "Failed exporting OBJ files."},
207 {CLI_EXPORT_3MF_ERROR, "Failed exporting 3mf files."},
208 {CLI_OUT_OF_MEMORY, "Out of memory during slicing. Please upload a model with lower geometry resolution and try again."},
209 {CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE, "The selected printer is not supported."},
210 {CLI_3MF_NEW_MACHINE_NOT_SUPPORTED, "The selected printer is not compatible with the 3mf."},
211 {CLI_PROCESS_NOT_COMPATIBLE, "The selected printer is not compatible with the process preset in the 3mf."},
212 {CLI_INVALID_VALUES_IN_3MF, "Invalid parameter value(s) included in the 3mf file."},
213 {CLI_POSTPROCESS_NOT_SUPPORTED, "post_process is not supported under CLI."},
214 {CLI_PRINTABLE_SIZE_REDUCED, "The selected printer's bed size is smaller than the bed size used in the print profile."},
215 {CLI_OBJECT_ARRANGE_FAILED, "An error occurred when auto-arranging object(s)."},
216 {CLI_OBJECT_ORIENT_FAILED, "An error occurred when auto-orienting object(s)."},
217 {CLI_MODIFIED_PARAMS_TO_PRINTER, "Found modified parameter in printer preset in the 3mf file, which should not be changed."},
218 {CLI_FILE_VERSION_NOT_SUPPORTED, "Unsupported 3MF version. Please make sure the 3MF file was created with the official version of Bambu Studio, not a beta version."},
219 {CLI_EXPORT_STATISTICS_ERROR, "Failed exporting the G-code statistics."},
220 {CLI_NO_SUITABLE_OBJECTS, "The plate has nothing to slice: it is empty, or no object on it is both printable and fully inside the print volume."},
221 {CLI_VALIDATE_ERROR, "There are some incorrect slicing parameters in the 3mf. Please verify the slicing of all plates in Orca Slicer before uploading."},
222 {CLI_OBJECTS_PARTLY_INSIDE, "Some objects are located over the boundary of the heated bed."},
223 {CLI_EXPORT_CACHE_DIRECTORY_CREATE_FAILED, "Failed creating directory when exporting cache data."},
224 {CLI_EXPORT_CACHE_WRITE_FAILED, "Failed exporting cache data."},
225 {CLI_IMPORT_CACHE_NOT_FOUND, "Cache data not found."},
226 {CLI_IMPORT_CACHE_DATA_CAN_NOT_USE, "Cache data can not be parsed."},
227 {CLI_IMPORT_CACHE_LOAD_FAILED, "Failed importing cache data."},
228 {CLI_SLICING_TIME_EXCEEDS_LIMIT, "Slicing time of a certain plate exceeds the limit. Please simplify the model or use a larger slicing layer height."},
229 {CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT, "Triangle count of single plate exceeds the limit. Please simplify the model and try to upload again."},
230 {CLI_NO_SUITABLE_OBJECTS_AFTER_SKIP, "No printable objects to slice after skipping."},
231 {CLI_FILAMENT_NOT_MATCH_BED_TYPE, "Filaments are not compatible with the plate type. Please verify the slicing of all plates in Orca Slicer before uploading."},
232 {CLI_FILAMENTS_DIFFERENT_TEMP, "The temperature difference of the filaments used is too large. Please verify the slicing of all plates in Orca Slicer before uploading."},
233 {CLI_OBJECT_COLLISION_IN_SEQ_PRINT, "Object conflicts were detected when using print-by-object mode. Please verify the slicing of all plates in Orca Slicer before uploading."},
234 {CLI_OBJECT_COLLISION_IN_LAYER_PRINT, "Object conflicts were detected. Please verify the slicing of all plates in Orca Slicer before uploading."},
235 {CLI_SPIRAL_MODE_INVALID_PARAMS, "Some slicing parameters cannot work with Spiral Vase mode. Please solve the issue in Orca Slicer before uploading."},
236 {CLI_FILAMENT_CAN_NOT_MAP, "Some filaments cannot be mapped to correct extruders for multi-extruder Printer."},
237 {CLI_ONLY_ONE_TPU_SUPPORTED, "Not support printing 2 or more TPU filaments."},
238 {CLI_FILAMENTS_NOT_SUPPORTED_BY_EXTRUDER, "Some filaments cannot be printed on the extruder mapped to."},
239 {CLI_MIXED_FILAMENT_INVALID, "A mixed filament is invalid: its components are different filament types, or it has no filament of its own."},
240 {CLI_SLICING_ERROR, "Failed slicing the model. Please verify the slicing of all plates on Orca Slicer before uploading."},
241 {CLI_GCODE_PATH_CONFLICTS, " G-code conflicts detected after slicing. Please make sure the 3mf file can be successfully sliced in the latest Orca Slicer. If the file slices normally in Orca Slicer, try moving the wipe tower further from other models, as we use more conservative parameters for it during upload."},
242 {CLI_GCODE_PATH_IN_UNPRINTABLE_AREA, "Found G-code in unprintable area of multi-extruder printers after slicing. Please make sure the 3mf file can be successfully sliced in the latest Orca Slicer."}
243};
#define CLI_EXPORT_CACHE_DIRECTORY_CREATE_FAILED
Definition Utils.hpp:74
#define CLI_ENVIRONMENT_ERROR
Definition Utils.hpp:43
#define CLI_EXPORT_CACHE_WRITE_FAILED
Definition Utils.hpp:75
#define CLI_OBJECT_COLLISION_IN_LAYER_PRINT
Definition Utils.hpp:85
#define CLI_POSTPROCESS_NOT_SUPPORTED
Definition Utils.hpp:62
#define CLI_3MF_NEW_MACHINE_NOT_SUPPORTED
Definition Utils.hpp:59
#define CLI_OBJECT_ARRANGE_FAILED
Definition Utils.hpp:64
#define CLI_EXPORT_OBJ_ERROR
Definition Utils.hpp:55
#define CLI_GCODE_PATH_CONFLICTS
Definition Utils.hpp:93
#define CLI_SLICING_ERROR
Definition Utils.hpp:92
#define CLI_IMPORT_CACHE_DATA_CAN_NOT_USE
Definition Utils.hpp:77
#define CLI_MODIFIED_PARAMS_TO_PRINTER
Definition Utils.hpp:66
#define CLI_FILAMENTS_NOT_SUPPORTED_BY_EXTRUDER
Definition Utils.hpp:89
#define CLI_NO_SUITABLE_OBJECTS
Definition Utils.hpp:71
#define CLI_SUCCESS
Definition Utils.hpp:42
#define CLI_PROCESS_NOT_COMPATIBLE
Definition Utils.hpp:60
#define CLI_UNSUPPORTED_OPERATION
Definition Utils.hpp:50
#define CLI_PRINTABLE_SIZE_REDUCED
Definition Utils.hpp:63
#define CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT
Definition Utils.hpp:80
#define CLI_MIXED_FILAMENT_INVALID
Definition Utils.hpp:90
#define CLI_CONFIG_FILE_ERROR
Definition Utils.hpp:47
#define CLI_EXPORT_STL_ERROR
Definition Utils.hpp:54
#define CLI_FILAMENTS_DIFFERENT_TEMP
Definition Utils.hpp:83
#define CLI_OUT_OF_MEMORY
Definition Utils.hpp:57
#define CLI_IMPORT_CACHE_LOAD_FAILED
Definition Utils.hpp:78
#define CLI_OBJECT_COLLISION_IN_SEQ_PRINT
Definition Utils.hpp:84
#define CLI_INVALID_VALUES_IN_3MF
Definition Utils.hpp:61
#define CLI_SCALE_TO_FIT_ERROR
Definition Utils.hpp:53
#define CLI_FILAMENT_CAN_NOT_MAP
Definition Utils.hpp:87
#define CLI_GCODE_PATH_IN_UNPRINTABLE_AREA
Definition Utils.hpp:94
#define CLI_FILE_VERSION_NOT_SUPPORTED
Definition Utils.hpp:67
#define CLI_EXPORT_STATISTICS_ERROR
Definition Utils.hpp:68
#define CLI_ONLY_ONE_TPU_SUPPORTED
Definition Utils.hpp:88
#define CLI_EXPORT_3MF_ERROR
Definition Utils.hpp:56
#define CLI_SPIRAL_MODE_INVALID_PARAMS
Definition Utils.hpp:86
#define CLI_NO_SUITABLE_OBJECTS_AFTER_SKIP
Definition Utils.hpp:81
#define CLI_COPY_OBJECTS_ERROR
Definition Utils.hpp:52
#define CLI_OBJECTS_PARTLY_INSIDE
Definition Utils.hpp:73
#define CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE
Definition Utils.hpp:58
#define CLI_FILAMENT_NOT_MATCH_BED_TYPE
Definition Utils.hpp:82
#define CLI_INVALID_PRINTER_TECH
Definition Utils.hpp:49
#define CLI_IMPORT_CACHE_NOT_FOUND
Definition Utils.hpp:76
#define CLI_FILELIST_INVALID_ORDER
Definition Utils.hpp:46
#define CLI_SLICING_TIME_EXCEEDS_LIMIT
Definition Utils.hpp:79
#define CLI_OBJECT_ORIENT_FAILED
Definition Utils.hpp:65
#define CLI_VALIDATE_ERROR
Definition Utils.hpp:72

Referenced by Slic3r::CLI::run().

◆ g_slicing_warnings

std::vector<PrintBase::SlicingStatus> g_slicing_warnings

◆ gcodes_key_set

std::set<std::string> gcodes_key_set
static
Initial value:
= {"filament_end_gcode", "filament_start_gcode", "change_filament_gcode", "layer_change_gcode", "machine_end_gcode", "machine_pause_gcode", "machine_start_gcode",
"template_custom_gcode", "printing_by_object_gcode", "before_layer_change_gcode", "time_lapse_gcode", "wrapping_detection_gcode"}
650 {"filament_end_gcode", "filament_start_gcode", "change_filament_gcode", "layer_change_gcode", "machine_end_gcode", "machine_pause_gcode", "machine_start_gcode",
651 "template_custom_gcode", "printing_by_object_gcode", "before_layer_change_gcode", "time_lapse_gcode", "wrapping_detection_gcode"};