Ensure bed shape is in correct orientation (SoftFever/OrcaSlicer#9345)

This commit is contained in:
Noisyfox 2025-04-14 22:51:58 +08:00
parent 035b047fef
commit 228b50f858
15 changed files with 40 additions and 28 deletions

View file

@ -3081,7 +3081,7 @@ int CLI::run(int argc, char **argv)
else {
partplate_list.reset_size(old_printable_width, old_printable_depth, old_printable_height, false);
}
partplate_list.set_shapes(current_printable_area, current_exclude_area, bed_texture, height_to_lid, height_to_rod);
partplate_list.set_shapes(make_counter_clockwise(current_printable_area), current_exclude_area, bed_texture, height_to_lid, height_to_rod);
//plate_stride = partplate_list.plate_stride_x();
}

View file

@ -14,6 +14,7 @@ BuildVolume::BuildVolume(const std::vector<Vec2d> &printable_area, const double
assert(printable_height >= 0);
m_polygon = Polygon::new_scale(printable_area);
assert(m_polygon.is_counter_clockwise());
// Calcuate various metrics of the input polygon.
m_convex_hull = Geometry::convex_hull(m_polygon.points);

View file

@ -1410,4 +1410,14 @@ ExPolygons variable_offset_inner_ex(const ExPolygon &expoly, const std::vector<s
return output;
}
Pointfs make_counter_clockwise(const Pointfs& pointfs)
{
Pointfs ps = pointfs;
if (Polygon::new_scale(pointfs).is_clockwise()) {
std::reverse(ps.begin(), ps.end());
}
return ps;
}
}

View file

@ -661,6 +661,8 @@ Polygons variable_offset_outer(const ExPolygon &expoly, const std::vector<std::
ExPolygons variable_offset_outer_ex(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
ExPolygons variable_offset_inner_ex(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
Pointfs make_counter_clockwise(const Pointfs& pointfs);
} // namespace Slic3r
#endif // slic3r_ClipperUtils_hpp_

View file

@ -831,7 +831,7 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
const ConfigOptionPoints* printable_area = config.option<ConfigOptionPoints>("printable_area");
if (printable_area != nullptr)
m_result.printable_area = printable_area->values;
m_result.printable_area = make_counter_clockwise(printable_area->values);
//BBS: add bed_exclude_area
const ConfigOptionPoints* bed_exclude_area = config.option<ConfigOptionPoints>("bed_exclude_area");

View file

@ -8086,15 +8086,15 @@ Points get_bed_shape(const DynamicPrintConfig &config)
return {};
}
return to_points(bed_shape_opt->values);
return to_points(make_counter_clockwise(bed_shape_opt->values));
}
Points get_bed_shape(const PrintConfig &cfg)
{
return to_points(cfg.printable_area.values);
return to_points(make_counter_clockwise(cfg.printable_area.values));
}
Points get_bed_shape(const SLAPrinterConfig &cfg) { return to_points(cfg.printable_area.values); }
Points get_bed_shape(const SLAPrinterConfig &cfg) { return to_points(make_counter_clockwise(cfg.printable_area.values)); }
Polygon get_bed_shape_with_excluded_area(const PrintConfig& cfg)
{

View file

@ -432,7 +432,7 @@ std::tuple<Bed3D::Type, std::string, std::string> Bed3D::detect_type(const Point
while (curr != nullptr) {
if (curr->config.has("printable_area")) {
std::string texture_filename, model_filename;
if (shape == dynamic_cast<const ConfigOptionPoints*>(curr->config.option("printable_area"))->values) {
if (shape == make_counter_clockwise(dynamic_cast<const ConfigOptionPoints*>(curr->config.option("printable_area"))->values)) {
if (curr->is_system)
model_filename = PresetUtils::system_printer_bed_model(*curr);
else {

View file

@ -20,9 +20,9 @@
namespace Slic3r {
namespace GUI {
BedShape::BedShape(const ConfigOptionPoints& points)
BedShape::BedShape(const Pointfs& points)
{
m_build_volume = { points.values, 0. };
m_build_volume = { points, 0. };
}
static std::string get_option_label(BedShape::Parameter param)
@ -130,7 +130,7 @@ void BedShape::apply_optgroup_values(ConfigOptionsGroupShp optgroup)
}
}
void BedShapeDialog::build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model)
void BedShapeDialog::build_dialog(const Pointfs& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model)
{
SetFont(wxGetApp().normal_font());
@ -172,10 +172,10 @@ void BedShapeDialog::on_dpi_changed(const wxRect &suggested_rect)
const std::string BedShapePanel::NONE = "None";
const std::string BedShapePanel::EMPTY_STRING = "";
void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const std::string& custom_texture, const std::string& custom_model)
void BedShapePanel::build_panel(const Pointfs& default_pt, const std::string& custom_texture, const std::string& custom_model)
{
wxGetApp().UpdateDarkUI(this);
m_shape = default_pt.values;
m_shape = make_counter_clockwise(default_pt);
m_custom_texture = custom_texture.empty() ? NONE : custom_texture;
m_custom_model = custom_model.empty() ? NONE : custom_model;
@ -240,7 +240,7 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const std:
SetSizerAndFit(top_sizer);
set_shape(default_pt);
set_shape(m_shape);
update_preview();
}
@ -454,7 +454,7 @@ wxPanel* BedShapePanel::init_model_panel()
// Deduce the bed shape type(rect, circle, custom)
// This routine shall be smart enough if the user messes up
// with the list of points in the ini file directly.
void BedShapePanel::set_shape(const ConfigOptionPoints& points)
void BedShapePanel::set_shape(const Pointfs& points)
{
BedShape shape(points);
@ -463,7 +463,7 @@ void BedShapePanel::set_shape(const ConfigOptionPoints& points)
// Copy the polygon to the canvas, make a copy of the array, if custom shape is selected
if (shape.is_custom())
m_loaded_shape = points.values;
m_loaded_shape = points;
update_shape();
@ -580,6 +580,7 @@ void BedShapePanel::load_stl()
}
auto polygon = expolygons[0].contour;
polygon.make_counter_clockwise();
std::vector<Vec2d> points;
for (auto pt : polygon.points)
points.push_back(unscale(pt));

View file

@ -34,7 +34,7 @@ struct BedShape
Diameter
};
BedShape(const ConfigOptionPoints& points);
BedShape(const Pointfs& points);
bool is_custom() { return m_build_volume.type() == BuildVolume_Type::Convex || m_build_volume.type() == BuildVolume_Type::Custom; }
@ -56,18 +56,18 @@ class BedShapePanel : public wxPanel
static const std::string EMPTY_STRING;
Bed_2D* m_canvas;
std::vector<Vec2d> m_shape;
std::vector<Vec2d> m_loaded_shape;
Pointfs m_shape;
Pointfs m_loaded_shape;
std::string m_custom_texture;
std::string m_custom_model;
public:
BedShapePanel(wxWindow* parent) : wxPanel(parent, wxID_ANY), m_custom_texture(NONE), m_custom_model(NONE) {}
void build_panel(const ConfigOptionPoints& default_pt, const std::string& custom_texture, const std::string& custom_model);
void build_panel(const Pointfs& default_pt, const std::string& custom_texture, const std::string& custom_model);
// Returns the resulting bed shape polygon. This value will be stored to the ini file.
const std::vector<Vec2d>& get_shape() const { return m_shape; }
const Pointfs& get_shape() const { return m_shape; }
const std::string& get_custom_texture() const { return (m_custom_texture != NONE) ? m_custom_texture : EMPTY_STRING; }
const std::string& get_custom_model() const { return (m_custom_model != NONE) ? m_custom_model : EMPTY_STRING; }
@ -76,7 +76,7 @@ private:
void activate_options_page(ConfigOptionsGroupShp options_group);
wxPanel* init_texture_panel();
wxPanel* init_model_panel();
void set_shape(const ConfigOptionPoints& points);
void set_shape(const Pointfs& points);
void update_preview();
void update_shape();
void load_stl();
@ -96,9 +96,9 @@ public:
BedShapeDialog(wxWindow* parent) : DPIDialog(parent, wxID_ANY, _(L("Bed Shape")),
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE) {}
void build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model);
void build_dialog(const Pointfs& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model);
const std::vector<Vec2d>& get_shape() const { return m_panel->get_shape(); }
const Pointfs& get_shape() const { return m_panel->get_shape(); }
const std::string& get_custom_texture() const { return m_panel->get_custom_texture(); }
const std::string& get_custom_model() const { return m_panel->get_custom_model(); }

View file

@ -1278,7 +1278,7 @@ PageBedShape::PageBedShape(ConfigWizard* parent)
{
append_text(_L("Set the shape of your printer's bed."));
shape_panel->build_panel(*wizard_p()->custom_config->option<ConfigOptionPoints>("printable_area"),
shape_panel->build_panel(wizard_p()->custom_config->option<ConfigOptionPoints>("printable_area")->values,
*wizard_p()->custom_config->option<ConfigOptionString>("bed_custom_texture"),
*wizard_p()->custom_config->option<ConfigOptionString>("bed_custom_model"));

View file

@ -2656,7 +2656,6 @@ void PartPlate::generate_exclude_polygon(ExPolygon &exclude_polygon)
bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Vec2d position, float height_to_lid, float height_to_rod)
{
Pointfs new_shape, new_exclude_areas;
m_raw_shape = shape;
for (const Vec2d& p : shape) {
new_shape.push_back(Vec2d(p.x() + position.x(), p.y() + position.y()));
}

View file

@ -117,7 +117,6 @@ private:
friend class PartPlateList;
Pointfs m_raw_shape;
Pointfs m_shape;
Pointfs m_exclude_area;
BoundingBoxf3 m_bounding_box;

View file

@ -13369,7 +13369,7 @@ void Plater::set_bed_shape() const
//BBS: add bed exclude area
void Plater::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_area, const double printable_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) const
{
p->set_bed_shape(shape, exclude_area, printable_height, custom_texture, custom_model, force_as_custom);
p->set_bed_shape(make_counter_clockwise(shape), exclude_area, printable_height, custom_texture, custom_model, force_as_custom);
}
void Plater::force_filament_colors_update()

View file

@ -5941,7 +5941,7 @@ wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent)
btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e) {
bool is_configed_by_BBL = PresetUtils::system_printer_bed_model(m_preset_bundle->printers.get_edited_preset()).size() > 0;
BedShapeDialog dlg(this);
dlg.build_dialog(*m_config->option<ConfigOptionPoints>("printable_area"),
dlg.build_dialog(m_config->option<ConfigOptionPoints>("printable_area")->values,
*m_config->option<ConfigOptionString>("bed_custom_texture"),
*m_config->option<ConfigOptionString>("bed_custom_model"));
if (dlg.ShowModal() == wxID_OK) {

View file

@ -990,7 +990,7 @@ bool CalibUtils::get_pa_k_n_value_by_cali_idx(const MachineObject *obj, int cali
bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &full_config, const Calib_Params &params, wxString &error_message)
{
Pointfs bedfs = full_config.opt<ConfigOptionPoints>("printable_area")->values;
Pointfs bedfs = make_counter_clockwise(full_config.opt<ConfigOptionPoints>("printable_area")->values);
double print_height = full_config.opt_float("printable_height");
double current_width = bedfs[2].x() - bedfs[0].x();
double current_depth = bedfs[2].y() - bedfs[0].y();