Merge branch 'tm_arrange_alignment_251_SPE-1416' into master_251
This commit is contained in:
commit
d97c486ecd
@ -85,7 +85,13 @@ template<class PConf>
|
|||||||
void fill_config(PConf& pcfg, const ArrangeParams ¶ms) {
|
void fill_config(PConf& pcfg, const ArrangeParams ¶ms) {
|
||||||
|
|
||||||
// Align the arranged pile into the center of the bin
|
// Align the arranged pile into the center of the bin
|
||||||
pcfg.alignment = PConf::Alignment::CENTER;
|
switch (params.alignment) {
|
||||||
|
case Pivots::Center: pcfg.alignment = PConf::Alignment::CENTER; break;
|
||||||
|
case Pivots::BottomLeft: pcfg.alignment = PConf::Alignment::BOTTOM_LEFT; break;
|
||||||
|
case Pivots::BottomRight: pcfg.alignment = PConf::Alignment::BOTTOM_RIGHT; break;
|
||||||
|
case Pivots::TopLeft: pcfg.alignment = PConf::Alignment::TOP_LEFT; break;
|
||||||
|
case Pivots::TopRight: pcfg.alignment = PConf::Alignment::TOP_RIGHT; break;
|
||||||
|
}
|
||||||
|
|
||||||
// Start placing the items from the center of the print bed
|
// Start placing the items from the center of the print bed
|
||||||
pcfg.starting_point = PConf::Alignment::CENTER;
|
pcfg.starting_point = PConf::Alignment::CENTER;
|
||||||
@ -613,6 +619,12 @@ template<class Fn> auto call_with_bed(const Points &bed, Fn &&fn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_box(const Points &bed)
|
||||||
|
{
|
||||||
|
return !bed.empty() &&
|
||||||
|
((1.0 - poly_area(bed) / area(BoundingBox(bed))) < 1e-3);
|
||||||
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void arrange(ArrangePolygons & items,
|
void arrange(ArrangePolygons & items,
|
||||||
const ArrangePolygons &excludes,
|
const ArrangePolygons &excludes,
|
||||||
|
@ -75,6 +75,10 @@ struct ArrangePolygon {
|
|||||||
|
|
||||||
using ArrangePolygons = std::vector<ArrangePolygon>;
|
using ArrangePolygons = std::vector<ArrangePolygon>;
|
||||||
|
|
||||||
|
enum class Pivots {
|
||||||
|
Center, TopLeft, BottomLeft, BottomRight, TopRight
|
||||||
|
};
|
||||||
|
|
||||||
struct ArrangeParams {
|
struct ArrangeParams {
|
||||||
|
|
||||||
/// The minimum distance which is allowed for any
|
/// The minimum distance which is allowed for any
|
||||||
@ -89,7 +93,13 @@ struct ArrangeParams {
|
|||||||
bool parallel = true;
|
bool parallel = true;
|
||||||
|
|
||||||
bool allow_rotations = false;
|
bool allow_rotations = false;
|
||||||
|
|
||||||
|
/// Final alignment of the merged pile after arrangement
|
||||||
|
Pivots alignment = Pivots::Center;
|
||||||
|
|
||||||
|
/// Starting position hint for the arrangement
|
||||||
|
Pivots starting_point = Pivots::Center;
|
||||||
|
|
||||||
/// Progress indicator callback called when an object gets packed.
|
/// Progress indicator callback called when an object gets packed.
|
||||||
/// The unsigned argument is the number of items remaining to pack.
|
/// The unsigned argument is the number of items remaining to pack.
|
||||||
std::function<void(unsigned)> progressind;
|
std::function<void(unsigned)> progressind;
|
||||||
@ -130,6 +140,8 @@ inline void arrange(ArrangePolygons &items, const CircleBed &bed, const ArrangeP
|
|||||||
inline void arrange(ArrangePolygons &items, const Polygon &bed, const ArrangeParams ¶ms = {}) { arrange(items, {}, bed, params); }
|
inline void arrange(ArrangePolygons &items, const Polygon &bed, const ArrangeParams ¶ms = {}) { arrange(items, {}, bed, params); }
|
||||||
inline void arrange(ArrangePolygons &items, const InfiniteBed &bed, const ArrangeParams ¶ms = {}) { arrange(items, {}, bed, params); }
|
inline void arrange(ArrangePolygons &items, const InfiniteBed &bed, const ArrangeParams ¶ms = {}) { arrange(items, {}, bed, params); }
|
||||||
|
|
||||||
|
bool is_box(const Points &bed);
|
||||||
|
|
||||||
}} // namespace Slic3r::arrangement
|
}} // namespace Slic3r::arrangement
|
||||||
|
|
||||||
#endif // MODELARRANGE_HPP
|
#endif // MODELARRANGE_HPP
|
||||||
|
@ -931,6 +931,19 @@ void GLCanvas3D::load_arrange_settings()
|
|||||||
std::string en_rot_sla_str =
|
std::string en_rot_sla_str =
|
||||||
wxGetApp().app_config->get("arrange", "enable_rotation_sla");
|
wxGetApp().app_config->get("arrange", "enable_rotation_sla");
|
||||||
|
|
||||||
|
// std::string alignment_fff_str =
|
||||||
|
// wxGetApp().app_config->get("arrange", "alignment_fff");
|
||||||
|
|
||||||
|
// std::string alignment_fff_seqp_str =
|
||||||
|
// wxGetApp().app_config->get("arrange", "alignment_fff_seq_pring");
|
||||||
|
|
||||||
|
// std::string alignment_sla_str =
|
||||||
|
// wxGetApp().app_config->get("arrange", "alignment_sla");
|
||||||
|
|
||||||
|
// Override default alignment and save save/load it to a temporary slot "alignment_xl"
|
||||||
|
std::string alignment_xl_str =
|
||||||
|
wxGetApp().app_config->get("arrange", "alignment_xl");
|
||||||
|
|
||||||
if (!dist_fff_str.empty())
|
if (!dist_fff_str.empty())
|
||||||
m_arrange_settings_fff.distance = std::stof(dist_fff_str);
|
m_arrange_settings_fff.distance = std::stof(dist_fff_str);
|
||||||
|
|
||||||
@ -948,6 +961,24 @@ void GLCanvas3D::load_arrange_settings()
|
|||||||
|
|
||||||
if (!en_rot_sla_str.empty())
|
if (!en_rot_sla_str.empty())
|
||||||
m_arrange_settings_sla.enable_rotation = (en_rot_sla_str == "1" || en_rot_sla_str == "yes");
|
m_arrange_settings_sla.enable_rotation = (en_rot_sla_str == "1" || en_rot_sla_str == "yes");
|
||||||
|
|
||||||
|
// if (!alignment_sla_str.empty())
|
||||||
|
// m_arrange_settings_sla.alignment = std::stoi(alignment_sla_str);
|
||||||
|
|
||||||
|
// if (!alignment_fff_str.empty())
|
||||||
|
// m_arrange_settings_fff.alignment = std::stoi(alignment_fff_str);
|
||||||
|
|
||||||
|
// if (!alignment_fff_seqp_str.empty())
|
||||||
|
// m_arrange_settings_fff_seq_print.alignment = std::stoi(alignment_fff_seqp_str);
|
||||||
|
|
||||||
|
// Override default alignment and save save/load it to a temporary slot "alignment_xl"
|
||||||
|
int arr_alignment = static_cast<int>(arrangement::Pivots::BottomLeft);
|
||||||
|
if (!alignment_xl_str.empty())
|
||||||
|
arr_alignment = std::stoi(alignment_xl_str);
|
||||||
|
|
||||||
|
m_arrange_settings_sla.alignment = arr_alignment ;
|
||||||
|
m_arrange_settings_fff.alignment = arr_alignment ;
|
||||||
|
m_arrange_settings_fff_seq_print.alignment = arr_alignment ;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrinterTechnology GLCanvas3D::current_printer_technology() const
|
PrinterTechnology GLCanvas3D::current_printer_technology() const
|
||||||
@ -955,6 +986,20 @@ PrinterTechnology GLCanvas3D::current_printer_technology() const
|
|||||||
return m_process->current_printer_technology();
|
return m_process->current_printer_technology();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GLCanvas3D::is_arrange_alignment_enabled() const
|
||||||
|
{
|
||||||
|
static constexpr const char *ALIGN_ONLY_FOR = "XL";
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
auto *printer_model = m_config->opt<ConfigOptionString>("printer_model");
|
||||||
|
|
||||||
|
if (printer_model)
|
||||||
|
ret = boost::algorithm::contains(printer_model->value, ALIGN_ONLY_FOR);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed)
|
GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed)
|
||||||
: m_canvas(canvas)
|
: m_canvas(canvas)
|
||||||
, m_context(nullptr)
|
, m_context(nullptr)
|
||||||
@ -4019,14 +4064,16 @@ bool GLCanvas3D::_render_arrange_menu(float pos_x)
|
|||||||
imgui->begin(_L("Arrange options"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
|
imgui->begin(_L("Arrange options"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
|
||||||
|
|
||||||
ArrangeSettings settings = get_arrange_settings();
|
ArrangeSettings settings = get_arrange_settings();
|
||||||
ArrangeSettings &settings_out = get_arrange_settings();
|
ArrangeSettings &settings_out = get_arrange_settings_ref(this);
|
||||||
|
|
||||||
auto &appcfg = wxGetApp().app_config;
|
auto &appcfg = wxGetApp().app_config;
|
||||||
PrinterTechnology ptech = current_printer_technology();
|
PrinterTechnology ptech = current_printer_technology();
|
||||||
|
|
||||||
bool settings_changed = false;
|
bool settings_changed = false;
|
||||||
float dist_min = 0.f;
|
float dist_min = 0.f;
|
||||||
std::string dist_key = "min_object_distance", rot_key = "enable_rotation";
|
std::string dist_key = "min_object_distance";
|
||||||
|
std::string rot_key = "enable_rotation";
|
||||||
|
std::string align_key = "alignment";
|
||||||
std::string postfix;
|
std::string postfix;
|
||||||
|
|
||||||
if (ptech == ptSLA) {
|
if (ptech == ptSLA) {
|
||||||
@ -4044,7 +4091,8 @@ bool GLCanvas3D::_render_arrange_menu(float pos_x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dist_key += postfix;
|
dist_key += postfix;
|
||||||
rot_key += postfix;
|
rot_key += postfix;
|
||||||
|
align_key += postfix;
|
||||||
|
|
||||||
imgui->text(GUI::format_wxstr(_L("Press %1%left mouse button to enter the exact value"), shortkey_ctrl_prefix()));
|
imgui->text(GUI::format_wxstr(_L("Press %1%left mouse button to enter the exact value"), shortkey_ctrl_prefix()));
|
||||||
|
|
||||||
@ -4061,6 +4109,14 @@ bool GLCanvas3D::_render_arrange_menu(float pos_x)
|
|||||||
settings_changed = true;
|
settings_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Points bed = m_config ? get_bed_shape(*m_config) : Points{};
|
||||||
|
|
||||||
|
if (arrangement::is_box(bed) && settings.alignment >= 0 && imgui->combo(_("Alignment"), {"Center", "Top left", "Bottom left", "Bottom right", "Top right", "Random"}, settings.alignment)) {
|
||||||
|
settings_out.alignment = settings.alignment;
|
||||||
|
appcfg->set("arrange", align_key.c_str(), std::to_string(settings_out.alignment));
|
||||||
|
settings_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (imgui->button(_L("Reset"))) {
|
if (imgui->button(_L("Reset"))) {
|
||||||
|
@ -444,6 +444,7 @@ public:
|
|||||||
// float distance_sla = 6.;
|
// float distance_sla = 6.;
|
||||||
float accuracy = 0.65f; // Unused currently
|
float accuracy = 0.65f; // Unused currently
|
||||||
bool enable_rotation = false;
|
bool enable_rotation = false;
|
||||||
|
int alignment = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -525,8 +526,10 @@ private:
|
|||||||
|
|
||||||
PrinterTechnology current_printer_technology() const;
|
PrinterTechnology current_printer_technology() const;
|
||||||
|
|
||||||
|
bool is_arrange_alignment_enabled() const;
|
||||||
|
|
||||||
template<class Self>
|
template<class Self>
|
||||||
static auto & get_arrange_settings(Self *self) {
|
static auto & get_arrange_settings_ref(Self *self) {
|
||||||
PrinterTechnology ptech = self->current_printer_technology();
|
PrinterTechnology ptech = self->current_printer_technology();
|
||||||
|
|
||||||
auto *ptr = &self->m_arrange_settings_fff;
|
auto *ptr = &self->m_arrange_settings_fff;
|
||||||
@ -544,8 +547,22 @@ private:
|
|||||||
return *ptr;
|
return *ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrangeSettings &get_arrange_settings() { return get_arrange_settings(this); }
|
public:
|
||||||
|
ArrangeSettings get_arrange_settings() const {
|
||||||
|
const ArrangeSettings &settings = get_arrange_settings_ref(this);
|
||||||
|
ArrangeSettings ret = settings;
|
||||||
|
if (&settings == &m_arrange_settings_fff_seq_print) {
|
||||||
|
ret.distance = std::max(ret.distance,
|
||||||
|
float(min_object_distance(*m_config)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_arrange_alignment_enabled())
|
||||||
|
ret.alignment = -1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
void load_arrange_settings();
|
void load_arrange_settings();
|
||||||
|
|
||||||
class SequentialPrintClearance
|
class SequentialPrintClearance
|
||||||
@ -831,17 +848,6 @@ public:
|
|||||||
void highlight_toolbar_item(const std::string& item_name);
|
void highlight_toolbar_item(const std::string& item_name);
|
||||||
void highlight_gizmo(const std::string& gizmo_name);
|
void highlight_gizmo(const std::string& gizmo_name);
|
||||||
|
|
||||||
ArrangeSettings get_arrange_settings() const {
|
|
||||||
const ArrangeSettings &settings = get_arrange_settings(this);
|
|
||||||
ArrangeSettings ret = settings;
|
|
||||||
if (&settings == &m_arrange_settings_fff_seq_print) {
|
|
||||||
ret.distance = std::max(ret.distance,
|
|
||||||
float(min_object_distance(*m_config)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Timestamp for FPS calculation and notification fade-outs.
|
// Timestamp for FPS calculation and notification fade-outs.
|
||||||
static int64_t timestamp_now() {
|
static int64_t timestamp_now() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
|
|
||||||
#include "libnest2d/common.hpp"
|
#include "libnest2d/common.hpp"
|
||||||
|
|
||||||
|
#include <numeric>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
namespace Slic3r { namespace GUI {
|
namespace Slic3r { namespace GUI {
|
||||||
|
|
||||||
// Cache the wti info
|
// Cache the wti info
|
||||||
@ -278,12 +281,29 @@ arrangement::ArrangePolygon get_arrange_poly(ModelInstance *inst,
|
|||||||
arrangement::ArrangeParams get_arrange_params(Plater *p)
|
arrangement::ArrangeParams get_arrange_params(Plater *p)
|
||||||
{
|
{
|
||||||
const GLCanvas3D::ArrangeSettings &settings =
|
const GLCanvas3D::ArrangeSettings &settings =
|
||||||
static_cast<const GLCanvas3D*>(p->canvas3D())->get_arrange_settings();
|
p->canvas3D()->get_arrange_settings();
|
||||||
|
|
||||||
arrangement::ArrangeParams params;
|
arrangement::ArrangeParams params;
|
||||||
params.allow_rotations = settings.enable_rotation;
|
params.allow_rotations = settings.enable_rotation;
|
||||||
params.min_obj_distance = scaled(settings.distance);
|
params.min_obj_distance = scaled(settings.distance);
|
||||||
|
|
||||||
|
arrangement::Pivots pivot = arrangement::Pivots::Center;
|
||||||
|
|
||||||
|
int pivot_max = static_cast<int>(arrangement::Pivots::TopRight);
|
||||||
|
if (settings.alignment < 0) {
|
||||||
|
pivot = arrangement::Pivots::Center;
|
||||||
|
} else if (settings.alignment > pivot_max) {
|
||||||
|
// means it should be random
|
||||||
|
std::random_device rd{};
|
||||||
|
std::mt19937 rng(rd());
|
||||||
|
std::uniform_int_distribution<std::mt19937::result_type> dist(0, pivot_max);
|
||||||
|
pivot = static_cast<arrangement::Pivots>(dist(rng));
|
||||||
|
} else {
|
||||||
|
pivot = static_cast<arrangement::Pivots>(settings.alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
params.alignment = pivot;
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,14 +104,10 @@ void FillBedJob::prepare()
|
|||||||
|
|
||||||
void FillBedJob::process()
|
void FillBedJob::process()
|
||||||
{
|
{
|
||||||
if (m_object_idx == -1 || m_selected.empty()) return;
|
if (m_object_idx == -1 || m_selected.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
const GLCanvas3D::ArrangeSettings &settings =
|
arrangement::ArrangeParams params = get_arrange_params(m_plater);
|
||||||
static_cast<const GLCanvas3D*>(m_plater->canvas3D())->get_arrange_settings();
|
|
||||||
|
|
||||||
arrangement::ArrangeParams params;
|
|
||||||
params.allow_rotations = settings.enable_rotation;
|
|
||||||
params.min_obj_distance = scaled(settings.distance);
|
|
||||||
|
|
||||||
bool do_stop = false;
|
bool do_stop = false;
|
||||||
params.stopcondition = [this, &do_stop]() {
|
params.stopcondition = [this, &do_stop]() {
|
||||||
|
Loading…
Reference in New Issue
Block a user