6432 {
6433 PackingTemporaryData temp_data;
6434
6435 mz_zip_archive archive;
6436 mz_zip_zero_struct(&archive);
6437
6438 bool cb_cancel = false;
6439
6440
6441 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ <<
6443 if (proFn) {
6445 if (cb_cancel)
6446 return false;
6447 }
6448
6450 add_error(
"Unable to open the file"+filename);
6451 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", Unable to open the file\n");
6452 return false;
6453 }
6454
6455 struct close_lock
6456 {
6457 mz_zip_archive & archive;
6458 std::string const * filename;
6459 ~close_lock() {
6461 if (filename) {
6462 boost::system::error_code ec;
6463 boost::filesystem::remove(*filename, ec);
6464 }
6465 }
6466 }
lock{ archive, &filename};
6467
6468
6469 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", before add _add_content_types_file_to_archive\n");
6470 if (proFn) {
6472 if (cb_cancel)
6473 return false;
6474 }
6475
6476
6477
6479 return false;
6480 }
6481
6482
6483 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(",before add thumbnails, count %1%") % thumbnail_data.size();
6484 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(",top&&pick thumbnails, count %1%")%top_thumbnail_data.size();
6485
6486
6487
6488
6489 const size_t rels_plate_idx = (export_plate_idx < 0) ? 0 : static_cast<size_t>(export_plate_idx);
6490 bool rels_thumbnail_written = false;
6491 bool rels_small_thumbnail_written = false;
6493 std::vector<bool> thumbnail_status(plate_data_list.size(), false);
6494 std::vector<bool> no_light_thumbnail_status(plate_data_list.size(), false);
6495 std::vector<bool> top_thumbnail_status(plate_data_list.size(), false);
6496 std::vector<bool> pick_thumbnail_status(plate_data_list.size(), false);
6497
6498 if ((thumbnail_data.size() > 0)&&(thumbnail_data.size() > plate_data_list.size())) {
6499 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", thumbnail_data size %1% > plate count %2%")
6500 % thumbnail_data.size() %plate_data_list.size();
6501 return false;
6502 }
6503 if ((no_light_thumbnail_data.size() > 0) && (no_light_thumbnail_data.size() > plate_data_list.size())) {
6504 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", no_light_thumbnail_data size %1% > plate count %2%") %
6505 no_light_thumbnail_data.size() % plate_data_list.size();
6506 return false;
6507 }
6508 if ((top_thumbnail_data.size() > 0)&&(top_thumbnail_data.size() > plate_data_list.size())) {
6509 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", top_thumbnail_data size %1% > plate count %2%")
6510 % top_thumbnail_data.size() %plate_data_list.size();
6511 return false;
6512 }
6513 if ((pick_thumbnail_data.size() > 0)&&(pick_thumbnail_data.size() > plate_data_list.size())) {
6514 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", pick_thumbnail_data size %1% > plate count %2%")
6515 % pick_thumbnail_data.size() %plate_data_list.size();
6516 return false;
6517 }
6518 if (top_thumbnail_data.size() != pick_thumbnail_data.size()) {
6519 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", top_thumbnail_data size %1% != pick_thumbnail_data size %2%")
6520 % top_thumbnail_data.size() %pick_thumbnail_data.size();
6521 return false;
6522 }
6523
6524 if (proFn) {
6526 if (cb_cancel)
6527 return false;
6528 }
6529
6530 for (unsigned int index = 0; index < thumbnail_data.size(); index++)
6531 {
6532 if (thumbnail_data[index]->
is_valid())
6533 {
6535 return false;
6536 }
6537
6538 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(",add thumbnail %1%'s data into 3mf")%(index+1);
6539 thumbnail_status[index] = true;
6540 if (static_cast<size_t>(index) == rels_plate_idx) {
6541
6542 rels_thumbnail_written = true;
6543 rels_small_thumbnail_written = true;
6544 }
6545 }
6546 }
6547
6548 for (unsigned int index = 0; index < no_light_thumbnail_data.size(); index++) {
6549 if (no_light_thumbnail_data[index]->
is_valid()) {
6551 return false;
6552 }
6553
6554 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(",add no light thumbnail %1%'s data into 3mf") % (index + 1);
6555 no_light_thumbnail_status[index] = true;
6556 }
6557 }
6558
6559 for (unsigned int index = 0; index < top_thumbnail_data.size(); index++)
6560 {
6561 if (top_thumbnail_data[index]->
is_valid())
6562 {
6563 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(",add top thumbnail %1%'s data into 3mf")%(index+1);
6565 return false;
6566 }
6567 top_thumbnail_status[index] = true;
6568 }
6569
6570 if (pick_thumbnail_data[index]->
is_valid())
6571 {
6572 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(",add pick thumbnail %1%'s data into 3mf")%(index+1);
6574 return false;
6575 }
6576 pick_thumbnail_status[index] = true;
6577 }
6578 }
6579
6580 for (int i = 0; i < plate_data_list.size(); i++) {
6581 PlateData *plate_data = plate_data_list[i];
6582
6583 if (!thumbnail_status[i] && !plate_data->thumbnail_file.empty() && (boost::filesystem::exists(plate_data->thumbnail_file))){
6584 std::string dst_in_3mf = (boost::format("Metadata/plate_%1%.png") % (i + 1)).str();
6585 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", add thumbnail %1% from file %2%") % (i+1) %plate_data->thumbnail_file;
6586
6588 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", add thumbnail %1% from file %2% failed\n") % (i+1) %plate_data->thumbnail_file;
6589 return false;
6590 }
6591
6592 if (static_cast<size_t>(i) == rels_plate_idx)
6593 rels_thumbnail_written = true;
6594 }
6595
6596 if (!no_light_thumbnail_status[i] && !plate_data->no_light_thumbnail_file.empty() && (boost::filesystem::exists(plate_data->no_light_thumbnail_file))){
6597 std::string dst_in_3mf = (boost::format("Metadata/plate_no_light_%1%.png") % (i + 1)).str();
6598 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", add no light thumbnail %1% from file %2%") % (i+1) %plate_data->no_light_thumbnail_file;
6599
6601 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", add no light thumbnail %1% from file %2% failed\n") % (i+1) %plate_data->no_light_thumbnail_file;
6602 return false;
6603 }
6604 }
6605
6606 if (!top_thumbnail_status[i] && !plate_data->top_file.empty() && (boost::filesystem::exists(plate_data->top_file))){
6607 std::string dst_in_3mf = (boost::format("Metadata/top_%1%.png") % (i + 1)).str();
6608
6609 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", add top thumbnail %1% from file %2%") % (i+1) %plate_data->top_file;
6611 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", add top thumbnail %1% failed") % (i+1);
6612 return false;
6613 }
6614 top_thumbnail_status[i] = true;
6615 }
6616
6617 if (!pick_thumbnail_status[i] && !plate_data->pick_file.empty() && (boost::filesystem::exists(plate_data->pick_file))){
6618 std::string dst_in_3mf = (boost::format("Metadata/pick_%1%.png") % (i + 1)).str();
6619
6620 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", add pick thumbnail %1% from file %2%") % (i+1) %plate_data->pick_file;
6622 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", add pick thumbnail %1% failed") % (i+1);
6623 return false;
6624 }
6625 pick_thumbnail_status[i] = true;
6626 }
6627 }
6628 if (proFn) {
6630 if (cb_cancel)
6631 return false;
6632 }
6633 }
6634
6635 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(",before add calibration thumbnails, count %1%\n")%calibration_data.size();
6636
6638
6639 for (unsigned int index = 0; index < calibration_data.size(); index++)
6640 {
6641 if (proFn) {
6643 if (cb_cancel)
6644 return false;
6645 }
6646
6647 if (calibration_data[index]->
is_valid())
6648 {
6651 return false;
6652 }
6653 }
6654 }
6655 }
6656
6657 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(",before add calibration boundingbox, count %1%\n")%id_bboxes.size();
6659
6660 for (unsigned int index = 0; index < id_bboxes.size(); index++)
6661 {
6662
6663 if (id_bboxes[index]->
is_valid()) {
6666 return false;
6667 }
6668 }
6669 }
6670 }
6671
6672
6673 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", before add models\n");
6674 if (proFn) {
6676 if (cb_cancel)
6677 return false;
6678 }
6679
6680
6681
6683
6684 {
6686
6687
6688
6689
6692 return false;
6693 }
6694
6697 return false;
6698 }
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6713 return false;
6714 }
6715
6718 return false;
6719 }
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", before add custom gcodes\n");
6742 if (proFn) {
6744 if (cb_cancel) return false;
6745 }
6746
6747
6748
6750
6751
6752 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", before add project_settings\n");
6753 if (proFn) {
6755 if (cb_cancel) return false;
6756 }
6757
6758
6759
6760
6761
6762
6764
6765
6767 }
6768
6769
6770 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", before add project embedded settings\n");
6771 if (proFn) {
6773 if (cb_cancel) return false;
6774 }
6775
6776
6778
6780
6781 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", finished add project embedded settings, size %1%\n")%project_presets.size();
6782 if (proFn) {
6784 if (cb_cancel) return false;
6785 }
6786 }
6787 }
6788
6789
6791 for (int i = 0; i < plate_data_list.size(); i++) {
6792 PlateData *plate_data = plate_data_list[i];
6793 if (!plate_data->gcode_file.empty() && plate_data->is_sliced_valid && boost::filesystem::exists(plate_data->gcode_file)) {
6794 unsigned char digest[16];
6795 MD5_CTX ctx;
6796 MD5_Init(&ctx);
6797 auto src_gcode_file = plate_data->gcode_file;
6798 boost::filesystem::ifstream ifs(src_gcode_file, std::ios::binary);
6799 std::string buf(64 * 1024, 0);
6800 const std::size_t & size = boost::filesystem::file_size(src_gcode_file);
6801 std::size_t left_size = size;
6802 while (ifs) {
6803 ifs.read(buf.data(), buf.size());
6804 int read_bytes = ifs.gcount();
6805 MD5_Update(&ctx, (unsigned char *) buf.data(), read_bytes);
6806 }
6807 MD5_Final(digest, &ctx);
6808 char md5_str[33];
6809 for (int j = 0; j < 16; j++) { sprintf(&md5_str[j * 2], "%02X", (unsigned int) digest[j]); }
6810 plate_data->gcode_file_md5 = std::string(md5_str);
6811 std::string target_file = (boost::format("Metadata/plate_%1%.gcode.md5") % (plate_data->plate_index + 1)).str();
6812 if (!mz_zip_writer_add_mem(&archive, target_file.c_str(), (const void *) plate_data->gcode_file_md5.c_str(), plate_data->gcode_file_md5.length(),
6813 MZ_DEFAULT_COMPRESSION)) {
6814 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__
6815 << boost::format(", store gcode md5 to 3mf's %1%, length %2%, failed\n") %target_file %plate_data->gcode_file_md5.length();
6816 return false;
6817 }
6818 }
6819 }
6820 }
6821
6822
6823
6824
6826 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", _add_gcode_file_to_archive failed\n");
6827 return false;
6828 }
6829
6830
6831
6832
6833
6835 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", _add_model_config_file_to_archive failed\n");
6836 return false;
6837 }
6838
6840 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", _add_cut_information_file_to_archive failed\n");
6841 return false;
6842 }
6843
6844
6845 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", before add sliced info to 3mf\n");
6846 if (proFn) {
6848 if (cb_cancel)
6849 return false;
6850 }
6851
6852
6853
6855 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", _add_slice_info_config_file_to_archive failed\n");
6856 return false;
6857 }
6858
6860 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", _add_filament_sequence_file_to_archive failed\n");
6861 return false;
6862 }
6863
6864
6865 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", before add auxiliary dir to 3mf\n");
6866 if (proFn) {
6868 if (cb_cancel)
6869 return false;
6870 }
6871
6873 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", _add_auxiliary_dir_to_archive failed\n");
6874 return false;
6875 }
6876
6877
6878 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", before add relation file to 3mf\n");
6879 if (proFn) {
6881 if (cb_cancel)
6882 return false;
6883 }
6884
6885
6886
6887
6889 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", _add_relationships_file_to_archive failed\n");
6890 return false;
6891 }
6892
6893 if (!mz_zip_writer_finalize_archive(&archive)) {
6894 add_error(
"Unable to finalize the archive");
6895 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", Unable to finalize the archive\n");
6896 return false;
6897 }
6898
6899
6900 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(", finished exporting 3mf\n");
6901 if (proFn) {
6903 if (cb_cancel)
6904 return false;
6905 }
6906
6907 lock.filename =
nullptr;
6908
6909 return true;
6910 }
bool _add_calibration_file_to_archive(mz_zip_archive &archive, const ThumbnailData &thumbnail_data, int index)
Definition bbs_3mf.cpp:7025
bool _add_custom_gcode_per_print_z_file_to_archive(mz_zip_archive &archive, Model &model, const DynamicPrintConfig *config)
Definition bbs_3mf.cpp:9079
bool _add_model_config_file_to_archive(mz_zip_archive &archive, const Model &model, PlateDataPtrs &plate_data_list, const ObjectToObjectDataMap &objects_data, const DynamicPrintConfig &config, int export_plate_idx=-1, bool save_gcode=true, bool use_loaded_id=false)
Definition bbs_3mf.cpp:8296
bool _add_project_embedded_presets_to_archive(mz_zip_archive &archive, Model &model, std::vector< Preset * > project_presets)
Definition bbs_3mf.cpp:8208
bool m_skip_static
Definition bbs_3mf.cpp:6223
bool _add_project_config_file_to_archive(mz_zip_archive &archive, const DynamicPrintConfig &config, Model &model)
Definition bbs_3mf.cpp:8199
bool _add_layer_config_ranges_file_to_archive(mz_zip_archive &archive, Model &model)
Definition bbs_3mf.cpp:7994
bool _add_content_types_file_to_archive(mz_zip_archive &archive)
Definition bbs_3mf.cpp:6934
bool _add_brim_ear_points_file_to_archive(mz_zip_archive &archive, Model &model)
Definition bbs_3mf.cpp:8053
bool _add_layer_height_profile_file_to_archive(mz_zip_archive &archive, Model &model)
Definition bbs_3mf.cpp:7946
bool _add_thumbnail_file_to_archive(mz_zip_archive &archive, const ThumbnailData &thumbnail_data, const char *local_path, int index, bool generate_small_thumbnail=false)
Definition bbs_3mf.cpp:6959
bool _add_model_file_to_archive(const std::string &filename, mz_zip_archive &archive, const Model &model, ObjectToObjectDataMap &objects_data, Export3mfProgressFn proFn=nullptr, BBLProject *project=nullptr) const
Definition bbs_3mf.cpp:7159
std::map< ModelObject const *, ObjectData > ObjectToObjectDataMap
Definition bbs_3mf.cpp:6218
bool _add_gcode_file_to_archive(mz_zip_archive &archive, const Model &model, PlateDataPtrs &plate_data_list, Export3mfProgressFn proFn=nullptr)
Definition bbs_3mf.cpp:9005
bool m_save_gcode
Definition bbs_3mf.cpp:6226
bool _add_cad_recipe_file_to_archive(mz_zip_archive &archive, Model &model)
Definition bbs_3mf.cpp:7981
bool _add_filament_sequence_file_to_archive(mz_zip_archive &archive, const PlateDataPtrs &plate_data_list)
Definition bbs_3mf.cpp:8662
bool _add_cut_information_file_to_archive(mz_zip_archive &archive, Model &model)
Definition bbs_3mf.cpp:7883
bool _add_slice_info_config_file_to_archive(mz_zip_archive &archive, const Model &model, PlateDataPtrs &plate_data_list, const ObjectToObjectDataMap &objects_data, const DynamicPrintConfig &config)
Definition bbs_3mf.cpp:8715
bool _add_auxiliary_dir_to_archive(mz_zip_archive &archive, const std::string &aux_dir, PackingTemporaryData &data)
Definition bbs_3mf.cpp:9136
bool _add_bbox_file_to_archive(mz_zip_archive &archive, const PlateBBoxData &id_bboxes, int index)
Definition bbs_3mf.cpp:7045
const int EXPORT_STAGE_ADD_THUMBNAILS
Definition bbs_3mf.hpp:245
bool close_zip_writer(mz_zip_archive *zip)
Definition miniz_extension.cpp:130
const int EXPORT_STAGE_ADD_CUSTOM_GCODE
Definition bbs_3mf.hpp:250
const int EXPORT_STAGE_OPEN_3MF
Definition bbs_3mf.hpp:243
const int EXPORT_STAGE_ADD_AUXILIARIES
Definition bbs_3mf.hpp:256
const int EXPORT_STAGE_ADD_PRINT_CONFIG
Definition bbs_3mf.hpp:251
bool open_zip_writer(mz_zip_archive *zip, const std::string &fname)
Definition miniz_extension.cpp:124
const int EXPORT_STAGE_CONTENT_TYPES
Definition bbs_3mf.hpp:244
const int EXPORT_STAGE_ADD_SLICE_INFO
Definition bbs_3mf.hpp:254
const int EXPORT_STAGE_FINISH
Definition bbs_3mf.hpp:257
const int EXPORT_STAGE_ADD_PROJECT_CONFIG
Definition bbs_3mf.hpp:252
const int EXPORT_STAGE_ADD_RELATIONS
Definition bbs_3mf.hpp:246
const int EXPORT_STAGE_ADD_CONFIG_FILE
Definition bbs_3mf.hpp:253
bool is_valid(const FontFile &font, unsigned int index)
Definition Emboss.cpp:284
@ lock
Definition GLGizmoEmboss.cpp:209