mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-15 14:15:56 +08:00
add bride & over-bridge calibration (print & pics wip)
refined calibration code
This commit is contained in:
parent
16c51403aa
commit
e562fbeef9
@ -2,11 +2,29 @@
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Document HTML</title>
|
||||
<title>Bridge flow ratio calibration</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>hello you</h1>
|
||||
bonjour le monde
|
||||
<h1>Bridge flow calibration</h1>
|
||||
<p>You need to do the bed level calibration and the filament flow calibration before this one. It's better if you have done the filament temperature calibration also.</p>
|
||||
<p>This test will print tests samples with various level of bridge flow ratio, and then you can also tune your bridge overlap ratio, if lines of bridges are too far apart from each other. It start at your current setting, so you may want to set them to 100% before clicking on the button.</p>
|
||||
<h2>Results</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
<h4>Exemple:</h4>
|
||||
<tr>
|
||||
<td>TODO</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">TODO</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Advice</h2>
|
||||
<p>TODO</p>
|
||||
</ul>
|
||||
<h2>Notes</h2>
|
||||
<p>This test set the setting "complete individual objects" to true, so you may want to reset your print settings afterwards</p>
|
||||
<p>Licence for models used for this calibration test: CC BY-SA 3.0</p>
|
||||
</body>
|
||||
</html>
|
BIN
resources/calibration/bridge_flow/bridge_test.amf
Normal file
BIN
resources/calibration/bridge_flow/bridge_test.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f100.amf
Normal file
BIN
resources/calibration/bridge_flow/f100.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f105.amf
Normal file
BIN
resources/calibration/bridge_flow/f105.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f110.amf
Normal file
BIN
resources/calibration/bridge_flow/f110.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f115.amf
Normal file
BIN
resources/calibration/bridge_flow/f115.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f120.amf
Normal file
BIN
resources/calibration/bridge_flow/f120.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f125.amf
Normal file
BIN
resources/calibration/bridge_flow/f125.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f130.amf
Normal file
BIN
resources/calibration/bridge_flow/f130.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f135.amf
Normal file
BIN
resources/calibration/bridge_flow/f135.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f140.amf
Normal file
BIN
resources/calibration/bridge_flow/f140.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f145.amf
Normal file
BIN
resources/calibration/bridge_flow/f145.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f150.amf
Normal file
BIN
resources/calibration/bridge_flow/f150.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f155.amf
Normal file
BIN
resources/calibration/bridge_flow/f155.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f160.amf
Normal file
BIN
resources/calibration/bridge_flow/f160.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f165.amf
Normal file
BIN
resources/calibration/bridge_flow/f165.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f170.amf
Normal file
BIN
resources/calibration/bridge_flow/f170.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f175.amf
Normal file
BIN
resources/calibration/bridge_flow/f175.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f20.amf
Normal file
BIN
resources/calibration/bridge_flow/f20.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f25.amf
Normal file
BIN
resources/calibration/bridge_flow/f25.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f30.amf
Normal file
BIN
resources/calibration/bridge_flow/f30.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f35.amf
Normal file
BIN
resources/calibration/bridge_flow/f35.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f40.amf
Normal file
BIN
resources/calibration/bridge_flow/f40.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f45.amf
Normal file
BIN
resources/calibration/bridge_flow/f45.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f50.amf
Normal file
BIN
resources/calibration/bridge_flow/f50.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f55.amf
Normal file
BIN
resources/calibration/bridge_flow/f55.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f60.amf
Normal file
BIN
resources/calibration/bridge_flow/f60.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f65.amf
Normal file
BIN
resources/calibration/bridge_flow/f65.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f70.amf
Normal file
BIN
resources/calibration/bridge_flow/f70.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f75.amf
Normal file
BIN
resources/calibration/bridge_flow/f75.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f80.amf
Normal file
BIN
resources/calibration/bridge_flow/f80.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f85.amf
Normal file
BIN
resources/calibration/bridge_flow/f85.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f90.amf
Normal file
BIN
resources/calibration/bridge_flow/f90.amf
Normal file
Binary file not shown.
BIN
resources/calibration/bridge_flow/f95.amf
Normal file
BIN
resources/calibration/bridge_flow/f95.amf
Normal file
Binary file not shown.
@ -14,29 +14,32 @@
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><img src="./low_ll.jpg" width="100" height="200" /></td>
|
||||
<td><img src="./low_l.jpg" width="100" height="200" /></td>
|
||||
<td><img src="./low.jpg" width="100" height="200" /></td>
|
||||
<td><img src="./good.jpg" width="100" height="200" /></td>
|
||||
<td><img src="./high.jpg" width="100" height="200" /></td>
|
||||
<td><img src="./high_h.jpg" width="100" height="200" /></td>
|
||||
<td><img src="./high_hh.jpg" width="100" height="200" /></td>
|
||||
<td><img src="./high_h.jpg" width="100" height="200" /></td>
|
||||
<td><img src="./high_hh.jpg" width="100" height="200" /></td>
|
||||
<td><img src="./temp_tower.jpg" width="400" height="500" /></td>
|
||||
<td>
|
||||
<table style="height: 500px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>too cold, it can't be extruded</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">TODO</td>
|
||||
<td style="text-align: center;">TODO</td>
|
||||
<td style="text-align: center;">TODO</td>
|
||||
<td style="text-align: center;">TODO</td>
|
||||
<td style="text-align: center;">TODO</td>
|
||||
<td style="text-align: center;">TODO</td>
|
||||
<td style="text-align: center;">TODO</td>
|
||||
<td style="text-align: center;">TODO</td>
|
||||
<td style="text-align: center;">TODO</td>
|
||||
<td>good</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>good</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>too hot, you can see some ooze</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>too hot, you can see some ooze</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>TODO</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Here, you can see that the 210 degree is the hottest we can print without problems (at least not heat-dependant, bad quality is due to high speed). Also, i succeed to break (with difficulty) a chunk of the 195 degree, so it's a bit too cold.</p>
|
||||
<h2>Results: destruction</h2>
|
||||
<p>Finally, you want to tear it apart to see if the lower temperature doesn't have adverse effect on layer bonding. It should be impossible to tear it apart with your own hands. If a floor can be easily broken, then this floor temperature is definitely too low (or you put too much cooling = fan are blowing too hard), so you should choose a higher temperature or try again with less cooling. When trying to break one, don't put your hands on the ends of the tower but on the tested floor and the next one, leaving only the bridge gaps between them.</p>
|
||||
<h2>How to tune your printer</h2>
|
||||
|
BIN
resources/calibration/filament_temp/temp_tower.jpg
Normal file
BIN
resources/calibration/filament_temp/temp_tower.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
@ -2,11 +2,29 @@
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Document HTML</title>
|
||||
<title>Ironing pattern calibration</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>hello you</h1>
|
||||
bonjour le monde
|
||||
<h1>Ironing pattern calibration</h1>
|
||||
<p>You need to do the filament flow calibration and the bridge flow ratio before this one. It's better if you have done the filament temperature.</p>
|
||||
<p>This test will print tests samples with various level of obver-bridge flow ratio, between 100 and 125. Choose the lowest value where the top surface is smooth without rough "holes".</p>
|
||||
<h2>Results</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
<h4>Exemple:</h4>
|
||||
<tr>
|
||||
<td>TODO</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">TODO</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Advice</h2>
|
||||
<p>TODO</p>
|
||||
</ul>
|
||||
<h2>Notes</h2>
|
||||
<p>This test set the setting "complete individual objects" to true, so you may want to reset your print settings afterwards</p>
|
||||
<p>Licence for models used for this calibration test: CC BY-SA 3.0</p>
|
||||
</body>
|
||||
</html>
|
@ -2084,10 +2084,11 @@ void PrintConfigDef::init_fff_params()
|
||||
def->label = L("No perimeters on bridge areas");
|
||||
def->category = OptionCategory::perimeter;
|
||||
def->tooltip = L("Experimental option to remove perimeters where there is nothing under it and where a bridged infill should be better. "
|
||||
"\n * Remove perimeters: remove the unsupported perimeter, let the bridge area as-is."
|
||||
"\n * Keep only bridges: remove the unsupported perimeter, kep only bridges that end in solid area."
|
||||
"\n * Keep bridges and overhangs: remove the unsupported perimeter, keep only bridges that end in solid area, fill the rest with overhang perimeters+bridges."
|
||||
"\n * Fill the voids with bridges: remove the unsupported perimeter, draw bridges over the whole hole. !! can lead to problems with overhangs shape like /\\, consider carefully before using this option!"
|
||||
"\n * Remove perimeters: remove the unsupported perimeters, let the bridge area as-is."
|
||||
"\n * Keep only bridges: remove the perimeters in the bridge areas, keep only bridges that end in solid area."
|
||||
"\n * Keep bridges and overhangs: remove the unsupported perimeters, keep only bridges that end in solid area, fill the rest with overhang perimeters+bridges."
|
||||
"\n * Fill the voids with bridges: remove the unsupported perimeters, draw bridges over the whole hole.*"
|
||||
" !! this one can escalate to problems with overhangs shape like /\\, so you should use it only on one layer at a time via the height-range modifier!"
|
||||
"\n!!Computationally intensive!!. ");
|
||||
def->enum_keys_map = &ConfigOptionEnum<NoPerimeterUnsupportedAlgo>::get_enum_values();
|
||||
def->enum_values.push_back("none");
|
||||
|
@ -18,12 +18,16 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/BackgroundSlicingProcess.hpp
|
||||
GUI/BitmapCache.cpp
|
||||
GUI/BitmapCache.hpp
|
||||
GUI/CalibrationAbstractDialog.cpp
|
||||
GUI/CalibrationAbstractDialog.hpp
|
||||
GUI/CalibrationBedDialog.cpp
|
||||
GUI/CalibrationBedDialog.hpp
|
||||
GUI/CalibrationBridgeDialog.cpp
|
||||
GUI/CalibrationBridgeDialog.hpp
|
||||
GUI/CalibrationFlowDialog.cpp
|
||||
GUI/CalibrationFlowDialog.hpp
|
||||
GUI/CalibrationOverBridgeDialog.cpp
|
||||
GUI/CalibrationOverBridgeDialog.hpp
|
||||
GUI/CalibrationTempDialog.cpp
|
||||
GUI/CalibrationTempDialog.hpp
|
||||
GUI/ConfigSnapshotDialog.cpp
|
||||
|
153
src/slic3r/GUI/CalibrationAbstractDialog.cpp
Normal file
153
src/slic3r/GUI/CalibrationAbstractDialog.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
#include "CalibrationAbstractDialog.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "GUI.hpp"
|
||||
#include "GUI_ObjectList.hpp"
|
||||
#include "Tab.hpp"
|
||||
#include <wx/scrolwin.h>
|
||||
#include <wx/display.h>
|
||||
#include <wx/file.h>
|
||||
|
||||
#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 {
|
||||
|
||||
CalibrationAbstractDialog::CalibrationAbstractDialog(GUI_App* app, MainFrame* mainframe, std::string name)
|
||||
: DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L(name)),
|
||||
#if ENABLE_SCROLLABLE
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
#else
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
|
||||
#endif // ENABLE_SCROLLABLE
|
||||
{
|
||||
this->gui_app = app;
|
||||
this->main_frame = mainframe;
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
|
||||
// fonts
|
||||
const wxFont& font = wxGetApp().normal_font();
|
||||
const wxFont& bold_font = wxGetApp().bold_font();
|
||||
SetFont(font);
|
||||
|
||||
}
|
||||
|
||||
void CalibrationAbstractDialog::create(std::string html_path){
|
||||
|
||||
auto main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
//html
|
||||
html_viewer = new wxHtmlWindow(this, wxID_ANY,
|
||||
wxDefaultPosition, wxSize(800, 500), wxHW_SCROLLBAR_AUTO);
|
||||
html_viewer->LoadPage(Slic3r::resources_dir()+ html_path);
|
||||
main_sizer->Add(html_viewer, 1, wxEXPAND | wxALL, 5);
|
||||
|
||||
wxStdDialogButtonSizer* buttons = new wxStdDialogButtonSizer();
|
||||
create_buttons(buttons);
|
||||
|
||||
wxButton* close = new wxButton(this, wxID_CLOSE, _(L("Close")));
|
||||
close->Bind(wxEVT_BUTTON, &CalibrationAbstractDialog::closeMe, this);
|
||||
buttons->AddButton(close);
|
||||
close->SetDefault();
|
||||
close->SetFocus();
|
||||
SetAffirmativeId(wxID_CLOSE);
|
||||
buttons->Realize();
|
||||
main_sizer->Add(buttons, 0, wxEXPAND | wxALL, 5);
|
||||
|
||||
SetSizer(main_sizer);
|
||||
main_sizer->SetSizeHints(this);
|
||||
}
|
||||
|
||||
void CalibrationAbstractDialog::closeMe(wxCommandEvent& event_args) {
|
||||
this->Destroy();
|
||||
}
|
||||
|
||||
ModelObject* CalibrationAbstractDialog::add_part(ModelObject* model_object, std::string input_file, Vec3d move, Vec3d scale) {
|
||||
Model model;
|
||||
try {
|
||||
model = Model::read_from_file(input_file);
|
||||
}
|
||||
catch (std::exception & e) {
|
||||
auto msg = _(L("Error!")) + " " + input_file + " : " + e.what() + ".";
|
||||
show_error(this, msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (ModelObject* object : model.objects) {
|
||||
Vec3d delta = Vec3d::Zero();
|
||||
if (model_object->origin_translation != Vec3d::Zero())
|
||||
{
|
||||
object->center_around_origin();
|
||||
delta = model_object->origin_translation - object->origin_translation;
|
||||
}
|
||||
for (ModelVolume* volume : object->volumes) {
|
||||
volume->translate(delta + move);
|
||||
if (scale != Vec3d{ 1,1,1 }) {
|
||||
volume->scale(scale);
|
||||
}
|
||||
ModelVolume* new_volume = model_object->add_volume(*volume);
|
||||
new_volume->set_type(ModelVolumeType::MODEL_PART);
|
||||
new_volume->name = boost::filesystem::path(input_file).filename().string();
|
||||
|
||||
//volumes_info.push_back(std::make_pair(from_u8(new_volume->name), new_volume->get_mesh_errors_count() > 0));
|
||||
|
||||
// set a default extruder value, since user can't add it manually
|
||||
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||
|
||||
//move to bed
|
||||
/* const TriangleMesh& hull = new_volume->get_convex_hull();
|
||||
float min_z = std::numeric_limits<float>::max();
|
||||
for (const stl_facet& facet : hull.stl.facet_start) {
|
||||
for (int i = 0; i < 3; ++i)
|
||||
min_z = std::min(min_z, Vec3f::UnitZ().dot(facet.vertex[i]));
|
||||
}
|
||||
volume->translate(Vec3d(0,0,-min_z));*/
|
||||
}
|
||||
}
|
||||
assert(model.objects.size() == 1);
|
||||
return model.objects.empty()?nullptr: model.objects[0];
|
||||
}
|
||||
|
||||
void CalibrationAbstractDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||
{
|
||||
msw_buttons_rescale(this, em_unit(), { wxID_OK });
|
||||
|
||||
Layout();
|
||||
Fit();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
wxPanel* CalibrationAbstractDialog::create_header(wxWindow* parent, const wxFont& bold_font)
|
||||
{
|
||||
wxPanel* panel = new wxPanel(parent);
|
||||
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wxFont header_font = bold_font;
|
||||
#ifdef __WXOSX__
|
||||
header_font.SetPointSize(14);
|
||||
#else
|
||||
header_font.SetPointSize(bold_font.GetPointSize() + 2);
|
||||
#endif // __WXOSX__
|
||||
|
||||
sizer->AddStretchSpacer();
|
||||
|
||||
// text
|
||||
wxStaticText* text = new wxStaticText(panel, wxID_ANY, _(L("Keyboard shortcuts")));
|
||||
text->SetFont(header_font);
|
||||
sizer->Add(text, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
sizer->AddStretchSpacer();
|
||||
|
||||
panel->SetSizer(sizer);
|
||||
return panel;
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
42
src/slic3r/GUI/CalibrationAbstractDialog.hpp
Normal file
42
src/slic3r/GUI/CalibrationAbstractDialog.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef slic3r_GUI_CalibrationAbstractDialog_hpp_
|
||||
#define slic3r_GUI_CalibrationAbstractDialog_hpp_
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include <wx/html/htmlwin.h>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class CalibrationAbstractDialog : public DPIDialog
|
||||
{
|
||||
|
||||
public:
|
||||
CalibrationAbstractDialog(GUI_App* app, MainFrame* mainframe, std::string name);
|
||||
virtual ~CalibrationAbstractDialog(){ if(gui_app!=nullptr) gui_app->change_calibration_dialog(this, nullptr);}
|
||||
|
||||
private:
|
||||
wxPanel* create_header(wxWindow* parent, const wxFont& bold_font);
|
||||
protected:
|
||||
void create(std::string html_path);
|
||||
virtual void create_buttons(wxStdDialogButtonSizer*) = 0;
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
void closeMe(wxCommandEvent& event_args);
|
||||
ModelObject* add_part(ModelObject* model_object, std::string input_file, Vec3d move, Vec3d scale = Vec3d{ 1,1,1 });
|
||||
|
||||
wxHtmlWindow* html_viewer;
|
||||
MainFrame* main_frame;
|
||||
GUI_App* gui_app;
|
||||
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif
|
@ -21,50 +21,10 @@ static wxSize get_screen_size(wxWindow* window)
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
CalibrationBedDialog::CalibrationBedDialog(GUI_App* app, MainFrame* mainframe)
|
||||
: DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("Bed calibration - test objects generation")),
|
||||
#if ENABLE_SCROLLABLE
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
#else
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
|
||||
#endif // ENABLE_SCROLLABLE
|
||||
{
|
||||
this->gui_app = app;
|
||||
this->main_frame = mainframe;
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
|
||||
// fonts
|
||||
const wxFont& font = wxGetApp().normal_font();
|
||||
const wxFont& bold_font = wxGetApp().bold_font();
|
||||
SetFont(font);
|
||||
|
||||
auto main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
//html
|
||||
html_viewer = new wxHtmlWindow(this, wxID_ANY,
|
||||
wxDefaultPosition, wxSize(800, 500), wxHW_SCROLLBAR_AUTO);
|
||||
html_viewer->LoadPage(Slic3r::resources_dir()+"/calibration/bed_leveling/bed_leveling.html");
|
||||
main_sizer->Add(html_viewer, 1, wxEXPAND | wxALL, 5);
|
||||
|
||||
wxStdDialogButtonSizer* buttons = new wxStdDialogButtonSizer();
|
||||
void CalibrationBedDialog::create_buttons(wxStdDialogButtonSizer* buttons){
|
||||
wxButton* bt = new wxButton(this, wxID_FILE1, _(L("Generate")));
|
||||
bt->Bind(wxEVT_BUTTON, &CalibrationBedDialog::create_geometry, this);
|
||||
buttons->Add(bt);
|
||||
wxButton* close = new wxButton(this, wxID_CLOSE, _(L("Close")));
|
||||
close->Bind(wxEVT_BUTTON, &CalibrationBedDialog::closeMe, this);
|
||||
buttons->AddButton(close);
|
||||
close->SetDefault();
|
||||
close->SetFocus();
|
||||
SetAffirmativeId(wxID_CLOSE);
|
||||
buttons->Realize();
|
||||
main_sizer->Add(buttons, 0, wxEXPAND | wxALL, 5);
|
||||
|
||||
SetSizer(main_sizer);
|
||||
main_sizer->SetSizeHints(this);
|
||||
}
|
||||
|
||||
void CalibrationBedDialog::closeMe(wxCommandEvent& event_args) {
|
||||
this->Destroy();
|
||||
}
|
||||
|
||||
void CalibrationBedDialog::create_geometry(wxCommandEvent& event_args) {
|
||||
@ -177,39 +137,5 @@ void CalibrationBedDialog::create_geometry(wxCommandEvent& event_args) {
|
||||
|
||||
}
|
||||
|
||||
void CalibrationBedDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||
{
|
||||
msw_buttons_rescale(this, em_unit(), { wxID_OK });
|
||||
|
||||
Layout();
|
||||
Fit();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
wxPanel* CalibrationBedDialog::create_header(wxWindow* parent, const wxFont& bold_font)
|
||||
{
|
||||
wxPanel* panel = new wxPanel(parent);
|
||||
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wxFont header_font = bold_font;
|
||||
#ifdef __WXOSX__
|
||||
header_font.SetPointSize(14);
|
||||
#else
|
||||
header_font.SetPointSize(bold_font.GetPointSize() + 2);
|
||||
#endif // __WXOSX__
|
||||
|
||||
sizer->AddStretchSpacer();
|
||||
|
||||
// text
|
||||
wxStaticText* text = new wxStaticText(panel, wxID_ANY, _(L("Keyboard shortcuts")));
|
||||
text->SetFont(header_font);
|
||||
sizer->Add(text, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
sizer->AddStretchSpacer();
|
||||
|
||||
panel->SetSizer(sizer);
|
||||
return panel;
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
@ -1,38 +1,21 @@
|
||||
#ifndef slic3r_GUI_CalibrationBedDialog_hpp_
|
||||
#define slic3r_GUI_CalibrationBedDialog_hpp_
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include <wx/html/htmlwin.h>
|
||||
#include "CalibrationAbstractDialog.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class CalibrationBedDialog : public DPIDialog
|
||||
class CalibrationBedDialog : public CalibrationAbstractDialog
|
||||
{
|
||||
|
||||
public:
|
||||
CalibrationBedDialog(GUI_App* app, MainFrame* mainframe);
|
||||
virtual ~CalibrationBedDialog() { if (gui_app != nullptr) gui_app->change_calibration_dialog(this, nullptr); }
|
||||
|
||||
CalibrationBedDialog(GUI_App* app, MainFrame* mainframe) : CalibrationAbstractDialog(app, mainframe, "Bed leveling calibration") { create("/calibration/bed_leveling/bed_leveling.html"); }
|
||||
virtual ~CalibrationBedDialog() {}
|
||||
protected:
|
||||
void on_dpi_changed(const wxRect &suggested_rect) override;
|
||||
|
||||
void create_buttons(wxStdDialogButtonSizer* sizer) override;
|
||||
private:
|
||||
|
||||
void closeMe(wxCommandEvent& event_args);
|
||||
void create_geometry(wxCommandEvent& event_args);
|
||||
wxPanel* create_header(wxWindow* parent, const wxFont& bold_font);
|
||||
|
||||
wxHtmlWindow* html_viewer;
|
||||
MainFrame* main_frame;
|
||||
GUI_App* gui_app;
|
||||
|
||||
};
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "I18N.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "GUI.hpp"
|
||||
#include "GUI_ObjectList.hpp"
|
||||
#include "Tab.hpp"
|
||||
#include <wx/scrolwin.h>
|
||||
#include <wx/display.h>
|
||||
@ -20,177 +21,114 @@ static wxSize get_screen_size(wxWindow* window)
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
CalibrationBridgeDialog::CalibrationBridgeDialog(GUI_App* app, MainFrame* mainframe)
|
||||
: DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("Bridge calibration - test objects generation")),
|
||||
#if ENABLE_SCROLLABLE
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
#else
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
|
||||
#endif // ENABLE_SCROLLABLE
|
||||
{
|
||||
this->gui_app = app;
|
||||
this->main_frame = mainframe;
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
void CalibrationBridgeDialog::create_buttons(wxStdDialogButtonSizer* buttons){
|
||||
wxString choices_steps[] = { "2.5","5","10" };
|
||||
steps = new wxComboBox(this, wxID_ANY, wxString{ "5" }, wxDefaultPosition, wxDefaultSize, 3, choices_steps);
|
||||
steps->SetToolTip(_(L("Select the step in % between two tests.")));
|
||||
steps->SetSelection(1);
|
||||
wxString choices_nb[] = { "1","2","3","4","5","6" };
|
||||
nb_tests = new wxComboBox(this, wxID_ANY, wxString{ "5" }, wxDefaultPosition, wxDefaultSize, 6, choices_nb);
|
||||
nb_tests->SetToolTip(_(L("Select the number of tests")));
|
||||
nb_tests->SetSelection(4);
|
||||
|
||||
// fonts
|
||||
const wxFont& font = wxGetApp().normal_font();
|
||||
const wxFont& bold_font = wxGetApp().bold_font();
|
||||
SetFont(font);
|
||||
|
||||
auto main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
//html
|
||||
std::cout << "display test.html\n";
|
||||
html_viewer = new wxHtmlWindow(this, wxID_ANY,
|
||||
wxDefaultPosition, wxSize(400, 400), wxHW_SCROLLBAR_AUTO);
|
||||
html_viewer->LoadPage("./resources/calibration/bed_leveling/bed_leveling.html");
|
||||
main_sizer->Add(html_viewer, 1, wxEXPAND | wxALL, 5);
|
||||
|
||||
wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxAPPLY| wxCLOSE);
|
||||
buttons->GetApplyButton()->Bind(wxEVT_BUTTON, &CalibrationBridgeDialog::create_geometry, this);
|
||||
this->SetEscapeId(wxCLOSE);
|
||||
main_sizer->Add(buttons, 0, wxEXPAND | wxALL, 5);
|
||||
|
||||
SetSizer(main_sizer);
|
||||
main_sizer->SetSizeHints(this);
|
||||
buttons->Add(new wxStaticText(this, wxID_ANY, wxString{ "step:" }));
|
||||
buttons->Add(steps);
|
||||
buttons->AddSpacer(15);
|
||||
buttons->Add(new wxStaticText(this, wxID_ANY, wxString{ "nb tests:" }));
|
||||
buttons->Add(nb_tests);
|
||||
buttons->AddSpacer(40);
|
||||
wxButton* bt = new wxButton(this, wxID_FILE1, _(L("Test Flow Ratio")));
|
||||
bt->Bind(wxEVT_BUTTON, &CalibrationBridgeDialog::create_geometry_flow_ratio, this);
|
||||
buttons->Add(bt);
|
||||
buttons->AddSpacer(15);
|
||||
bt = new wxButton(this, wxID_FILE1, _(L("Test Overlap")));
|
||||
bt->Bind(wxEVT_BUTTON, &CalibrationBridgeDialog::create_geometry_overlap, this);
|
||||
buttons->Add(bt);
|
||||
}
|
||||
|
||||
void CalibrationBridgeDialog::create_geometry(wxCommandEvent& event_args) {
|
||||
void CalibrationBridgeDialog::create_geometry(std::string setting_to_test, bool add) {
|
||||
Plater* plat = this->main_frame->plater();
|
||||
Model& model = plat->model();
|
||||
plat->reset();
|
||||
std::vector<size_t> objs_idx = plat->load_files(std::vector<std::string>{
|
||||
"./resources/calibration/bed_leveling/patch.amf",
|
||||
"./resources/calibration/bed_leveling/patch.amf",
|
||||
"./resources/calibration/bed_leveling/patch.amf",
|
||||
"./resources/calibration/bed_leveling/patch.amf",
|
||||
"./resources/calibration/bed_leveling/patch.amf"}, true, false);
|
||||
|
||||
assert(objs_idx.size() == 5);
|
||||
const DynamicPrintConfig* printConfig = this->gui_app->get_tab(Preset::TYPE_PRINT)->get_config();
|
||||
const DynamicPrintConfig* printerConfig = this->gui_app->get_tab(Preset::TYPE_PRINTER)->get_config();
|
||||
|
||||
int idx_steps = steps->GetSelection();
|
||||
int idx_nb = nb_tests->GetSelection();
|
||||
size_t step = 5 + (idx_steps == wxNOT_FOUND ? 0 : (idx_steps == 0 ? 2.5f : idx_steps == 1 ? 5.F : 10.f));
|
||||
size_t nb_items = 1 + (idx_nb == wxNOT_FOUND ? 0 : idx_nb);
|
||||
|
||||
std::vector<std::string> items;
|
||||
for (size_t i = 0; i < nb_items; i++)
|
||||
items.emplace_back("./resources/calibration/bridge_flow/bridge_test.amf");
|
||||
std::vector<size_t> objs_idx = plat->load_files(items, true, false);
|
||||
|
||||
assert(objs_idx.size() == nb_items);
|
||||
const DynamicPrintConfig* print_config = this->gui_app->get_tab(Preset::TYPE_PRINT)->get_config();
|
||||
const DynamicPrintConfig* printer_config = 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 = printerConfig->option<ConfigOptionFloats>("nozzle_diameter");
|
||||
assert(nozzle_diameter->values.size() > 0);
|
||||
float xyScale = nozzle_diameter->values[0] / 0.4;
|
||||
//scale z with the first_layer_height
|
||||
const ConfigOptionFloatOrPercent* first_layer_height = printConfig->option<ConfigOptionFloatOrPercent>("first_layer_height");
|
||||
float zscale = first_layer_height->get_abs_value(nozzle_diameter->values[0]) / 0.2;
|
||||
// model is created for a 0.4 nozzle, scale xy with nozzle size.
|
||||
const ConfigOptionFloats* nozzle_diameter_config = printer_config->option<ConfigOptionFloats>("nozzle_diameter");
|
||||
assert(nozzle_diameter_config->values.size() > 0);
|
||||
float nozzle_diameter = nozzle_diameter_config->values[0];
|
||||
float z_scale = nozzle_diameter / 0.4;
|
||||
//do scaling
|
||||
if (xyScale < 0.9 || 1.2 < xyScale) {
|
||||
if (z_scale < 0.9 || 1.2 < z_scale) {
|
||||
for (size_t i = 0; i < 5; i++)
|
||||
model.objects[objs_idx[i]]->scale(xyScale, xyScale, zscale);
|
||||
}
|
||||
|
||||
/// --- rotate ---
|
||||
const ConfigOptionPoints* bed_shape = printerConfig->option<ConfigOptionPoints>("bed_shape");
|
||||
if (bed_shape->values.size() == 4) {
|
||||
model.objects[objs_idx[0]]->rotate(PI / 4, { 0,0,1 });
|
||||
model.objects[objs_idx[1]]->rotate(5 * PI / 4, { 0,0,1 });
|
||||
model.objects[objs_idx[3]]->rotate(3 * PI / 4, { 0,0,1 });
|
||||
model.objects[objs_idx[4]]->rotate(7 * PI / 4, { 0,0,1 });
|
||||
model.objects[objs_idx[i]]->scale(1, 1, z_scale);
|
||||
} else {
|
||||
model.objects[objs_idx[3]]->rotate(PI / 2, { 0,0,1 });
|
||||
model.objects[objs_idx[4]]->rotate(PI / 2, { 0,0,1 });
|
||||
z_scale = 1;
|
||||
}
|
||||
|
||||
/// --- translate ---
|
||||
//three first will stay with this orientation (top left, middle, bottom right)
|
||||
//last two with 90deg (top left, middle, bottom right)
|
||||
//get position for patches
|
||||
//add sub-part after scale
|
||||
const ConfigOptionPercent* bridge_flow_ratio = print_config->option<ConfigOptionPercent>(setting_to_test);
|
||||
int start = bridge_flow_ratio->value;
|
||||
float zshift = 2.3 * (1 - z_scale);
|
||||
for (size_t i = 0; i < nb_items; i++) {
|
||||
if((start + (add ? 1 : -1) * i * step) < 180 && start + (start + (add ? 1 : -1) * i * step) > 20)
|
||||
add_part(model.objects[objs_idx[i]], Slic3r::resources_dir() + "/calibration/bridge_flow/f"+std::to_string(start + (add ? 1 : -1) * i * step)+".amf", Vec3d{ -10,0, zshift + 4.6 * z_scale }, Vec3d{ 1,1,z_scale });
|
||||
}
|
||||
|
||||
/// --- translate ---;
|
||||
const ConfigOptionFloat* extruder_clearance_radius = print_config->option<ConfigOptionFloat>("extruder_clearance_radius");
|
||||
const ConfigOptionPoints* bed_shape = printer_config->option<ConfigOptionPoints>("bed_shape");
|
||||
Vec2d bed_size = BoundingBoxf(bed_shape->values).size();
|
||||
Vec2d bed_min = BoundingBoxf(bed_shape->values).min;
|
||||
float offsetx = 10 + 10 * xyScale;
|
||||
float offsety = 10 + 10 * xyScale;
|
||||
if (bed_shape->values.size() > 4) {
|
||||
offsetx = bed_size.x() / 2 - bed_size.x() * 1.412 / 4 + 10 * xyScale;
|
||||
offsety = bed_size.y() / 2 - bed_size.y() * 1.412 / 4 + 10 * xyScale;
|
||||
}
|
||||
bool large_enough = bed_shape->values.size() == 4 ?
|
||||
(bed_size.x() > offsetx * 3 && bed_size.y() > offsety * 3) :
|
||||
(bed_size.x() > offsetx * 2 + 10 * xyScale && bed_size.y() > offsety * 2 + 10 * xyScale);
|
||||
if (!large_enough){
|
||||
//problem : too small, use arrange instead and let the user place them.
|
||||
model.arrange_objects(20);
|
||||
//TODO add message
|
||||
} else {
|
||||
model.objects[objs_idx[0]]->translate({ bed_min.x() + offsetx, bed_min.y() + bed_size.y() - offsety,0 });
|
||||
model.objects[objs_idx[1]]->translate({ bed_min.x() + bed_size.x() - offsetx,bed_min.y() + offsety , 0 });
|
||||
model.objects[objs_idx[2]]->translate({ bed_min.x() + bed_size.x()/2, bed_min.y() + bed_size.y() / 2, 0 });
|
||||
model.objects[objs_idx[3]]->translate({ bed_min.x() + offsetx, bed_min.y() + offsety, 0 });
|
||||
model.objects[objs_idx[4]]->translate({ bed_min.x() + bed_size.x() - offsetx,bed_min.y() + bed_size.y() - offsety,0 });
|
||||
float offsety = 5 + extruder_clearance_radius->value + 10;
|
||||
model.objects[objs_idx[0]]->translate({ bed_min.x() + bed_size.x() / 2, bed_min.y() + bed_size.y() / 2, 0 });
|
||||
for (int i = 1; i < nb_items; i++) {
|
||||
model.objects[objs_idx[i]]->translate({ bed_min.x() + bed_size.x() / 2, bed_min.y() + bed_size.y() / 2 + (i%2==0?-1:1) * offsety * ((i+1)/2), 0 });
|
||||
}
|
||||
//TODO: if not enough space, forget about complete_objects
|
||||
|
||||
|
||||
/// --- main config, please modify object config when possible ---
|
||||
DynamicPrintConfig new_print_config = *printConfig; //make a copy
|
||||
DynamicPrintConfig new_print_config = *print_config; //make a copy
|
||||
new_print_config.set_key_value("complete_objects", new ConfigOptionBool(true));
|
||||
new_print_config.set_key_value("skirts", new ConfigOptionInt(0));
|
||||
|
||||
/// --- custom config ---
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
for (size_t i = 0; i < nb_items; i++) {
|
||||
model.objects[objs_idx[i]]->config.set_key_value("perimeters", new ConfigOptionInt(2));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("bottom_solid_layers", new ConfigOptionInt(2));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("gap_fill", new ConfigOptionBool(false));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("first_layer_extrusion_width", new ConfigOptionFloatOrPercent(140, true));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("bottom_fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinearWGapFill));
|
||||
}
|
||||
if (bed_shape->values.size() == 4) {
|
||||
model.objects[objs_idx[0]]->config.set_key_value("fill_angle", new ConfigOptionFloat(90));
|
||||
model.objects[objs_idx[1]]->config.set_key_value("fill_angle", new ConfigOptionFloat(90));
|
||||
model.objects[objs_idx[2]]->config.set_key_value("fill_angle", new ConfigOptionFloat(45));
|
||||
model.objects[objs_idx[3]]->config.set_key_value("fill_angle", new ConfigOptionFloat(0));
|
||||
model.objects[objs_idx[4]]->config.set_key_value("fill_angle", new ConfigOptionFloat(0));
|
||||
} else {
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
for (size_t i = 3; i < 5; i++)
|
||||
model.objects[objs_idx[i]]->config.set_key_value("fill_angle", new ConfigOptionFloat(135));
|
||||
model.objects[objs_idx[i]]->config.set_key_value(setting_to_test, new ConfigOptionPercent(start + (add ? 1 : -1) * i * step));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("layer_height", new ConfigOptionFloat(nozzle_diameter / 2));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("no_perimeter_unsupported_algo", new ConfigOptionEnum<NoPerimeterUnsupportedAlgo>(npuaBridges));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("top_fill_pattern", new ConfigOptionEnum<InfillPattern>(ipSmooth));
|
||||
}
|
||||
|
||||
//update plater
|
||||
this->gui_app->get_tab(Preset::TYPE_PRINT)->load_config(new_print_config);
|
||||
plat->on_config_change(new_print_config);
|
||||
plat->changed_objects(objs_idx);
|
||||
//if(!plat->is_background_process_update_scheduled())
|
||||
// plat->schedule_background_process();
|
||||
//this->gui_app->get_tab(Preset::TYPE_PRINT)->update_dirty();
|
||||
//update everything, easier to code.
|
||||
ObjectList* obj = this->gui_app->obj_list();
|
||||
obj->update_after_undo_redo();
|
||||
|
||||
|
||||
plat->reslice();
|
||||
plat->select_view_3D("Preview");
|
||||
}
|
||||
|
||||
void CalibrationBridgeDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||
{
|
||||
msw_buttons_rescale(this, em_unit(), { wxID_OK });
|
||||
|
||||
Layout();
|
||||
Fit();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
wxPanel* CalibrationBridgeDialog::create_header(wxWindow* parent, const wxFont& bold_font)
|
||||
{
|
||||
wxPanel* panel = new wxPanel(parent);
|
||||
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wxFont header_font = bold_font;
|
||||
#ifdef __WXOSX__
|
||||
header_font.SetPointSize(14);
|
||||
#else
|
||||
header_font.SetPointSize(bold_font.GetPointSize() + 2);
|
||||
#endif // __WXOSX__
|
||||
|
||||
sizer->AddStretchSpacer();
|
||||
|
||||
// text
|
||||
wxStaticText* text = new wxStaticText(panel, wxID_ANY, _(L("Keyboard shortcuts")));
|
||||
text->SetFont(header_font);
|
||||
sizer->Add(text, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
sizer->AddStretchSpacer();
|
||||
|
||||
panel->SetSizer(sizer);
|
||||
return panel;
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
@ -1,37 +1,26 @@
|
||||
#ifndef slic3r_GUI_CalibrationBridgeDialog_hpp_
|
||||
#define slic3r_GUI_CalibrationBridgeDialog_hpp_
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include <wx/html/htmlwin.h>
|
||||
#include "CalibrationAbstractDialog.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class CalibrationBridgeDialog : public DPIDialog
|
||||
class CalibrationBridgeDialog : public CalibrationAbstractDialog
|
||||
{
|
||||
|
||||
public:
|
||||
CalibrationBridgeDialog(GUI_App* app, MainFrame* mainframe);
|
||||
virtual ~CalibrationBridgeDialog() { if (gui_app != nullptr) gui_app->change_calibration_dialog(this, nullptr); }
|
||||
CalibrationBridgeDialog(GUI_App* app, MainFrame* mainframe) : CalibrationAbstractDialog(app, mainframe, "Bridge calibration") { create("/calibration/bridge_flow/bridge_flow.html"); }
|
||||
virtual ~CalibrationBridgeDialog() { }
|
||||
|
||||
protected:
|
||||
void on_dpi_changed(const wxRect &suggested_rect) override;
|
||||
|
||||
private:
|
||||
void create_geometry(wxCommandEvent& event_args);
|
||||
wxPanel* create_header(wxWindow* parent, const wxFont& bold_font);
|
||||
|
||||
wxHtmlWindow* html_viewer;
|
||||
MainFrame* main_frame;
|
||||
GUI_App* gui_app;
|
||||
void create_buttons(wxStdDialogButtonSizer* buttons) override;
|
||||
void create_geometry(std::string setting_key, bool add);
|
||||
void CalibrationBridgeDialog::create_geometry_flow_ratio(wxCommandEvent& event_args) { create_geometry("bridge_flow_ratio", false); }
|
||||
void CalibrationBridgeDialog::create_geometry_overlap(wxCommandEvent& event_args) { create_geometry("bridge_overlap", true); }
|
||||
|
||||
wxComboBox* steps;
|
||||
wxComboBox* nb_tests;
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|
@ -21,109 +21,15 @@ static wxSize get_screen_size(wxWindow* window)
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
CalibrationFlowDialog::CalibrationFlowDialog(GUI_App* app, MainFrame* mainframe)
|
||||
: DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("Flow calibration - test objects generation")),
|
||||
#if ENABLE_SCROLLABLE
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
#else
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
|
||||
#endif // ENABLE_SCROLLABLE
|
||||
{
|
||||
this->gui_app = app;
|
||||
this->main_frame = mainframe;
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
|
||||
// fonts
|
||||
const wxFont& font = wxGetApp().normal_font();
|
||||
const wxFont& bold_font = wxGetApp().bold_font();
|
||||
SetFont(font);
|
||||
|
||||
auto main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
//html
|
||||
html_viewer = new wxHtmlWindow(this, wxID_ANY,
|
||||
wxDefaultPosition, wxSize(500, 500), wxHW_SCROLLBAR_AUTO);
|
||||
html_viewer->SetMinSize(wxSize(900, 500));
|
||||
html_viewer->LoadPage(Slic3r::resources_dir()+"/calibration/filament_flow/filament_flow.html");
|
||||
main_sizer->Add(html_viewer, 1, wxEXPAND | wxALL, 5);
|
||||
|
||||
wxStdDialogButtonSizer* buttons = new wxStdDialogButtonSizer();
|
||||
void CalibrationFlowDialog::create_buttons(wxStdDialogButtonSizer* buttons){
|
||||
wxButton* bt = new wxButton(this, wxID_FILE1, _(L("Generate 10% intervals")));
|
||||
bt->Bind(wxEVT_BUTTON, &CalibrationFlowDialog::create_geometry_10, this);
|
||||
buttons->Add(bt);
|
||||
bt = new wxButton(this, wxID_FILE2, _(L("Generate 2.5% intervals")));
|
||||
bt->Bind(wxEVT_BUTTON, &CalibrationFlowDialog::create_geometry_2_5, this);
|
||||
buttons->Add(bt);
|
||||
wxButton* close = new wxButton(this, wxID_CLOSE, _(L("Close")));
|
||||
close->Bind(wxEVT_BUTTON, &CalibrationFlowDialog::closeMe, this);
|
||||
buttons->AddButton(close);
|
||||
close->SetDefault();
|
||||
close->SetFocus();
|
||||
SetAffirmativeId(wxID_CLOSE);
|
||||
buttons->Realize();
|
||||
main_sizer->Add(buttons, 0, wxEXPAND | wxALL, 5);
|
||||
|
||||
SetSizer(main_sizer);
|
||||
main_sizer->SetSizeHints(this);
|
||||
|
||||
this->SetEscapeId(wxCLOSE);
|
||||
this->SetAffirmativeId(wxCLOSE);
|
||||
}
|
||||
|
||||
void CalibrationFlowDialog::closeMe(wxCommandEvent& event_args) {
|
||||
this->Destroy();
|
||||
}
|
||||
|
||||
void CalibrationFlowDialog::create_geometry_10(wxCommandEvent& event_args) {
|
||||
create_geometry(80.f, 10.f);
|
||||
}
|
||||
|
||||
void CalibrationFlowDialog::create_geometry_2_5(wxCommandEvent& event_args) {
|
||||
create_geometry(92.f, 2.F);
|
||||
}
|
||||
|
||||
void CalibrationFlowDialog::add_part(ModelObject* model_object, std::string input_file, Vec3d move, Vec3d scale) {
|
||||
Model model;
|
||||
try {
|
||||
model = Model::read_from_file(input_file);
|
||||
}
|
||||
catch (std::exception & e) {
|
||||
auto msg = _(L("Error!")) + " " + input_file + " : " + e.what() + ".";
|
||||
show_error(this, msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (ModelObject *object : model.objects) {
|
||||
Vec3d delta = Vec3d::Zero();
|
||||
if (model_object->origin_translation != Vec3d::Zero())
|
||||
{
|
||||
object->center_around_origin();
|
||||
delta = model_object->origin_translation - object->origin_translation;
|
||||
}
|
||||
for (ModelVolume *volume : object->volumes) {
|
||||
volume->translate(delta + move);
|
||||
if (scale != Vec3d{ 1,1,1 })
|
||||
volume->scale(scale);
|
||||
ModelVolume* new_volume = model_object->add_volume(*volume);
|
||||
new_volume->set_type(ModelVolumeType::MODEL_PART);
|
||||
new_volume->name = boost::filesystem::path(input_file).filename().string();
|
||||
|
||||
//volumes_info.push_back(std::make_pair(from_u8(new_volume->name), new_volume->get_mesh_errors_count() > 0));
|
||||
|
||||
// set a default extruder value, since user can't add it manually
|
||||
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||
|
||||
//move to bed
|
||||
/* const TriangleMesh& hull = new_volume->get_convex_hull();
|
||||
float min_z = std::numeric_limits<float>::max();
|
||||
for (const stl_facet& facet : hull.stl.facet_start) {
|
||||
for (int i = 0; i < 3; ++i)
|
||||
min_z = std::min(min_z, Vec3f::UnitZ().dot(facet.vertex[i]));
|
||||
}
|
||||
volume->translate(Vec3d(0,0,-min_z));*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CalibrationFlowDialog::create_geometry(float start, float delta) {
|
||||
Plater* plat = this->main_frame->plater();
|
||||
@ -143,13 +49,14 @@ void CalibrationFlowDialog::create_geometry(float start, float delta) {
|
||||
|
||||
/// --- scale ---
|
||||
// model is created for a 0.4 nozzle, scale xy with nozzle size.
|
||||
const ConfigOptionFloats* nozzle_diameter = printerConfig->option<ConfigOptionFloats>("nozzle_diameter");
|
||||
assert(nozzle_diameter->values.size() > 0);
|
||||
float xyScale = nozzle_diameter->values[0] / 0.4;
|
||||
const ConfigOptionFloats* nozzle_diameter_config = printerConfig->option<ConfigOptionFloats>("nozzle_diameter");
|
||||
assert(nozzle_diameter_config->values.size() > 0);
|
||||
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<ConfigOptionFloatOrPercent>("first_layer_height");
|
||||
const ConfigOptionFloat* layer_height = printConfig->option<ConfigOptionFloat>("layer_height");
|
||||
float zscale = first_layer_height->get_abs_value(nozzle_diameter->values[0]) + 5 * layer_height->value;
|
||||
float zscale = first_layer_height->get_abs_value(nozzle_diameter) + 5 * layer_height->value;
|
||||
zscale *= (1 + 0.3 * (10. / delta));
|
||||
//do scaling
|
||||
if (xyScale < 0.9 || 1.2 < xyScale) {
|
||||
@ -200,7 +107,8 @@ void CalibrationFlowDialog::create_geometry(float start, float delta) {
|
||||
|
||||
/// --- custom config ---
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
model.objects[objs_idx[i]]->config.set_key_value("brim_width", new ConfigOptionFloat(nozzle_diameter->values[0] * 3));
|
||||
//brim to have some time to build up pressure in the nozzle
|
||||
model.objects[objs_idx[i]]->config.set_key_value("brim_width", new ConfigOptionFloat(nozzle_diameter * 3.5));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("brim_ears", new ConfigOptionBool(false));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("perimeters", new ConfigOptionInt(3));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("only_one_perimeter_top", new ConfigOptionBool(true));
|
||||
@ -210,8 +118,14 @@ 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->values[0]/2));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(nozzle_diameter->values[0] / 2, false));
|
||||
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("external_infill_margin", new ConfigOptionFloatOrPercent(100, true));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("solid_fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinearWGapFill));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("top_fill_pattern", new ConfigOptionEnum<InfillPattern>(ipSmooth));
|
||||
@ -233,39 +147,5 @@ void CalibrationFlowDialog::create_geometry(float start, float delta) {
|
||||
plat->select_view_3D("Preview");
|
||||
}
|
||||
|
||||
void CalibrationFlowDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||
{
|
||||
msw_buttons_rescale(this, em_unit(), { wxID_OK });
|
||||
|
||||
Layout();
|
||||
Fit();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
wxPanel* CalibrationFlowDialog::create_header(wxWindow* parent, const wxFont& bold_font)
|
||||
{
|
||||
wxPanel* panel = new wxPanel(parent);
|
||||
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wxFont header_font = bold_font;
|
||||
#ifdef __WXOSX__
|
||||
header_font.SetPointSize(14);
|
||||
#else
|
||||
header_font.SetPointSize(bold_font.GetPointSize() + 2);
|
||||
#endif // __WXOSX__
|
||||
|
||||
sizer->AddStretchSpacer();
|
||||
|
||||
// text
|
||||
wxStaticText* text = new wxStaticText(panel, wxID_ANY, _(L("Keyboard shortcuts")));
|
||||
text->SetFont(header_font);
|
||||
sizer->Add(text, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
sizer->AddStretchSpacer();
|
||||
|
||||
panel->SetSizer(sizer);
|
||||
return panel;
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
@ -1,40 +1,23 @@
|
||||
#ifndef slic3r_GUI_CalibrationFlowDialog_hpp_
|
||||
#define slic3r_GUI_CalibrationFlowDialog_hpp_
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include <wx/html/htmlwin.h>
|
||||
#include "CalibrationAbstractDialog.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class CalibrationFlowDialog : public DPIDialog
|
||||
class CalibrationFlowDialog : public CalibrationAbstractDialog
|
||||
{
|
||||
|
||||
public:
|
||||
CalibrationFlowDialog(GUI_App* app, MainFrame* mainframe);
|
||||
virtual ~CalibrationFlowDialog() { if (gui_app != nullptr) gui_app->change_calibration_dialog(this, nullptr); }
|
||||
CalibrationFlowDialog(GUI_App* app, MainFrame* mainframe) : CalibrationAbstractDialog(app, mainframe, "Flow calibration") { create("/calibration/filament_flow/filament_flow.html"); }
|
||||
virtual ~CalibrationFlowDialog() {}
|
||||
|
||||
protected:
|
||||
void on_dpi_changed(const wxRect &suggested_rect) override;
|
||||
|
||||
private:
|
||||
void closeMe(wxCommandEvent& event_args);
|
||||
void create_geometry_10(wxCommandEvent& event_args);
|
||||
void create_geometry_2_5(wxCommandEvent& event_args);
|
||||
void add_part(ModelObject* model_object, std::string input_file, Vec3d move, Vec3d scale = Vec3d{ 1,1,1 });
|
||||
void create_buttons(wxStdDialogButtonSizer* sizer) override;
|
||||
void create_geometry(float start, float delta);
|
||||
wxPanel* create_header(wxWindow* parent, const wxFont& bold_font);
|
||||
|
||||
wxHtmlWindow* html_viewer;
|
||||
MainFrame* main_frame;
|
||||
GUI_App* gui_app;
|
||||
void create_geometry_10(wxCommandEvent& event_args) { create_geometry(80.f, 10.f); }
|
||||
void create_geometry_2_5(wxCommandEvent& event_args) { create_geometry(92.f, 2.F); }
|
||||
|
||||
};
|
||||
|
||||
|
118
src/slic3r/GUI/CalibrationOverBridgeDialog.cpp
Normal file
118
src/slic3r/GUI/CalibrationOverBridgeDialog.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
#include "CalibrationOverBridgeDialog.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "GUI.hpp"
|
||||
#include "GUI_ObjectList.hpp"
|
||||
#include "Tab.hpp"
|
||||
#include <wx/scrolwin.h>
|
||||
#include <wx/display.h>
|
||||
#include <wx/file.h>
|
||||
#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 CalibrationOverBridgeDialog::create_buttons(wxStdDialogButtonSizer* buttons){
|
||||
wxButton* bt = new wxButton(this, wxID_FILE1, _(L("Generate")));
|
||||
bt->Bind(wxEVT_BUTTON, &CalibrationOverBridgeDialog::create_geometry, this);
|
||||
buttons->Add(bt);
|
||||
}
|
||||
|
||||
void CalibrationOverBridgeDialog::create_geometry(wxCommandEvent& event_args) {
|
||||
Plater* plat = this->main_frame->plater();
|
||||
Model& model = plat->model();
|
||||
plat->reset();
|
||||
std::vector<size_t> objs_idx = plat->load_files(std::vector<std::string>{
|
||||
"./resources/calibration/over-bridge_tuning/over-bridge_flow_ratio_test.amf",
|
||||
"./resources/calibration/over-bridge_tuning/over-bridge_flow_ratio_test.amf",
|
||||
"./resources/calibration/over-bridge_tuning/over-bridge_flow_ratio_test.amf",
|
||||
"./resources/calibration/over-bridge_tuning/over-bridge_flow_ratio_test.amf",
|
||||
"./resources/calibration/over-bridge_tuning/over-bridge_flow_ratio_test.amf",
|
||||
"./resources/calibration/over-bridge_tuning/over-bridge_flow_ratio_test.amf"}, true, false);
|
||||
|
||||
assert(objs_idx.size() == 6);
|
||||
const DynamicPrintConfig* printConfig = this->gui_app->get_tab(Preset::TYPE_PRINT)->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<ConfigOptionFloats>("nozzle_diameter");
|
||||
assert(nozzle_diameter_config->values.size() > 0);
|
||||
float nozzle_diameter = nozzle_diameter_config->values[0];
|
||||
float xyz_scale = (0.2 + nozzle_diameter) / 0.6;
|
||||
//do scaling
|
||||
if (xyz_scale < 0.9 || 1.2 < xyz_scale) {
|
||||
} else {
|
||||
xyz_scale = 1;
|
||||
}
|
||||
for (size_t i = 0; i < 6; i++)
|
||||
model.objects[objs_idx[i]]->scale(xyz_scale * 1.5f, xyz_scale * 1.5f, xyz_scale);
|
||||
|
||||
//add sub-part after scale
|
||||
const ConfigOptionFloatOrPercent* first_layer_height = printConfig->option<ConfigOptionFloatOrPercent>("first_layer_height");
|
||||
float patch_zscale = (first_layer_height->get_abs_value(nozzle_diameter) + nozzle_diameter / 2) / 0.4;
|
||||
float zshift = 0.8 * (1 - xyz_scale);
|
||||
for (size_t i = 0; i < 6; i++) {
|
||||
model.objects[objs_idx[i]]->rotate(PI / 2, { 0,0,1 });
|
||||
ModelObject* obj = add_part(model.objects[objs_idx[i]], Slic3r::resources_dir() + "/calibration/bridge_flow/f"+std::to_string(100 + i * 5)+".amf", Vec3d{ 0, 10 * xyz_scale ,zshift }, Vec3d{ 1, 1, patch_zscale });
|
||||
}
|
||||
|
||||
/// --- translate ---;
|
||||
const ConfigOptionFloat* extruder_clearance_radius = printConfig->option<ConfigOptionFloat>("extruder_clearance_radius");
|
||||
const ConfigOptionPoints* bed_shape = printerConfig->option<ConfigOptionPoints>("bed_shape");
|
||||
Vec2d bed_size = BoundingBoxf(bed_shape->values).size();
|
||||
Vec2d bed_min = BoundingBoxf(bed_shape->values).min;
|
||||
float offsetx = 5 + extruder_clearance_radius->value * 0.6 + 21 * xyz_scale;
|
||||
float offsety = 5 + extruder_clearance_radius->value * 0.6 + 21 * xyz_scale;
|
||||
model.objects[objs_idx[0]]->translate({ bed_min.x() + bed_size.x() / 2 - offsetx, bed_min.y() + bed_size.y() / 2 - offsety * 1.5, 0 });
|
||||
model.objects[objs_idx[1]]->translate({ bed_min.x() + bed_size.x() / 2 - offsetx, bed_min.y() + bed_size.y() / 2 , 0 });
|
||||
model.objects[objs_idx[2]]->translate({ bed_min.x() + bed_size.x() / 2 - offsetx, bed_min.y() + bed_size.y() / 2 + offsety * 1.5, 0 });
|
||||
model.objects[objs_idx[3]]->translate({ bed_min.x() + bed_size.x() / 2 + offsetx, bed_min.y() + bed_size.y() / 2 - offsety * 1.5, 0 });
|
||||
model.objects[objs_idx[4]]->translate({ bed_min.x() + bed_size.x() / 2 + offsetx, bed_min.y() + bed_size.y() / 2 , 0 });
|
||||
model.objects[objs_idx[5]]->translate({ bed_min.x() + bed_size.x() / 2 + offsetx, bed_min.y() + bed_size.y() / 2 + offsety * 1.5, 0 });
|
||||
//TODO: if not enough space, forget about complete_objects
|
||||
|
||||
|
||||
/// --- main config, please modify object config when possible ---
|
||||
DynamicPrintConfig new_print_config = *printConfig; //make a copy
|
||||
new_print_config.set_key_value("complete_objects", new ConfigOptionBool(true));
|
||||
|
||||
/// --- custom config ---
|
||||
for (size_t i = 0; i < 6; i++) {
|
||||
model.objects[objs_idx[i]]->config.set_key_value("perimeters", new ConfigOptionInt(2));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("bottom_solid_layers", new ConfigOptionInt(0));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("top_solid_layers", new ConfigOptionInt(3));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("fill_density", new ConfigOptionPercent(5.5));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("infill_dense", new ConfigOptionBool(false));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("over_bridge_flow_ratio", new ConfigOptionPercent(100 + i * 5));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("layer_height", new ConfigOptionFloat(nozzle_diameter / 2));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("external_infill_margin", new ConfigOptionFloatOrPercent(400,true));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("top_fill_pattern", new ConfigOptionEnum<InfillPattern>(ipSmooth));
|
||||
model.objects[objs_idx[i]]->config.set_key_value("fill_angle", new ConfigOptionFloat(45));
|
||||
}
|
||||
|
||||
//update plater
|
||||
this->gui_app->get_tab(Preset::TYPE_PRINT)->load_config(new_print_config);
|
||||
plat->on_config_change(new_print_config);
|
||||
plat->changed_objects(objs_idx);
|
||||
//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
|
25
src/slic3r/GUI/CalibrationOverBridgeDialog.hpp
Normal file
25
src/slic3r/GUI/CalibrationOverBridgeDialog.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef slic3r_GUI_CalibrationOverBridgeDialog_hpp_
|
||||
#define slic3r_GUI_CalibrationOverBridgeDialog_hpp_
|
||||
|
||||
#include "CalibrationAbstractDialog.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class CalibrationOverBridgeDialog : public CalibrationAbstractDialog
|
||||
{
|
||||
|
||||
public:
|
||||
CalibrationOverBridgeDialog(GUI_App* app, MainFrame* mainframe) : CalibrationAbstractDialog(app, mainframe, "Ironing pattern calibration") { std::cout << " html = /calibration/over-bridge_tuning/over-bridge_tuning.html\n"; create("/calibration/over-bridge_tuning/over-bridge_tuning.html"); }
|
||||
virtual ~CalibrationOverBridgeDialog() { }
|
||||
|
||||
protected:
|
||||
void create_buttons(wxStdDialogButtonSizer* sizer) override;
|
||||
void create_geometry(wxCommandEvent& event_args);
|
||||
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif
|
@ -21,43 +21,19 @@ static wxSize get_screen_size(wxWindow* window)
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
CalibrationTempDialog::CalibrationTempDialog(GUI_App* app, MainFrame* mainframe)
|
||||
: DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("Temp calibration - test objects generation")),
|
||||
#if ENABLE_SCROLLABLE
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
#else
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
|
||||
#endif // ENABLE_SCROLLABLE
|
||||
{
|
||||
this->gui_app = app;
|
||||
this->main_frame = mainframe;
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
|
||||
// fonts
|
||||
const wxFont& font = wxGetApp().normal_font();
|
||||
const wxFont& bold_font = wxGetApp().bold_font();
|
||||
SetFont(font);
|
||||
|
||||
auto main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
//html
|
||||
html_viewer = new wxHtmlWindow(this, wxID_ANY,
|
||||
wxDefaultPosition, wxSize(800, 500), wxHW_SCROLLBAR_AUTO);
|
||||
html_viewer->LoadPage(Slic3r::resources_dir()+"/calibration/filament_temp/filament_temp.html");
|
||||
main_sizer->Add(html_viewer, 1, wxEXPAND | wxALL, 5);
|
||||
void CalibrationTempDialog::create_buttons(wxStdDialogButtonSizer* buttons){
|
||||
wxString choices_steps[] = { "5","10","15","20" };
|
||||
steps = new wxComboBox(this, wxID_ANY, wxString{ "10" }, wxDefaultPosition, wxDefaultSize, 4, choices_steps);
|
||||
steps->SetToolTip(_(L("Select the step in celcius between two tests.")));
|
||||
steps->SetSelection(1);
|
||||
wxString choices_nb[] = { "0","1","2","3","4","5","6","7" };
|
||||
nb_down = new wxComboBox(this, wxID_ANY, wxString{ "2" }, wxDefaultPosition, wxDefaultSize, 4, choices_nb);
|
||||
nb_down = new wxComboBox(this, wxID_ANY, wxString{ "2" }, wxDefaultPosition, wxDefaultSize, 8, choices_nb);
|
||||
nb_down->SetToolTip(_(L("Select the number of tests with lower temperature than the current one.")));
|
||||
nb_down->SetSelection(2);
|
||||
nb_up = new wxComboBox(this, wxID_ANY, wxString{ "2" }, wxDefaultPosition, wxDefaultSize, 4, choices_nb);
|
||||
nb_up = new wxComboBox(this, wxID_ANY, wxString{ "2" }, wxDefaultPosition, wxDefaultSize, 8, choices_nb);
|
||||
nb_up->SetToolTip(_(L("Select the number of tests with higher temperature than the current one.")));
|
||||
nb_up->SetSelection(2);
|
||||
|
||||
wxStdDialogButtonSizer* buttons = new wxStdDialogButtonSizer();
|
||||
buttons->Add(new wxStaticText(this, wxID_ANY, wxString{ "nb down:" }));
|
||||
buttons->Add(nb_down);
|
||||
buttons->AddSpacer(15);
|
||||
@ -71,67 +47,6 @@ namespace GUI {
|
||||
wxButton* bt = new wxButton(this, wxID_FILE1, _(L("Generate")));
|
||||
bt->Bind(wxEVT_BUTTON, &CalibrationTempDialog::create_geometry, this);
|
||||
buttons->Add(bt);
|
||||
wxButton* close = new wxButton(this, wxID_CLOSE, _(L("Close")));
|
||||
close->Bind(wxEVT_BUTTON, &CalibrationTempDialog::closeMe, this);
|
||||
buttons->AddButton(close);
|
||||
close->SetDefault();
|
||||
close->SetFocus();
|
||||
SetAffirmativeId(wxID_CLOSE);
|
||||
buttons->Realize();
|
||||
main_sizer->Add(buttons, 0, wxEXPAND | wxALL, 5);
|
||||
|
||||
SetSizer(main_sizer);
|
||||
main_sizer->SetSizeHints(this);
|
||||
}
|
||||
|
||||
void CalibrationTempDialog::closeMe(wxCommandEvent& event_args) {
|
||||
this->Destroy();
|
||||
}
|
||||
|
||||
ModelObject* CalibrationTempDialog::add_part(ModelObject* model_object, std::string input_file, Vec3d move, Vec3d scale) {
|
||||
Model model;
|
||||
try {
|
||||
model = Model::read_from_file(input_file);
|
||||
}
|
||||
catch (std::exception & e) {
|
||||
auto msg = _(L("Error!")) + " " + input_file + " : " + e.what() + ".";
|
||||
show_error(this, msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (ModelObject* object : model.objects) {
|
||||
Vec3d delta = Vec3d::Zero();
|
||||
if (model_object->origin_translation != Vec3d::Zero())
|
||||
{
|
||||
object->center_around_origin();
|
||||
delta = model_object->origin_translation - object->origin_translation;
|
||||
}
|
||||
for (ModelVolume* volume : object->volumes) {
|
||||
volume->translate(delta + move);
|
||||
if (scale != Vec3d{ 1,1,1 }) {
|
||||
volume->scale(scale);
|
||||
}
|
||||
ModelVolume* new_volume = model_object->add_volume(*volume);
|
||||
new_volume->set_type(ModelVolumeType::MODEL_PART);
|
||||
new_volume->name = boost::filesystem::path(input_file).filename().string();
|
||||
|
||||
//volumes_info.push_back(std::make_pair(from_u8(new_volume->name), new_volume->get_mesh_errors_count() > 0));
|
||||
|
||||
// set a default extruder value, since user can't add it manually
|
||||
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||
|
||||
//move to bed
|
||||
/* const TriangleMesh& hull = new_volume->get_convex_hull();
|
||||
float min_z = std::numeric_limits<float>::max();
|
||||
for (const stl_facet& facet : hull.stl.facet_start) {
|
||||
for (int i = 0; i < 3; ++i)
|
||||
min_z = std::min(min_z, Vec3f::UnitZ().dot(facet.vertex[i]));
|
||||
}
|
||||
volume->translate(Vec3d(0,0,-min_z));*/
|
||||
}
|
||||
}
|
||||
assert(model.objects.size() == 1);
|
||||
return model.objects.empty()?nullptr: model.objects[0];
|
||||
}
|
||||
|
||||
void CalibrationTempDialog::create_geometry(wxCommandEvent& event_args) {
|
||||
@ -227,7 +142,6 @@ void CalibrationTempDialog::create_geometry(wxCommandEvent& event_args) {
|
||||
model.objects[objs_idx[0]]->config.set_key_value("gap_fill", new ConfigOptionBool(false));
|
||||
model.objects[objs_idx[0]]->config.set_key_value("thin_perimeters", new ConfigOptionBool(true));
|
||||
model.objects[objs_idx[0]]->config.set_key_value("layer_height", new ConfigOptionFloat(nozzle_diameter / 2));
|
||||
model.objects[objs_idx[0]]->config.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(nozzle_diameter / 2, false));
|
||||
model.objects[objs_idx[0]]->config.set_key_value("fill_density", new ConfigOptionPercent(7));
|
||||
model.objects[objs_idx[0]]->config.set_key_value("solid_fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinearWGapFill));
|
||||
model.objects[objs_idx[0]]->config.set_key_value("top_fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinearWGapFill));
|
||||
@ -250,39 +164,5 @@ void CalibrationTempDialog::create_geometry(wxCommandEvent& event_args) {
|
||||
plat->select_view_3D("Preview");
|
||||
}
|
||||
|
||||
void CalibrationTempDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||
{
|
||||
msw_buttons_rescale(this, em_unit(), { wxID_OK });
|
||||
|
||||
Layout();
|
||||
Fit();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
wxPanel* CalibrationTempDialog::create_header(wxWindow* parent, const wxFont& bold_font)
|
||||
{
|
||||
wxPanel* panel = new wxPanel(parent);
|
||||
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wxFont header_font = bold_font;
|
||||
#ifdef __WXOSX__
|
||||
header_font.SetPointSize(14);
|
||||
#else
|
||||
header_font.SetPointSize(bold_font.GetPointSize() + 2);
|
||||
#endif // __WXOSX__
|
||||
|
||||
sizer->AddStretchSpacer();
|
||||
|
||||
// text
|
||||
wxStaticText* text = new wxStaticText(panel, wxID_ANY, _(L("Keyboard shortcuts")));
|
||||
text->SetFont(header_font);
|
||||
sizer->Add(text, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
sizer->AddStretchSpacer();
|
||||
|
||||
panel->SetSizer(sizer);
|
||||
return panel;
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
@ -1,38 +1,22 @@
|
||||
#ifndef slic3r_GUI_CalibrationTempDialog_hpp_
|
||||
#define slic3r_GUI_CalibrationTempDialog_hpp_
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include <wx/html/htmlwin.h>
|
||||
#include "CalibrationAbstractDialog.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class CalibrationTempDialog : public DPIDialog
|
||||
class CalibrationTempDialog : public CalibrationAbstractDialog
|
||||
{
|
||||
|
||||
public:
|
||||
CalibrationTempDialog(GUI_App* app, MainFrame* mainframe);
|
||||
virtual ~CalibrationTempDialog(){ if(gui_app!=nullptr) gui_app->change_calibration_dialog(this, nullptr);}
|
||||
CalibrationTempDialog(GUI_App* app, MainFrame* mainframe) : CalibrationAbstractDialog(app, mainframe, "Temperature calibration") { create("/calibration/filament_temp/filament_temp.html"); }
|
||||
virtual ~CalibrationTempDialog(){ }
|
||||
|
||||
protected:
|
||||
void on_dpi_changed(const wxRect &suggested_rect) override;
|
||||
|
||||
private:
|
||||
void closeMe(wxCommandEvent& event_args);
|
||||
ModelObject* add_part(ModelObject* model_object, std::string input_file, Vec3d move, Vec3d scale = Vec3d{ 1,1,1 });
|
||||
void create_buttons(wxStdDialogButtonSizer* sizer) override;
|
||||
void create_geometry(wxCommandEvent& event_args);
|
||||
wxPanel* create_header(wxWindow* parent, const wxFont& bold_font);
|
||||
|
||||
wxHtmlWindow* html_viewer;
|
||||
MainFrame* main_frame;
|
||||
GUI_App* gui_app;
|
||||
wxComboBox* steps;
|
||||
wxComboBox* nb_down;
|
||||
wxComboBox* nb_up;
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "CalibrationBedDialog.hpp"
|
||||
#include "CalibrationBridgeDialog.hpp"
|
||||
#include "CalibrationFlowDialog.hpp"
|
||||
#include "CalibrationOverBridgeDialog.hpp"
|
||||
#include "CalibrationTempDialog.hpp"
|
||||
#include "ConfigSnapshotDialog.hpp"
|
||||
#include "FirmwareDialog.hpp"
|
||||
@ -581,7 +582,7 @@ void GUI_App::flow_ratio_dialog()
|
||||
}
|
||||
void GUI_App::over_bridge_dialog()
|
||||
{
|
||||
change_calibration_dialog(nullptr, new CalibrationFlowDialog(this, mainframe));
|
||||
change_calibration_dialog(nullptr, new CalibrationOverBridgeDialog(this, mainframe));
|
||||
}
|
||||
void GUI_App::bridge_tuning_dialog()
|
||||
{
|
||||
|
@ -771,10 +771,10 @@ void MainFrame::init_menubar()
|
||||
[this](wxCommandEvent&) { wxGetApp().flow_ratio_dialog(); });
|
||||
append_menu_item(objectsMenu, wxID_ANY, _(L("Filament temperature tuning")), _(L("Create a test print to help you to set your filament temperature.")),
|
||||
[this](wxCommandEvent&) { wxGetApp().filament_temperature_dialog(); });
|
||||
//append_menu_item(objectsMenu, wxID_ANY, _(L("Ironing pattern tuning")), _(L("Create a test print to help you to set your over-bridge flow ratio.")),
|
||||
// [this](wxCommandEvent&) { wxGetApp().over_bridge_dialog(); });
|
||||
//append_menu_item(objectsMenu, wxID_ANY, _(L("Bridge pattern tuning")), _(L("Create a test print to help you to set your over-bridge flow ratio.")),
|
||||
// [this](wxCommandEvent&) { wxGetApp().bridge_tuning_dialog(); });
|
||||
append_menu_item(objectsMenu, wxID_ANY, _(L("Bridge pattern tuning")), _(L("Create a test print to help you to set your bridge flow ratio.")),
|
||||
[this](wxCommandEvent&) { wxGetApp().bridge_tuning_dialog(); });
|
||||
append_menu_item(objectsMenu, wxID_ANY, _(L("Ironing pattern tuning")), _(L("Create a test print to help you to set your over-bridge flow ratio and ironing pattern.")),
|
||||
[this](wxCommandEvent&) { wxGetApp().over_bridge_dialog(); });
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user