diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 80ced7d4e7..cf59933773 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -1388,7 +1388,9 @@ int CLI::run(int argc, char **argv) if (format == static_cast(m_print_config.def()->get("filename_format")->default_value.get())->value) format = "[input_filename_base].SL1"; }*/ - print->apply(model, m_print_config); + DynamicPrintConfig new_print_config = m_print_config; + new_print_config.apply(*part_plate->config()); + print->apply(model, new_print_config); StringObjectException warning; auto err = print->validate(&warning); if (!err.string.empty()) { @@ -1687,9 +1689,11 @@ int CLI::run(int argc, char **argv) int print_index; part_plate->get_print(&print_base, &gcode_result, &print_index); - BuildVolume build_volume(part_plate->get_shape(), print_height); - const std::vector& exclude_bounding_box = part_plate->get_exclude_areas(); Print *print = dynamic_cast(print_base); + + //don't render calibration picture + /*BuildVolume build_volume(part_plate->get_shape(), print_height); + const std::vector& exclude_bounding_box = part_plate->get_exclude_areas(); Slic3r::GUI::GCodeViewer gcode_viewer; gcode_viewer.init(ConfigOptionMode::comAdvanced, nullptr); gcode_viewer.load(*gcode_result, *print, build_volume, exclude_bounding_box, false, ConfigOptionMode::comAdvanced, false); @@ -1708,7 +1712,7 @@ int CLI::run(int argc, char **argv) calibration_params, partplate_list, opengl_mgr); //generate_calibration_thumbnail(*calibration_data, thumbnail_width, thumbnail_height, calibration_params); //*plate_bboxes[index] = p->generate_first_layer_bbox(); - calibration_thumbnails.push_back(calibration_data); + calibration_thumbnails.push_back(calibration_data);*/ PlateBBoxData* plate_bbox = new PlateBBoxData(); std::vector& id_bboxes = plate_bbox->bbox_objs; @@ -1734,6 +1738,23 @@ int CLI::run(int argc, char **argv) data.bbox = { bb.min.x(),bb.min.y(),bb.max.x(),bb.max.y() }; id_bboxes.emplace_back(std::move(data)); } + // add wipe tower bounding box + if (print->has_wipe_tower()) { + BBoxData data; + auto wt_corners = print->first_layer_wipe_tower_corners(); + // when loading gcode.3mf, wipe tower info may not be correct + if (!wt_corners.empty()) { + BoundingBox bb_scaled = {wt_corners[0], wt_corners[2]}; + auto bb = unscaled(bb_scaled); + bb.min -= orig2d; + bb.max -= orig2d; + bbox_all.merge(bb); + data.name = "wipe_tower"; + data.id = partplate_list.get_curr_plate()->get_index() + 1000; + data.bbox = {bb.min.x(), bb.min.y(), bb.max.x(), bb.max.y()}; + id_bboxes.emplace_back(std::move(data)); + } + } plate_bbox->bbox_all = { bbox_all.min.x(),bbox_all.min.y(),bbox_all.max.x(),bbox_all.max.y() }; plate_bboxes.push_back(plate_bbox); } diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index e9e69dcd57..b541b613ea 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -1535,6 +1535,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) plate_data_list[it->first-1]->thumbnail_file = (m_load_restore || it->second->thumbnail_file.empty()) ? it->second->thumbnail_file : m_backup_path + "/" + it->second->thumbnail_file; plate_data_list[it->first-1]->pattern_file = (m_load_restore || it->second->pattern_file.empty()) ? it->second->pattern_file : m_backup_path + "/" + it->second->pattern_file; plate_data_list[it->first-1]->pattern_bbox_file = (m_load_restore || it->second->pattern_bbox_file.empty()) ? it->second->pattern_bbox_file : m_backup_path + "/" + it->second->pattern_bbox_file; + plate_data_list[it->first-1]->config = it->second->config; it++; } @@ -4110,8 +4111,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) } } - - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(",before add calibration data, count %1%\n")%calibration_data.size(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(",before add calibration thumbnails, count %1%\n")%calibration_data.size(); //BBS add calibration thumbnail for each plate if (!m_skip_static && calibration_data.size() > 0) { // Adds the file Metadata/calibration_p[X].png. @@ -4131,7 +4131,14 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) return false; } } + } + } + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(",before add calibration boundingbox, count %1%\n")%id_bboxes.size(); + if (!m_skip_static && id_bboxes.size() > 0) { + // Adds the file Metadata/calibration_p[X].png. + for (unsigned int index = 0; index < id_bboxes.size(); index++) + { // BBS: save bounding box to json if (id_bboxes[index]->is_valid()) { if (!_add_bbox_file_to_archive(archive, *id_bboxes[index], index)) { diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 21d51861e6..485c9fafaa 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -157,10 +157,10 @@ void PartPlate::set_bed_type(BedType bed_type, bool& same_as_global) m_config.set_key_value("curr_bed_type", new ConfigOptionEnum(bed_type)); if (m_plater) { - m_plater->schedule_background_process(); + //m_plater->schedule_background_process(); DynamicConfig& proj_cfg = wxGetApp().preset_bundle->project_config; if (proj_cfg.has(bed_type_key)) { - std::string bed_type_key = "curr_bed_type"; + //std::string bed_type_key = "curr_bed_type"; BedType global_bed_type = proj_cfg.opt_enum(bed_type_key); same_as_global = bed_type == global_bed_type; is_same_bedtype_with_global = same_as_global; @@ -3971,10 +3971,10 @@ bool PartPlateList::is_all_plates_ready_for_slice() const { for (unsigned int i = 0; i < (unsigned int)m_plate_list.size(); ++i) { - if (!m_plate_list[i]->can_slice()) - return false; + if (m_plate_list[i]->can_slice()) + return true; } - return true; + return false; } //will create a plate and load gcode, return the plate index diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index bf5174baf6..6b31737246 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -92,6 +92,7 @@ private: bool m_locked; bool m_ready_for_slice; bool m_slice_result_valid; + bool m_apply_invalid {false}; float m_slice_percent; Print *m_print; //Print reference, not own it, no need to serialize @@ -331,11 +332,30 @@ public: bool is_printable() const { return m_printable; } //can be sliced or not - bool can_slice() const { return m_ready_for_slice; } - void update_slice_ready_status(bool ready_slice) { m_ready_for_slice = ready_slice; } + bool can_slice() const + { + return m_ready_for_slice && !m_apply_invalid; + } + void update_slice_ready_status(bool ready_slice) + { + m_ready_for_slice = ready_slice; + } + + //bedtype mismatch or not + bool is_apply_result_invalid() const + { + return m_apply_invalid; + } + void update_apply_result_invalid(bool invalid) + { + m_apply_invalid = invalid; + } //is slice result valid or not - bool is_slice_result_valid() const { return m_slice_result_valid; } + bool is_slice_result_valid() const + { + return m_slice_result_valid; + } //is slice result ready for print bool is_slice_result_ready_for_print() const @@ -389,7 +409,7 @@ public: std::vector> objects_and_instances; std::vector> instances_outside; - ar(m_plate_index, m_print_index, m_origin, m_width, m_depth, m_height, m_locked, m_selected, m_ready_for_slice, m_slice_result_valid, m_printable, m_tmp_gcode_path, objects_and_instances, instances_outside, m_config); + ar(m_plate_index, m_print_index, m_origin, m_width, m_depth, m_height, m_locked, m_selected, m_ready_for_slice, m_slice_result_valid, m_apply_invalid, m_printable, m_tmp_gcode_path, objects_and_instances, instances_outside, m_config); for (std::vector>::iterator it = objects_and_instances.begin(); it != objects_and_instances.end(); ++it) obj_to_instance_set.insert(std::pair(it->first, it->second)); @@ -407,7 +427,7 @@ public: for (std::set>::iterator it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); ++it) objects_and_instances.emplace_back(it->first, it->second); - ar(m_plate_index, m_print_index, m_origin, m_width, m_depth, m_height, m_locked, m_selected, m_ready_for_slice, m_slice_result_valid, m_printable, m_tmp_gcode_path, objects_and_instances, instances_outside, m_config); + ar(m_plate_index, m_print_index, m_origin, m_width, m_depth, m_height, m_locked, m_selected, m_ready_for_slice, m_slice_result_valid, m_apply_invalid, m_printable, m_tmp_gcode_path, objects_and_instances, instances_outside, m_config); } /*template void serialize(Archive& ar) { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 77c3fcdfbc..1c41ab9efc 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1984,7 +1984,7 @@ struct Plater::priv //BBS store machine_sn and 3mf_path for PrintJob PrintPrepareData m_print_job_data; bool inside_snapshot_capture() { return m_prevent_snapshots != 0; } - bool process_completed_with_error { false }; + int process_completed_with_error { -1 }; //-1 means no error //BBS: project BBLProject project; @@ -2162,7 +2162,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) if (wxGetApp().is_editor()) { // 3DScene events: - view3D_canvas->Bind(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent&) { + view3D_canvas->Bind(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent&) { delayed_error_message.clear(); this->background_process_timer.Start(500, wxTIMER_ONE_SHOT); }); @@ -4096,6 +4096,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": validate err=%1%, warning=%2%")%err.string%warning.string; if (err.string.empty()) { + this->partplate_list.get_curr_plate()->update_apply_result_invalid(false); notification_manager->set_all_slicing_errors_gray(true); notification_manager->close_notification_of_type(NotificationType::ValidateError); if (invalidated != Print::APPLY_STATUS_UNCHANGED && background_processing_enabled()) @@ -4111,9 +4112,12 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool } } else { + this->partplate_list.get_curr_plate()->update_apply_result_invalid(true); // The print is not valid. // Show error as notification. notification_manager->push_validate_error_notification(err); + //also update the warnings + process_validation_warning(warning); return_state |= UPDATE_BACKGROUND_PROCESS_INVALID; if (printer_technology == ptFFF) { const Print* print = background_process.fff_print(); @@ -4138,7 +4142,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool actualize_slicing_warnings(*this->background_process.current_print()); actualize_object_warnings(*this->background_process.current_print()); show_warning_dialog = false; - process_completed_with_error = false; + process_completed_with_error = -1; } if (invalidated != Print::APPLY_STATUS_UNCHANGED && was_running && ! this->background_process.running() && @@ -4157,7 +4161,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool //BBS: add slice&&print status update logic this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, false); - process_completed_with_error = true; + process_completed_with_error = partplate_list.get_curr_plate_index(); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: set to process_completed_with_error, return_state=%2%")%__LINE__%return_state; } else @@ -5535,7 +5539,7 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) for (auto btn : { ActionButtonType::abReslice, ActionButtonType::abSendGCode, ActionButtonType::abExport }) sidebar->set_btn_label(btn, invalid_str); #endif - process_completed_with_error = true; + process_completed_with_error = partplate_list.get_curr_plate_index();; } has_error = true; is_finished = true; @@ -5563,21 +5567,6 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) //BBS: remove this update here, will be updated in update_fff_scene later //this->object_list_changed(); - // BBS, Generate calibration thumbnail for current plate - if (preview) { - // generate calibration data - /* BBS generate calibration data by printer - preview->reload_print(); - ThumbnailData* calibration_data = &partplate_list.get_curr_plate()->cali_thumbnail_data; - const ThumbnailsParams calibration_params = { {}, false, true, true, true, partplate_list.get_curr_plate_index() }; - generate_calibration_thumbnail(*calibration_data, PartPlate::cali_thumbnail_width, PartPlate::cali_thumbnail_height, calibration_params); - preview->get_canvas3d()->reset_gcode_toolpaths();*/ - - // generate bbox data - PlateBBoxData* plate_bbox_data = &partplate_list.get_curr_plate()->cali_bboxes_data; - *plate_bbox_data = generate_first_layer_bbox(); - } - // refresh preview if (view3D->is_dragging()) // updating scene now would interfere with the gizmo dragging delayed_scene_refresh = true; @@ -5623,6 +5612,21 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) }else if (exporting_status == ExportingStatus::EXPORTING_TO_LOCAL && !has_error) notification_manager->push_exporting_finished_notification(last_output_path, last_output_dir_path, false); + + // BBS, Generate calibration thumbnail for current plate + if (!has_error && preview) { + // generate calibration data + /* BBS generate calibration data by printer + preview->reload_print(); + ThumbnailData* calibration_data = &partplate_list.get_curr_plate()->cali_thumbnail_data; + const ThumbnailsParams calibration_params = { {}, false, true, true, true, partplate_list.get_curr_plate_index() }; + generate_calibration_thumbnail(*calibration_data, PartPlate::cali_thumbnail_width, PartPlate::cali_thumbnail_height, calibration_params); + preview->get_canvas3d()->reset_gcode_toolpaths();*/ + + // generate bbox data + PlateBBoxData* plate_bbox_data = &partplate_list.get_curr_plate()->cali_bboxes_data; + *plate_bbox_data = generate_first_layer_bbox(); + } } exporting_status = ExportingStatus::NOT_EXPORTING; @@ -5664,7 +5668,11 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) q->Freeze(); q->select_plate(m_cur_slice_plate); partplate_list.select_plate_view(); - q->start_next_slice(); + int ret = q->start_next_slice(); + if (ret) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":slicing all, plate %1% can not be sliced, will stop")%m_cur_slice_plate; + m_is_slicing = false; + } //not the last plate update_fff_scene_only_shells(); q->Thaw(); @@ -5757,7 +5765,7 @@ void Plater::priv::on_action_publish(wxCommandEvent &event) if (q != nullptr) { if (event.GetInt() == EVT_PUBLISHING_START) { // update by background slicing process - if (process_completed_with_error) { + if (process_completed_with_error >= 0) { wxString msg = _L("Please resolve the slicing errors and publish again."); this->m_publish_dlg->UpdateStatus(msg, false); return; @@ -8354,7 +8362,7 @@ int GUI::Plater::close_with_confirm(std::function second_check) auto result = MessageDialog(static_cast(this), _L("The current project has unsaved changes, save it before continue?"), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Save"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal(); if (result == wxID_CANCEL) - return result; + return result; else if (result == wxID_YES) { result = save_project(); if (result == wxID_CANCEL) @@ -8659,7 +8667,7 @@ void Plater::export_gcode(bool prefer_removable) //if (get_view3D_canvas3D()->get_gizmos_manager().is_in_editing_mode(true)) // return; - if (p->process_completed_with_error) + if (p->process_completed_with_error == p->partplate_list.get_curr_plate_index()) return; // If possible, remove accents from accented latin characters. @@ -8744,7 +8752,7 @@ void Plater::export_gcode_3mf(bool export_all) if (p->model.objects.empty()) return; - if (p->process_completed_with_error) + if (p->process_completed_with_error == p->partplate_list.get_curr_plate_index()) return; //calc default_output_file, get default output file from background process @@ -9214,7 +9222,7 @@ void Plater::reslice() { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: enter, process_completed_with_error=%2%")%__LINE__ %p->process_completed_with_error; // There is "invalid data" button instead "slice now" - if (p->process_completed_with_error) + if (p->process_completed_with_error == p->partplate_list.get_curr_plate_index()) { BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": process_completed_with_error, return directly"); reset_gcode_toolpaths(); @@ -9312,7 +9320,7 @@ void Plater::reslice() } //BBS: add project slicing related logic -void Plater::start_next_slice() +int Plater::start_next_slice() { // Stop arrange and (or) optimize rotation tasks. //this->stop_jobs(); @@ -9324,6 +9332,12 @@ void Plater::start_next_slice() this->p->view3D->reload_scene(false); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": update_background_process returns %1%")%state; + if (p->partplate_list.get_curr_plate()->is_apply_result_invalid()) { + p->process_completed_with_error = p->partplate_list.get_curr_plate_index(); + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": found invalidated apply in update_background_process."); + return -1; + } + // Only restarts if the state is valid. bool result = this->p->restart_background_process(state | priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART); if (!result) @@ -9335,6 +9349,8 @@ void Plater::start_next_slice() wxQueueEvent(this, evt.Clone()); } BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": restart_background_process returns %1%")%result; + + return 0; } @@ -10264,6 +10280,7 @@ int Plater::select_plate(int plate_index, bool need_slice) //always apply the current plate's print invalidated = p->background_process.apply(this->model(), wxGetApp().preset_bundle->full_config()); + bool model_fits, validate_err; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, after apply, invalidated= %3%, previous result_valid %4% ")%__LINE__ %plate_index %invalidated %result_valid; if (result_valid) @@ -10273,12 +10290,13 @@ int Plater::select_plate(int plate_index, bool need_slice) if (need_slice) { //from preview's thumbnail if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) || (gcode_result->moves.empty())){ //part_plate->update_slice_result_valid_state(false); - p->process_completed_with_error = false; + p->process_completed_with_error = -1; p->m_slice_all = false; reset_gcode_toolpaths(); reslice(); } else { + validate_current_plate(model_fits, validate_err); //just refresh_print refresh_print(); p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false, true); @@ -10290,6 +10308,7 @@ int Plater::select_plate(int plate_index, bool need_slice) } else { + validate_current_plate(model_fits, validate_err); if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED) { part_plate->update_slice_result_valid_state(false); @@ -10313,11 +10332,12 @@ int Plater::select_plate(int plate_index, bool need_slice) { //check inside status bool model_fits = p->view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside; + //bool validate_err = false; if (is_preview_shown()) { if (need_slice) { - p->process_completed_with_error = false; + p->process_completed_with_error = -1; p->m_slice_all = false; reset_gcode_toolpaths(); if (model_fits) @@ -10331,60 +10351,13 @@ int Plater::select_plate(int plate_index, bool need_slice) } else { - if (p->printer_technology == ptFFF) { - StringObjectException warning; - Polygons polygons; - std::vector> height_polygons; - StringObjectException err = p->background_process.validate(&warning, &polygons, &height_polygons); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": validate err=%1%, warning=%2%")%err.string%warning.string; - - if (err.string.empty()) { - p->notification_manager->set_all_slicing_errors_gray(true); - p->notification_manager->close_notification_of_type(NotificationType::ValidateError); - - // Pass a warning from validation and either show a notification, - // or hide the old one. - p->process_validation_warning(warning); - p->view3D->get_canvas3d()->reset_sequential_print_clearance(); - p->view3D->get_canvas3d()->set_as_dirty(); - p->view3D->get_canvas3d()->request_extra_frame(); - } - else { - // The print is not valid. - // Show error as notification. - p->notification_manager->push_validate_error_notification(err); - model_fits = false; - p->view3D->get_canvas3d()->set_sequential_print_clearance_visible(true); - p->view3D->get_canvas3d()->set_sequential_print_clearance_render_fill(true); - p->view3D->get_canvas3d()->set_sequential_print_clearance_polygons(polygons, height_polygons); - } - /*if (fff_print->config().print_sequence == PrintSequence::ByObject) - { - Polygons polygons; - std::vector> height_polygons; - auto ret = Print::sequential_print_clearance_valid(*fff_print, &polygons, &height_polygons); - if (!ret.string.empty()) { - model_fits = false; - p->view3D->get_canvas3d()->set_sequential_print_clearance_visible(true); - p->view3D->get_canvas3d()->set_sequential_print_clearance_render_fill(true); - p->view3D->get_canvas3d()->set_sequential_print_clearance_polygons(polygons, height_polygons); - } - else { - p->view3D->get_canvas3d()->reset_sequential_print_clearance(); - p->view3D->get_canvas3d()->set_as_dirty(); - p->view3D->get_canvas3d()->request_extra_frame(); - } - }*/ - } - //BBS: add partplate logic - PartPlate* part_plate = p->partplate_list.get_curr_plate(); - part_plate->update_slice_ready_status(model_fits); - - if (model_fits){ - p->process_completed_with_error = false; + validate_current_plate(model_fits, validate_err); + //check inside status + if (model_fits && !validate_err){ + p->process_completed_with_error = -1; } else { - p->process_completed_with_error = true; + p->process_completed_with_error = p->partplate_list.get_curr_plate_index(); } // BBS: don't show action buttons @@ -10430,6 +10403,50 @@ int Plater::select_sliced_plate(int plate_index) return ret; } +void Plater::validate_current_plate(bool& model_fits, bool& validate_error) +{ + model_fits = p->view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside; + validate_error = false; + if (p->printer_technology == ptFFF) { + StringObjectException warning; + Polygons polygons; + std::vector> height_polygons; + StringObjectException err = p->background_process.validate(&warning, &polygons, &height_polygons); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": validate err=%1%, warning=%2%, model_fits %3%")%err.string%warning.string %model_fits; + + if (err.string.empty()) { + p->partplate_list.get_curr_plate()->update_apply_result_invalid(false); + p->notification_manager->set_all_slicing_errors_gray(true); + p->notification_manager->close_notification_of_type(NotificationType::ValidateError); + + // Pass a warning from validation and either show a notification, + // or hide the old one. + p->process_validation_warning(warning); + p->view3D->get_canvas3d()->reset_sequential_print_clearance(); + p->view3D->get_canvas3d()->set_as_dirty(); + p->view3D->get_canvas3d()->request_extra_frame(); + } + else { + // The print is not valid. + p->partplate_list.get_curr_plate()->update_apply_result_invalid(true); + // Show error as notification. + p->notification_manager->push_validate_error_notification(err); + p->process_validation_warning(warning); + //model_fits = false; + validate_error = true; + p->view3D->get_canvas3d()->set_sequential_print_clearance_visible(true); + p->view3D->get_canvas3d()->set_sequential_print_clearance_render_fill(true); + p->view3D->get_canvas3d()->set_sequential_print_clearance_polygons(polygons, height_polygons); + } + } + + PartPlate* part_plate = p->partplate_list.get_curr_plate(); + part_plate->update_slice_ready_status(model_fits); + + return; +} + + //BBS: select Plate by hover_id int Plater::select_plate_by_hover_id(int hover_id, bool right_click) { @@ -10460,12 +10477,16 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click) part_plate->get_print(&print, &gcode_result, NULL); //always apply the current plate's print invalidated = p->background_process.apply(this->model(), wxGetApp().preset_bundle->full_config()); + bool model_fits, validate_err; + validate_current_plate(model_fits, validate_err); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: after apply, invalidated= %2%, previous result_valid %3% ")%__LINE__ % invalidated %result_valid; if (result_valid) { if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED) { + //bool model_fits, validate_err; + //validate_current_plate(model_fits, validate_err); part_plate->update_slice_result_valid_state(false); // BBS @@ -10477,6 +10498,7 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click) { // BBS //p->show_action_buttons(false); + //validate_current_plate(model_fits, validate_err); p->ready_to_slice = false; p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false); @@ -10486,61 +10508,11 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click) else { //check inside status - bool model_fits = p->view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside; - if (p->printer_technology == ptFFF) { - StringObjectException warning; - Polygons polygons; - std::vector> height_polygons; - StringObjectException err = p->background_process.validate(&warning, &polygons, &height_polygons); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": validate err=%1%, warning=%2%, model_fits %3%")%err.string%warning.string %model_fits; - - if (err.string.empty()) { - p->notification_manager->set_all_slicing_errors_gray(true); - p->notification_manager->close_notification_of_type(NotificationType::ValidateError); - - // Pass a warning from validation and either show a notification, - // or hide the old one. - p->process_validation_warning(warning); - p->view3D->get_canvas3d()->reset_sequential_print_clearance(); - p->view3D->get_canvas3d()->set_as_dirty(); - p->view3D->get_canvas3d()->request_extra_frame(); - } - else { - // The print is not valid. - // Show error as notification. - p->notification_manager->push_validate_error_notification(err); - model_fits = false; - p->view3D->get_canvas3d()->set_sequential_print_clearance_visible(true); - p->view3D->get_canvas3d()->set_sequential_print_clearance_render_fill(true); - p->view3D->get_canvas3d()->set_sequential_print_clearance_polygons(polygons, height_polygons); - } - /*if (fff_print->config().print_sequence == PrintSequence::ByObject) - { - Polygons polygons; - std::vector> height_polygons; - auto ret = Print::sequential_print_clearance_valid(*fff_print, &polygons, &height_polygons); - if (!ret.string.empty()) { - model_fits = false; - p->view3D->get_canvas3d()->set_sequential_print_clearance_visible(true); - p->view3D->get_canvas3d()->set_sequential_print_clearance_render_fill(true); - p->view3D->get_canvas3d()->set_sequential_print_clearance_polygons(polygons, height_polygons); - } - else { - p->view3D->get_canvas3d()->reset_sequential_print_clearance(); - p->view3D->get_canvas3d()->set_as_dirty(); - p->view3D->get_canvas3d()->request_extra_frame(); - } - }*/ - } - //BBS: add partplate logic - PartPlate* part_plate = p->partplate_list.get_curr_plate(); - part_plate->update_slice_ready_status(model_fits); - - if (model_fits){ - p->process_completed_with_error = false; + if (model_fits && !validate_err){ + p->process_completed_with_error = -1; } else { - p->process_completed_with_error = true; + p->process_completed_with_error = p->partplate_list.get_curr_plate_index(); } // BBS: don't show action buttons @@ -10618,6 +10590,8 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click) BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select bed type %1% for plate %2% at plate side")%type %plate_index; }); dlg.ShowModal(); + + this->schedule_background_process(); } else { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "can not select plate %1%" << plate_index; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 0561f2f5ee..d6019cf10c 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -481,6 +481,7 @@ public: //BBS: partplate list related functions PartPlateList& get_partplate_list(); + void validate_current_plate(bool& model_fits, bool& validate_error); //BBS: select the plate by index int select_plate(int plate_index, bool need_slice = false); //BBS: update progress result @@ -673,7 +674,7 @@ private: void single_snapshots_enter(SingleSnapshot *single); void single_snapshots_leave(SingleSnapshot *single); // BBS: add project slice related functions - void start_next_slice(); + int start_next_slice(); friend class SuppressBackgroundProcessingUpdate; };