mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-12-24 00:28:38 -07:00
Merge 5a464344d2 into 506fde8f86
This commit is contained in:
commit
beee680776
18 changed files with 737 additions and 28 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue