This commit is contained in:
π² 2025-12-23 22:50:46 -03:00 committed by GitHub
commit beee680776
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 737 additions and 28 deletions

View file

@ -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<Emboss::ProjectZ>(dx_y_z_size.z());
Transform3d tr = Eigen::Translation<double, 3>() * Eigen::Scaling<double>(scale * width, scale, 1.);
return Emboss::polygons2model(shapes.expolygons, Emboss::ProjectTransform(std::move(pt), tr));
}
namespace {
/// <summary>
/// Align shape against pivot

View file

@ -155,6 +155,16 @@ namespace Emboss
HealedExPolygons text2shapes (FontFileWithCache &font, const char *text, const FontProp &font_prop, const std::function<bool()> &was_canceled = []() {return false;});
ExPolygonsWithIds text2vshapes(FontFileWithCache &font, const std::wstring& text, const FontProp &font_prop, const std::function<bool()>& was_canceled = []() {return false;});
/// <summary>
/// Convert text into triangle set
/// </summary>
/// <param name="font">Define fonts + cache, which could extend</param>
/// <param name="text">Characters to convert</param>
/// <param name="font_prop">User defined property of the font</param>
/// <param name="dx_y_z_size">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.</param>
/// <returns>Indexed triangle set</returns>
indexed_triangle_set text2model(FontFileWithCache& font, const char *text, const FontProp &font_prop, Vec3d dx_y_z_size);
const unsigned ENTER_UNICODE = static_cast<unsigned>('\n');
/// Sum of character '\n'
unsigned get_count_lines(const std::wstring &ws);

View file

@ -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<FillConcentricInternal *>(f.get());
assert(fill_concentric != nullptr);

View file

@ -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<ExtrusionPath*>(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<ExtrusionPath*> a, b;
int _i = 0;
for (ExtrusionEntity* e : eec->entities) {
ExtrusionPath* _p = static_cast<ExtrusionPath*>(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<ExtrusionPath*>(e);
_p->width *= 0.825;
_p->mm3_per_mm *= 0.825;
}
} else if (layer_id > 0) { // Prepare a smooth base
std::vector<ExtrusionPath*> a;
int _i = 1;
for (ExtrusionEntity* e : eec->entities) {
ExtrusionPath* _p = static_cast<ExtrusionPath*>(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);
}
}
}

View file

@ -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;

View file

@ -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<FillArchimedeanChords*>(this);
if (is_flow_calib) {
// We want the spiral part to be printed inside-out

View file

@ -91,6 +91,8 @@ Model& Model::assign_copy(const Model &rhs)
this->calib_pa_pattern = std::make_unique<CalibPressureAdvancePattern>(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;

View file

@ -1690,6 +1690,7 @@ public:
bool is_fuzzy_skin_painted() const;
std::unique_ptr<CalibPressureAdvancePattern> calib_pa_pattern;
Calib_Params calib_params;
private:
explicit Model(int) : ObjectBase(-1)

View file

@ -952,7 +952,7 @@ static std::vector<std::string> 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<std::string> s_Preset_filament_options {/*"filament_colour", */ "default_filament_colour", "required_nozzle_HRC", "filament_diameter", "pellet_flow_coefficient", "volumetric_speed_coefficients", "filament_type",

View file

@ -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");

View file

@ -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.

View file

@ -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<double> accelerations;
std::vector<double> speeds;

View file

@ -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

View file

@ -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.

View file

@ -38,6 +38,7 @@
#include <wx/busyinfo.h>
#include <wx/event.h>
#include <wx/wrapsizer.h>
#include <wx/font.h>
#ifdef _WIN32
#include <wx/richtooltip.h>
#include <wx/custombgwin.h>
@ -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)));
/// <summary>
/// Get the orthogonal box mesh (Experemental, can rethink and add)
/// </summary>
/// <param name="size">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.</param>
/// <param name="position">Position of model against text pivot.</param>
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;
}
/// <summary>
/// Get the triangle mesh (Experemental, can rethink and add)
/// </summary>
/// <param name="size">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.</param>
/// <param name="position">Position of model against its pivot.</param>
/// <param name="rotation">Rotation angle of model against its pivot.</param>
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;
}
/// <summary>
/// Get the text mesh (Experemental, can rethink and add)
/// </summary>
/// <param name="text">The text</param>
/// <param name="font_props">Font properties. Containe Horizontal and vertical alignment.</param>
/// <param name="size">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.</param>
/// <param name="position">Position of model against text pivot</param>
/// <param name="background">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.</param>
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<ConfigOptionFloats>("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<ConfigOptionFloat>("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<ConfigOptionPoints>("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<ConfigOptionFloatsNullable>("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<EnableExtraBridgeLayer>(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<InfillPattern>(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<InfillPattern>(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<InfillPattern>(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<InfillPattern>(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>(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>(SeamScarfType::None));
print_config->set_key_value("gap_fill_target", new ConfigOptionEnum<GapFillTarget>(GapFillTarget::gftNowhere));
print_config->set_key_value("fuzzy_skin", new ConfigOptionEnum<FuzzySkinType>(FuzzySkinType::None));
print_config->set_key_value("wall_generator", new ConfigOptionEnum<PerimeterGeneratorType>(PerimeterGeneratorType::Arachne));
print_config->set_key_value("wall_sequence", new ConfigOptionEnum<WallSequence>(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>(SeamScarfType::None));
_obj->config.set_key_value("gap_fill_target", new ConfigOptionEnum<GapFillTarget>(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;

View file

@ -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);

View file

@ -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<wxString>{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<ConfigOptionFloatsNullable>("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

View file

@ -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