mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	Merge branch 'master' of https://github.com/prusa3d/Slic3r
This commit is contained in:
		
						commit
						dc64b4d971
					
				
					 13 changed files with 204 additions and 147 deletions
				
			
		|  | @ -49,8 +49,8 @@ float SLAAutoSupports::distance_limit(float angle) const | |||
| }*/ | ||||
| 
 | ||||
| SLAAutoSupports::SLAAutoSupports(const TriangleMesh& mesh, const sla::EigenMesh3D& emesh, const std::vector<ExPolygons>& slices, const std::vector<float>& heights, | ||||
|                                    const Config& config, std::function<void(void)> throw_on_cancel) | ||||
| : m_config(config), m_emesh(emesh), m_throw_on_cancel(throw_on_cancel) | ||||
|                                    const Config& config, std::function<void(void)> throw_on_cancel, std::function<void(int)> statusfn) | ||||
| : m_config(config), m_emesh(emesh), m_throw_on_cancel(throw_on_cancel), m_statusfn(statusfn) | ||||
| { | ||||
|     process(slices, heights); | ||||
|     project_onto_mesh(m_output); | ||||
|  | @ -197,6 +197,9 @@ void SLAAutoSupports::process(const std::vector<ExPolygons>& slices, const std:: | |||
|     PointGrid3D point_grid; | ||||
|     point_grid.cell_size = Vec3f(10.f, 10.f, 10.f); | ||||
| 
 | ||||
|     double increment = 100.0 / layers.size(); | ||||
|     double status    = 0; | ||||
| 
 | ||||
|     for (unsigned int layer_id = 0; layer_id < layers.size(); ++ layer_id) { | ||||
|         SLAAutoSupports::MyLayer *layer_top     = &layers[layer_id]; | ||||
|         SLAAutoSupports::MyLayer *layer_bottom  = (layer_id > 0) ? &layers[layer_id - 1] : nullptr; | ||||
|  | @ -252,6 +255,9 @@ void SLAAutoSupports::process(const std::vector<ExPolygons>& slices, const std:: | |||
| 
 | ||||
|         m_throw_on_cancel(); | ||||
| 
 | ||||
|         status += increment; | ||||
|         m_statusfn(int(std::round(status))); | ||||
| 
 | ||||
| #ifdef SLA_AUTOSUPPORTS_DEBUG | ||||
|         /*std::string layer_num_str = std::string((i<10 ? "0" : "")) + std::string((i<100 ? "0" : "")) + std::to_string(i);
 | ||||
|         output_expolygons(expolys_top, "top" + layer_num_str + ".svg"); | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ public: | |||
|         }; | ||||
| 
 | ||||
|     SLAAutoSupports(const TriangleMesh& mesh, const sla::EigenMesh3D& emesh, const std::vector<ExPolygons>& slices, | ||||
|                      const std::vector<float>& heights, const Config& config, std::function<void(void)> throw_on_cancel); | ||||
|                      const std::vector<float>& heights, const Config& config, std::function<void(void)> throw_on_cancel, std::function<void(int)> statusfn); | ||||
|     const std::vector<sla::SupportPoint>& output() { return m_output; } | ||||
| 
 | ||||
| 	struct MyLayer; | ||||
|  | @ -196,12 +196,13 @@ private: | |||
|     static void output_structures(const std::vector<Structure> &structures); | ||||
| #endif // SLA_AUTOSUPPORTS_DEBUG
 | ||||
| 
 | ||||
|     std::function<void(void)> m_throw_on_cancel; | ||||
|     const sla::EigenMesh3D& m_emesh; | ||||
|     std::function<void(void)> m_throw_on_cancel; | ||||
|     std::function<void(int)>  m_statusfn; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
| 
 | ||||
| 
 | ||||
| #endif // SLAAUTOSUPPORTS_HPP_
 | ||||
| #endif // SLAAUTOSUPPORTS_HPP_
 | ||||
|  |  | |||
|  | @ -42,11 +42,11 @@ namespace { | |||
| // should add up to 100 (%)
 | ||||
| const std::array<unsigned, slaposCount>     OBJ_STEP_LEVELS = | ||||
| { | ||||
|     10,     // slaposObjectSlice,
 | ||||
|     30,     // slaposSupportPoints,
 | ||||
|     25,     // slaposSupportTree,
 | ||||
|     25,     // slaposBasePool,
 | ||||
|     10,     // slaposSliceSupports,
 | ||||
|     30,     // slaposObjectSlice,
 | ||||
|     20,     // slaposSupportPoints,
 | ||||
|     10,     // slaposSupportTree,
 | ||||
|     10,     // slaposBasePool,
 | ||||
|     30,     // slaposSliceSupports,
 | ||||
| }; | ||||
| 
 | ||||
| const std::array<std::string, slaposCount> OBJ_STEP_LABELS = | ||||
|  | @ -61,8 +61,8 @@ const std::array<std::string, slaposCount> OBJ_STEP_LABELS = | |||
| // Should also add up to 100 (%)
 | ||||
| const std::array<unsigned, slapsCount> PRINT_STEP_LEVELS = | ||||
| { | ||||
|     5,      // slapsMergeSlicesAndEval
 | ||||
|     95,     // slapsRasterize
 | ||||
|     10,      // slapsMergeSlicesAndEval
 | ||||
|     90,      // slapsRasterize
 | ||||
| }; | ||||
| 
 | ||||
| const std::array<std::string, slapsCount> PRINT_STEP_LABELS = | ||||
|  | @ -622,14 +622,6 @@ bool SLAPrint::invalidate_step(SLAPrintStep step) | |||
|     return invalidated; | ||||
| } | ||||
| 
 | ||||
| template<class...Args> | ||||
| void report_status(SLAPrint& p, int st, const std::string& msg, Args&&...args) | ||||
| { | ||||
|     BOOST_LOG_TRIVIAL(info) << st << "% " << msg; | ||||
|     p.set_status(st, msg, std::forward<Args>(args)...); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void SLAPrint::process() | ||||
| { | ||||
|     using namespace sla; | ||||
|  | @ -723,7 +715,7 @@ void SLAPrint::process() | |||
| 
 | ||||
|     // In this step we check the slices, identify island and cover them with
 | ||||
|     // support points. Then we sprinkle the rest of the mesh.
 | ||||
|     auto support_points = [this](SLAPrintObject& po) { | ||||
|     auto support_points = [this, ostepd](SLAPrintObject& po) { | ||||
|         const ModelObject& mo = *po.m_model_object; | ||||
|         po.m_supportdata.reset( | ||||
|                     new SLAPrintObject::SupportData(po.transformed_mesh()) ); | ||||
|  | @ -757,6 +749,19 @@ void SLAPrint::process() | |||
|             config.minimal_distance = float(cfg.support_points_minimal_distance); | ||||
|             config.head_diameter    = float(cfg.support_head_front_diameter); | ||||
| 
 | ||||
|             // scaling for the sub operations
 | ||||
|             double d = ostepd * OBJ_STEP_LEVELS[slaposSupportPoints] / 100.0; | ||||
|             double init = m_report_status.status(); | ||||
| 
 | ||||
|             auto statuscb = [this, d, init](unsigned st) | ||||
|             { | ||||
|                 double current = init + st * d; | ||||
|                 if(std::round(m_report_status.status()) < std::round(current)) | ||||
|                     m_report_status(*this, current, | ||||
|                                     OBJ_STEP_LABELS[slaposSupportPoints]); | ||||
| 
 | ||||
|             }; | ||||
| 
 | ||||
|             // Construction of this object does the calculation.
 | ||||
|             this->throw_if_canceled(); | ||||
|             SLAAutoSupports auto_supports(po.transformed_mesh(), | ||||
|  | @ -764,7 +769,8 @@ void SLAPrint::process() | |||
|                                           po.get_model_slices(), | ||||
|                                           heights, | ||||
|                                           config,  | ||||
|                                           [this]() { throw_if_canceled(); }); | ||||
|                                           [this]() { throw_if_canceled(); }, | ||||
|                                           statuscb); | ||||
| 
 | ||||
|             // Now let's extract the result.
 | ||||
|             const std::vector<sla::SupportPoint>& points = auto_supports.output(); | ||||
|  | @ -775,7 +781,7 @@ void SLAPrint::process() | |||
|                                      << po.m_supportdata->support_points.size(); | ||||
| 
 | ||||
|             // Using RELOAD_SLA_SUPPORT_POINTS to tell the Plater to pass the update status to GLGizmoSlaSupports
 | ||||
|             report_status(*this, -1, L("Generating support points"), SlicingStatus::RELOAD_SLA_SUPPORT_POINTS); | ||||
|             m_report_status(*this, -1, L("Generating support points"), SlicingStatus::RELOAD_SLA_SUPPORT_POINTS); | ||||
|         } | ||||
|         else { | ||||
|             // There are either some points on the front-end, or the user removed them on purpose. No calculation will be done.
 | ||||
|  | @ -784,7 +790,8 @@ void SLAPrint::process() | |||
|     }; | ||||
| 
 | ||||
|     // In this step we create the supports
 | ||||
|     auto support_tree = [this, objcount, ostepd](SLAPrintObject& po) { | ||||
|     auto support_tree = [this, ostepd](SLAPrintObject& po) | ||||
|     { | ||||
|         if(!po.m_supportdata) return; | ||||
| 
 | ||||
|         if(!po.m_config.supports_enable.getBool()) { | ||||
|  | @ -796,22 +803,17 @@ void SLAPrint::process() | |||
|         sla::SupportConfig scfg = make_support_cfg(po.m_config); | ||||
|         sla::Controller ctl; | ||||
| 
 | ||||
|         // some magic to scale the status values coming from the support
 | ||||
|         // tree creation into the whole print process
 | ||||
|         auto stfirst = OBJ_STEP_LEVELS.begin(); | ||||
|         auto stthis = stfirst + slaposSupportTree; | ||||
|         // we need to add up the status portions until this operation
 | ||||
|         int init = std::accumulate(stfirst, stthis, 0); | ||||
|         init = int(init * ostepd);     // scale the init portion
 | ||||
| 
 | ||||
|         // scaling for the sub operations
 | ||||
|         double d = *stthis / 100.0; | ||||
|         double d = ostepd * OBJ_STEP_LEVELS[slaposSupportTree] / 100.0; | ||||
|         double init = m_report_status.status(); | ||||
| 
 | ||||
|         ctl.statuscb = [this, init, d, ostepd](unsigned st, const std::string& /*msg*/) | ||||
|         ctl.statuscb = [this, d, init](unsigned st, const std::string&) | ||||
|         { | ||||
|             //FIXME this status line scaling does not seem to be correct.
 | ||||
|             // How does it account for an increasing object index?
 | ||||
|             report_status(*this, int(init + st*d*ostepd), OBJ_STEP_LABELS[slaposSupportTree]); | ||||
|             double current = init + st * d; | ||||
|             if(std::round(m_report_status.status()) < std::round(current)) | ||||
|                 m_report_status(*this, current, | ||||
|                                 OBJ_STEP_LABELS[slaposSupportTree]); | ||||
| 
 | ||||
|         }; | ||||
| 
 | ||||
|         ctl.stopcondition = [this](){ return canceled(); }; | ||||
|  | @ -827,7 +829,7 @@ void SLAPrint::process() | |||
|         auto rc = SlicingStatus::RELOAD_SCENE; | ||||
| 
 | ||||
|         // This is to prevent "Done." being displayed during merged_mesh()
 | ||||
|         report_status(*this, -1, L("Visualizing supports")); | ||||
|         m_report_status(*this, -1, L("Visualizing supports")); | ||||
|         po.m_supportdata->support_tree_ptr->merged_mesh(); | ||||
| 
 | ||||
|         BOOST_LOG_TRIVIAL(debug) << "Processed support point count " | ||||
|  | @ -837,8 +839,7 @@ void SLAPrint::process() | |||
|         if(po.support_mesh().empty()) | ||||
|             BOOST_LOG_TRIVIAL(warning) << "Support mesh is empty"; | ||||
| 
 | ||||
|         report_status(*this, -1, L("Visualizing supports"), rc); | ||||
| 
 | ||||
|         m_report_status(*this, -1, L("Visualizing supports"), rc); | ||||
|     }; | ||||
| 
 | ||||
|     // This step generates the sla base pad
 | ||||
|  | @ -886,7 +887,7 @@ void SLAPrint::process() | |||
| 
 | ||||
|         po.throw_if_canceled(); | ||||
|         auto rc = SlicingStatus::RELOAD_SCENE; | ||||
|         report_status(*this, -1, L("Visualizing supports"), rc); | ||||
|         m_report_status(*this, -1, L("Visualizing supports"), rc); | ||||
|     }; | ||||
| 
 | ||||
|     // Slicing the support geometries similarly to the model slicing procedure.
 | ||||
|  | @ -917,7 +918,7 @@ void SLAPrint::process() | |||
|         } | ||||
| 
 | ||||
|         // Using RELOAD_SLA_PREVIEW to tell the Plater to pass the update status to the 3D preview to load the SLA slices.
 | ||||
|         report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW); | ||||
|         m_report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW); | ||||
|     }; | ||||
| 
 | ||||
|     // Merging the slices from all the print objects into one slice grid and
 | ||||
|  | @ -1216,7 +1217,7 @@ void SLAPrint::process() | |||
|         m_print_statistics.fast_layers_count = fast_layers; | ||||
|         m_print_statistics.slow_layers_count = slow_layers; | ||||
| 
 | ||||
|         report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW); | ||||
|         m_report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW); | ||||
|     }; | ||||
| 
 | ||||
|     // Rasterizing the model objects, and their supports
 | ||||
|  | @ -1262,16 +1263,11 @@ void SLAPrint::process() | |||
|         // slot is the portion of 100% that is realted to rasterization
 | ||||
|         unsigned slot = PRINT_STEP_LEVELS[slapsRasterize]; | ||||
| 
 | ||||
|         // ist: initial state; pst: previous state
 | ||||
|         unsigned ist = std::accumulate(PRINT_STEP_LEVELS.begin(), | ||||
|                                        PRINT_STEP_LEVELS.begin()+slapsRasterize, | ||||
|                                        0u); | ||||
| 
 | ||||
|         ist = max_objstatus + unsigned(ist * sd); | ||||
|         unsigned pst = ist; | ||||
|         // pst: previous state
 | ||||
|         double pst = m_report_status.status(); | ||||
| 
 | ||||
|         double increment = (slot * sd) / m_printer_input.size(); | ||||
|         double dstatus = double(ist); | ||||
|         double dstatus = m_report_status.status(); | ||||
| 
 | ||||
|         SpinMutex slck; | ||||
| 
 | ||||
|  | @ -1297,10 +1293,10 @@ void SLAPrint::process() | |||
|             { | ||||
|                 std::lock_guard<SpinMutex> lck(slck); | ||||
|                 dstatus += increment; | ||||
|                 auto st = unsigned(dstatus); | ||||
|                 if( st > pst) { | ||||
|                     report_status(*this, int(st), | ||||
|                                   PRINT_STEP_LABELS[slapsRasterize]); | ||||
|                 double st = std::round(dstatus); | ||||
|                 if(st > pst) { | ||||
|                     m_report_status(*this, st, | ||||
|                                     PRINT_STEP_LABELS[slapsRasterize]); | ||||
|                     pst = st; | ||||
|                 } | ||||
|             } | ||||
|  | @ -1341,7 +1337,7 @@ void SLAPrint::process() | |||
|         rasterize | ||||
|     }; | ||||
| 
 | ||||
|     unsigned st = min_objstatus; | ||||
|     double st = min_objstatus; | ||||
|     unsigned incr = 0; | ||||
| 
 | ||||
|     BOOST_LOG_TRIVIAL(info) << "Start slicing process."; | ||||
|  | @ -1355,18 +1351,18 @@ void SLAPrint::process() | |||
| 
 | ||||
|             BOOST_LOG_TRIVIAL(info) << "Slicing object " << po->model_object()->name; | ||||
| 
 | ||||
|             for (int s = (int)step_ranges[idx_range]; s < (int)step_ranges[idx_range + 1]; ++s) { | ||||
|                 auto currentstep = (SLAPrintObjectStep)s; | ||||
|             for (int s = int(step_ranges[idx_range]); s < int(step_ranges[idx_range + 1]); ++s) { | ||||
|                 auto currentstep = static_cast<SLAPrintObjectStep>(s); | ||||
| 
 | ||||
|                 // Cancellation checking. Each step will check for cancellation
 | ||||
|                 // on its own and return earlier gracefully. Just after it returns
 | ||||
|                 // execution gets to this point and throws the canceled signal.
 | ||||
|                 throw_if_canceled(); | ||||
| 
 | ||||
|                 st += unsigned(incr * ostepd); | ||||
|                 st += incr * ostepd; | ||||
| 
 | ||||
|                 if(po->m_stepmask[currentstep] && po->set_started(currentstep)) { | ||||
|                     report_status(*this, int(st), OBJ_STEP_LABELS[currentstep]); | ||||
|                     m_report_status(*this, st, OBJ_STEP_LABELS[currentstep]); | ||||
|                     pobj_program[currentstep](*po); | ||||
|                     throw_if_canceled(); | ||||
|                     po->set_done(currentstep); | ||||
|  | @ -1393,17 +1389,17 @@ void SLAPrint::process() | |||
| 
 | ||||
|         if(m_stepmask[currentstep] && set_started(currentstep)) | ||||
|         { | ||||
|             report_status(*this, int(st), PRINT_STEP_LABELS[currentstep]); | ||||
|             m_report_status(*this, st, PRINT_STEP_LABELS[currentstep]); | ||||
|             print_program[currentstep](); | ||||
|             throw_if_canceled(); | ||||
|             set_done(currentstep); | ||||
|         } | ||||
| 
 | ||||
|         st += unsigned(PRINT_STEP_LEVELS[currentstep] * pstd); | ||||
|         st += PRINT_STEP_LEVELS[currentstep] * pstd; | ||||
|     } | ||||
| 
 | ||||
|     // If everything vent well
 | ||||
|     report_status(*this, 100, L("Slicing done")); | ||||
|     m_report_status(*this, 100, L("Slicing done")); | ||||
| } | ||||
| 
 | ||||
| bool SLAPrint::invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys) | ||||
|  | @ -1727,7 +1723,8 @@ DynamicConfig SLAPrintStatistics::placeholders() | |||
|         "print_time", "total_cost", "total_weight", | ||||
|         "objects_used_material", "support_used_material" }) | ||||
|         config.set_key_value(key, new ConfigOptionString(std::string("{") + key + "}")); | ||||
|         return config; | ||||
| 
 | ||||
|     return config; | ||||
| } | ||||
| 
 | ||||
| std::string SLAPrintStatistics::finalize_output_path(const std::string &path_in) const | ||||
|  | @ -1747,4 +1744,12 @@ std::string SLAPrintStatistics::finalize_output_path(const std::string &path_in) | |||
|     return final_path; | ||||
| } | ||||
| 
 | ||||
| void SLAPrint::StatusReporter::operator()( | ||||
|         SLAPrint &p, double st, const std::string &msg, unsigned flags) | ||||
| { | ||||
|     m_st = st; | ||||
|     BOOST_LOG_TRIVIAL(info) << st << "% " << msg; | ||||
|     p.set_status(int(std::round(st)), msg, flags); | ||||
| } | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
|  |  | |||
|  | @ -474,6 +474,15 @@ private: | |||
|     // Estimated print time, material consumed.
 | ||||
|     SLAPrintStatistics                      m_print_statistics; | ||||
| 
 | ||||
|     class StatusReporter { | ||||
|         double m_st = 0; | ||||
|     public: | ||||
|         void operator() (SLAPrint& p, double st, const std::string& msg, | ||||
|                          unsigned flags = SlicingStatus::DEFAULT); | ||||
|         double status() const { return m_st; } | ||||
|     } m_report_status; | ||||
| 
 | ||||
| 
 | ||||
| 	friend SLAPrintObject; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -59,6 +59,8 @@ enum { | |||
| 	USB_PID_MK3      = 2, | ||||
| 	USB_PID_MMU_BOOT = 3, | ||||
| 	USB_PID_MMU_APP  = 4, | ||||
| 	USB_PID_CW1_BOOT = 7, | ||||
| 	USB_PID_CW1_APP  = 8, | ||||
| }; | ||||
| 
 | ||||
| // This enum discriminates the kind of information in EVT_AVRDUDE,
 | ||||
|  | @ -77,6 +79,13 @@ wxDEFINE_EVENT(EVT_AVRDUDE, wxCommandEvent); | |||
| wxDECLARE_EVENT(EVT_ASYNC_DIALOG, wxCommandEvent); | ||||
| wxDEFINE_EVENT(EVT_ASYNC_DIALOG, wxCommandEvent); | ||||
| 
 | ||||
| struct Avr109Pid | ||||
| { | ||||
| 	unsigned boot; | ||||
| 	unsigned app; | ||||
| 
 | ||||
| 	Avr109Pid(unsigned boot, unsigned app) : boot(boot), app(app) {} | ||||
| }; | ||||
| 
 | ||||
| // Private
 | ||||
| 
 | ||||
|  | @ -146,24 +155,40 @@ struct FirmwareDialog::priv | |||
| 	void flashing_done(AvrDudeComplete complete); | ||||
| 	void enable_port_picker(bool enable); | ||||
| 	void load_hex_file(const wxString &path); | ||||
| 	void queue_status(wxString message); | ||||
| 	void queue_error(const wxString &message); | ||||
| 	void queue_event(AvrdudeEvent aevt, wxString message); | ||||
| 
 | ||||
| 	bool ask_model_id_mismatch(const std::string &printer_model); | ||||
| 	bool check_model_id(); | ||||
| 	void wait_for_mmu_bootloader(unsigned retries); | ||||
| 	void mmu_reboot(const SerialPortInfo &port); | ||||
| 	void lookup_port_mmu(); | ||||
| 	void avr109_wait_for_bootloader(Avr109Pid usb_pid, unsigned retries); | ||||
| 	void avr109_reboot(const SerialPortInfo &port); | ||||
| 	void avr109_lookup_port(Avr109Pid usb_pid); | ||||
| 	void prepare_common(); | ||||
| 	void prepare_mk2(); | ||||
| 	void prepare_mk3(); | ||||
| 	void prepare_mm_control(); | ||||
| 	void prepare_avr109(Avr109Pid usb_pid); | ||||
| 	void perform_upload(); | ||||
| 
 | ||||
| 	void user_cancel(); | ||||
| 	void on_avrdude(const wxCommandEvent &evt); | ||||
| 	void on_async_dialog(const wxCommandEvent &evt); | ||||
| 	void ensure_joined(); | ||||
| 
 | ||||
| 	void queue_status(wxString message) { queue_event(AE_STATUS, std::move(message)); } | ||||
| 
 | ||||
| 	template<class ...Args> void queue_message(const wxString &format, Args... args) { | ||||
| 		auto message = wxString::Format(format, args...); | ||||
| 		BOOST_LOG_TRIVIAL(info) << message; | ||||
| 		message.Append('\n'); | ||||
| 		queue_event(AE_MESSAGE, std::move(message)); | ||||
| 	} | ||||
| 
 | ||||
| 	template<class ...Args> void queue_error(const wxString &format, Args... args) { | ||||
| 		queue_message(format, args...); | ||||
| 		queue_event(AE_STATUS, _(L("Flashing failed: ")) + wxString::Format(format, args...)); | ||||
| 		avrdude->cancel(); | ||||
| 	} | ||||
| 
 | ||||
| 	static const char* avr109_dev_name(Avr109Pid usb_pid); | ||||
| }; | ||||
| 
 | ||||
| void FirmwareDialog::priv::find_serial_ports() | ||||
|  | @ -259,26 +284,18 @@ void FirmwareDialog::priv::enable_port_picker(bool enable) | |||
| void FirmwareDialog::priv::load_hex_file(const wxString &path) | ||||
| { | ||||
| 	hex_file = HexFile(path.wx_str()); | ||||
| 	enable_port_picker(hex_file.device != HexFile::DEV_MM_CONTROL); | ||||
| 	const bool auto_lookup = hex_file.device == HexFile::DEV_MM_CONTROL || hex_file.device == HexFile::DEV_CW1; | ||||
| 	enable_port_picker(! auto_lookup); | ||||
| } | ||||
| 
 | ||||
| void FirmwareDialog::priv::queue_status(wxString message) | ||||
| void FirmwareDialog::priv::queue_event(AvrdudeEvent aevt, wxString message) | ||||
| { | ||||
| 	auto evt = new wxCommandEvent(EVT_AVRDUDE, this->q->GetId()); | ||||
| 	evt->SetExtraLong(AE_STATUS); | ||||
| 	evt->SetExtraLong(aevt); | ||||
| 	evt->SetString(std::move(message)); | ||||
| 	wxQueueEvent(this->q, evt); | ||||
| } | ||||
| 
 | ||||
| void FirmwareDialog::priv::queue_error(const wxString &message) | ||||
| { | ||||
| 	auto evt = new wxCommandEvent(EVT_AVRDUDE, this->q->GetId()); | ||||
| 	evt->SetExtraLong(AE_STATUS); | ||||
| 	evt->SetString(wxString::Format(_(L("Flashing failed: %s")), message)); | ||||
| 
 | ||||
| 	wxQueueEvent(this->q, evt);	avrdude->cancel(); | ||||
| } | ||||
| 
 | ||||
| bool FirmwareDialog::priv::ask_model_id_mismatch(const std::string &printer_model) | ||||
| { | ||||
| 	// model_id in the hex file doesn't match what the printer repoted.
 | ||||
|  | @ -356,7 +373,7 @@ bool FirmwareDialog::priv::check_model_id() | |||
| 	// return false;
 | ||||
| } | ||||
| 
 | ||||
| void FirmwareDialog::priv::wait_for_mmu_bootloader(unsigned retries) | ||||
| void FirmwareDialog::priv::avr109_wait_for_bootloader(Avr109Pid usb_pid, unsigned retries) | ||||
| { | ||||
| 	enum { | ||||
| 		SLEEP_MS = 500, | ||||
|  | @ -367,61 +384,63 @@ void FirmwareDialog::priv::wait_for_mmu_bootloader(unsigned retries) | |||
| 
 | ||||
| 		auto ports = Utils::scan_serial_ports_extended(); | ||||
| 		ports.erase(std::remove_if(ports.begin(), ports.end(), [=](const SerialPortInfo &port ) { | ||||
| 			return port.id_vendor != USB_VID_PRUSA || port.id_product != USB_PID_MMU_BOOT; | ||||
| 			return port.id_vendor != USB_VID_PRUSA || port.id_product != usb_pid.boot; | ||||
| 		}), ports.end()); | ||||
| 
 | ||||
| 		if (ports.size() == 1) { | ||||
| 			port = ports[0]; | ||||
| 			return; | ||||
| 		} else if (ports.size() > 1) { | ||||
| 			BOOST_LOG_TRIVIAL(error) << "Several VID/PID 0x2c99/3 devices found"; | ||||
| 			queue_error(_(L("Multiple Original Prusa i3 MMU 2.0 devices found. Please only connect one at a time for flashing."))); | ||||
| 			queue_message("Several VID/PID 0x2c99/%u devices found", usb_pid.boot); | ||||
| 			queue_error(_(L("Multiple %s devices found. Please only connect one at a time for flashing.")), avr109_dev_name(usb_pid)); | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void FirmwareDialog::priv::mmu_reboot(const SerialPortInfo &port) | ||||
| void FirmwareDialog::priv::avr109_reboot(const SerialPortInfo &port) | ||||
| { | ||||
| 	asio::io_service io; | ||||
| 	Serial serial(io, port.port, 1200); | ||||
| 	std::this_thread::sleep_for(std::chrono::milliseconds(50)); | ||||
| } | ||||
| 
 | ||||
| void FirmwareDialog::priv::lookup_port_mmu() | ||||
| void FirmwareDialog::priv::avr109_lookup_port(Avr109Pid usb_pid) | ||||
| { | ||||
| 	static const auto msg_not_found = | ||||
| 		"The Multi Material Control device was not found.\n" | ||||
| 		"If the device is connected, please press the Reset button next to the USB connector ..."; | ||||
| 	const char *dev_name = avr109_dev_name(usb_pid); | ||||
| 	const wxString msg_not_found = wxString::Format( | ||||
| 		_(L("The %s device was not found.\n" | ||||
| 			"If the device is connected, please press the Reset button next to the USB connector ...")), | ||||
| 		dev_name); | ||||
| 
 | ||||
| 	BOOST_LOG_TRIVIAL(info) << "Flashing MMU 2.0, looking for VID/PID 0x2c99/3 or 0x2c99/4 ..."; | ||||
| 	queue_message("Flashing %s, looking for VID/PID 0x2c99/%u or 0x2c99/%u ...", dev_name, usb_pid.boot, usb_pid.app); | ||||
| 
 | ||||
| 	auto ports = Utils::scan_serial_ports_extended(); | ||||
| 	ports.erase(std::remove_if(ports.begin(), ports.end(), [=](const SerialPortInfo &port ) { | ||||
| 		return port.id_vendor != USB_VID_PRUSA || | ||||
| 			port.id_product != USB_PID_MMU_BOOT && | ||||
| 			port.id_product != USB_PID_MMU_APP; | ||||
| 			port.id_product != usb_pid.boot && | ||||
| 			port.id_product != usb_pid.app; | ||||
| 	}), ports.end()); | ||||
| 
 | ||||
| 	if (ports.size() == 0) { | ||||
| 		BOOST_LOG_TRIVIAL(info) << "MMU 2.0 device not found, asking the user to press Reset and waiting for the device to show up ..."; | ||||
| 		queue_status(_(L(msg_not_found))); | ||||
| 		wait_for_mmu_bootloader(30); | ||||
| 		queue_message("The %s device was not found.", dev_name); | ||||
| 		queue_status(msg_not_found); | ||||
| 		avr109_wait_for_bootloader(usb_pid, 30); | ||||
| 	} else if (ports.size() > 1) { | ||||
| 		BOOST_LOG_TRIVIAL(error) << "Several VID/PID 0x2c99/3 devices found"; | ||||
| 		queue_error(_(L("Multiple Original Prusa i3 MMU 2.0 devices found. Please only connect one at a time for flashing."))); | ||||
| 		queue_message("Several VID/PID 0x2c99/%u devices found", usb_pid.boot); | ||||
| 		queue_error(_(L("Multiple %s devices found. Please only connect one at a time for flashing.")), dev_name); | ||||
| 	} else { | ||||
| 		if (ports[0].id_product == USB_PID_MMU_APP) { | ||||
| 		if (ports[0].id_product == usb_pid.app) { | ||||
| 			// The device needs to be rebooted into the bootloader mode
 | ||||
| 			BOOST_LOG_TRIVIAL(info) << boost::format("Found VID/PID 0x2c99/4 at `%1%`, rebooting the device ...") % ports[0].port; | ||||
| 			mmu_reboot(ports[0]); | ||||
| 			wait_for_mmu_bootloader(10); | ||||
| 			queue_message("Found VID/PID 0x2c99/%u at `%s`, rebooting the device ...", usb_pid.app, ports[0].port); | ||||
| 			avr109_reboot(ports[0]); | ||||
| 			avr109_wait_for_bootloader(usb_pid, 10); | ||||
| 
 | ||||
| 			if (! port) { | ||||
| 				// The device in bootloader mode was not found, inform the user and wait some more...
 | ||||
| 				BOOST_LOG_TRIVIAL(info) << "MMU 2.0 bootloader device not found after reboot, asking the user to press Reset and waiting for the device to show up ..."; | ||||
| 				queue_status(_(L(msg_not_found))); | ||||
| 				wait_for_mmu_bootloader(30); | ||||
| 				queue_message("%s device not found after reboot", dev_name); | ||||
| 				queue_status(msg_not_found); | ||||
| 				avr109_wait_for_bootloader(usb_pid, 30); | ||||
| 			} | ||||
| 		} else { | ||||
| 			port = ports[0]; | ||||
|  | @ -498,16 +517,16 @@ void FirmwareDialog::priv::prepare_mk3() | |||
| 	avrdude->push_args(std::move(args)); | ||||
| } | ||||
| 
 | ||||
| void FirmwareDialog::priv::prepare_mm_control() | ||||
| void FirmwareDialog::priv::prepare_avr109(Avr109Pid usb_pid) | ||||
| { | ||||
| 	port = boost::none; | ||||
| 	lookup_port_mmu(); | ||||
| 	avr109_lookup_port(usb_pid); | ||||
| 	if (! port) { | ||||
| 		queue_error(_(L("The device could not have been found"))); | ||||
| 		queue_error(_(L("The %s device could not have been found")), avr109_dev_name(usb_pid)); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	BOOST_LOG_TRIVIAL(info) << boost::format("Found VID/PID 0x2c99/3 at `%1%`, flashing ...") % port->port; | ||||
| 	queue_message("Found VID/PID 0x2c99/%u at `%s`, flashing ...", usb_pid.boot, port->port); | ||||
| 	queue_status(label_status_flashing); | ||||
| 
 | ||||
| 	std::vector<std::string> args {{ | ||||
|  | @ -568,7 +587,11 @@ void FirmwareDialog::priv::perform_upload() | |||
| 					break; | ||||
| 
 | ||||
| 				case HexFile::DEV_MM_CONTROL: | ||||
| 					this->prepare_mm_control(); | ||||
| 					this->prepare_avr109(Avr109Pid(USB_PID_MMU_BOOT, USB_PID_MMU_APP)); | ||||
| 					break; | ||||
| 
 | ||||
| 				case HexFile::DEV_CW1: | ||||
| 					this->prepare_avr109(Avr109Pid(USB_PID_CW1_BOOT, USB_PID_CW1_APP)); | ||||
| 					break; | ||||
| 
 | ||||
| 				default: | ||||
|  | @ -576,7 +599,11 @@ void FirmwareDialog::priv::perform_upload() | |||
| 					break; | ||||
| 				} | ||||
| 			} catch (const std::exception &ex) { | ||||
| 				queue_error(wxString::Format(_(L("Error accessing port at %s: %s")), port->port, ex.what())); | ||||
| 				if (port) { | ||||
| 					queue_error(_(L("Error accessing port at %s: %s")), port->port, ex.what()); | ||||
| 				} else { | ||||
| 					queue_error(_(L("Error: %s")), ex.what()); | ||||
| 				} | ||||
| 			} | ||||
| 		}) | ||||
| 		.on_message(std::move([q, extra_verbose](const char *msg, unsigned /* size */) { | ||||
|  | @ -688,6 +715,19 @@ void FirmwareDialog::priv::ensure_joined() | |||
| 	avrdude.reset(); | ||||
| } | ||||
| 
 | ||||
| const char* FirmwareDialog::priv::avr109_dev_name(Avr109Pid usb_pid) { | ||||
| 	switch (usb_pid.boot) { | ||||
| 		case USB_PID_MMU_BOOT: | ||||
| 			return "Prusa MMU 2.0 Control"; | ||||
| 		break; | ||||
| 		case USB_PID_CW1_BOOT: | ||||
| 			return "Prusa CurWa"; | ||||
| 		break; | ||||
| 
 | ||||
| 		default: throw std::runtime_error((boost::format("Invalid avr109 device USB PID: %1%") % usb_pid.boot).str()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Public
 | ||||
| 
 | ||||
|  | @ -757,7 +797,7 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) : | |||
| 
 | ||||
| 	vsizer->Add(grid, 0, wxEXPAND | wxTOP | wxBOTTOM, SPACING); | ||||
| 
 | ||||
| 	p->spoiler = new wxCollapsiblePane(panel, wxID_ANY, _(L("Advanced: avrdude output log")), wxDefaultPosition, wxDefaultSize, wxCP_DEFAULT_STYLE | wxCP_NO_TLW_RESIZE); | ||||
| 	p->spoiler = new wxCollapsiblePane(panel, wxID_ANY, _(L("Advanced: Output log")), wxDefaultPosition, wxDefaultSize, wxCP_DEFAULT_STYLE | wxCP_NO_TLW_RESIZE); | ||||
| 	auto *spoiler_pane = p->spoiler->GetPane(); | ||||
| 	auto *spoiler_sizer = new wxBoxSizer(wxVERTICAL); | ||||
| 	p->txt_stdout = new wxTextCtrl(spoiler_pane, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY); | ||||
|  |  | |||
|  | @ -4405,12 +4405,12 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) | |||
| 
 | ||||
|     auto *imgui = wxGetApp().imgui(); | ||||
|     imgui->set_display_size((float)w, (float)h); | ||||
|     imgui->set_font_size(m_canvas->GetFont().GetPixelSize().y); | ||||
| #if ENABLE_RETINA_GL | ||||
|     imgui->set_style_scaling(m_retina_helper->get_scale_factor()); | ||||
|     const float scaling = m_retina_helper->get_scale_factor(); | ||||
| #else | ||||
|     imgui->set_style_scaling(m_canvas->GetContentScaleFactor()); | ||||
|     const float scaling = m_canvas->GetContentScaleFactor(); | ||||
| #endif | ||||
|     imgui->set_scaling(m_canvas->GetFont().GetPixelSize().y, scaling); | ||||
| 
 | ||||
|     // ensures that this canvas is current
 | ||||
|     _set_current(); | ||||
|  |  | |||
|  | @ -185,7 +185,10 @@ void GLGizmoCut::on_render_for_picking(const Selection& selection) const | |||
| 
 | ||||
| void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit, const Selection& selection) | ||||
| { | ||||
|     const float approx_height = m_imgui->scaled(11.0f); | ||||
|     y = std::min(y, bottom_limit - approx_height); | ||||
|     m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); | ||||
| 
 | ||||
|     m_imgui->set_next_window_bg_alpha(0.5f); | ||||
|     m_imgui->begin(_(L("Cut")), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); | ||||
| 
 | ||||
|  |  | |||
|  | @ -565,7 +565,7 @@ void GLGizmoSlaSupports::on_render_input_window(float x, float y, float bottom_l | |||
| RENDER_AGAIN: | ||||
|     m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); | ||||
| 
 | ||||
|     const ImVec2 window_size(m_imgui->scaled_vec(15.f, 16.5f)); | ||||
|     const ImVec2 window_size(m_imgui->scaled(15.f, 16.5f)); | ||||
|     ImGui::SetNextWindowPos(ImVec2(x, y - std::max(0.f, y+window_size.y-bottom_limit) )); | ||||
|     ImGui::SetNextWindowSize(ImVec2(window_size)); | ||||
| 
 | ||||
|  | @ -816,7 +816,7 @@ void GLGizmoSlaSupports::editing_mode_apply_changes() | |||
|         // Recalculate support structures once the editing mode is left.
 | ||||
|         // m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
 | ||||
|         // m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
 | ||||
|         wxGetApp().plater()->reslice_SLA_supports(*m_model_object); | ||||
|         wxGetApp().CallAfter([this]() { wxGetApp().plater()->reslice_SLA_supports(*m_model_object); }); | ||||
|     } | ||||
|     m_editing_mode = false; | ||||
|     m_unsaved_changes = false; | ||||
|  | @ -869,7 +869,7 @@ void GLGizmoSlaSupports::auto_generate() | |||
|         m_model_object->sla_support_points.clear(); | ||||
|         m_model_object->sla_points_status = sla::PointsStatus::Generating; | ||||
|         m_editing_mode_cache.clear(); | ||||
|         wxGetApp().plater()->reslice_SLA_supports(*m_model_object); | ||||
|         wxGetApp().CallAfter([this]() { wxGetApp().plater()->reslice_SLA_supports(*m_model_object); }); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -92,21 +92,18 @@ void ImGuiWrapper::set_display_size(float w, float h) | |||
|     io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f); | ||||
| } | ||||
| 
 | ||||
| void ImGuiWrapper::set_font_size(float font_size) | ||||
| void ImGuiWrapper::set_scaling(float font_size, float scaling) | ||||
| { | ||||
|     if (m_font_size != font_size) { | ||||
|         m_font_size = font_size; | ||||
|         destroy_font(); | ||||
|     if (m_font_size == font_size && m_style_scaling == scaling) { | ||||
|         return; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ImGuiWrapper::set_style_scaling(float scaling) | ||||
| { | ||||
|     if (!std::isnan(scaling) && !std::isinf(scaling) && scaling != m_style_scaling) { | ||||
|         ImGui::GetStyle().ScaleAllSizes(scaling / m_style_scaling); | ||||
|         m_style_scaling = scaling; | ||||
|         destroy_font(); | ||||
|     } | ||||
|     m_font_size = font_size; | ||||
| 
 | ||||
|     ImGui::GetStyle().ScaleAllSizes(scaling / m_style_scaling); | ||||
|     m_style_scaling = scaling; | ||||
| 
 | ||||
|     destroy_font(); | ||||
| } | ||||
| 
 | ||||
| bool ImGuiWrapper::update_mouse_data(wxMouseEvent& evt) | ||||
|  | @ -163,8 +160,6 @@ bool ImGuiWrapper::update_key_data(wxKeyEvent &evt) | |||
| 
 | ||||
| void ImGuiWrapper::new_frame() | ||||
| { | ||||
|     printf("ImGuiWrapper: new_frame()\n"); | ||||
| 
 | ||||
|     if (m_new_frame_open) { | ||||
|         return; | ||||
|     } | ||||
|  | @ -184,6 +179,12 @@ void ImGuiWrapper::render() | |||
|     m_new_frame_open = false; | ||||
| } | ||||
| 
 | ||||
| ImVec2 ImGuiWrapper::calc_text_size(const wxString &text) | ||||
| { | ||||
|     auto text_utf8 = into_u8(text); | ||||
|     return ImGui::CalcTextSize(text_utf8.c_str()); | ||||
| } | ||||
| 
 | ||||
| void ImGuiWrapper::set_next_window_pos(float x, float y, int flag) | ||||
| { | ||||
|     ImGui::SetNextWindowPos(ImVec2(x, y), (ImGuiCond)flag); | ||||
|  | @ -293,12 +294,6 @@ bool ImGuiWrapper::combo(const wxString& label, const std::vector<std::string>& | |||
|     return res; | ||||
| } | ||||
| 
 | ||||
| ImVec2 ImGuiWrapper::calc_text_size(const wxString &text) | ||||
| { | ||||
|     auto text_utf8 = into_u8(text); | ||||
|     return ImGui::CalcTextSize(text_utf8.c_str()); | ||||
| } | ||||
| 
 | ||||
| void ImGuiWrapper::disabled_begin(bool disabled) | ||||
| { | ||||
|     wxCHECK_RET(!m_disabled, "ImGUI: Unbalanced disabled_begin() call"); | ||||
|  | @ -342,8 +337,6 @@ bool ImGuiWrapper::want_any_input() const | |||
| 
 | ||||
| void ImGuiWrapper::init_font() | ||||
| { | ||||
|     printf("ImGuiWrapper: init_font()\n"); | ||||
| 
 | ||||
|     const float font_size = m_font_size * m_style_scaling; | ||||
| 
 | ||||
|     destroy_font(); | ||||
|  |  | |||
|  | @ -35,8 +35,7 @@ public: | |||
| 
 | ||||
|     void set_language(const std::string &language); | ||||
|     void set_display_size(float w, float h); | ||||
|     void set_font_size(float font_size); | ||||
|     void set_style_scaling(float scaling); | ||||
|     void set_scaling(float font_size, float scaling); | ||||
|     bool update_mouse_data(wxMouseEvent &evt); | ||||
|     bool update_key_data(wxKeyEvent &evt); | ||||
| 
 | ||||
|  | @ -47,7 +46,8 @@ public: | |||
|     void render(); | ||||
| 
 | ||||
|     float scaled(float x) const { return x * m_font_size * m_style_scaling; } | ||||
|     ImVec2 scaled_vec(float x, float y) const { return ImVec2(x * m_font_size * m_style_scaling, y * m_font_size * m_style_scaling); } | ||||
|     ImVec2 scaled(float x, float y) const { return ImVec2(x * m_font_size * m_style_scaling, y * m_font_size * m_style_scaling); } | ||||
|     ImVec2 calc_text_size(const wxString &text); | ||||
| 
 | ||||
|     void set_next_window_pos(float x, float y, int flag); | ||||
|     void set_next_window_bg_alpha(float alpha); | ||||
|  | @ -66,8 +66,6 @@ public: | |||
|     void text(const wxString &label); | ||||
|     bool combo(const wxString& label, const std::vector<std::string>& options, int& selection);   // Use -1 to not mark any option as selected
 | ||||
| 
 | ||||
|     ImVec2 calc_text_size(const wxString &text); | ||||
| 
 | ||||
|     void disabled_begin(bool disabled); | ||||
|     void disabled_end(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1703,7 +1703,7 @@ bool Selection::_is_from_fully_selected_instance(unsigned int volume_idx) const | |||
|         GLVolumePtrs& volumes; | ||||
| 
 | ||||
|         SameInstance(int obj_idx, int inst_idx, GLVolumePtrs& volumes) : obj_idx(obj_idx), inst_idx(inst_idx), volumes(volumes) {} | ||||
|         bool operator () (unsigned int i) { return (volumes[i]->object_idx() == obj_idx) && (volumes[i]->instance_idx() == inst_idx); } | ||||
|         bool operator () (unsigned int i) { return (volumes[i]->volume_idx() >= 0) && (volumes[i]->object_idx() == obj_idx) && (volumes[i]->instance_idx() == inst_idx); } | ||||
|     }; | ||||
| 
 | ||||
|     if ((unsigned int)m_volumes->size() <= volume_idx) | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ static HexFile::DeviceKind parse_device_kind(const std::string &str) | |||
| 	     if (str == "mk2") { return HexFile::DEV_MK2; } | ||||
| 	else if (str == "mk3") { return HexFile::DEV_MK3; } | ||||
| 	else if (str == "mm-control") { return HexFile::DEV_MM_CONTROL; } | ||||
| 	else if (str == "cw1") { return HexFile::DEV_CW1; } | ||||
| 	else { return HexFile::DEV_GENERIC; } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ struct HexFile | |||
| 		DEV_MK2, | ||||
| 		DEV_MK3, | ||||
| 		DEV_MM_CONTROL, | ||||
| 		DEV_CW1, | ||||
| 	}; | ||||
| 
 | ||||
| 	boost::filesystem::path path; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv