From ffec4ee330511ab55629acfc5213666d88fb3250 Mon Sep 17 00:00:00 2001 From: supermerill Date: Thu, 28 May 2020 18:07:54 +0200 Subject: [PATCH] add calibration cubes update to flow calibration scaling --- resources/calibration/cube/LICENCE.txt | 2 + resources/calibration/cube/cube.html | 22 ++++ .../calibration/cube/voron_design_cube_v6.amf | Bin 0 -> 35934 bytes .../calibration/cube/xyzCalibration_cube.amf | Bin 0 -> 2158 bytes .../filament_temp/filament_temp.html | 3 +- src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/CalibrationCubeDialog.cpp | 107 ++++++++++++++++++ src/slic3r/GUI/CalibrationCubeDialog.hpp | 30 +++++ src/slic3r/GUI/CalibrationFlowDialog.cpp | 40 ++++--- src/slic3r/GUI/GUI_App.cpp | 5 + src/slic3r/GUI/GUI_App.hpp | 1 + src/slic3r/GUI/MainFrame.cpp | 4 +- 12 files changed, 192 insertions(+), 24 deletions(-) create mode 100644 resources/calibration/cube/LICENCE.txt create mode 100644 resources/calibration/cube/cube.html create mode 100644 resources/calibration/cube/voron_design_cube_v6.amf create mode 100644 resources/calibration/cube/xyzCalibration_cube.amf create mode 100644 src/slic3r/GUI/CalibrationCubeDialog.cpp create mode 100644 src/slic3r/GUI/CalibrationCubeDialog.hpp diff --git a/resources/calibration/cube/LICENCE.txt b/resources/calibration/cube/LICENCE.txt new file mode 100644 index 000000000..219827f42 --- /dev/null +++ b/resources/calibration/cube/LICENCE.txt @@ -0,0 +1,2 @@ +voron_design_cube_v6.amf is under GPL V3, made by vorondesign (https://github.com/VoronDesign/Voron-2) +xyzCalibration_cube is under CC BY-SA 3.0, made by iDig3Dprinting (https://www.thingiverse.com/thing:1278865) \ No newline at end of file diff --git a/resources/calibration/cube/cube.html b/resources/calibration/cube/cube.html new file mode 100644 index 000000000..38ae86f35 --- /dev/null +++ b/resources/calibration/cube/cube.html @@ -0,0 +1,22 @@ + + + + + Calibration cube + + +

Calibration cube

+

This page allow you to print the loved calibration cube. It's useful to see if your printer is accurate, and calibrate some settings. First thing is to select your goal.

+

Goal: Dimensional accuracy

+

You have to print two cubes, with different sizes. If the dimensional inaccuracy scale with the size of the cubes, then it's the steps/mm of your steppers that needs some adjustments (note: if it's the case, you should also adjust the flow, and maybe redo some calibrations if the change is big). If it doesn't scale, you can correct it by adjusting your xy compensation (slicing tab). With the voron cube, you can also test the hole calibration, as these are often too small.

+

Goal: infill/perimeter overlap

+

This test is about to see if the pattern of the infill can be seen on the perimeters. Try to reduce it as low as you can but check the top solid fill, as it can create artifacts if it's too low. It's better with the standard cube, as you have a larger top surface.

+

Goal: external perimeter overlap

+

As the external perimeter is printed last, the real position depends on the position and flow of the whole layer. So you have to be sure that your flow is perfect before doing this test. The main difference is between solid infill layers and sparse infill layers, as the solid one can push the external perimeter outwards. Decreasing the infill/perimeter overlap, decreasing the external perimeter overlap can help to reduce this effect.

+

Notes

+

These tests should be the last ones.

+

Default size of the standard cube is 20mm and the standard size of the voron cube is 30mm.

+

Licence for the standard calibration cube: CC BY-SA 3.0, made by iDig3Dprinting

+

Licence for the voron calibration cube: GPL V3, made by vorondesign

+ + \ No newline at end of file diff --git a/resources/calibration/cube/voron_design_cube_v6.amf b/resources/calibration/cube/voron_design_cube_v6.amf new file mode 100644 index 0000000000000000000000000000000000000000..d79cddc9ed68ec76e48493d48dbf41f5be9df5d8 GIT binary patch literal 35934 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 literal 0 HcmV?d00001 diff --git a/resources/calibration/cube/xyzCalibration_cube.amf b/resources/calibration/cube/xyzCalibration_cube.amf new file mode 100644 index 0000000000000000000000000000000000000000..35af49d2cdee0ca31f16544f5384abf69bcd5b83 GIT binary patch literal 2158 zcmaKuXE+-Q7snG67a^`yD>UJ@DaA`{Dt1++h+d=i4B}c*N~zRnjFi};s#;=eEB2~U zqoNwzQn5$XR;_W3)YbR<`=0aR|D5xj=Q;lm=XuW0+?1Jx9{>Qb16E?&%&V~e4@TJl zfRft)fcSaW#@5bBQNhp8N#6zQ?Hc5Q^Y;JCNk7EZL(av|v)6tK1v3Um#=k;Fd99up zDmog9R(}_h{y5?s?_k_v&?h;+G3LiCIw9y;6gO-M!khFj`|y^3df4-5{*f%Nsqr^gSG93R(?#rn8Iz0ET3YZKC5rs zBDa6mIvaCH>8Nhq-jILmIIA_Z()czsg_3-7H{#3| zpVKhQzTn^1#JN`3;XH7} zfLOCf%ez3&Y~q4&R|3t}onl0_(%)ku+^4h@xMei=!I!-icUEuiH)jl@#)1OygMvgQ z*KamT#EEVZtwvF2{_Vp4m#Oo6T1ivupGranv&*eDOC$OMEFz6*)JY0c0w=P3*8-%= zb8?_8an)RVCp=Wy7U;`g$3WOsTWF0Cf`*`aODS24=|gM{GB2Ak@JZR_dvo!QqA4@VHWztLCOB<_-Shr@CJjEm6NoTI2+C#wb?mQDdDP+NZ(nUI?x-8i^GC#tK_xT^u zSqY`wVqr3=%w^s+Bb%vYFt3$6`Bj~jp@{Mua4Ktv^WwB z)Y|wym}JW*P@NDxaEF8fl|hw?c4@ev0hpJ?CNjZ%2#0r$)eqL}(nXRVA-Z2YenaQ%y99fg1t8Z4&P1Mu4jv3%5C$0)g0;gL*8ce1xSqdP6LaWk7 z4B5~EZLK8!(%T~TXH_#nA)EYQhJ(_>Kl8*_Ag zu0nj4IK46v$Z3*P-T(t^FdNvurEXpDK8u6DOz#!bGXR{=&Ph}O8lCP@vdCTZwD3x@#=+iM(s&RO@8(z+Br^=WH$t zM2NIbph7*B^$q^HmsSar4RsFgu1X=?IH_Mk0bZ*E$-VV3EDC8X2i@X$4htQ@6Y7LC zYP`7ppXYqy;`QDN976XfvStyVObUo?DV4eH&Jyog_t(R=l)}y}U=0??AkW^Ad0{nW zN^sGWy2YTz2Eq-Qnx$G7x&YU=ZdZeK--Bmt+tF~xApmp}ep3}5=CjQmeN4}&QNXu~ ztWK0*KlA$=dJ8U=H%C}BE&K*H^|I%DT8XP|RCpY$E<}W|1&6_tD817HS#iCmdBZ7$ z0gpT!y$2l}d44C*(7p>!%!Ld0teZeQ;AS+(gDGITwh(EhK1R3^2Q_@Ri0+w252lLU zf=e8B@AaJ!>yNDG8g%wlI_M0XeUyg7wH?)&2OW&Srn8?})3WWea_7%!o1!zPE;@Jb zhgmD5sCL3j$0;)EVMu7`x3G4`tDpN+6ke59{d>fV%U_o&?**!=p9z_p0-5*${~HI+ eiQvCchyNx27Y@u#FR=a^0-mSoxq{e#RsRBsxC9*l literal 0 HcmV?d00001 diff --git a/resources/calibration/filament_temp/filament_temp.html b/resources/calibration/filament_temp/filament_temp.html index 69ead7848..7f17e995b 100644 --- a/resources/calibration/filament_temp/filament_temp.html +++ b/resources/calibration/filament_temp/filament_temp.html @@ -48,7 +48,6 @@

Notes

Most of the calibrations need to done is the right order. This one should be the third.

The temperature numbers will only be shown between 180 and 285. Higher or lower values won't be displayed but the test will be conducted successfully, you just have to remember them.

-

This tower is made with the 3D model created by gaaZolee and available here https://www.thingiverse.com/thing:2729076 with the CC BY-SA 3.0 licence.

-

Licence for models used for this calibration test: CC BY-SA 3.0

+

This tower is made with the 3D model created by gaaZolee with the CC BY-SA 3.0 licence.

\ No newline at end of file diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 336c2f49e..75031f7bd 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -24,6 +24,8 @@ set(SLIC3R_GUI_SOURCES GUI/CalibrationBedDialog.hpp GUI/CalibrationBridgeDialog.cpp GUI/CalibrationBridgeDialog.hpp + GUI/CalibrationCubeDialog.cpp + GUI/CalibrationCubeDialog.hpp GUI/CalibrationFlowDialog.cpp GUI/CalibrationFlowDialog.hpp GUI/CalibrationOverBridgeDialog.cpp diff --git a/src/slic3r/GUI/CalibrationCubeDialog.cpp b/src/slic3r/GUI/CalibrationCubeDialog.cpp new file mode 100644 index 000000000..7dda4bea7 --- /dev/null +++ b/src/slic3r/GUI/CalibrationCubeDialog.cpp @@ -0,0 +1,107 @@ +#include "CalibrationCubeDialog.hpp" +#include "I18N.hpp" +#include "libslic3r/Utils.hpp" +#include "GUI.hpp" +#include "GUI_ObjectList.hpp" +#include "Tab.hpp" +#include +#include +#include +#include "wxExtensions.hpp" + +#if ENABLE_SCROLLABLE +static wxSize get_screen_size(wxWindow* window) +{ + const auto idx = wxDisplay::GetFromWindow(window); + wxDisplay display(idx != wxNOT_FOUND ? idx : 0u); + return display.GetClientArea().GetSize(); +} +#endif // ENABLE_SCROLLABLE + +namespace Slic3r { +namespace GUI { + +void CalibrationCubeDialog::create_buttons(wxStdDialogButtonSizer* buttons){ + wxString choices_scale[] = { "10mm", "20mm", "30mm", "40mm" }; + scale = new wxComboBox(this, wxID_ANY, wxString{ "20mm" }, wxDefaultPosition, wxDefaultSize, 4, choices_scale); + scale->SetToolTip(_(L("You can choose the dimension of the cube. It's a simple scale, you can modify it in the right panel yourself if you prefer. It's just quicker to select it here."))); + scale->SetSelection(1); + wxString choices_goal[] = { "Dimensional accuracy (default)" , "infill/perimeter overlap", "external perimeter overlap"}; + calibrate = new wxComboBox(this, wxID_ANY, wxString{ "Dimensional accuracy (default)" }, wxDefaultPosition, wxDefaultSize, 3, choices_goal); + calibrate->SetToolTip(_(L("Select a goal, this will change settings to increase the effects to search."))); + calibrate->SetSelection(0); + + buttons->Add(new wxStaticText(this, wxID_ANY, wxString{ "dimension:" })); + buttons->Add(scale); + buttons->AddSpacer(40); + buttons->Add(new wxStaticText(this, wxID_ANY, wxString{ "goal:" })); + buttons->Add(calibrate); + buttons->AddSpacer(40); + + wxButton* bt = new wxButton(this, wxID_FILE1, _(L("Standard Cube"))); + bt->Bind(wxEVT_BUTTON, &CalibrationCubeDialog::create_geometry_standard, this); + bt->SetToolTip(_(L("Standard cubic xyz cube, with a flat top. Better for infill/perimeter overlap calibration."))); + buttons->Add(bt); + buttons->AddSpacer(10); + bt = new wxButton(this, wxID_FILE1, _(L("Voron Cube"))); + bt->Bind(wxEVT_BUTTON, &CalibrationCubeDialog::create_geometry_voron, this); + bt->SetToolTip(_(L("Voron cubic cube with many features inside, with a bearing slot on top. Better to check dimensional accuracy."))); + buttons->Add(bt); +} + +void CalibrationCubeDialog::create_geometry(std::string calibration_path) { + Plater* plat = this->main_frame->plater(); + Model& model = plat->model(); + plat->reset(); + std::vector objs_idx = plat->load_files(std::vector{ + Slic3r::resources_dir()+"/calibration/cube/"+ calibration_path}, true, false); + + assert(objs_idx.size() == 1); + const DynamicPrintConfig* printConfig = this->gui_app->get_tab(Preset::TYPE_PRINT)->get_config(); + const DynamicPrintConfig* filamentConfig = this->gui_app->get_tab(Preset::TYPE_FILAMENT)->get_config(); + const DynamicPrintConfig* printerConfig = this->gui_app->get_tab(Preset::TYPE_PRINTER)->get_config(); + + /// --- scale --- + //model is created for a 0.4 nozzle, scale xy with nozzle size. + const ConfigOptionFloats* nozzle_diameter_config = printerConfig->option("nozzle_diameter"); + assert(nozzle_diameter_config->values.size() > 0); + float nozzle_diameter = nozzle_diameter_config->values[0]; + float cube_size = 30; + if (calibration_path == "xyzCalibration_cube.amf") + cube_size = 20; + int idx_scale = scale->GetSelection(); + float xyzScale = (10/cube_size) * (idx_scale+1); + //do scaling + model.objects[objs_idx[0]]->scale(xyzScale, xyzScale, xyzScale); + + + /// --- translate --- + const ConfigOptionPoints* bed_shape = printerConfig->option("bed_shape"); + Vec2d bed_size = BoundingBoxf(bed_shape->values).size(); + Vec2d bed_min = BoundingBoxf(bed_shape->values).min; + model.objects[objs_idx[0]]->translate({ bed_min.x() + bed_size.x() / 2, bed_min.y() + bed_size.y() / 2, 0 }); + + /// --- custom config --- + int idx_goal = calibrate->GetSelection(); + if (idx_goal == 1) { + model.objects[objs_idx[0]]->config.set_key_value("perimeters", new ConfigOptionInt(1)); + model.objects[objs_idx[0]]->config.set_key_value("fill_pattern", new ConfigOptionEnum(ipCubic)); + } else if (idx_goal == 2) { + model.objects[objs_idx[0]]->config.set_key_value("perimeters", new ConfigOptionInt(3)); + //add full solid layers + } + + //update plater + plat->changed_objects(objs_idx); + plat->is_preview_shown(); + //update everything, easier to code. + ObjectList* obj = this->gui_app->obj_list(); + obj->update_after_undo_redo(); + + + plat->reslice(); + plat->select_view_3D("Preview"); +} + +} // namespace GUI +} // namespace Slic3r diff --git a/src/slic3r/GUI/CalibrationCubeDialog.hpp b/src/slic3r/GUI/CalibrationCubeDialog.hpp new file mode 100644 index 000000000..cb5f18f3c --- /dev/null +++ b/src/slic3r/GUI/CalibrationCubeDialog.hpp @@ -0,0 +1,30 @@ +#ifndef slic3r_GUI_CalibrationCubeDialog_hpp_ +#define slic3r_GUI_CalibrationCubeDialog_hpp_ + +#include "CalibrationAbstractDialog.hpp" + +namespace Slic3r { +namespace GUI { + +class CalibrationCubeDialog : public CalibrationAbstractDialog +{ + +public: + CalibrationCubeDialog(GUI_App* app, MainFrame* mainframe) : CalibrationAbstractDialog(app, mainframe, "Calibration cube") { create("/calibration/cube/cube.html"); } + virtual ~CalibrationCubeDialog(){ } + +protected: + void create_buttons(wxStdDialogButtonSizer* sizer) override; + void create_geometry(std::string cube_path); + void create_geometry_voron(wxCommandEvent& event_args) { create_geometry("voron_design_cube_v6.amf"); } + void create_geometry_standard(wxCommandEvent& event_args) { create_geometry("xyzCalibration_cube.amf"); } + + wxComboBox* scale; + wxComboBox* calibrate; + +}; + +} // namespace GUI +} // namespace Slic3r + +#endif diff --git a/src/slic3r/GUI/CalibrationFlowDialog.cpp b/src/slic3r/GUI/CalibrationFlowDialog.cpp index f9ca6502c..75432773a 100644 --- a/src/slic3r/GUI/CalibrationFlowDialog.cpp +++ b/src/slic3r/GUI/CalibrationFlowDialog.cpp @@ -54,9 +54,12 @@ void CalibrationFlowDialog::create_geometry(float start, float delta) { float nozzle_diameter = nozzle_diameter_config->values[0]; float xyScale = nozzle_diameter / 0.4; //scale z to have 6 layers - const ConfigOptionFloatOrPercent* first_layer_height = printConfig->option("first_layer_height"); - const ConfigOptionFloat* layer_height = printConfig->option("layer_height"); - float zscale = first_layer_height->get_abs_value(nozzle_diameter) + 5 * layer_height->value; + const ConfigOptionFloatOrPercent* first_layer_height_setting = printConfig->option("first_layer_height"); + double first_layer_height = first_layer_height_setting->get_abs_value(nozzle_diameter); + double layer_height = nozzle_diameter / 2.; + first_layer_height = std::max(first_layer_height, nozzle_diameter / 2.); + + float zscale = first_layer_height + 5 * layer_height; zscale *= (1 + 0.3 * (10. / delta)); //do scaling if (xyScale < 0.9 || 1.2 < xyScale) { @@ -69,18 +72,19 @@ void CalibrationFlowDialog::create_geometry(float start, float delta) { //add sub-part after scale float zshift = (1 - zscale) / 2; + float zscale_number = (first_layer_height + layer_height) / 0.4; if (delta == 10.f && start == 80.f) { - add_part(model.objects[objs_idx[0]], Slic3r::resources_dir()+"/calibration/filament_flow/m20.amf", Vec3d{ 9,0,zshift }); - add_part(model.objects[objs_idx[1]], Slic3r::resources_dir()+"/calibration/filament_flow/m10.amf", Vec3d{ 9,0,zshift }); - add_part(model.objects[objs_idx[2]], Slic3r::resources_dir()+"/calibration/filament_flow/_0.amf", Vec3d{ 9,0,zshift }); - add_part(model.objects[objs_idx[3]], Slic3r::resources_dir()+"/calibration/filament_flow/p10.amf", Vec3d{ 9,0,zshift }); - add_part(model.objects[objs_idx[4]], Slic3r::resources_dir()+"/calibration/filament_flow/p20.amf", Vec3d{ 9,0,zshift }); + add_part(model.objects[objs_idx[0]], Slic3r::resources_dir()+"/calibration/filament_flow/m20.amf", Vec3d{ 3 + 6 * xyScale,0,zshift }, Vec3d{ 1,1, zscale_number}); + add_part(model.objects[objs_idx[1]], Slic3r::resources_dir()+"/calibration/filament_flow/m10.amf", Vec3d{ 3 + 6 * xyScale,0,zshift }, Vec3d{ 1,1, zscale_number }); + add_part(model.objects[objs_idx[2]], Slic3r::resources_dir()+"/calibration/filament_flow/_0.amf", Vec3d{ 3 + 6 * xyScale,0,zshift }, Vec3d{ 1,1, zscale_number }); + add_part(model.objects[objs_idx[3]], Slic3r::resources_dir()+"/calibration/filament_flow/p10.amf", Vec3d{ 3 + 6 * xyScale,0,zshift }, Vec3d{ 1,1, zscale_number }); + add_part(model.objects[objs_idx[4]], Slic3r::resources_dir()+"/calibration/filament_flow/p20.amf", Vec3d{ 3 + 6 * xyScale,0,zshift }, Vec3d{ 1,1, zscale_number }); } else if (delta == 2.f && start == 92.f) { - add_part(model.objects[objs_idx[0]], Slic3r::resources_dir()+"/calibration/filament_flow/m8.amf", Vec3d{ 9,0,zshift }); - add_part(model.objects[objs_idx[1]], Slic3r::resources_dir()+"/calibration/filament_flow/m6.amf", Vec3d{ 9,0,zshift }); - add_part(model.objects[objs_idx[2]], Slic3r::resources_dir()+"/calibration/filament_flow/m4.amf", Vec3d{ 9,0,zshift }); - add_part(model.objects[objs_idx[3]], Slic3r::resources_dir()+"/calibration/filament_flow/m2.amf", Vec3d{ 9,0,zshift }); - add_part(model.objects[objs_idx[4]], Slic3r::resources_dir()+"/calibration/filament_flow/_0.amf", Vec3d{ 9,0,zshift }); + add_part(model.objects[objs_idx[0]], Slic3r::resources_dir()+"/calibration/filament_flow/m8.amf", Vec3d{ 3 + 6 * xyScale,0,zshift }, Vec3d{ 1,1, zscale_number }); + add_part(model.objects[objs_idx[1]], Slic3r::resources_dir()+"/calibration/filament_flow/m6.amf", Vec3d{ 3 + 6 * xyScale,0,zshift }, Vec3d{ 1,1, zscale_number }); + add_part(model.objects[objs_idx[2]], Slic3r::resources_dir()+"/calibration/filament_flow/m4.amf", Vec3d{ 3 + 6 * xyScale,0,zshift }, Vec3d{ 1,1, zscale_number }); + add_part(model.objects[objs_idx[3]], Slic3r::resources_dir()+"/calibration/filament_flow/m2.amf", Vec3d{ 3 + 6 * xyScale,0,zshift }, Vec3d{ 1,1, zscale_number }); + add_part(model.objects[objs_idx[4]], Slic3r::resources_dir()+"/calibration/filament_flow/_0.amf", Vec3d{ 3 + 6 * xyScale,0,zshift }, Vec3d{ 1,1, zscale_number }); } for (size_t i = 0; i < 5; i++) { add_part(model.objects[objs_idx[i]], Slic3r::resources_dir()+"/calibration/filament_flow/O.amf", Vec3d{ 0,0,zscale/2.f + 0.5 }, Vec3d{1,1,xyScale }); @@ -118,14 +122,8 @@ void CalibrationFlowDialog::create_geometry(float start, float delta) { model.objects[objs_idx[i]]->config.set_key_value("thin_walls", new ConfigOptionBool(true)); model.objects[objs_idx[i]]->config.set_key_value("thin_walls_min_width", new ConfigOptionFloatOrPercent(50,true)); model.objects[objs_idx[i]]->config.set_key_value("gap_fill", new ConfigOptionBool(true)); - model.objects[objs_idx[i]]->config.set_key_value("layer_height", new ConfigOptionFloat(nozzle_diameter/2)); - if (nozzle_diameter < 0.3) { - //ensure that the first layer is good and safe, mandatory as we mess wit the first_layer_height. - model.objects[objs_idx[i]]->config.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(nozzle_diameter, false)); - model.objects[objs_idx[i]]->config.set_key_value("first_layer_extrusion_width", new ConfigOptionFloatOrPercent(150, true)); - } else { - model.objects[objs_idx[i]]->config.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(std::max(0.2f, nozzle_diameter / 2), false)); - } + model.objects[objs_idx[i]]->config.set_key_value("layer_height", new ConfigOptionFloat(layer_height)); + model.objects[objs_idx[i]]->config.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(first_layer_height, false)); model.objects[objs_idx[i]]->config.set_key_value("external_infill_margin", new ConfigOptionFloatOrPercent(100, true)); model.objects[objs_idx[i]]->config.set_key_value("solid_fill_pattern", new ConfigOptionEnum(ipRectilinearWGapFill)); model.objects[objs_idx[i]]->config.set_key_value("top_fill_pattern", new ConfigOptionEnum(ipSmooth)); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 4aaf874dd..fdaae7026 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -42,6 +42,7 @@ #include "slic3r/Config/Snapshot.hpp" #include "CalibrationBedDialog.hpp" #include "CalibrationBridgeDialog.hpp" +#include "CalibrationCubeDialog.hpp" #include "CalibrationFlowDialog.hpp" #include "CalibrationOverBridgeDialog.hpp" #include "CalibrationTempDialog.hpp" @@ -592,6 +593,10 @@ void GUI_App::filament_temperature_dialog() { change_calibration_dialog(nullptr, new CalibrationTempDialog(this, mainframe)); } +void GUI_App::calibration_cube_dialog() +{ + change_calibration_dialog(nullptr, new CalibrationCubeDialog(this, mainframe)); +} // static method accepting a wxWindow object as first parameter bool GUI_App::catch_error(std::function cb, diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 945411fcf..56ff8935f 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -137,6 +137,7 @@ public: void filament_temperature_dialog(); void bridge_tuning_dialog(); void over_bridge_dialog(); + void calibration_cube_dialog(); //void support_tuning(); //have to do multiple, in a submenu void load_project(wxWindow *parent, wxString& input_file) const; void import_model(wxWindow *parent, wxArrayString& input_files) const; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index d5c29ea5b..392ab4c4a 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -775,7 +775,9 @@ void MainFrame::init_menubar() [this](wxCommandEvent&) { wxGetApp().bridge_tuning_dialog(); }); append_menu_item(objectsMenu, wxID_ANY, _(L("Ironing pattern calibration")), _(L("Create a test print to help you to set your over-bridge flow ratio and ironing pattern.")), [this](wxCommandEvent&) { wxGetApp().over_bridge_dialog(); }); - + append_menu_item(objectsMenu, wxID_ANY, _(L("Calibration cube")), _(L("Print a calibration cube, for various calibration goals.")), + [this](wxCommandEvent&) { wxGetApp().calibration_cube_dialog(); }); + } // Help menu