806{
807 int ret = 0;
808 int plate_count = assemble_plate_info_list.size();
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
817 std::map<int, ModelObject*> merged_objects;
818 std::set<int> used_filaments;
819
820
822
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();
827 plate_list[index] = plate_data;
830
832 {
833 for (
auto plate_iter = assemble_plate_info.
plate_params.begin(); plate_iter != assemble_plate_info.
plate_params.end(); plate_iter++)
834 {
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
841 for (size_t obj_index = 0; obj_index < object_count; obj_index++)
842 {
844 std::string object_name;
845 std::string object_1_name;
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);
854 }
855
856 const char* path_str = assemble_object.
path.c_str();
858 object_name.assign((last_slash == nullptr) ? path_str : last_slash + 1);
859
860 if (boost::algorithm::iends_with(assemble_object.
path,
".stl"))
861 {
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);
865 }
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);
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);
876 }
877 }
878 else if (boost::algorithm::iends_with(assemble_object.
path,
".obj"))
879 {
880 std::string message;
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;
886 }
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") %
891 }
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);
900 }
901 }
902 object_name.erase(object_name.end() - 4, object_name.end());
903 object_1_name = object_name + "_1";
904
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);
910 }
911
912 std::vector<unsigned char> output_filament_ids;
915 if (output_filament_ids.size() > 0) {
916 unsigned char first_extruder_id = output_filament_ids.front();
918 }
919 skip_filament = true;
922 if (output_filament_ids.size() > 0) {
923 unsigned char first_extruder_id = output_filament_ids.front();
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;
931 }
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);
936 }
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);
943 }
944
945 if (!skip_filament) {
947 used_filaments.emplace(assemble_object.
filaments[0]);
948 }
949 else {
953 used_filaments.insert(volume_extruders.begin(), volume_extruders.end());
954 }
955 }
956
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
967 {
968 for (
int range_index = 0; range_index < assemble_object.
height_ranges.size(); range_index++)
969 {
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);
989
990 object->translate(assemble_object.
pos_x[0], assemble_object.
pos_y[0], assemble_object.
pos_z[0]);
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%")
995
996 for (
size_t copy_index = 1; copy_index < assemble_object.
count; copy_index++)
997 {
998 int array_index = copy_index;
999
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) {
1014 used_filaments.emplace(assemble_object.
filaments[array_index]);
1015 }
1016 else {
1017 assemble_object.
filaments[array_index] = 0;
1018 }
1019
1021 array_index = copy_index;
1022 else
1023 array_index = 0;
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();
1033 {
1034 for (auto& iter : merged_objects)
1035 {
1037 int assemble_index = iter.first;
1038
1040
1042 {
1045 {
1046 for (
auto param_iter = assembled_param.
print_params.begin(); param_iter != assembled_param.
print_params.end(); param_iter++)
1047 {
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
1054 {
1055 for (
int range_index = 0; range_index < assembled_param.
height_ranges.size(); range_index++)
1056 {
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 }
1065 }
1066 }
1067 }
1068 }
1069 }
1070
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
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
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
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 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