mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-05-17 16:56:48 +08:00
BedShape is extracted to the separate structure
This commit is contained in:
parent
4641d44544
commit
15285a68a0
@ -59,6 +59,81 @@ void BedShapeDialog::on_dpi_changed(const wxRect &suggested_rect)
|
|||||||
const std::string BedShapePanel::NONE = "None";
|
const std::string BedShapePanel::NONE = "None";
|
||||||
const std::string BedShapePanel::EMPTY_STRING = "";
|
const std::string BedShapePanel::EMPTY_STRING = "";
|
||||||
|
|
||||||
|
static std::string get_option_label(BedShape::Parameter param)
|
||||||
|
{
|
||||||
|
switch (param) {
|
||||||
|
case BedShape::Parameter::RectSize : return L("Size");
|
||||||
|
case BedShape::Parameter::RectOrigin: return L("Origin");
|
||||||
|
case BedShape::Parameter::Diameter : return L("Diameter");
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BedShape::append_option_line(ConfigOptionsGroupShp optgroup, Parameter param)
|
||||||
|
{
|
||||||
|
ConfigOptionDef def;
|
||||||
|
|
||||||
|
if (param == Parameter::RectSize) {
|
||||||
|
def.type = coPoints;
|
||||||
|
def.set_default_value(new ConfigOptionPoints{ Vec2d(200, 200) });
|
||||||
|
def.min = 0;
|
||||||
|
def.max = 1200;
|
||||||
|
def.label = get_option_label(param);
|
||||||
|
def.tooltip = L("Size in X and Y of the rectangular plate.");
|
||||||
|
|
||||||
|
Option option(def, "rect_size");
|
||||||
|
optgroup->append_single_option_line(option);
|
||||||
|
}
|
||||||
|
else if (param == Parameter::RectOrigin) {
|
||||||
|
def.type = coPoints;
|
||||||
|
def.set_default_value(new ConfigOptionPoints{ Vec2d(0, 0) });
|
||||||
|
def.min = -600;
|
||||||
|
def.max = 600;
|
||||||
|
def.label = get_option_label(param);
|
||||||
|
def.tooltip = L("Distance of the 0,0 G-code coordinate from the front left corner of the rectangle.");
|
||||||
|
|
||||||
|
Option option(def, "rect_origin");
|
||||||
|
optgroup->append_single_option_line(option);
|
||||||
|
}
|
||||||
|
else if (param == Parameter::Diameter) {
|
||||||
|
def.type = coFloat;
|
||||||
|
def.set_default_value(new ConfigOptionFloat(200));
|
||||||
|
def.sidetext = L("mm");
|
||||||
|
def.label = get_option_label(param);
|
||||||
|
def.tooltip = L("Diameter of the print bed. It is assumed that origin (0,0) is located in the center.");
|
||||||
|
|
||||||
|
Option option(def, "diameter");
|
||||||
|
optgroup->append_single_option_line(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString BedShape::get_name(Type type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case Type::Rectangular : return _L("Rectangular");
|
||||||
|
case Type::Circular : return _L("Circular");
|
||||||
|
case Type::Custom : return _L("Custom");
|
||||||
|
case Type::Invalid :
|
||||||
|
default : return _L("Invalid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString BedShape::get_full_name_with_params()
|
||||||
|
{
|
||||||
|
wxString out = _L("Shape") + ": " + get_name(type);
|
||||||
|
|
||||||
|
if (type == Type::Rectangular) {
|
||||||
|
out += "\n" + get_option_label(Parameter::RectSize) + +": [" + ConfigOptionPoint(rectSize).serialize() + "]";
|
||||||
|
out += "\n" + get_option_label(Parameter::RectOrigin) + +": [" + ConfigOptionPoint(rectOrigin).serialize() + "]";
|
||||||
|
}
|
||||||
|
else if (type == Type::Circular)
|
||||||
|
out += "\n" + get_option_label(Parameter::Diameter) + +": [" + double_to_string(diameter) + "]";
|
||||||
|
else if (type == Type::Custom)
|
||||||
|
out += "\n" + double_to_string(diameter);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model)
|
void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model)
|
||||||
{
|
{
|
||||||
m_shape = default_pt.values;
|
m_shape = default_pt.values;
|
||||||
@ -72,7 +147,7 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf
|
|||||||
m_shape_options_book = new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxSize(25*wxGetApp().em_unit(), -1), wxCHB_TOP);
|
m_shape_options_book = new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxSize(25*wxGetApp().em_unit(), -1), wxCHB_TOP);
|
||||||
sbsizer->Add(m_shape_options_book);
|
sbsizer->Add(m_shape_options_book);
|
||||||
|
|
||||||
auto optgroup = init_shape_options_page(_(L("Rectangular")));
|
/* auto optgroup = init_shape_options_page(_(L("Rectangular")));
|
||||||
ConfigOptionDef def;
|
ConfigOptionDef def;
|
||||||
def.type = coPoints;
|
def.type = coPoints;
|
||||||
def.set_default_value(new ConfigOptionPoints{ Vec2d(200, 200) });
|
def.set_default_value(new ConfigOptionPoints{ Vec2d(200, 200) });
|
||||||
@ -100,22 +175,31 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf
|
|||||||
def.tooltip = L("Diameter of the print bed. It is assumed that origin (0,0) is located in the center.");
|
def.tooltip = L("Diameter of the print bed. It is assumed that origin (0,0) is located in the center.");
|
||||||
option = Option(def, "diameter");
|
option = Option(def, "diameter");
|
||||||
optgroup->append_single_option_line(option);
|
optgroup->append_single_option_line(option);
|
||||||
|
*/
|
||||||
|
|
||||||
|
auto optgroup = init_shape_options_page(BedShape::get_name(BedShape::Type::Rectangular));
|
||||||
|
BedShape::append_option_line(optgroup, BedShape::Parameter::RectSize);
|
||||||
|
BedShape::append_option_line(optgroup, BedShape::Parameter::RectOrigin);
|
||||||
|
|
||||||
|
optgroup = init_shape_options_page(BedShape::get_name(BedShape::Type::Circular));
|
||||||
|
BedShape::append_option_line(optgroup, BedShape::Parameter::Diameter);
|
||||||
|
|
||||||
|
// optgroup = init_shape_options_page(_(L("Custom")));
|
||||||
|
optgroup = init_shape_options_page(BedShape::get_name(BedShape::Type::Custom));
|
||||||
|
|
||||||
optgroup = init_shape_options_page(_(L("Custom")));
|
|
||||||
Line line{ "", "" };
|
Line line{ "", "" };
|
||||||
line.full_width = 1;
|
line.full_width = 1;
|
||||||
line.widget = [this](wxWindow* parent) {
|
line.widget = [this](wxWindow* parent) {
|
||||||
wxButton* shape_btn = new wxButton(parent, wxID_ANY, _(L("Load shape from STL...")));
|
wxButton* shape_btn = new wxButton(parent, wxID_ANY, _L("Load shape from STL..."));
|
||||||
wxSizer* shape_sizer = new wxBoxSizer(wxHORIZONTAL);
|
wxSizer* shape_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
shape_sizer->Add(shape_btn, 1, wxEXPAND);
|
shape_sizer->Add(shape_btn, 1, wxEXPAND);
|
||||||
|
|
||||||
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
sizer->Add(shape_sizer, 1, wxEXPAND);
|
sizer->Add(shape_sizer, 1, wxEXPAND);
|
||||||
|
|
||||||
shape_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e)
|
shape_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
|
||||||
{
|
|
||||||
load_stl();
|
load_stl();
|
||||||
}));
|
});
|
||||||
|
|
||||||
return sizer;
|
return sizer;
|
||||||
};
|
};
|
||||||
@ -494,8 +578,8 @@ void BedShapePanel::load_stl()
|
|||||||
if (dialog.ShowModal() != wxID_OK)
|
if (dialog.ShowModal() != wxID_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string file_name = dialog.GetPath().ToUTF8().data();
|
m_custom_shape = dialog.GetPath().ToUTF8().data();
|
||||||
if (!boost::algorithm::iends_with(file_name, ".stl"))
|
if (!boost::algorithm::iends_with(m_custom_shape, ".stl"))
|
||||||
{
|
{
|
||||||
show_error(this, _(L("Invalid file format.")));
|
show_error(this, _(L("Invalid file format.")));
|
||||||
return;
|
return;
|
||||||
@ -505,7 +589,7 @@ void BedShapePanel::load_stl()
|
|||||||
|
|
||||||
Model model;
|
Model model;
|
||||||
try {
|
try {
|
||||||
model = Model::read_from_file(file_name);
|
model = Model::read_from_file(m_custom_shape);
|
||||||
}
|
}
|
||||||
catch (std::exception &) {
|
catch (std::exception &) {
|
||||||
show_error(this, _(L("Error! Invalid model")));
|
show_error(this, _(L("Error! Invalid model")));
|
||||||
|
@ -16,6 +16,101 @@ namespace GUI {
|
|||||||
class ConfigOptionsGroup;
|
class ConfigOptionsGroup;
|
||||||
|
|
||||||
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
|
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
|
||||||
|
|
||||||
|
struct BedShape {
|
||||||
|
|
||||||
|
enum class Type {
|
||||||
|
Rectangular = 0,
|
||||||
|
Circular,
|
||||||
|
Custom,
|
||||||
|
Invalid
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Parameter {
|
||||||
|
RectSize,
|
||||||
|
RectOrigin,
|
||||||
|
Diameter
|
||||||
|
};
|
||||||
|
|
||||||
|
BedShape(const ConfigOptionPoints& points) {
|
||||||
|
auto polygon = Polygon::new_scale(points.values);
|
||||||
|
|
||||||
|
// is this a rectangle ?
|
||||||
|
if (points.size() == 4) {
|
||||||
|
auto lines = polygon.lines();
|
||||||
|
if (lines[0].parallel_to(lines[2]) && lines[1].parallel_to(lines[3])) {
|
||||||
|
// okay, it's a rectangle
|
||||||
|
// find origin
|
||||||
|
coordf_t x_min, x_max, y_min, y_max;
|
||||||
|
x_max = x_min = points.values[0](0);
|
||||||
|
y_max = y_min = points.values[0](1);
|
||||||
|
for (auto pt : points.values)
|
||||||
|
{
|
||||||
|
x_min = std::min(x_min, pt(0));
|
||||||
|
x_max = std::max(x_max, pt(0));
|
||||||
|
y_min = std::min(y_min, pt(1));
|
||||||
|
y_max = std::max(y_max, pt(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
type = Type::Rectangular;
|
||||||
|
rectSize = Vec2d(x_max - x_min, y_max - y_min);
|
||||||
|
rectOrigin = Vec2d(-x_min, -y_min);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// is this a circle ?
|
||||||
|
{
|
||||||
|
// Analyze the array of points.Do they reside on a circle ?
|
||||||
|
auto center = polygon.bounding_box().center();
|
||||||
|
std::vector<double> vertex_distances;
|
||||||
|
double avg_dist = 0;
|
||||||
|
for (auto pt : polygon.points)
|
||||||
|
{
|
||||||
|
double distance = (pt - center).cast<double>().norm();
|
||||||
|
vertex_distances.push_back(distance);
|
||||||
|
avg_dist += distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
avg_dist /= vertex_distances.size();
|
||||||
|
bool defined_value = true;
|
||||||
|
for (auto el : vertex_distances)
|
||||||
|
{
|
||||||
|
if (abs(el - avg_dist) > 10 * SCALED_EPSILON)
|
||||||
|
defined_value = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (defined_value) {
|
||||||
|
// all vertices are equidistant to center
|
||||||
|
type = Type::Circular;
|
||||||
|
diameter = unscale<double>(avg_dist * 2);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (points.size() < 3) {
|
||||||
|
type = Type::Invalid;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a custom bed shape, use the polygon provided.
|
||||||
|
type = Type::Custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void append_option_line(ConfigOptionsGroupShp optgroup, Parameter param);
|
||||||
|
static wxString get_name(Type type);
|
||||||
|
|
||||||
|
wxString get_full_name_with_params();
|
||||||
|
|
||||||
|
Type type = Type::Invalid;
|
||||||
|
Vec2d rectSize;
|
||||||
|
Vec2d rectOrigin;
|
||||||
|
|
||||||
|
double diameter;
|
||||||
|
};
|
||||||
|
|
||||||
class BedShapePanel : public wxPanel
|
class BedShapePanel : public wxPanel
|
||||||
{
|
{
|
||||||
static const std::string NONE;
|
static const std::string NONE;
|
||||||
@ -24,6 +119,7 @@ class BedShapePanel : public wxPanel
|
|||||||
Bed_2D* m_canvas;
|
Bed_2D* m_canvas;
|
||||||
std::vector<Vec2d> m_shape;
|
std::vector<Vec2d> m_shape;
|
||||||
std::vector<Vec2d> m_loaded_shape;
|
std::vector<Vec2d> m_loaded_shape;
|
||||||
|
std::string m_custom_shape;
|
||||||
std::string m_custom_texture;
|
std::string m_custom_texture;
|
||||||
std::string m_custom_model;
|
std::string m_custom_model;
|
||||||
|
|
||||||
|
@ -732,16 +732,14 @@ static std::string get_pure_opt_key(std::string opt_key)
|
|||||||
|
|
||||||
static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& config)
|
static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& config)
|
||||||
{
|
{
|
||||||
int opt_idx = get_id_from_opt_key(opt_key);
|
|
||||||
opt_key = get_pure_opt_key(opt_key);
|
opt_key = get_pure_opt_key(opt_key);
|
||||||
|
|
||||||
if (config.option(opt_key)->is_nil())
|
if (config.option(opt_key)->is_nil())
|
||||||
return _L("N/A");
|
return _L("N/A");
|
||||||
|
|
||||||
|
int opt_idx = get_id_from_opt_key(opt_key);
|
||||||
wxString out;
|
wxString out;
|
||||||
|
|
||||||
// FIXME controll, if opt_key has index
|
|
||||||
|
|
||||||
const ConfigOptionDef* opt = config.def()->get(opt_key);
|
const ConfigOptionDef* opt = config.def()->get(opt_key);
|
||||||
bool is_nullable = opt->nullable;
|
bool is_nullable = opt->nullable;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user