8949{
8950 if (config_loaded_out != nullptr)
8951 *config_loaded_out = false;
8952
8953 std::vector<size_t> empty_result;
8954 bool dlg_cont = true;
8955 bool is_user_cancel = false;
8956 bool translate_old = false;
8957 int current_width = 0, current_depth = 0, project_filament_count = 1;
8958 double current_height = 0;
8959
8960 if (input_files.empty())
8961 return std::vector<size_t>();
8962
8963 if (!input_files.empty())
8964 q->m_3mf_path = input_files[0].string();
8965
8966
8968
8969
8970
8971 int filaments_cnt =
config->opt<ConfigOptionStrings>(
"filament_colour")->values.size();
8973 if (! one_by_one) {
8974 for (const auto &path : input_files) {
8976 one_by_one = true;
8977 break;
8978 }
8979 }
8980 }
8981
8986
8987 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(
": load_model %1%, load_config %2%, input_files size %3%")%load_model %
load_config %input_files.size();
8988
8989 const auto loading =
_L(
"Loading") +
dots;
8990 ProgressDialog dlg(loading,
"", 100,
find_toplevel_parent(
q), wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_APP_MODAL);
8991 wxBusyCursor busy;
8992
8993 auto *new_model = (!load_model || one_by_one) ? nullptr : new Slic3r::Model();
8994 std::vector<size_t> obj_idxs;
8995
8996 std::string designer_model_id;
8997 std::string designer_country_code;
8998
8999 int answer_convert_from_meters = wxOK_DEFAULT;
9000 int answer_convert_from_imperial_units = wxOK_DEFAULT;
9001 int tolal_model_count = 0;
9002
9003
9004 bool loaded_cad_recipe = false;
9005
9006 int progress_percent = 0;
9007 int total_files = input_files.size();
9009 5,
9010 10,
9011 30,
9012 50,
9013 60,
9014 70,
9015 80,
9016 85,
9017 90,
9018 92,
9019 95,
9020 98,
9021 99,
9022 100
9023 };
9025 5,
9026 30,
9027 60,
9028 100
9029 };
9030
9031 const float INPUT_FILES_RATIO = 0.7;
9032 const float INIT_MODEL_RATIO = 0.75;
9033 const float CENTER_AROUND_ORIGIN_RATIO = 0.8;
9034
9035 const float LOAD_MODEL_RATIO = 0.9;
9036
9037 for (size_t i = 0; i < input_files.size(); ++i) {
9038
9039#ifdef _WIN32
9040 auto path = input_files[i];
9041
9042 path.make_preferred();
9043#else
9044
9045 const auto &path = input_files[i];
9046#endif
9047 const auto filename = path.filename();
9048 int progress_percent = static_cast<int>(100.0f * static_cast<float>(i) / static_cast<float>(input_files.size()));
9049 const auto real_filename = (strategy &
LoadStrategy::Restore) ? input_files[++i].filename() : filename;
9050 const auto dlg_info =
_L(
"Loading file") +
": " +
from_path(real_filename);
9051 BOOST_LOG_TRIVIAL(
trace) << __FUNCTION__ << boost::format(
": load file %1%") % filename;
9052 dlg_cont = dlg.Update(progress_percent, dlg_info);
9053 if (!dlg_cont) return empty_result;
9054
9055 const bool type_3mf = std::regex_match(path.string(),
pattern_3mf);
9056
9057 const bool type_any_amf = !type_3mf && std::regex_match(path.string(),
pattern_any_amf);
9058
9059
9060 Slic3r::Model
model;
9061
9064 load_aux = true;
9066 }
9068 bool is_project_file = false;
9069 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": is_project_file %1%, type_3mf %2%") % is_project_file % type_3mf;
9070 try {
9071 if (type_3mf) {
9072 DynamicPrintConfig
config;
9073 Semver file_version;
9075
9076
9077
9078
9079 PublishedConfig published_config;
9080 {
9081 DynamicPrintConfig config_loaded;
9082
9083
9086 std::vector<Preset *> project_presets;
9087
9088 q->skip_thumbnail_invalid =
true;
9090 &file_version,
9091 [&dlg, real_filename, &progress_percent, stage_percent, INPUT_FILES_RATIO, total_files, i,
9092 &is_user_cancel](int import_stage, int current, int total, bool &cancel) {
9093 bool cont = true;
9094 float percent_float = (100.0f * (float)i / (float)total_files) + INPUT_FILES_RATIO * ((float)stage_percent[import_stage] + (float)current * (float)(stage_percent[import_stage + 1] - stage_percent[import_stage]) /(float) total) / (float)total_files;
9095 BOOST_LOG_TRIVIAL(trace) << "load_3mf_file: percent(float)=" << percent_float << ", stage = " << import_stage << ", curr = " << current << ", total = " << total;
9096 progress_percent = (int)percent_float;
9097 wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename));
9098 cont = dlg.Update(progress_percent, msg);
9099 cancel = !cont;
9100 if (cancel)
9101 is_user_cancel = cancel;
9102 });
9103 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__
9104 << boost::format(", plate_data.size %1%, project_preset.size %2%, is_bbs_or_orca_3mf %3%, file_version %4% \n") % plate_data.size() %
9106
9107
9108
9109
9110
9111
9112
9113 if (
model.model_info !=
nullptr) {
9116 published_config.published = true;
9118 if (keys_it !=
model.model_info->metadata_items.end()) {
9119 try {
9120 auto j = nlohmann::json::parse(keys_it->second);
9121 if (j.is_array())
9122 for (const auto& k : j)
9123 if (k.is_string())
9124 published_config.published_keys.emplace_back(k.get<std::string>());
9125 } catch (...) {
9126
9127 }
9128 }
9129
9131 if (material_keys_it !=
model.model_info->metadata_items.end()) {
9132 try {
9133 auto jm = nlohmann::json::parse(material_keys_it->second);
9134 if (jm.is_array())
9135 for (const auto& m : jm) {
9136 try {
9137
9138
9139 if (!m.is_object())
9140 continue;
9141 PublishedMaterialEntry entry;
9142 const auto mat_it = m.find("material");
9143 if (mat_it != m.end() && mat_it->is_object()) {
9144 const auto& mat = *mat_it;
9145 if (mat.contains("filament_type") && mat["filament_type"].is_string())
9146 entry.filament_type = mat["filament_type"].get<std::string>();
9147 if (mat.contains("filament_vendor") && mat["filament_vendor"].is_string())
9148 entry.filament_vendor = mat["filament_vendor"].get<std::string>();
9149 if (mat.contains("filament_id") && mat["filament_id"].is_string())
9150 entry.filament_id = mat["filament_id"].get<std::string>();
9151 if (mat.contains("setting_id") && mat["setting_id"].is_string())
9152 entry.setting_id = mat["setting_id"].get<std::string>();
9153 if (mat.contains("name") && mat["name"].is_string())
9154 entry.preset_name = mat["name"].get<std::string>();
9155 }
9156 if (m.contains("slot") && m["slot"].is_number_integer())
9157 entry.slot = m["slot"].get<int>();
9158 const auto entry_keys_it = m.find("keys");
9159 if (entry_keys_it != m.end() && entry_keys_it->is_array())
9160 for (const auto& k : *entry_keys_it)
9161 if (k.is_string())
9162 entry.keys.emplace_back(k.get<std::string>());
9163
9164 if (m.contains("full") && m["full"].is_boolean())
9165 entry.full = m["full"].get<bool>();
9166 const auto entry_full_keys_it = m.find("full_keys");
9167 if (entry_full_keys_it != m.end() && entry_full_keys_it->is_array())
9168 for (const auto& k : *entry_full_keys_it)
9169 if (k.is_string())
9170 entry.full_keys.emplace_back(k.get<std::string>());
9171 if (m.contains("publish_type") && m["publish_type"].is_boolean())
9172 entry.publish_type = m["publish_type"].get<bool>();
9173 if (m.contains("type") && m["type"].is_string())
9174 entry.publish_type_value = m["type"].get<std::string>();
9175 if (m.contains("publish_color") && m["publish_color"].is_boolean())
9176 entry.publish_color = m["publish_color"].get<bool>();
9177 if (m.contains("color") && m["color"].is_string())
9178 entry.color = m["color"].get<std::string>();
9179 published_config.material_keys.emplace_back(std::move(entry));
9180 } catch (const nlohmann::json::exception&) {
9181
9182 }
9183 }
9184 } catch (const nlohmann::json::exception&) {
9185
9186 }
9187 }
9188
9189
9190
9191
9192
9194 if (payload_it !=
model.model_info->metadata_items.end()) {
9195 try {
9198 config_substitutions.substitutions.insert(config_substitutions.substitutions.end(),
9199 std::make_move_iterator(payload_substitutions.begin()),
9200 std::make_move_iterator(payload_substitutions.end()));
9201 } catch (...) {
9202
9203 }
9204 }
9205 }
9206 }
9207
9208
9209
9211 std::set<int> extruderIds;
9212 for (ModelObject *o :
model.objects) {
9213 if (o->config.option("extruder")) extruderIds.insert(o->config.extruder());
9214 for (auto volume : o->volumes) {
9215 if (volume->config.option("extruder")) extruderIds.insert(volume->config.extruder());
9216 for (int extruder : volume->get_extruders()) { extruderIds.insert(extruder); }
9217 }
9218 }
9219 int size = extruderIds.size() == 0 ? 0 : *(extruderIds.rbegin());
9220
9221 int filament_size =
sidebar->combos_filament().size();
9223 int filament_count = filament_size + 1;
9225 std::string new_color = new_col.GetAsString(wxC2S_HTML_SYNTAX).ToStdString();
9226 wxGetApp().preset_bundle->set_num_filaments(filament_count, new_color);
9227 wxGetApp().plater()->on_filament_count_change(filament_count);
9228 ++filament_size;
9229 }
9231 }
9232
9233 std::string import_project_action = wxGetApp().app_config->get("import_project_action");
9235 if (import_project_action.empty())
9237 else
9238 load_type =
static_cast<LoadType>(std::stoi(import_project_action));
9239
9240
9242 const wxString load_3mf_title =
_L(
"Load 3MF");
9243 const wxString newer_3mf_title =
_L(
"Newer 3MF version");
9244 const wxString msg_unsupported_geometry =
_L(
"The 3MF is not supported by OrcaSlicer, loading geometry data only.");
9245 const wxString msg_old_orca_geometry =
_L(
"The 3MF file was generated by an old OrcaSlicer version, loading geometry data only.");
9246 const wxString msg_older_geometry =
_L(
"The 3MF file was generated by an older version, loading geometry data only.");
9247 const wxString msg_bambu_geometry =
_L(
"The 3MF file was generated by BambuStudio, loading geometry data only.");
9248 auto log_and_show_3mf_info = [&](const wxString& text, const wxString& title) {
9249 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__
9250 << " "
9251 << boost::format(
"3MF import message [%1%]: %2% | file: %3%") %
into_u8(title) %
into_u8(text) % path.string();
9253 };
9254
9255 const bool is_bambu_studio_project = en_3mf_file_type ==
En3mfType::From_BBS && file_version > Semver(2, 3, 2);
9257
9260 log_and_show_3mf_info(msg_unsupported_geometry, load_3mf_title);
9261 }
9263
9264
9265 if (
load_config && (file_version < app_version) && file_version == Semver(
"2.3.1-alpha")) {
9266 if (!config_loaded.opt_string("sparse_infill_rotate_template").empty()) {
9267 const auto _sparse_infill_pattern =
9268 config_loaded.option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->value;
9269 bool is_safe_to_rotate = _sparse_infill_pattern ==
ipRectilinear || _sparse_infill_pattern ==
ipLine ||
9272 if (!is_safe_to_rotate) {
9273 wxString msg_text =
_(
9274 L(
"This project was created with an OrcaSlicer 2.3.1-alpha and uses "
9275 "infill rotation template settings that may not work properly with your current infill pattern. "
9276 "This could result in weak support or print quality issues."));
9277 msg_text += "\n\n" +
9278 _(
L(
"Would you like OrcaSlicer to automatically fix this by clearing the rotation template settings?"));
9279 MessageDialog dialog(wxGetApp().
plater(), msg_text,
"", wxICON_WARNING | wxYES | wxNO);
9280 dialog.SetButtonLabel(wxID_YES,
_L(
"Yes"));
9281 dialog.SetButtonLabel(wxID_NO,
_L(
"No"));
9282 if (dialog.ShowModal() == wxID_YES) {
9283 config_loaded.opt_string("sparse_infill_rotate_template") = "";
9284 }
9285 }
9286 }
9287 }
else if (
load_config && (file_version > app_version)) {
9288 if (config_substitutions.unrecogized_keys.size() > 0) {
9289 wxString text = wxString::Format(
_L(
"The 3MF file version %s is newer than %s's version %s, found the following unrecognized keys:"),
9291 text +=
"\n" +
from_u8(boost::algorithm::join(config_substitutions.unrecogized_keys,
", ")) +
"\n\n";
9292 text +=
_L(
"You should update your software.\n");
9293 log_and_show_3mf_info(text, newer_3mf_title);
9294 }
9295 else {
9296
9297 if (file_version.min() != app_version.min()) {
9298 wxString text = wxString::Format(
_L(
"The 3MF file version %s is newer than %s's version %s, we suggest to upgrade your software."),
9300 text += "\n";
9301 log_and_show_3mf_info(text, newer_3mf_title);
9302 }
9303 }
9304 }
9307 log_and_show_3mf_info(msg_old_orca_geometry, load_3mf_title);
9308 }
9309 }
9311
9312 if (!is_bambu_studio_project) {
9313
9314
9315
9316 if (
load_config && (file_version == Semver(
"2.3.1-alpha"))) {
9317 if (!config_loaded.opt_string("sparse_infill_rotate_template").empty()) {
9318 const auto _sparse_infill_pattern =
9319 config_loaded.option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->value;
9320 bool is_safe_to_rotate = _sparse_infill_pattern ==
ipRectilinear || _sparse_infill_pattern ==
ipLine ||
9323 if (!is_safe_to_rotate) {
9324 wxString msg_text =
_(
9325 L(
"This project was created with an OrcaSlicer 2.3.1-alpha and uses "
9326 "infill rotation template settings that may not work properly with your current infill pattern. "
9327 "This could result in weak support or print quality issues."));
9328 msg_text += "\n\n" +
9329 _(
L(
"Would you like OrcaSlicer to automatically fix this by clearing the rotation template settings?"));
9330 MessageDialog dialog(wxGetApp().
plater(), msg_text,
"", wxICON_WARNING | wxYES | wxNO);
9331 dialog.SetButtonLabel(wxID_YES,
_L(
"Yes"));
9332 dialog.SetButtonLabel(wxID_NO,
_L(
"No"));
9333 if (dialog.ShowModal() == wxID_YES) {
9334 config_loaded.opt_string("sparse_infill_rotate_template") = "";
9335 }
9336 }
9337 }
9338 }
9341 log_and_show_3mf_info(msg_older_geometry, load_3mf_title);
9342 }
9343 } else {
9344
9347 log_and_show_3mf_info(msg_bambu_geometry, load_3mf_title);
9348 }
9350
9351 const std::string unrecognized = boost::algorithm::join(config_substitutions.unrecogized_keys, ", ");
9352 BOOST_LOG_TRIVIAL(info) << "BambuStudio " << file_version.to_string() << " project " << path.string()
9353 << ", unrecognized settings: " << (unrecognized.empty() ? "none" : unrecognized);
9354 }
9355 }
9356 }
9358
9360 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__
9361 << " "
9362 << boost::format("3MF has no slicer metadata/project config, importing geometry only: %1%") % path.string();
9364 }
9365 }
9368 log_and_show_3mf_info(msg_old_orca_geometry, load_3mf_title);
9369 }
9371
9372 for (ModelObject *model_object :
model.objects) {
9373 bool has_extruder = model_object->config.has("extruder");
9374 int extruder_id = -1;
9375
9376 if (has_extruder) { extruder_id = model_object->config.extruder(); }
9377
9378 model_object->config.reset();
9379
9380
9381 if (has_extruder) { model_object->config.set("extruder", extruder_id); }
9382
9383
9384 for (ModelVolume *model_volume : model_object->volumes) {
9385 has_extruder = model_volume->config.has("extruder");
9386 if (has_extruder) { extruder_id = model_volume->config.extruder(); }
9387
9388 model_volume->config.reset();
9389
9390 if (has_extruder) { model_volume->config.set("extruder", extruder_id); }
9391 }
9392 }
9393 }
9394
9395
9396
9397
9398
9399
9400 if (plate_data.size() > 0) {
9401 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", import 3mf UPDATE_GCODE_RESULT \n");
9402 wxString msg = wxString::Format(
_L(
"Loading file: %s"),
from_path(real_filename));
9403 dlg_cont = dlg.Update(progress_percent, msg);
9404 if (!dlg_cont) {
9405 q->skip_thumbnail_invalid =
false;
9406 return empty_result;
9407 }
9408
9409 Semver old_version(1, 5, 9);
9410
9411
9413 translate_old = true;
9414 partplate_list.get_plate_size(current_width, current_depth, current_height);
9415 }
9416
9418 if (translate_old) {
9419
9421 }
9422 project_filament_count = config_loaded.option<ConfigOptionStrings>("filament_colour")->size();
9423 partplate_list.load_from_3mf_structure(plate_data, project_filament_count);
9427 sidebar->obj_list()->reload_all_plates();
9428 q->suppress_background_process(
true);
9429 } else {
9431 }
9432 }
9433
9434
9435
9436
9437 if ((project_presets.size() > 0) &&
load_config && !published_config.published) {
9438
9440 PresetBundle & preset_bundle = *wxGetApp().preset_bundle;
9442 if (is_bambu_studio_project)
9444 else if (!preset_substitutions.empty())
9446 }
9447 if (project_presets.size() > 0) {
9448 for (unsigned int i = 0; i < project_presets.size(); i++) { delete project_presets[i]; }
9449 project_presets.clear();
9450 }
9451
9453 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", import 3mf IMPORT_LOAD_CONFIG \n");
9454 wxString msg = wxString::Format(
_L(
"Loading file: %s"),
from_path(real_filename));
9455 dlg_cont = dlg.Update(progress_percent, msg);
9456 if (!dlg_cont) {
9457 q->skip_thumbnail_invalid =
false;
9458 return empty_result;
9459 }
9460
9461
9463
9464 config.apply(
static_cast<const ConfigBase &
>(FullPrintConfig::defaults()));
9465
9466 config += std::move(config_loaded);
9467 std::map<std::string, std::string> validity =
config.validate();
9468 if (!validity.empty()) {
9469 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << " " << boost::format("Param values in 3mf error: ");
9470 for (std::map<std::string, std::string>::iterator it=validity.begin(); it!=validity.end(); ++it)
9471 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << " " << boost::format("%1%: %2%")%it->first %it->second;
9472
9473 NotificationManager *notify_manager =
q->get_notification_manager();
9474 std::string error_message =
_u8L(
"Invalid values found in the 3MF:");
9475 error_message += "\n";
9476 for (std::map<std::string, std::string>::iterator it=validity.begin(); it!=validity.end(); ++it)
9477 error_message += "-" + it->first + ": " + it->second + "\n";
9478 error_message += "\n";
9479 error_message +=
_u8L(
"Please correct them in the Param tabs");
9480 notify_manager->bbl_show_3mf_warn_notification(error_message);
9481 }
9482 }
9483
9484 if (is_bambu_studio_project)
9486 else if (!config_substitutions.empty())
9488
9489
9491 ;
9492 }
9493 else {
9494 this->
model.plates_custom_gcodes =
model.plates_custom_gcodes;
9497 }
9498 }
9499
9500
9501
9502
9503
9504 if (published_out != nullptr && published_config.published)
9505 *published_out = true;
9506 if (published_config.published &&
load_config && this->model.model_info !=
nullptr) {
9511 }
9512
9516 PresetBundle *preset_bundle = wxGetApp().preset_bundle;
9517
9518 {
9519
9520 Semver old_version3(2, 0, 0);
9522 double old_filament_prime_volume = 0.;
9523 int filament_count = 0;
9524 {
9526 ConfigOptionStrings *filament_colors_option =
config.option<ConfigOptionStrings>(
"filament_colour",
true);
9527 filament_count = filament_colors_option->values.size();
9528 if (filament_prime_volume_option) {
9529 std::vector<double> &filament_prime_volume_values = filament_prime_volume_option->values;
9530 if (!filament_prime_volume_values.empty()) {
9531 old_filament_prime_volume = filament_prime_volume_values[0];
9532 if (filament_count > 1) filament_prime_volume_values.resize(filament_count, old_filament_prime_volume);
9533 }
9534 }
9535 }
9536 ConfigOptionEnum<WipeTowerWallType> *prime_tower_rib_wall_option =
config.option<ConfigOptionEnum<WipeTowerWallType>>(
"wipe_tower_wall_type",
true);
9538
9539 ConfigOptionPercent *prime_tower_infill_gap_option =
config.option<ConfigOptionPercent>(
"prime_tower_infill_gap",
true);
9540 prime_tower_infill_gap_option->value = 100;
9541
9543 std::vector<int> &filament_adhesiveness_category_values = filament_adhesiveness_category_option->
values;
9544 filament_adhesiveness_category_values.resize(filament_count);
9545 for (int index = 0; index < filament_count; index++)
9546 filament_adhesiveness_category_values[index] = 100;
9547
9548 std::vector<std::string> &diff_settings =
config.option<ConfigOptionStrings>(
"different_settings_to_system",
true)->values;
9549 diff_settings.resize(filament_count + 2);
9550
9551 std::vector<std::string> diff_process_keys;
9552 std::string diff_process_settings = diff_settings[0];
9554 diff_process_keys.emplace_back("wipe_tower_wall_type");
9555 diff_process_keys.emplace_back("prime_tower_infill_gap");
9557 diff_settings[0] = diff_process_settings;
9558
9559 for (int index = 0; index < filament_count; index++) {
9560 std::vector<std::string> diff_filament_keys;
9561 std::string diff_filament_settings = diff_settings[index + 1];
9563 diff_filament_keys.emplace_back("filament_adhesiveness_category");
9565 diff_settings[index + 1] = diff_filament_settings;
9566 }
9567 }
9568 }
9569
9570 auto choise = wxGetApp().app_config->get("no_warn_when_modified_gcodes");
9571 if (!published_config.published && (choise.empty() || choise != "true")) {
9572
9573
9574 std::set<std::string> modified_gcodes;
9575 int validated = preset_bundle->validate_presets(filename.string(),
config, modified_gcodes);
9577 std::string warning_message;
9578 warning_message += "\n";
9579 for (std::set<std::string>::iterator it=modified_gcodes.begin(); it!=modified_gcodes.end(); ++it)
9580 warning_message += "-" + *it + "\n";
9581 warning_message += "\n";
9582
9583 MessageDialog dlg(
q,
_L(
"The 3MF has the following modified G-code in filament or printer presets:") + warning_message +
_L(
"Please confirm that all modified G-code is safe to prevent any damage to the machine!"),
_L(
"Modified G-code"));
9584 dlg.show_dsa_button();
9585 auto res = dlg.ShowModal();
9586 if (dlg.get_checkbox_state())
9587 wxGetApp().app_config->set("no_warn_when_modified_gcodes", "true");
9588 }
9590 std::string warning_message;
9591 warning_message += "\n";
9592 for (std::set<std::string>::iterator it=modified_gcodes.begin(); it!=modified_gcodes.end(); ++it)
9593 warning_message += "-" + *it + "\n";
9594 warning_message += "\n";
9595
9596 MessageDialog dlg(
q,
_L(
"The 3MF has the following customized filament or printer presets:") +
from_u8(warning_message)+
_L(
"Please confirm that the G-code within these presets is safe to prevent any damage to the machine!"),
_L(
"Customized Preset"));
9597 dlg.show_dsa_button();
9598 auto res = dlg.ShowModal();
9599 if (dlg.get_checkbox_state())
9600 wxGetApp().app_config->set("no_warn_when_modified_gcodes", "true");
9601 }
9602 }
9603
9604
9605 {
9606
9609 std::optional<ConfigOptionFloats>file_wipe_tower_x;
9610 std::optional<ConfigOptionFloats>file_wipe_tower_y;
9611 if (wipe_tower_x_opt)
9612 file_wipe_tower_x = *wipe_tower_x_opt;
9613 if (wipe_tower_y_opt)
9614 file_wipe_tower_y = *wipe_tower_y_opt;
9615
9616
9617 if (auto* agent = wxGetApp().getAgent()) {
9618 if (
auto* ids =
config.opt<ConfigOptionStrings>(
"filament_ids"))
9619 for (std::string& id : ids->values)
9620 id = agent->to_orca_filament_id(id);
9621 }
9622 preset_bundle->load_config_model(filename.string(), std::move(
config), file_version, &published_config);
9623 if (config_loaded_out != nullptr)
9624 *config_loaded_out = true;
9625
9626
9627
9628
9629
9630
9631
9632 if (load_model && !published_config.mixed_slot_relocations.empty())
9634
9635
9636 if (!published_config.skipped_keys.empty()) {
9637 NotificationManager* notify_manager =
q->get_notification_manager();
9638 std::string message =
_u8L(
"Some published settings could not be applied:");
9639 for (const std::string& key : published_config.skipped_keys)
9640 message += "\n-" + key;
9641
9642 notify_manager
9643 ->bbl_show_3mf_warn_notification(message,
9645 }
9646
9647
9648
9649 if (!published_config.material_replacements.empty()) {
9650 NotificationManager* notify_manager =
q->get_notification_manager();
9651 std::string message =
_u8L(
"Some filament slots were changed:");
9652 for (const std::string& replacement : published_config.material_replacements)
9653 message += "\n-" + replacement;
9654
9655 notify_manager
9656 ->bbl_show_3mf_warn_notification(message,
9658 }
9659
9660
9661
9662
9663 if (published_config.published) {
9667 }
9668
9669 ConfigOption* bed_type_opt = preset_bundle->project_config.option("curr_bed_type");
9670 if (bed_type_opt != nullptr) {
9672
9673 bool is_bbl_preset = preset_bundle->is_bbl_vendor();
9674 if (is_bbl_preset) {
9675 AppConfig* app_config = wxGetApp().app_config;
9676 if (app_config)
9677 app_config->set("curr_bed_type", std::to_string(int(bed_type)));
9678 }
9679 q->on_bed_type_change(bed_type);
9680 }
9681
9682
9683
9684
9685
9686
9687
9688
9689
9690
9691
9692
9693
9694
9695
9696
9697
9698
9699
9700
9701
9702
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733
9734
9735
9736 wxGetApp().load_current_presets(false, false);
9737
9738
9739
9740 q->on_filament_count_change(preset_bundle->filament_presets.size());
9741 is_project_file = true;
9742
9743 DynamicConfig& proj_cfg = preset_bundle->project_config;
9744
9745 {
9746
9749 if (file_wipe_tower_x)
9750 *wipe_tower_x = *file_wipe_tower_x;
9751 if (file_wipe_tower_y)
9753
9755 }
9756
9757 if (published_config.published) {
9758 q->update_filament_colors_in_full_config();
9759 wxGetApp().plater()->sidebar().update_all_preset_comboboxes();
9760 wxGetApp().plater()->sidebar().update_dynamic_filament_list();
9761 } else {
9763 }
9764
9765
9766 if (
auto *nozzle_volumes = wxGetApp().preset_bundle->project_config.option<
ConfigOptionEnumsGeneric>(
"nozzle_volume_type")) {
9767 const int extruder_count = wxGetApp().preset_bundle->get_printer_extruder_count();
9768 for (int extruder_id = 0; extruder_id < extruder_count && extruder_id < (int) nozzle_volumes->values.size(); ++extruder_id)
9770 }
9771 }
9772 }
9773 if (!silence) wxGetApp().app_config->update_config_dir(path.parent_path().string());
9774 }
9775 } else {
9776
9778
9779 std::vector<Preset *> project_presets;
9780 bool is_xxx;
9781 Semver file_version;
9782
9783 if (boost::iends_with(path.string(), ".stp") ||
9784 boost::iends_with(path.string(), ".step")) {
9786 if (linear <= 0) linear = 0.003;
9789 bool split_compound = wxGetApp().app_config->get_bool("is_split_compound");
9791 [&dlg, real_filename, &progress_percent, step_percent, INPUT_FILES_RATIO, total_files, i](int load_stage, int current, int total, bool &cancel)
9792 {
9793 bool cont = true;
9794 float percent_float = (100.0f * (float)i / (float)total_files) + INPUT_FILES_RATIO * ((float)step_percent[load_stage] + (float)current * (float)(step_percent[load_stage + 1] - step_percent[load_stage]) / (float)total) / (float)total_files;
9795 BOOST_LOG_TRIVIAL(trace) << "load_step_file: percent(float)=" << percent_float << ", stage = " << load_stage << ", curr = " << current << ", total = " << total;
9796 progress_percent = (int)percent_float;
9797 wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename));
9798 cont = dlg.Update(progress_percent, msg);
9799 cancel = !cont;
9800 },
9801 [](int isUtf8StepFile) {
9802 if (!isUtf8StepFile) {
9803 const auto no_warn = wxGetApp().app_config->get_bool("step_not_utf8_no_warn");
9804 if (!no_warn) {
9805 MessageDialog dlg(nullptr, _L("Component name(s) inside step file not in UTF-8 format!") + "\n\n" + _L("Because of unsupported text encoding, garbage characters may appear!"),
9806 wxString(SLIC3R_APP_FULL_NAME " - ") + _L("Attention!"), wxOK | wxICON_INFORMATION);
9807 dlg.show_dsa_button(_L("Remember my choice."));
9808 dlg.ShowModal();
9809 if (dlg.get_checkbox_state()) {
9810 wxGetApp().app_config->set_bool("step_not_utf8_no_warn", true);
9811 }
9812 }
9813 }
9814 },
9815 [&is_user_cancel, &linear, &
angle, &split_compound](Slic3r::Step& file,
double& linear_value,
double& angle_value,
bool& is_split)->
int {
9816 if (wxGetApp().app_config->get_bool("enable_step_mesh_setting")) {
9817 StepMeshDialog mesh_dlg(
nullptr, file, linear,
angle);
9818 if (mesh_dlg.ShowModal() == wxID_OK) {
9819 linear_value = mesh_dlg.get_linear_deflection();
9820 angle_value = mesh_dlg.get_angle_deflection();
9821 is_split = mesh_dlg.get_split_compound_value();
9822 return 1;
9823 }
9824 }else {
9825 linear_value = linear;
9826 angle_value =
angle;
9827 is_split = split_compound;
9828 return 1;
9829 }
9830 is_user_cancel = true;
9831 return -1;
9832 }, linear,
angle, split_compound);
9833 }else {
9835 path.string(), nullptr, nullptr, strategy, &plate_data, &project_presets, &is_xxx, &file_version, nullptr,
9836 [&dlg, real_filename, &progress_percent, INPUT_FILES_RATIO, total_files, i, &designer_model_id, &designer_country_code](int current, int total, bool &cancel, std::string &mode_id, std::string &code)
9837 {
9838 designer_model_id = mode_id;
9839 designer_country_code = code;
9840
9841 bool cont = true;
9842 float percent_float = (100.0f * (float)i / (float)total_files) + INPUT_FILES_RATIO * 100.0f * ((float)current / (float)total) / (float)total_files;
9843 BOOST_LOG_TRIVIAL(trace) << "load_stl_file: percent(float)=" << percent_float << ", curr = " << current << ", total = " << total;
9844 progress_percent = (int)percent_float;
9845 wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename));
9846 cont = dlg.Update(progress_percent, msg);
9847 cancel = !cont;
9848 },
9849 nullptr, 0);
9850 }
9851
9852 if (designer_model_id.empty() && boost::algorithm::iends_with(path.string(), ".stl")) {
9853 read_binary_stl(path.string(), designer_model_id, designer_country_code);
9854 }
9855
9856 if (type_any_amf && is_xxx) imperial_units = true;
9857
9858 for (
auto obj :
model.objects) {
9859 if (obj->name.empty()) {
9860 obj->name = fs::path(obj->input_file).filename().string();
9861 }
9863 }
9864
9865 if (plate_data.size() > 0) {
9866 partplate_list.load_from_3mf_structure(plate_data, project_filament_count);
9870 sidebar->obj_list()->reload_all_plates();
9871 }
9872
9873
9874 if (project_presets.size() > 0) {
9875
9877 PresetBundle & preset_bundle = *wxGetApp().preset_bundle;
9880
9881 for (unsigned int i = 0; i < project_presets.size(); i++) { delete project_presets[i]; }
9882 project_presets.clear();
9883 }
9884 }
9885 } catch (const ConfigurationError &e) {
9886 std::string message =
GUI::format(
_L(
"Failed loading file \"%1%\". An invalid configuration was found."), filename.string()) +
"\n\n" + e.what();
9888 continue;
9889 } catch (const std::exception &e) {
9890 if (!is_user_cancel)
9892 continue;
9893 }
9894
9895 progress_percent = 100.0f * (float)i / (float)total_files + INIT_MODEL_RATIO * 100.0f / (float)total_files;
9896 dlg_cont = dlg.Update(progress_percent);
9897 if (!dlg_cont) {
9898 q->skip_thumbnail_invalid =
false;
9899 return empty_result;
9900 }
9901
9902 if (load_model) {
9903
9904 auto convert_from_imperial_units = [](Model &
model,
bool only_small_volumes) {
model.convert_from_imperial_units(only_small_volumes); };
9905
9906
9907 if ((!is_project_file) && (!load_old_project)) {
9908
9909 if (
int deleted_objects =
model.removed_objects_with_zero_volume(); deleted_objects > 0) {
9910 MessageDialog(
q,
_L(
"Objects with zero volume removed"),
_L(
"The volume of the object is zero"), wxICON_INFORMATION | wxOK).ShowModal();
9911 }
9912 if (imperial_units)
9913
9914 convert_from_imperial_units(
model,
false);
9915 else if (
model.looks_like_saved_in_meters()) {
9916
9917 MessageDialog dlg(
q,
9918 format_wxstr(
_L(
"The object from file %s is too small, and may be in meters or inches.\nDo you want to scale to millimeters\?"),
9920 _L(
"Object too small"), wxICON_QUESTION | wxYES_NO);
9921 int answer = dlg.ShowModal();
9922 if (answer == wxID_YES)
model.convert_from_meters(
true);
9923 }
else if (
model.looks_like_imperial_units()) {
9924
9925 MessageDialog dlg(
q,
9926 format_wxstr(
_L(
"The object from file %s is too small, and may be in meters or inches.\nDo you want to scale to millimeters\?"),
9928 _L(
"Object too small"), wxICON_QUESTION | wxYES_NO);
9929 int answer = dlg.ShowModal();
9930 if (answer == wxID_YES) convert_from_imperial_units(
model,
true);
9931 }
9932
9933
9934
9935
9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950
9951
9952
9953
9954 }
9955
9956 if (!is_project_file &&
model.looks_like_multipart_object()) {
9957 MessageDialog msg_dlg(
q,
_L(
"This file contains several objects positioned at multiple heights.\nInstead of considering them as multiple objects, should \nthe file be loaded as a single object with multiple parts\?") +
"\n",
9958 _L(
"Multi-part object detected"), wxICON_WARNING | wxYES | wxNO);
9959 if (msg_dlg.ShowModal() == wxID_YES) {
9960 model.convert_multipart_object(filaments_cnt);
9961 }
9962 }
9963 }
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975 progress_percent = 100.0f * (float)i / (float)total_files + CENTER_AROUND_ORIGIN_RATIO * 100.0f / (float)total_files;
9976 dlg_cont = dlg.Update(progress_percent);
9977 if (!dlg_cont) {
9978 q->skip_thumbnail_invalid =
false;
9979 return empty_result;
9980 }
9981
9982 int model_idx = 0;
9983 for (ModelObject *model_object :
model.objects) {
9984 if (!type_3mf && !type_any_amf)
9985 model_object->center_around_origin(false);
9986
9987
9988 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << " " << boost::format("import 3mf IMPORT_LOAD_MODEL_OBJECTS \n");
9989 wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename));
9990 model_idx++;
9991 dlg_cont = dlg.Update(progress_percent, msg);
9992 if (!dlg_cont) {
9993 q->skip_thumbnail_invalid = false;
9994 return empty_result;
9995 }
9996
9997 if (!model_object->instances.empty())
9998 model_object->ensure_on_bed(is_project_file);
9999 }
10000
10001 tolal_model_count += model_idx;
10002
10003 progress_percent = 100.0f * (float)i / (float)total_files + LOAD_MODEL_RATIO * 100.0f / (float)total_files;
10004 dlg_cont = dlg.Update(progress_percent);
10005 if (!dlg_cont) {
10006 q->skip_thumbnail_invalid =
false;
10007 return empty_result;
10008 }
10009
10010 if (one_by_one) {
10011
10012 if (type_3mf && !is_project_file && !load_old_project)
10013
10014 model.center_instances_around_point(this->
bed.build_volume().bed_center());
10015
10016
10017 if (load_aux) {
10018 q->model().load_from(
model);
10020 }
10021
10022
10023
10026 auto cancel_cb = [&dlg, &dlg_cont]() { return !dlg_cont || dlg.WasCancelled(); };
10027 auto progress_cb = [&dlg, &dlg_cont, &progress_percent](int percent) {
10028 progress_percent = std::clamp(percent, 0, 100);
10029 dlg_cont = dlg.Update(progress_percent,
_L(
"Matching textures to filaments"));
10030 return dlg_cont;
10031 };
10033 q->skip_thumbnail_invalid =
false;
10034 return empty_result;
10035 }
10036 if (texture_import_result.fallback_to_geometry_only && !texture_import_result.fallback_warning.empty()) {
10037 MessageDialog(
q, texture_import_result.fallback_warning,
10038 _L(
"Texture Import Warning"),
10039 wxOK | wxICON_WARNING).ShowModal();
10040 }
10041 if (!texture_import_result.painted.face_colors.empty()) {
10042 std::vector<size_t> texture_object_idxs(
model.objects.size());
10043 std::iota(texture_object_idxs.begin(), texture_object_idxs.end(), 0);
10044 auto apply_progress_cb = [&dlg](int percent, const wxString& msg) {
10045 dlg.Update(std::clamp(percent, 0, 100), msg);
10046 return true;
10047 };
10049 apply_progress_cb, false);
10050 }
10051 }
10052
10053 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ <<
":" << __LINE__ << boost::format(
", before load_model_objects, count %1%")%
model.objects.size();
10055 obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end());
10056
10057
10058
10059
10060
10061
10062 if (is_project_file) {
10063 q->model().cad_recipe =
model.cad_recipe;
10064 loaded_cad_recipe = !
model.cad_recipe.empty();
10065 }
10066
10067 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", finished load_model_objects");
10068 wxString msg = wxString::Format(
_L(
"Loading file: %s"),
from_path(real_filename));
10069 dlg_cont = dlg.Update(progress_percent, msg);
10070 if (!dlg_cont) {
10071 q->skip_thumbnail_invalid =
false;
10072 return empty_result;
10073 }
10074 } else {
10075
10076 for (
const ModelObject *model_object :
model.objects) {
10077 new_model->add_object(*model_object);
10078
10079 BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":" << __LINE__ << boost::format(", added object %1%")%model_object->name;
10080 wxString msg = wxString::Format(
_L(
"Loading file: %s"),
from_path(real_filename));
10081 dlg_cont = dlg.Update(progress_percent, msg);
10082 if (!dlg_cont) {
10083 q->skip_thumbnail_invalid =
false;
10084 return empty_result;
10085 }
10086 }
10087 }
10088 }
10089
10090 if (new_model != nullptr && new_model->objects.size() > 1) {
10091
10092
10093 bool new_model_auto_drop = true;
10094 int single_object_answer = false;
10095 if (ask_multi) {
10096 RichMessageDialog dlg(
q,
_L(
"Load these files as a single object with multiple parts?\n"),
10097 _L(
"An object with multiple parts was detected"), wxICON_QUESTION | wxYES_NO);
10098
10099 dlg.ShowCheckBox(
_L(
"Auto-Drop"),
true);
10100 single_object_answer = dlg.ShowModal();
10101
10102 if (dlg.IsCheckBoxChecked() == false)
10103 new_model_auto_drop = false;
10104
10105
10106
10107 if (single_object_answer == wxID_YES || new_model_auto_drop == false)
10108 new_model->convert_multipart_object(filaments_cnt);
10109 }
10110
10111
10112
10113
10114
10115
10116
10117
10118 auto loaded_idxs =
load_model_objects(new_model->objects,
false,
false, new_model_auto_drop);
10119 obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end());
10120
10121 if (single_object_answer == wxID_NO && new_model_auto_drop == false) {
10123 }
10124 }
10125
10127 DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
10128 if (dev) {
10129 MachineObject *obj = dev->get_selected_machine();
10130 if (obj && obj->is_info_ready()) {
10131 if (obj->GetExtderSystem()->GetTotalExtderCount() > 0) {
10132 PresetBundle *preset_bundle = wxGetApp().preset_bundle;
10133 Preset &printer_preset = preset_bundle->printers.get_selected_preset();
10134
10135 double preset_nozzle_diameter = 0.4;
10136 const ConfigOption *opt = printer_preset.config.option("nozzle_diameter");
10137 if (opt) preset_nozzle_diameter =
static_cast<const ConfigOptionFloats *
>(opt)->values[0];
10138
10139 std::string machine_type = obj->printer_type;
10140 if (obj->is_support_upgrade_kit && obj->installed_upgrade_kit) machine_type = "C12";
10141
10142 bool nozzle_mismatch = !obj->GetExtderSystem()->NozzleDiameterMatchesOrUnknown(0, (float) preset_nozzle_diameter);
10143 if (printer_preset.get_current_printer_type(preset_bundle) != machine_type || nozzle_mismatch) {
10145 if (machine_preset != nullptr) {
10146 std::string printer_model = machine_preset->config.option<
ConfigOptionString>(
"printer_model")->value;
10147 bool sync_printer_info = false;
10148 if (!wxGetApp().app_config->has("sync_after_load_file_show_flag")) {
10149 wxString tips =
from_u8((boost::format(
_u8L(
"Connected printer is %s. It must match the project preset for printing.\n")) % printer_model).str());
10150
10151 tips +=
_L(
"Do you want to sync the printer information and automatically switch the preset?");
10152 TipsDialog dlg(wxGetApp().mainframe,
_L(
"Tips"), tips,
"sync_after_load_file_show_flag", wxYES_NO);
10153 if (dlg.ShowModal() == wxID_YES) { sync_printer_info = true; }
10154 }
10155 else {
10156 sync_printer_info = wxGetApp().app_config->get("sync_after_load_file_show_flag") == "true";
10157 }
10158 if (sync_printer_info) {
10160 printer_tab->select_preset(machine_preset->name);
10161 if (obj->is_multi_extruders()) GUI::wxGetApp().sidebar().sync_extruder_list();
10162 }
10163 }
10164 }
10165 }
10166 }
10167 }
10168 }
10169
10170 if (new_model) delete new_model;
10171
10172
10173 if (translate_old) {
10174
10176 for (int index = 1; index < plate_count; index ++) {
10177 PartPlate* cur_plate = (PartPlate *)
partplate_list.get_plate(index);
10178
10179 Vec3d cur_origin = cur_plate->get_origin();
10180 Vec3d new_origin =
partplate_list.compute_origin_using_new_size(index, current_width, current_depth);
10181
10182 cur_plate->translate_all_instance(new_origin - cur_origin);
10183 }
10185 partplate_list.reset_size(current_width, current_depth, current_height,
true,
true);
10187 }
10188
10189
10190 q->m_exported_file =
false;
10191 q->skip_thumbnail_invalid =
false;
10193 if (
model.objects.empty()) {
10195 PartPlate * first_plate = nullptr, *cur_plate = nullptr;
10197 int index = 0, first_plate_index = 0;
10198 q->m_valid_plates_count = 0;
10199 for (index = 0; index < plate_cnt; index ++)
10200 {
10202 if (!first_plate && cur_plate->is_slice_result_valid()) {
10203 first_plate = cur_plate;
10204 first_plate_index = index;
10205 }
10206 if (cur_plate->is_slice_result_valid())
10207 q->m_valid_plates_count ++;
10208 }
10209 if (first_plate&&first_plate->is_slice_result_valid()) {
10210 q->m_exported_file =
true;
10211
10212 q->select_plate(first_plate_index);
10213
10214 q->select_view_3D(
"Preview");
10216 }
10217 else {
10218
10219 q->select_view_3D(
"3D");
10220
10221 q->select_plate(0);
10222 }
10223 }
10224 else {
10225
10226 q->select_view_3D(
"3D");
10227
10228 q->select_plate(0);
10229 }
10230 }
10231 else {
10232
10233 q->select_view_3D(
"3D");
10235 }
10236
10237 if (load_model) {
10238 if (!
q->m_exported_file &&
view3D !=
nullptr) {
10239
10240
10241 view3D->reload_scene(
true);
10243 }
10244 if (!silence) wxGetApp().app_config->update_skein_dir(input_files[input_files.size() - 1].parent_path().make_preferred().string());
10245
10246 }
10247
10248
10249 if (!obj_idxs.empty() &&
view3D !=
nullptr) {
10250
10251 wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects(obj_idxs);
10252
10255 selection.clear();
10256 for (size_t idx : obj_idxs) {
10257 selection.add_object((unsigned int)idx, false);
10258 }
10259 }
10260
10261 this->
sidebar->obj_list()->update_selections();
10262
10263 if (
view3D->get_canvas3d()->get_gizmos_manager().is_enabled())
10264
10265 view3D->get_canvas3d()->update_gizmos_on_off_state();
10266 }
10267
10270
10271
10272 q->model().stl_design_id = designer_model_id;
10273 q->model().stl_design_country = designer_country_code;
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292 bool cad_can_show = false;
10293#ifdef SLIC3R_CAD
10294 cad_can_show = wxGetApp().is_enable_cad_feature();
10295#endif
10296 if (tolal_model_count <= 0 && !q->
m_exported_file && (!loaded_cad_recipe || !cad_can_show)) {
10297 dlg.Hide();
10298 if (!is_user_cancel) {
10299 const wxString text = loaded_cad_recipe
10300 ?
_L(
"This project contains a model made in the Design tab and no other geometry. "
10301 "Enable \"CAD feature (experimental)\" in Preferences and restart to see and edit it; "
10302 "it is kept when the project is saved.")
10303 :
_L(
"The file does not contain any geometry data.");
10304 MessageDialog msg(wxGetApp().mainframe, text,
_L(
"Warning"), wxOK | wxICON_WARNING);
10305 msg.ShowModal();
10306 }
10307 }
10308 q->schedule_background_process(
true);
10309 q->mark_plate_toolbar_image_dirty();
10310 return obj_idxs;
10311}
#define _(s)
Definition 3mf.cpp:306
#define L(s)
Definition ExtrusionEntity.cpp:25
#define TAB_ID_PREPARE
Definition MainFrame.hpp:60
#define VALIDATE_PRESETS_PRINTER_NOT_FOUND
Definition PresetBundle.hpp:35
#define VALIDATE_PRESETS_MODIFIED_GCODES
Definition PresetBundle.hpp:37
#define VALIDATE_PRESETS_FILAMENTS_NOT_FOUND
Definition PresetBundle.hpp:36
std::vector< int > values
Definition Config.hpp:418
static const float DefaultTipRadius
Definition 3DBed.hpp:73
static void add_simplify_suggestion_notification(const std::vector< size_t > &object_ids, const std::vector< ModelObject * > &objects, NotificationManager &manager)
Definition GLGizmoSimplify.cpp:113
@ WarningNotificationLevel
Definition NotificationManager.hpp:224
bool m_exported_file
Definition Plater.hpp:1097
static wxColour get_next_color_for_filament()
Definition Plater.cpp:8511
@ Bed
Definition SceneRaycaster.hpp:49
static Model read_from_archive(const std::string &input_file, DynamicPrintConfig *config, ConfigSubstitutionContext *config_substitutions, En3mfType &out_file_type, LoadStrategy options=LoadStrategy::AddDefaultInstances, PlateDataPtrs *plate_data=nullptr, std::vector< Preset * > *project_presets=nullptr, Semver *file_version=nullptr, Import3mfProgressFn proFn=nullptr, BBLProject *project=nullptr)
Definition Model.cpp:522
static Model read_from_file(const std::string &input_file, DynamicPrintConfig *config=nullptr, ConfigSubstitutionContext *config_substitutions=nullptr, LoadStrategy options=LoadStrategy::AddDefaultInstances, PlateDataPtrs *plate_data=nullptr, std::vector< Preset * > *project_presets=nullptr, bool *is_xxx=nullptr, Semver *file_version=nullptr, Import3mfProgressFn proFn=nullptr, ImportstlProgressFn stlFn=nullptr, BBLProject *project=nullptr, int plate_id=0)
Definition Model.cpp:318
static Model read_from_step(const std::string &input_file, LoadStrategy options, ImportStepProgressFn stepFn, StepIsUtf8Fn stepIsUtf8Fn, std::function< int(Slic3r::Step &, double &, double &, bool &)> step_mesh_fn, double linear_deflection, double angle_deflection, bool is_split_compound)
Definition Model.cpp:240
PrinterTechnology printer_technology() const
Definition Preset.hpp:399
static void normalize(DynamicPrintConfig &config)
Definition Preset.cpp:524
@ TYPE_PRINTER
Definition Preset.hpp:250
@ TYPE_PRINT
Definition Preset.hpp:246
@ TYPE_FILAMENT
Definition Preset.hpp:248
static boost::optional< Semver > parse(const std::string &str)
Definition Semver.hpp:63
static constexpr size_t MAXIMUM_EXTRUDER_NUMBER
Definition libslic3r.h:70
LoadType
Definition Plater.cpp:484
@ Unknown
Definition Plater.cpp:485
@ LoadGeometry
Definition Plater.cpp:487
wxTopLevelWindow * find_toplevel_parent(wxWindow *window)
Definition GUI_Utils.cpp:155
wxString format_wxstr(const char *fmt, TArgs &&... args)
Definition format.hpp:22
static void sync_loaded_project_filament_config(DynamicConfig &proj_cfg)
Definition Plater.cpp:8887
static wxString dots("...", wxConvUTF8)
void updateNozzleCountDisplay(PresetBundle *preset_bundle, int extruder_id, NozzleVolumeType volume_type)
Definition MultiNozzleSync.cpp:263
void read_binary_stl(const std::string &filename, std::string &model_id, std::string &code)
Definition Plater.cpp:8808
void show_substitutions_info(const PresetsConfigSubstitutions &presets_config_substitutions)
Definition GUI.cpp:429
void show_info(wxWindow *parent, const wxString &message, const wxString &title)
Definition GUI.cpp:316
static void log_substitutions(const ConfigSubstitutions &substitutions, const std::string &source)
Definition Plater.cpp:8872
static bool has_importable_texture(const Slic3r::TexturedMesh &textured_mesh)
Definition Plater.cpp:315
Preset * get_printer_preset(const MachineObject *obj)
Definition Plater.cpp:19913
constexpr T deg2rad(const T angle)
Definition Geometry.hpp:312
@ ipZigZag
Definition PrintConfig.hpp:128
@ ipCrossZag
Definition PrintConfig.hpp:128
@ ipLine
Definition PrintConfig.hpp:129
@ ipRectilinear
Definition PrintConfig.hpp:128
@ ipLockedZag
Definition PrintConfig.hpp:128
std::vector< PlateData * > PlateDataPtrs
Definition bbs_3mf.hpp:278
@ Enable
Definition Config.hpp:245
void release_PlateData_list(PlateDataPtrs &plate_data_list)
Definition bbs_3mf.cpp:9740
@ Calib_None
Definition calib.hpp:24
bool unescape_strings_cstyle(const std::string &str, std::vector< std::string > &out)
Definition Config.cpp:173
std::vector< ConfigSubstitution > ConfigSubstitutions
Definition Config.hpp:269
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
void load_config(cereal::BinaryInputArchive &ar, DynamicPrintConfig &config, const CacheDictionary &dict)
Definition PresetCacheFormat.cpp:242
std::vector< PresetConfigSubstitutions > PresetsConfigSubstitutions
Definition Preset.hpp:552
BedType
Definition PrintConfig.hpp:507
PrinterTechnology
Definition Config.hpp:229
constexpr const char * ORCA_PUBLISHED_CONFIG_TAG
Definition bbs_3mf.hpp:195
@ Preset
Definition calib.hpp:39
En3mfType
Definition Model.hpp:751
@ From_Prusa
Definition Model.hpp:754
@ From_Other
Definition Model.hpp:755
@ From_BBS
Definition Model.hpp:753
@ From_Orca
Definition Model.hpp:752
constexpr const char * ORCA_PUBLISHED_TAG
Definition bbs_3mf.hpp:192
constexpr const char * ORCA_PUBLISHED_KEYS_TAG
Definition bbs_3mf.hpp:193
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:138
const int IMPORT_STAGE_MAX
Definition bbs_3mf.hpp:272
ConfigOptionIntsTempl< false > ConfigOptionInts
Definition Config.hpp:1154
constexpr const char * ORCA_PUBLISHED_MATERIAL_TAG
Definition bbs_3mf.hpp:194
zaa_minimize_perimeter_height ConfigOptionString
Definition PrintConfig.hpp:1702
bool is_published_3mf_flag(const std::string &value)
Definition bbs_3mf.cpp:724
const int LOAD_STEP_STAGE_NUM
Definition STEP.hpp:31
@ LoadModel
Definition bbs_3mf.hpp:222
@ Restore
Definition bbs_3mf.hpp:228
@ LoadConfig
Definition bbs_3mf.hpp:223
@ ImperialUnits
Definition bbs_3mf.hpp:226
@ Silence
Definition bbs_3mf.hpp:225
@ CheckVersion
Definition bbs_3mf.hpp:221
@ LoadAuxiliary
Definition bbs_3mf.hpp:224
double string_to_double_decimal_point(const std::string_view str, size_t *pos)
Definition LocalesUtils.cpp:86
@ wtwRectangle
Definition PrintConfig.hpp:606
void remap_model_filament_slots(Model &model, const std::map< int, int > &slot_relocations)
Definition Model.cpp:4336
@ Z
Definition libslic3r.h:143
zaa_minimize_perimeter_height wipe_tower_y((ConfigOptionFloat, prime_tower_width))((ConfigOptionFloat
std::string escape_strings_cstyle(const std::vector< std::string > &strs)
Definition Config.cpp:99
std::vector< std::string > m_pending_published_keys
Definition Plater.cpp:7187
std::vector< size_t > load_model_objects(const ModelObjectPtrs &model_objects, bool allow_negative_z=false, bool split_object=false, bool auto_drop=true)
Definition Plater.cpp:10315
std::vector< Slic3r::PublishedMaterialEntry > m_pending_material_keys
Definition Plater.cpp:7188
static const std::regex pattern_3mf
Definition Plater.cpp:7297
void load_auxiliary_files()
Definition Plater.cpp:10477
static const std::regex pattern_any_amf
Definition Plater.cpp:7299
void split_object(bool auto_drop=true)
Definition Plater.cpp:10974
bool m_has_pending_published
Definition Plater.cpp:7186
static const std::regex pattern_bundle
Definition Plater.cpp:7296