diff --git a/src/libslic3r/Emboss.cpp b/src/libslic3r/Emboss.cpp index ef144b48d3..e28605d48f 100644 --- a/src/libslic3r/Emboss.cpp +++ b/src/libslic3r/Emboss.cpp @@ -1299,6 +1299,16 @@ HealedExPolygons Emboss::text2shapes(FontFileWithCache &font_with_cache, const c return ::union_with_delta(vshapes, delta, MAX_HEAL_ITERATION_OF_TEXT); } +indexed_triangle_set Emboss::text2model(FontFileWithCache &font, const char *text, const FontProp &font_prop, Vec3d dx_y_z_size) +{ + const double scale = 0.000001 * 25.4 / 72 * dx_y_z_size.y(); // convert points to millimeters (represent interliniage) + const double width = dx_y_z_size.x() ? dx_y_z_size.x() : 1.0; + const auto shapes = Emboss::text2shapes(font, text, font_prop, []() { return false; }); + auto pt = std::make_unique(dx_y_z_size.z()); + Transform3d tr = Eigen::Translation() * Eigen::Scaling(scale * width, scale, 1.); + return Emboss::polygons2model(shapes.expolygons, Emboss::ProjectTransform(std::move(pt), tr)); +} + namespace { /// /// Align shape against pivot diff --git a/src/libslic3r/Emboss.hpp b/src/libslic3r/Emboss.hpp index 15f0316327..9c3a7a5c73 100644 --- a/src/libslic3r/Emboss.hpp +++ b/src/libslic3r/Emboss.hpp @@ -155,6 +155,16 @@ namespace Emboss HealedExPolygons text2shapes (FontFileWithCache &font, const char *text, const FontProp &font_prop, const std::function &was_canceled = []() {return false;}); ExPolygonsWithIds text2vshapes(FontFileWithCache &font, const std::wstring& text, const FontProp &font_prop, const std::function& was_canceled = []() {return false;}); + /// + /// Convert text into triangle set + /// + /// Define fonts + cache, which could extend + /// Characters to convert + /// User defined property of the font + /// The size of the printed text {dx, y, z}. "dx" is the width of the character relative to its size (default is 1.0). "y" is the font height in millimeters. "z"S is the height of the extruded text in millimeters. + /// Indexed triangle set + indexed_triangle_set text2model(FontFileWithCache& font, const char *text, const FontProp &font_prop, Vec3d dx_y_z_size); + const unsigned ENTER_UNICODE = static_cast('\n'); /// Sum of character '\n' unsigned get_count_lines(const std::wstring &ws); diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 8df2d2202d..158b858c8c 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -1203,6 +1203,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree; f->print_config = &this->object()->print()->config(); f->print_object_config = &this->object()->config(); + f->calib_params = &this->object()->model_object()->get_model()->calib_params; if (surface_fill.params.pattern == ipConcentricInternal) { FillConcentricInternal *fill_concentric = dynamic_cast(f.get()); assert(fill_concentric != nullptr); diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index c585329079..e71008e3c0 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -12,6 +12,7 @@ #include "../Surface.hpp" #include "../libslic3r.h" #include "../VariableWidth.hpp" +#include "../calib.hpp" #include "FillBase.hpp" #include "FillConcentric.hpp" @@ -162,12 +163,22 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para out.push_back(eec = new ExtrusionEntityCollection()); // Only concentric fills are not sorted. eec->no_sort = this->no_sort(); - // ORCA: special flag for flow rate calibration - auto is_flow_calib = params.extrusion_role == erTopSolidInfill && this->print_object_config->has("calib_flowrate_topinfill_special_order") && - this->print_object_config->option("calib_flowrate_topinfill_special_order")->getBool(); - if (is_flow_calib) { - eec->no_sort = true; + + // Calibration section (pre-extrusion) + if (calib_params != nullptr) { + switch (calib_params->mode) { + case CalibMode::Calib_Flow_Rate: + if (params.extrusion_role == erTopSolidInfill) { + eec->no_sort = true; + break; + } + case CalibMode::Calib_Practical_Flow_Ratio: + if (layer_id > 3) + eec->no_sort = true; + } } + + // Extrusion section size_t idx = eec->entities.size(); if (params.use_arachne) { Flow new_flow = params.flow.with_spacing(float(this->spacing)); @@ -180,13 +191,82 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para params.extrusion_role, flow_mm3_per_mm, float(flow_width), params.flow.height()); } - if (!params.can_reverse || is_flow_calib) { - for (size_t i = idx; i < eec->entities.size(); i++) - eec->entities[i]->set_reverse(); - } + // Calibration section (post-extrusion) with sended parameters + if (calib_params != nullptr) { + switch (calib_params->mode) { + case CalibMode::Calib_Flow_Rate: + for (size_t i = idx; i < eec->entities.size(); i++) { + eec->entities[i]->set_reverse(); + } + break; + case CalibMode::Calib_Practical_Flow_Ratio: + const BoundingBox _bbox = this->bounding_box; + const coord_t _width = _bbox.size().x(); + const coord_t _semiwidth = _width / 2; + const coord_t _xmin = _bbox.center().x() - _semiwidth; + const coord_t _xmax = _bbox.center().x() + _semiwidth; + const double _wmin = this->calib_params->start; + const double _wmax = this->calib_params->end; + const double _wlen = _wmax - _wmin; + if (layer_id > 3) { // Prepare calibration layers + eec->reverse(); + for (ExtrusionEntity* e : eec->entities) { + ExtrusionPath* _p = static_cast(e); + coord_t _x = _p->polyline.points.front().x(); + double _q = _wlen * (_x - _xmin) / _width + _wmin; + _p->width *= _q; + _p->mm3_per_mm *= _q; + if (_p->polyline.points.front().y() > _p->polyline.points.back().y()) + _p->reverse(); + } + if (calib_params->interlaced) { // Inrtleaced sort + std::vector a, b; + int _i = 0; + for (ExtrusionEntity* e : eec->entities) { + ExtrusionPath* _p = static_cast(e); + if (++_i % 2) + a.emplace_back(_p); + else + b.emplace_back(_p); + } + eec->entities.clear(); + for (ExtrusionPath* _p : a) + eec->entities.emplace_back(_p); + for (ExtrusionPath* _p : b) + eec->entities.emplace_back(_p); + } + } else if (layer_id == 3) { + for (ExtrusionEntity* e : eec->entities) { + ExtrusionPath* _p = static_cast(e); + _p->width *= 0.825; + _p->mm3_per_mm *= 0.825; + } + } else if (layer_id > 0) { // Prepare a smooth base + std::vector a; + int _i = 1; + for (ExtrusionEntity* e : eec->entities) { + ExtrusionPath* _p = static_cast(e); + if (++_i % 2) { + if ((_i / 2) % 2) + _p->reverse(); + //if (layer_id == 1) { + // _p->width *= 0.75; + // _p->mm3_per_mm *= 0.75; + //} + a.emplace_back(_p); + } + } + eec->entities.clear(); + for (ExtrusionPath* _p : a) + eec->entities.emplace_back(_p); + } else { // Additional job at first layer + } + } + } else { // Orca: run gap fill this->_create_gap_fill(surface, params, eec); + } } } diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index 010dff8a08..97d7cd5876 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -20,6 +20,7 @@ #include "../ExtrusionEntity.hpp" #include "../ExtrusionEntityCollection.hpp" #include "../ShortestPath.hpp" +#include "../calib.hpp" namespace Slic3r { @@ -138,6 +139,7 @@ public: // Orca: also used by gap fill function. const PrintConfig *print_config = nullptr; const PrintObjectConfig *print_object_config = nullptr; + const Calib_Params *calib_params = nullptr; // BBS: all no overlap expolygons in same layer ExPolygons no_overlap_expolygons; diff --git a/src/libslic3r/Fill/FillPlanePath.cpp b/src/libslic3r/Fill/FillPlanePath.cpp index b4681d05f9..5a33753ed2 100644 --- a/src/libslic3r/Fill/FillPlanePath.cpp +++ b/src/libslic3r/Fill/FillPlanePath.cpp @@ -132,8 +132,8 @@ void FillPlanePath::_fill_surface_single( if (params.dont_connect() || params.density > 0.5) { // ORCA: special flag for flow rate calibration auto is_flow_calib = params.extrusion_role == erTopSolidInfill && - this->print_object_config->has("calib_flowrate_topinfill_special_order") && - this->print_object_config->option("calib_flowrate_topinfill_special_order")->getBool() && + calib_params != nullptr && + (calib_params->mode == CalibMode::Calib_Flow_Rate) && dynamic_cast(this); if (is_flow_calib) { // We want the spiral part to be printed inside-out diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 8a128d511a..b5f263f9d5 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -91,6 +91,8 @@ Model& Model::assign_copy(const Model &rhs) this->calib_pa_pattern = std::make_unique(CalibPressureAdvancePattern(*rhs.calib_pa_pattern)); } + this->calib_params = rhs.calib_params; + // BBS: for design info this->design_info = rhs.design_info; this->model_info = rhs.model_info; @@ -129,6 +131,8 @@ Model& Model::assign_copy(Model &&rhs) this->calib_pa_pattern.reset(); this->calib_pa_pattern.swap(rhs.calib_pa_pattern); + this->calib_params = rhs.calib_params; + //BBS: add auxiliary path logic // BBS: backup, all in one temp dir this->stl_design_id = rhs.stl_design_id; diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 35333d6e2e..dc063812b6 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -1690,6 +1690,7 @@ public: bool is_fuzzy_skin_painted() const; std::unique_ptr calib_pa_pattern; + Calib_Params calib_params; private: explicit Model(int) : ObjectBase(-1) diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 3ca75d28f3..7aee6bd29a 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -952,7 +952,7 @@ static std::vector s_Preset_print_options { "small_area_infill_flow_compensation", "small_area_infill_flow_compensation_model", "enable_wrapping_detection", "seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "scarf_joint_speed", "scarf_joint_flow_ratio", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", "scarf_overhang_threshold", - "interlocking_beam", "interlocking_orientation", "interlocking_beam_layer_count", "interlocking_depth", "interlocking_boundary_avoidance", "interlocking_beam_width","calib_flowrate_topinfill_special_order", + "interlocking_beam", "interlocking_orientation", "interlocking_beam_layer_count", "interlocking_depth", "interlocking_boundary_avoidance", "interlocking_beam_width", }; static std::vector s_Preset_filament_options {/*"filament_colour", */ "default_filament_colour", "required_nozzle_HRC", "filament_diameter", "pellet_flow_coefficient", "volumetric_speed_coefficients", "filament_type", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 37fc895411..505b812b6c 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3860,11 +3860,6 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionInt(2)); - // ORCA: special flag for flow rate calibration - def = this->add("calib_flowrate_topinfill_special_order", coBool); - def->mode = comDevelop; - def->set_default_value(new ConfigOptionBool(false)); - def = this->add("ironing_type", coEnum); def->label = L("Ironing Type"); def->category = L("Quality"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 3e34a8362b..946060b2df 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -35,7 +35,6 @@ enum GCodeFlavor : unsigned char { gcfSmoothie, gcfNoExtrusion }; - enum class FuzzySkinType { None, External, @@ -1009,11 +1008,6 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionInt, interlocking_beam_layer_count)) ((ConfigOptionInt, interlocking_depth)) ((ConfigOptionInt, interlocking_boundary_avoidance)) - - // Orca: internal use only - ((ConfigOptionBool, calib_flowrate_topinfill_special_order)) // ORCA: special flag for flow rate calibration - - ) // This object is mapped to Perl as Slic3r::Config::PrintRegion. diff --git a/src/libslic3r/calib.hpp b/src/libslic3r/calib.hpp index 0cf509bcb7..416e9d7134 100644 --- a/src/libslic3r/calib.hpp +++ b/src/libslic3r/calib.hpp @@ -26,6 +26,8 @@ enum class CalibMode : int { Calib_Retraction_tower, Calib_Input_shaping_freq, Calib_Input_shaping_damp, + Calib_Junction_Deviation, + Calib_Practical_Flow_Ratio, Calib_Cornering }; @@ -35,10 +37,10 @@ struct Calib_Params { Calib_Params() : mode(CalibMode::Calib_None){}; int extruder_id = 0; - double start, end, step; - bool print_numbers; + double start, end, step; + bool print_numbers, print_ruler, use_zhop, interlaced; double freqStartX, freqEndX, freqStartY, freqEndY; - int test_model; + int test_model, model_variant; std::string shaper_type; std::vector accelerations; std::vector speeds; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 6d0023a0ba..15c8c0240a 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -3059,6 +3059,11 @@ void MainFrame::init_menubar_as_editor() append_menu_item(flowrate_menu, wxID_ANY, _L("YOLO (perfectionist version)"), _L("Orca YOLO flowrate calibration, 0.005 step"), [this](wxCommandEvent&) { if (m_plater) m_plater->calib_flowrate(true, 2); }, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); + flowrate_menu->AppendSeparator(); + append_menu_item(flowrate_menu, wxID_ANY, _L("Practical Flow Ratio Test"), _L("Practical Flow Ratio calibration test"), + [this](wxCommandEvent&) { if (!m_practical_flow_ratio_calib_dlg) + m_practical_flow_ratio_calib_dlg = new Practical_Flow_Ratio_Test_Dlg((wxWindow*)this, wxID_ANY, m_plater); + m_practical_flow_ratio_calib_dlg->ShowModal();}, "", nullptr, [this]() {return m_plater->is_view3D_shown();; }, this); m_topbar->GetCalibMenu()->AppendSubMenu(flowrate_menu, _L("Flow rate")); // Retraction test diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index faa6e10708..6c0b38644c 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -364,6 +364,7 @@ public: Retraction_Test_Dlg* m_retraction_calib_dlg{ nullptr }; Input_Shaping_Freq_Test_Dlg* m_IS_freq_calib_dlg{ nullptr }; Input_Shaping_Damp_Test_Dlg* m_IS_damp_calib_dlg{ nullptr }; + Practical_Flow_Ratio_Test_Dlg* m_practical_flow_ratio_calib_dlg{ nullptr }; Cornering_Test_Dlg* m_cornering_calib_dlg{ nullptr }; // BBS. Replace title bar and menu bar with top bar. diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cc67ee11fd..7685f6a82b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #ifdef _WIN32 #include #include @@ -165,6 +166,9 @@ #include "DeviceCore/DevFilaSystem.h" #include "DeviceCore/DevManager.h" +#include "../Utils/WxFontUtils.hpp" +#include "libslic3r/TextConfiguration.hpp" + using boost::optional; namespace fs = boost::filesystem; using Slic3r::_3DScene; @@ -218,6 +222,79 @@ wxDEFINE_EVENT(EVT_NOTICE_FULL_SCREEN_CHANGED, IntEvent); #define PRINTER_PANEL_RADIUS (6) // ORCA #define BTN_SYNC_SIZE (wxSize(FromDIP(96), FromDIP(98))) +wxFont calib_font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, "NotoSans"); +Emboss::FontFileWithCache calib_font_with_cache(std::move(WxFontUtils::create_font_file(calib_font))); + +/// +/// Get the orthogonal box mesh (Experemental, can rethink and add) +/// +/// The size of the printed text {dx, y, z}. +/// "dx" is the width of the character relative to its size (default is 1.0). +/// "y" is the font height in millimeters. +/// "z" is the height of the extruded text in millimeters. +/// Position of model against text pivot. +static TriangleMesh get_ortho_box_mesh(Vec3d size, Vec3f position = Vec3f()) +{ + TriangleMesh mesh(make_cube(size.x(), size.y(), size.z())); // get box + mesh.translate(position); // move mesh to indeed place + return mesh; +} + +/// +/// Get the triangle mesh (Experemental, can rethink and add) +/// +/// The size of the printed text {x, y, z}. +/// "x" is the size of the triangle in millimeters. +/// "y" define the line width in millimeters. +/// "z" is the height of the extruded shape in millimeters. +/// Position of model against its pivot. +/// Rotation angle of model against its pivot. +static TriangleMesh get_ortho_triangle_mesh(Vec3d size, Vec3f position = Vec3f(), double rotation = 0.) +{ + TriangleMesh mesh(make_cube(size.y(), size.x(), size.z())); // get triangle side + double _ypos = size.x() * sin(PI / 3); + mesh.translate(-size.y() / 2, 0., 0.); + TriangleMesh mesh2(mesh); + mesh2.rotate_z(PI / 3); + TriangleMesh mesh3(mesh2); + mesh3.rotate_z(PI / 3); + mesh.translate(-_ypos, -size.x() / 2, 0.); + mesh.merge(std::move(mesh2)); + mesh.merge(std::move(mesh3)); + mesh.rotate_z(rotation * PI / 180); + mesh.translate(position); // move mesh to indeed place + return mesh; +} + + +/// +/// Get the text mesh (Experemental, can rethink and add) +/// +/// The text +/// Font properties. Containe Horizontal and vertical alignment. +/// The size of the printed text {dx, y, z}. +/// "dx" is the width of the character relative to its size (default is 1.0). +/// "y" is the font height in millimeters. +/// "z" is the height of the extruded text in millimeters. +/// Position of model against text pivot +/// Place background box under text {depth, offset} +/// "depth" is the depth of the background box. Its height is added to the height of the entire model. +/// "offset" external expansion relative to the borders of the text. +static TriangleMesh get_text_mesh(const char *text, FontProp &font_props, Vec3d size, Vec3f position = Vec3f(), Vec2f background = Vec2f()) +{ + TriangleMesh mesh( + Emboss::text2model(calib_font_with_cache, text, font_props, Vec3d(size.x(), size.y(), size.z() + background.x()))); // get text mesh + if (background.x()) { + BoundingBoxf3 bb3 = mesh.bounding_box(); + float offset = background.y(); + TriangleMesh mesh_bg = get_ortho_box_mesh(Vec3d(bb3.size().x() + offset * 2, bb3.size().y() + offset * 2, background.x()), + Vec3f(bb3.min.x() - offset, bb3.min.y() - offset, 0.)); + mesh.merge(mesh_bg); + } + mesh.translate(position); // move text mesh to indeed place + return mesh; +} + static string get_diameter_string(float diameter) { std::ostringstream stream; // ORCA ensure 0.25 returned as 0.25. previous code returned as 0.2 because of std::setprecision(1) @@ -12407,6 +12484,260 @@ void Plater::_calib_pa_select_added_objects() { } } +// Adjust settings for Practical Flow ratio calibration +void Plater::Calib_Practical_Flow_Ratio(const Calib_Params& params) { + wxString calib_name = L"Practical Flow Ratio Test"; + if (new_project(false, false, calib_name) == wxID_CANCEL) + return; + wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor)); + + auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; + auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; + auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; + + /// --- scale --- + // model is created for a 0.4 nozzle, scale z with nozzle size. + const ConfigOptionFloats* nozzle_diameter_config = printer_config->option("nozzle_diameter"); + assert(nozzle_diameter_config->values.size() > 0); + const double nozzle_diameter = nozzle_diameter_config->values[0]; + // scale z to have 6 layers + double first_layer_height = print_config->option("initial_layer_print_height")->value; + const double layer_height = nozzle_diameter / 2.0; // prefer 0.2 layer height for 0.4 nozzle + first_layer_height = std::max(first_layer_height, layer_height); + + const double calib_scale[3] = {1.0, 1.5, 2.0}; + const double xscale = calib_scale[params.test_model]; + const double yscale = calib_scale[params.model_variant]; + const double zscale = (first_layer_height + (3 + params.step) * layer_height) / 1.2; + + model().calib_params = params; + + string _name = format("Practical_FR_Test_%.2f~%.2f_@%.0f%s", params.start, params.end, params.speeds[0], params.interlaced ? "i" : "p"); + + const auto bed_shape = printer_config->option("printable_area")->values; + const BoundingBoxf bed_ext = get_extents(bed_shape); + const Vec2d _center = bed_ext.center(); + const double _model_height = zscale * 1.2; + + auto test_model = model().add_object(); + TriangleMesh its_model = TriangleMesh(make_cube(xscale * 100, yscale * 10, _model_height)); + test_model->name = _name; + test_model->add_volume(its_model); + test_model->add_instance(); + + test_model->translate_instances(Vec3d(_center.x() - xscale * 50, _center.y() - yscale * 5, 0.0)); + test_model->ensure_on_bed(); + + const BoundingBoxf3 _bbox = test_model->bounding_box_exact(); + const double _width = _bbox.size().x(); // model width + const double _depth = _bbox.size().y(); // model depth + const double _div_width = nozzle_diameter * 1.25; // divider width for rulers + const double _div_semiwidth = _div_width / 2.; // divider half of width for rulers + const double _body_height = first_layer_height + layer_height; // rulers height + const double _offset = nozzle_diameter * 2.; // text labels offset + const double _font_size = nozzle_diameter * 16.25; // font size + Vec3d _size(1., _font_size, layer_height * 2.); // text dimensions + FontProp fp; // text properties + Vec2f _bg(_body_height, _offset); // set text background plate + const auto _filament_fr = filament_config->option("filament_flow_ratio")->get_at(0); // filament flow ratio + const auto _real_fr = 1. / _filament_fr; // filament flow ratio mark position + + if (params.print_ruler) { // Print ruler + const double _baseline = nozzle_diameter * 5; // baseline offset + test_model->add_volume(get_ortho_box_mesh(Vec3d(_width + _div_width, -_baseline + nozzle_diameter, _body_height), + Vec3f(-_div_semiwidth, -nozzle_diameter, 0.))); // ruler's body + + fp.align = FontProp::Align(FontProp::HorizontalAlign::right, FontProp::VerticalAlign::bottom); // correct the text position + TriangleMesh mesh = get_text_mesh(format("%s@%.0f%s fr=%.3f", filament_config->get_filament_type(), params.speeds[0], params.interlaced ? "i" : "p", _filament_fr).c_str(), fp, _size, + Vec3f(_width - _offset + _div_semiwidth, 0., 0.), _bg); + const double _basedepth = mesh.bounding_box().size().y() + 7.; // ruler's base depth + const double _delta_y = _baseline + _basedepth; // y displacement + mesh.translate(Vec3f(0., -_delta_y + _offset + _div_semiwidth, 0.)); + test_model->add_volume(mesh); + + double _phi = (params.end - params.start) * 10 / calib_scale[params.test_model]; + double _ksi; + for (_ksi = 1; _ksi < 6; _ksi++) { // Get a nice fractional value + float _teta = _phi * _ksi; + if (abs(_teta - round(_teta)) < 0.001) + break; + } + if (_ksi > 5) + _ksi = 1; + else + _phi *= _ksi; + + fp.align = FontProp::Align(FontProp::HorizontalAlign::left, FontProp::VerticalAlign::bottom); // correct the text position + mesh = get_text_mesh(format("%.0fcm=%.2f%%=%.4f", _ksi, _phi, _phi * 0.01).c_str(), fp, _size, + Vec3f(0., -_delta_y + _offset + _div_semiwidth, 0.), _bg); // ruler's notification + const double _rule_xmin = mesh.bounding_box().min.x(); + + mesh.translate(Vec3f(-_rule_xmin - _div_semiwidth, 0., 0.)); + test_model->add_volume(mesh); + test_model->add_volume(get_ortho_box_mesh(Vec3d(_width + _div_width, _div_width, _body_height), + Vec3f(-_div_semiwidth, -_delta_y, 0.))); // ruler's bottom line + + for (double _i = 0; _i <= _width; _i += 2.5) { + double _l = -1.; + if (_i == 0. || _i == _width) + _l = -_basedepth; + else if (!fmod(_i, 50)) + _l = -5.; + else if (!fmod(_i, 10)) + _l = -3.; + else if (!fmod(_i, 5)) + _l = -2.; + test_model->add_volume(get_ortho_box_mesh(Vec3d(_div_width, _l, _body_height), + Vec3f(_i - _div_semiwidth, -_baseline, 0.))); // ruler's dividers + } + + test_model->add_volume(get_ortho_box_mesh(Vec3d(_ksi * 10, -_div_width * 2, _body_height), + Vec3f(0., -_baseline - 5., 0.))); // ruler's scale + if (params.end > _real_fr && params.start < _real_fr) + test_model->add_volume(get_ortho_triangle_mesh(Vec3d(4., _div_width, _body_height), + Vec3f(_width / (params.end - params.start) * (_real_fr - params.start), -_baseline, 0.), 90)); // ruler's real flow pointer + } // end of print ruler + + if (params.print_numbers) { // Print scale + const double _baseline = nozzle_diameter * 5 + _depth; // baseline offset + test_model->add_volume(get_ortho_box_mesh(Vec3d(_width + _div_width, -nozzle_diameter * 4, _body_height), + Vec3f(-_div_semiwidth, _baseline, 0.))); // scale body + fp.align = FontProp::Align(FontProp::HorizontalAlign::left, FontProp::VerticalAlign::top); // correct the text position + TriangleMesh mesh = get_text_mesh(format("%.3f", params.start).c_str(), fp, _size, + Vec3f(_offset - _div_semiwidth, 0., 0.), _bg); // start scale value + const double _basedepth = mesh.bounding_box().size().y() * 2. + 5.; // ruler's base depth + const double _delta_y = _baseline + _basedepth; // y displacement + mesh.translate(Vec3f(0., _delta_y + _offset - _div_semiwidth, 0.)); + test_model->add_volume(mesh); + + fp.align = FontProp::Align(FontProp::HorizontalAlign::right, FontProp::VerticalAlign::top); // correct the text position + test_model->add_volume(get_text_mesh(format("%.3f", params.end).c_str(), fp, _size, + Vec3f(_width - _offset + _div_semiwidth, _delta_y + _offset - _div_semiwidth, 0.), _bg)); // start scale value + test_model->add_volume(get_ortho_box_mesh(Vec3d(_width + _div_width, _div_width, _body_height), + Vec3f(-_div_semiwidth, _delta_y, 0.))); // scale upper line + test_model->add_volume(get_ortho_box_mesh(Vec3d(_div_width, _basedepth, _body_height), + Vec3f(-_div_semiwidth, _baseline, 0.))); // start scale divider + test_model->add_volume(get_ortho_box_mesh(Vec3d(_div_width, _basedepth, _body_height), + Vec3f(_width - _div_semiwidth, _baseline, 0.))); // end scale divider + + fp.align = FontProp::Align(FontProp::HorizontalAlign::center, FontProp::VerticalAlign::bottom); // correct the text position + int _istart = params.start * 1000; + int _iend = params.end * 1000; + for (int _i = floor(params.start) * 1000; _i < _iend; _i++) { + if (_i > _istart) { + double _l = 0; + if (!(_i % 50)) + _l = 5; + else if (!(_i % 25)) + _l = 3; + else if (!(_i % 10)) + _l = 2; + else if (!(_i % 5)) + _l = 1; + if (_l) { + double _idbl = 0.001 * _i; + double _delta_x = _width / (params.end - params.start) * (_idbl - params.start) - _div_semiwidth; + test_model->add_volume( + get_ortho_box_mesh(Vec3d(_div_width, _l, _body_height), + Vec3f(_delta_x, _baseline, 0.))); // scale dividers + if (_l > 3) + test_model->add_volume(get_text_mesh(format("%.2f", _idbl).c_str(), fp, _size, + Vec3f(_delta_x + _div_semiwidth, _baseline + 5., 0.), + _bg)); // divider scale value + } + } + } + if (params.end > _real_fr && params.start < _real_fr) + test_model->add_volume(get_ortho_triangle_mesh(Vec3d(4., _div_width, _body_height), + Vec3f(_width / (params.end - params.start) * (_real_fr - params.start), _baseline, 0.), -90)); // scale real flow pointer + + } // end of print scale + + wxGetApp().plater()->canvas3D()->reload_scene(true); + + // adjust parameters + print_config->set_key_value("wall_loops", new ConfigOptionInt(1)); + print_config->set_key_value("internal_bridge_density", new ConfigOptionPercent(100)); + print_config->set_key_value("thick_internal_bridges", new ConfigOptionBool(false)); + print_config->set_key_value("enable_extra_bridge_layer", new ConfigOptionEnum(eblDisabled)); + print_config->set_key_value("min_width_top_surface", new ConfigOptionFloatOrPercent(100, true)); + print_config->set_key_value("only_one_wall_top", new ConfigOptionBool(true)); + print_config->set_key_value("print_flow_ratio", new ConfigOptionFloat(1.0f)); + print_config->set_key_value("top_shell_layers", new ConfigOptionInt(1)); + print_config->set_key_value("top_surface_pattern", new ConfigOptionEnum(ipMonotonicLine)); + print_config->set_key_value("top_solid_infill_flow_ratio", new ConfigOptionFloat(1.0f)); + print_config->set_key_value("top_shell_thickness", new ConfigOptionFloat(0)); + print_config->set_key_value("top_surface_density", new ConfigOptionPercent(100)); + print_config->set_key_value("bottom_shell_layers", new ConfigOptionInt(2)); + print_config->set_key_value("bottom_surface_pattern", new ConfigOptionEnum(ipMonotonic)); + print_config->set_key_value("bottom_shell_thickness", new ConfigOptionFloat(0)); + print_config->set_key_value("bottom_surface_density", new ConfigOptionPercent(100)); + print_config->set_key_value("sparse_infill_pattern", new ConfigOptionEnum(ipMonotonicLine)); + print_config->set_key_value("sparse_infill_density", new ConfigOptionPercent(100)); + print_config->set_key_value("solid_infill_direction", new ConfigOptionFloat(0)); + print_config->set_key_value("solid_infill_rotate_template", new ConfigOptionString("45, 0, 90, 0, 90#100")); + print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(true)); + print_config->set_key_value("filter_out_gap_fill", new ConfigOptionFloat(0)); + print_config->set_key_value("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(nozzle_diameter, false)); + print_config->set_key_value("infill_direction", new ConfigOptionFloat(0)); + print_config->set_key_value("internal_solid_infill_pattern", new ConfigOptionEnum(ipMonotonicLine)); + print_config->set_key_value("infill_combination", new ConfigOptionBool(false)); + print_config->set_key_value("align_infill_direction_to_model", new ConfigOptionBool(true)); + print_config->set_key_value("precise_outer_wall", new ConfigOptionBool(false)); + print_config->set_key_value("precise_z_height", new ConfigOptionBool(false)); + print_config->set_key_value("alternate_extra_wall", new ConfigOptionBool(false)); + print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(false)); + print_config->set_key_value("ironing_type", new ConfigOptionEnum(IroningType::NoIroning)); + print_config->set_key_value("top_surface_speed", new ConfigOptionFloat(params.speeds[0])); // internal_solid_speed + print_config->set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(params.speeds[0])); // internal_solid_speed + //print_config->set_key_value("initial_layer_infill_speed", new ConfigOptionFloat(20)); + print_config->set_key_value("seam_slope_type", new ConfigOptionEnum(SeamScarfType::None)); + print_config->set_key_value("gap_fill_target", new ConfigOptionEnum(GapFillTarget::gftNowhere)); + print_config->set_key_value("fuzzy_skin", new ConfigOptionEnum(FuzzySkinType::None)); + print_config->set_key_value("wall_generator", new ConfigOptionEnum(PerimeterGeneratorType::Arachne)); + print_config->set_key_value("wall_sequence", new ConfigOptionEnum(WallSequence::InnerOuter)); + + print_config->set_key_value("line_width", new ConfigOptionFloatOrPercent(nozzle_diameter, false)); + print_config->set_key_value("initial_layer_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + print_config->set_key_value("outer_wall_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + print_config->set_key_value("inner_wall_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + print_config->set_key_value("top_surface_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + print_config->set_key_value("sparse_infill_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + print_config->set_key_value("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + print_config->set_key_value("support_line_width", new ConfigOptionFloatOrPercent(0.0f, false)); + + print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0)); + print_config->set_key_value("layer_height", new ConfigOptionFloat(layer_height)); + print_config->set_key_value("initial_layer_print_height", new ConfigOptionFloat(first_layer_height)); + print_config->set_key_value("alternate_extra_wall", new ConfigOptionBool(false)); + print_config->set_key_value("reduce_crossing_wall", new ConfigOptionBool(true)); + + printer_config->set_key_value("retract_lift_enforce", new ConfigOptionEnumsGeneric{params.use_zhop ? RetractLiftEnforceType::rletTopAndBottom : RetractLiftEnforceType::rletBottomOnly}); + printer_config->set_key_value("z_hop", new ConfigOptionFloats{params.use_zhop ? 0.4f : 0.0f}); + printer_config->set_key_value("z_hop_types", new ConfigOptionEnumsGeneric{ZHopType::zhtNormal}); + printer_config->set_key_value("retraction_minimum_travel", new ConfigOptionFloats{5.0f}); + printer_config->set_key_value("retract_lift_above", new ConfigOptionFloats{0.f}); //_model_height - first_layer_height + printer_config->set_key_value("retract_lift_below", new ConfigOptionFloats{100.f}); //layer_height + printer_config->set_key_value("travel_slope", new ConfigOptionFloats{45.0f}); + printer_config->set_key_value("wipe_distance", new ConfigOptionFloats{0.0f}); + + filament_config->set_key_value("filament_z_hop", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); + filament_config->set_key_value("filament_wipe_distance", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); + filament_config->set_key_value("filament_retract_lift_enforce", new ConfigOptionEnumsGenericNullable{ConfigOptionEnumsGenericNullable::nil_value()}); + filament_config->set_key_value("filament_z_hop_types", new ConfigOptionEnumsGenericNullable{ConfigOptionEnumsGenericNullable::nil_value()}); + filament_config->set_key_value("filament_retraction_minimum_travel", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); + filament_config->set_key_value("filament_retract_lift_above", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); + filament_config->set_key_value("filament_retract_lift_below", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); + //filament_config->set_key_value("filament_travel_slope", new ConfigOptionFloatsNullable{ConfigOptionFloatsNullable::nil_value()}); + + wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty(); + wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty(); + wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); + wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config(); + wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config(); + wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config(); +} + // Adjust settings for flowrate calibration // For linear mode, pass 1 means normal version while pass 2 mean "for perfectionists" version void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, int pass) @@ -12483,7 +12814,6 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i _obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum(SeamScarfType::None)); _obj->config.set_key_value("gap_fill_target", new ConfigOptionEnum(GapFillTarget::gftNowhere)); print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0)); - _obj->config.set_key_value("calib_flowrate_topinfill_special_order", new ConfigOptionBool(true)); // extract flowrate from name, filename format: flowrate_xxx std::string obj_name = _obj->name; @@ -12554,7 +12884,9 @@ void Plater::calib_flowrate(bool is_linear, int pass) { add_model(false, (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "flowrate-test-pass2.3mf").string()); } - + Calib_Params params; + params.mode = CalibMode::Calib_Flow_Rate; + model().calib_params = params; adjust_settings_for_flowrate_calib(model().objects, is_linear, pass); wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config(); auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 5f70657e5f..cbc6a9fffc 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -331,6 +331,7 @@ public: // SoftFever void calib_pa(const Calib_Params& params); void calib_flowrate(bool is_linear, int pass); + void Calib_Practical_Flow_Ratio(const Calib_Params& params); void calib_temp(const Calib_Params& params); void calib_max_vol_speed(const Calib_Params& params); void calib_retraction(const Calib_Params& params); diff --git a/src/slic3r/GUI/calib_dlg.cpp b/src/slic3r/GUI/calib_dlg.cpp index 24eb46b4a5..b744ed158b 100644 --- a/src/slic3r/GUI/calib_dlg.cpp +++ b/src/slic3r/GUI/calib_dlg.cpp @@ -1424,4 +1424,246 @@ void Cornering_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) { Fit(); } +// Practical_Flow_Ratio_Test_Dlg + +Practical_Flow_Ratio_Test_Dlg::Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater) + : DPIDialog(parent, id, _L("Prectical flow ratio calibration test"), wxDefaultPosition, parent->FromDIP(wxSize(-1, 280)), wxDEFAULT_DIALOG_STYLE) + , m_plater(plater) +{ + SetBackgroundColour(*wxWHITE); // make sure background color set for dialog + SetForegroundColour(wxColour("#363636")); + SetFont(Label::Body_14); + + Bind(wxEVT_SHOW, &Practical_Flow_Ratio_Test_Dlg::on_show, this); + + wxBoxSizer* v_sizer = new wxBoxSizer(wxVERTICAL); + SetSizer(v_sizer); + + // Settings + auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config; + auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; + auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; + + wxString current_fr_str = _L("Current filament flowrate:"); + wxString start_fr_str = _L("Start flowrate value at:"); + wxString end_fr_str = _L("End flowrate value at:"); + wxString quant_fr_str = _L("Number of calibration layers (4~40):"); + wxString speed_fr_str = _L("Print speed:"); + wxString interlaced_fr_str = _L("Interlaced:"); + wxString zhop_fr_str = _L("Use Z-Hop at top surface:"); + wxString scale_fr_str = _L("Print Scale:"); + wxString ruler_fr_str = _L("Print Ruler:"); + int text_max = GetTextMax(this, std::vector{current_fr_str, start_fr_str, end_fr_str, quant_fr_str, speed_fr_str, + interlaced_fr_str, zhop_fr_str, scale_fr_str, ruler_fr_str}); + + // Model selection + auto labeled_box_model = new LabeledStaticBox(this, _L("Model width")); + auto model_box = new wxStaticBoxSizer(labeled_box_model, wxHORIZONTAL); + m_rbModel = new RadioGroup(this, {"100 mm", "150 mm", "200 mm"}, wxHORIZONTAL); + for (auto &_el : m_rbModel->GetChildren()) // sets the note of range unit converting into flow ratio + _el->Bind(wxEVT_MOTION, &Practical_Flow_Ratio_Test_Dlg::on_changed2, this); + model_box->Add(m_rbModel, 0, wxALL | wxEXPAND, FromDIP(4)); + v_sizer->Add(model_box, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); + + labeled_box_model = new LabeledStaticBox(this, _L("Model depth")); + model_box = new wxStaticBoxSizer(labeled_box_model, wxHORIZONTAL); + m_rbModelDepth = new RadioGroup(this, {"10 mm", "15 mm", "20 mm"}, wxHORIZONTAL); + model_box->Add(m_rbModelDepth, 0, wxALL | wxEXPAND, FromDIP(4)); + v_sizer->Add(model_box, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); + + auto st_size = FromDIP(wxSize(text_max, -1)); + auto ti_size = FromDIP(wxSize(120, -1)); + + wxBoxSizer* fr_sizer = new wxBoxSizer(wxHORIZONTAL); + LabeledStaticBox* ctb = new LabeledStaticBox(this, _L("Print conditions")); + wxStaticBoxSizer* conditions_sizer = new wxStaticBoxSizer(ctb, wxVERTICAL); + + // Start flow rate value + auto start_fr_text = new wxStaticText(this, wxID_ANY, start_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiJDStart = new TextInput(this, wxString::Format("%.2f", 0.9), "", "", wxDefaultPosition, ti_size); + m_tiJDStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + m_tiJDStart->Bind(wxEVT_TEXT, &Practical_Flow_Ratio_Test_Dlg::on_changed, this); + fr_sizer->Add(start_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + fr_sizer->Add(m_tiJDStart, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + conditions_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); + + // End flow rate value + fr_sizer = new wxBoxSizer(wxHORIZONTAL); + auto end_fr_text = new wxStaticText(this, wxID_ANY, end_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiJDEnd = new TextInput(this, wxString::Format("%.2f", 1.1), "", "", wxDefaultPosition, ti_size); + m_tiJDEnd->Bind(wxEVT_TEXT, &Practical_Flow_Ratio_Test_Dlg::on_changed, this); + m_tiJDEnd->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + fr_sizer->Add(end_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + fr_sizer->Add(m_tiJDEnd, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + conditions_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); + + // Add note about junction deviation + m_stNote = new wxStaticText(this, wxID_ANY, "\n\n", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + m_stNote->SetForegroundColour(wxColour(128, 128, 128)); + m_stNote->SetLabel(get_status()); + conditions_sizer->Add(m_stNote, 0, wxEXPAND, FromDIP(5)); + conditions_sizer->AddSpacer(FromDIP(5)); + + // Print speed value m_tiQuantity + fr_sizer = new wxBoxSizer(wxHORIZONTAL); + auto quant_fr_text = new wxStaticText(this, wxID_ANY, quant_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiQuantity = new TextInput(this, wxString::Format("%.0f", 10.0f), "", "", wxDefaultPosition, ti_size); + m_tiQuantity->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + fr_sizer->Add(quant_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + fr_sizer->Add(m_tiQuantity, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + conditions_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); + + fr_sizer = new wxBoxSizer(wxHORIZONTAL); + float _speed = 60; + auto speed_fr_text = new wxStaticText(this, wxID_ANY, speed_fr_str, wxDefaultPosition, st_size, wxALIGN_LEFT); + m_tiSpeed = new TextInput(this, wxString::Format("%.0f", _speed), "", "", wxDefaultPosition, ti_size); + m_tiSpeed->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + m_tiSpeed->SetLabel("mm/s"); + fr_sizer->Add(speed_fr_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + fr_sizer->Add(m_tiSpeed, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + conditions_sizer->Add(fr_sizer, 0, wxLEFT, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); + + // Print settings + wxBoxSizer* cb_sizer = new wxBoxSizer(wxHORIZONTAL); + auto cb_title = new wxStaticText(this, wxID_ANY, interlaced_fr_str, wxDefaultPosition, st_size, 0); + m_cbInterlaced = new CheckBox(this); + m_cbInterlaced->SetValue(false); + cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + cb_sizer->Add(m_cbInterlaced, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + conditions_sizer->Add(cb_sizer, 0, wxLEFT | wxTOP | wxBOTTOM, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); + + cb_title = new wxStaticText(this, wxID_ANY, zhop_fr_str, wxDefaultPosition, st_size, 0); + m_cbUseZHop = new CheckBox(this); + m_cbUseZHop->SetValue(false); + cb_sizer = new wxBoxSizer(wxHORIZONTAL); + cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + cb_sizer->Add(m_cbUseZHop, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + conditions_sizer->Add(cb_sizer, 0, wxLEFT | wxTOP | wxBOTTOM, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); + + cb_title = new wxStaticText(this, wxID_ANY, scale_fr_str, wxDefaultPosition, st_size, 0); + m_cbPrintScale = new CheckBox(this); + m_cbPrintScale->SetValue(false); + cb_sizer = new wxBoxSizer(wxHORIZONTAL); + cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + cb_sizer->Add(m_cbPrintScale, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + conditions_sizer->Add(cb_sizer, 0, wxLEFT | wxTOP | wxBOTTOM, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); + + cb_title = new wxStaticText(this, wxID_ANY, ruler_fr_str, wxDefaultPosition, st_size, 0); + m_cbPrintRuler = new CheckBox(this); + m_cbPrintRuler->SetValue(false); + cb_sizer = new wxBoxSizer(wxHORIZONTAL); + cb_sizer->Add(cb_title, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + cb_sizer->Add(m_cbPrintRuler, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + conditions_sizer->Add(cb_sizer, 0, wxLEFT | wxTOP | wxBOTTOM, FromDIP(3)); + conditions_sizer->AddSpacer(FromDIP(5)); + + v_sizer->Add(conditions_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); + v_sizer->AddSpacer(FromDIP(5)); + + auto dlg_btns = new DialogButtons(this, {"OK"}); + v_sizer->Add(dlg_btns, 0, wxEXPAND); + + dlg_btns->GetOK()->Bind(wxEVT_BUTTON, &Practical_Flow_Ratio_Test_Dlg::on_start, this); + + wxGetApp().UpdateDlgDarkUI(this); + Layout(); + Fit(); +} + +Practical_Flow_Ratio_Test_Dlg::~Practical_Flow_Ratio_Test_Dlg() { + // Disconnect Events +} + +wxString Practical_Flow_Ratio_Test_Dlg::get_status() { + auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config; + wxString addtext = "\n" + wxString::Format("%s %s filament: fr=%.3f", + filament_config->get_filament_vendor(), + filament_config->get_filament_type(), + filament_config->option("filament_flow_ratio")->get_at(0) + ).Trim(); + bool read_double = false; + read_double = m_tiJDStart->GetTextCtrl()->GetValue().ToDouble(&m_params.start); + read_double = read_double && m_tiJDEnd->GetTextCtrl()->GetValue().ToDouble(&m_params.end); + if (m_params.end < m_params.start) + std::swap(m_params.end, m_params.start); + if (!read_double || m_params.start >= 0.5 && m_params.end <= 1.5) { + float const calib_scale[3] = {1.0f, 1.5f, 2.0f}; + float _phi = (m_params.end - m_params.start) * 10 / calib_scale[m_rbModel->GetSelection()]; + float _ksi; + for (_ksi = 1; _ksi < 6; _ksi++) { // Get a nice fractional value + float _teta = _phi * _ksi; + if (abs(_teta - round(_teta)) < 0.001) + break; + } + if (_ksi > 5) + _ksi = 1; + else + _phi *= _ksi; + return wxString::Format(_L("Current meas: %.0fcm = %.2f%% or %.4f"), _ksi, _phi, _phi * 0.01) + addtext; + } else { + return _L("The value is out of range 0.5~1.5!"); + } +} + +void Practical_Flow_Ratio_Test_Dlg::on_start(wxCommandEvent& event) { + bool read_double = false; + read_double = m_tiJDStart->GetTextCtrl()->GetValue().ToDouble(&m_params.start); + read_double = read_double && m_tiJDEnd->GetTextCtrl()->GetValue().ToDouble(&m_params.end); + + if (!read_double || m_params.start < 0.5 || m_params.start > 1.5 || m_params.end < 0.5 || m_params.end > 1.5) { + MessageDialog msg_dlg(nullptr, _L("Please input valid values:\n(0.5 <= Flow Ratio <= 1.5)"), wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return; + } else if (!m_tiQuantity->GetTextCtrl()->GetValue().ToDouble(&m_params.step) || m_params.step < 4 || m_params.step > 40) { + MessageDialog msg_dlg(nullptr, _L("Please input valid layer value:\n(4 <= Number of Calibration Layers <= 40)"), wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return; + } else if (m_params.end < m_params.start) { + std::swap(m_params.end, m_params.start); + MessageDialog msg_dlg(nullptr, _L("NOTE: Parameters has swapped!"), wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + } + + m_params.mode = CalibMode::Calib_Practical_Flow_Ratio; + + // Set model type based on selection + m_params.test_model = m_rbModel->GetSelection(); + m_params.model_variant = m_rbModelDepth->GetSelection(); + m_params.interlaced = m_cbInterlaced->GetValue(); + m_params.use_zhop = m_cbUseZHop->GetValue(); + m_params.print_numbers = m_cbPrintScale->GetValue(); + m_params.print_ruler = m_cbPrintRuler->GetValue(); + double _speed; + m_tiSpeed->GetTextCtrl()->GetValue().ToDouble(&_speed); + m_params.speeds.clear(); + m_params.speeds.push_back(_speed); + m_plater->Calib_Practical_Flow_Ratio(m_params); + EndModal(wxID_OK); +} + +void Practical_Flow_Ratio_Test_Dlg::on_changed(wxCommandEvent& event) { + m_stNote->SetLabel(get_status()); + event.Skip(); +} + +void Practical_Flow_Ratio_Test_Dlg::on_changed2(wxMouseEvent& event) { + m_stNote->SetLabel(get_status()); + event.Skip(); +} + +void Practical_Flow_Ratio_Test_Dlg::on_dpi_changed(const wxRect& suggested_rect) { + this->Refresh(); + Fit(); +} + +void Practical_Flow_Ratio_Test_Dlg::on_show(wxShowEvent& event) { + m_stNote->SetLabel(get_status()); +} + }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/calib_dlg.hpp b/src/slic3r/GUI/calib_dlg.hpp index 759cde1d0d..59083205fa 100644 --- a/src/slic3r/GUI/calib_dlg.hpp +++ b/src/slic3r/GUI/calib_dlg.hpp @@ -180,5 +180,34 @@ protected: TextInput* m_tiJDEnd; Plater* m_plater; }; + +class Practical_Flow_Ratio_Test_Dlg : public DPIDialog +{ +public: + Practical_Flow_Ratio_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater); + ~Practical_Flow_Ratio_Test_Dlg(); + void on_dpi_changed(const wxRect& suggested_rect) override; + wxString get_status(); + +protected: + virtual void on_start(wxCommandEvent& event); + virtual void on_changed(wxCommandEvent& event); + virtual void on_changed2(wxMouseEvent& event); + virtual void on_show(wxShowEvent& event); + Calib_Params m_params; + + RadioGroup* m_rbModel; + RadioGroup* m_rbModelDepth; + TextInput* m_tiJDStart; + TextInput* m_tiJDEnd; + wxStaticText* m_stNote; + TextInput* m_tiSpeed; + TextInput* m_tiQuantity; + CheckBox* m_cbInterlaced; + CheckBox* m_cbUseZHop; + CheckBox* m_cbPrintScale; + CheckBox* m_cbPrintRuler; + Plater* m_plater; +}; }} // namespace Slic3r::GUI #endif