mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 01:36:14 +08:00
Merge branch 'master' of https://github.com/Prusa3d/PrusaSlicer
This commit is contained in:
commit
597a158a6e
BIN
resources/localization/ru/PrusaSlicer.mo
Normal file
BIN
resources/localization/ru/PrusaSlicer.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -167,6 +167,8 @@ struct NfpPConfig {
|
|||||||
const ItemGroup& // remaining items
|
const ItemGroup& // remaining items
|
||||||
)> before_packing;
|
)> before_packing;
|
||||||
|
|
||||||
|
std::function<void(const ItemGroup &, NfpPConfig &config)> on_preload;
|
||||||
|
|
||||||
NfpPConfig(): rotations({0.0, Pi/2.0, Pi, 3*Pi/2}),
|
NfpPConfig(): rotations({0.0, Pi/2.0, Pi, 3*Pi/2}),
|
||||||
alignment(Alignment::CENTER), starting_point(Alignment::CENTER) {}
|
alignment(Alignment::CENTER), starting_point(Alignment::CENTER) {}
|
||||||
};
|
};
|
||||||
@ -577,6 +579,12 @@ public:
|
|||||||
Base::clearItems();
|
Base::clearItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void preload(const ItemGroup& packeditems) {
|
||||||
|
Base::preload(packeditems);
|
||||||
|
if (config_.on_preload)
|
||||||
|
config_.on_preload(packeditems, config_);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
using Shapes = TMultiShape<RawShape>;
|
using Shapes = TMultiShape<RawShape>;
|
||||||
|
@ -109,6 +109,7 @@ void fill_config(PConf& pcfg, const ArrangeParams ¶ms) {
|
|||||||
|
|
||||||
// Apply penalty to object function result. This is used only when alignment
|
// Apply penalty to object function result. This is used only when alignment
|
||||||
// after arrange is explicitly disabled (PConfig::Alignment::DONT_ALIGN)
|
// after arrange is explicitly disabled (PConfig::Alignment::DONT_ALIGN)
|
||||||
|
// Also, this will only work well for Box shaped beds.
|
||||||
static double fixed_overfit(const std::tuple<double, Box>& result, const Box &binbb)
|
static double fixed_overfit(const std::tuple<double, Box>& result, const Box &binbb)
|
||||||
{
|
{
|
||||||
double score = std::get<0>(result);
|
double score = std::get<0>(result);
|
||||||
@ -348,6 +349,17 @@ public:
|
|||||||
|
|
||||||
m_pconf.object_function = get_objfn();
|
m_pconf.object_function = get_objfn();
|
||||||
|
|
||||||
|
m_pconf.on_preload = [this](const ItemGroup &items, PConfig &cfg) {
|
||||||
|
if (items.empty()) return;
|
||||||
|
|
||||||
|
cfg.alignment = PConfig::Alignment::DONT_ALIGN;
|
||||||
|
auto bb = sl::boundingBox(m_bin);
|
||||||
|
auto bbcenter = bb.center();
|
||||||
|
cfg.object_function = [this, bb, bbcenter](const Item &item) {
|
||||||
|
return fixed_overfit(objfunc(item, bbcenter), bb);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
auto on_packed = params.on_packed;
|
auto on_packed = params.on_packed;
|
||||||
|
|
||||||
if (progressind || on_packed)
|
if (progressind || on_packed)
|
||||||
@ -384,13 +396,6 @@ public:
|
|||||||
const PConfig& config() const { return m_pconf; }
|
const PConfig& config() const { return m_pconf; }
|
||||||
|
|
||||||
inline void preload(std::vector<Item>& fixeditems) {
|
inline void preload(std::vector<Item>& fixeditems) {
|
||||||
m_pconf.alignment = PConfig::Alignment::DONT_ALIGN;
|
|
||||||
auto bb = sl::boundingBox(m_bin);
|
|
||||||
auto bbcenter = bb.center();
|
|
||||||
m_pconf.object_function = [this, bb, bbcenter](const Item &item) {
|
|
||||||
return fixed_overfit(objfunc(item, bbcenter), bb);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build the rtree for queries to work
|
// Build the rtree for queries to work
|
||||||
|
|
||||||
for(unsigned idx = 0; idx < fixeditems.size(); ++idx) {
|
for(unsigned idx = 0; idx < fixeditems.size(); ++idx) {
|
||||||
@ -398,7 +403,6 @@ public:
|
|||||||
itm.markAsFixedInBin(itm.binId());
|
itm.markAsFixedInBin(itm.binId());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pck.configure(m_pconf);
|
|
||||||
m_item_count += fixeditems.size();
|
m_item_count += fixeditems.size();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -62,6 +62,15 @@ struct ArrangePolygon {
|
|||||||
|
|
||||||
/// Test if arrange() was called previously and gave a successful result.
|
/// Test if arrange() was called previously and gave a successful result.
|
||||||
bool is_arranged() const { return bed_idx != UNARRANGED; }
|
bool is_arranged() const { return bed_idx != UNARRANGED; }
|
||||||
|
|
||||||
|
inline ExPolygon transformed_poly() const
|
||||||
|
{
|
||||||
|
ExPolygon ret = poly;
|
||||||
|
ret.rotate(rotation);
|
||||||
|
ret.translate(translation.x(), translation.y());
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using ArrangePolygons = std::vector<ArrangePolygon>;
|
using ArrangePolygons = std::vector<ArrangePolygon>;
|
||||||
|
@ -53,6 +53,9 @@ public:
|
|||||||
return point(0) >= this->min(0) && point(0) <= this->max(0)
|
return point(0) >= this->min(0) && point(0) <= this->max(0)
|
||||||
&& point(1) >= this->min(1) && point(1) <= this->max(1);
|
&& point(1) >= this->min(1) && point(1) <= this->max(1);
|
||||||
}
|
}
|
||||||
|
bool contains(const BoundingBoxBase<PointClass> &other) const {
|
||||||
|
return contains(other.min) && contains(other.max);
|
||||||
|
}
|
||||||
bool overlap(const BoundingBoxBase<PointClass> &other) const {
|
bool overlap(const BoundingBoxBase<PointClass> &other) const {
|
||||||
return ! (this->max(0) < other.min(0) || this->min(0) > other.max(0) ||
|
return ! (this->max(0) < other.min(0) || this->min(0) > other.max(0) ||
|
||||||
this->max(1) < other.min(1) || this->min(1) > other.max(1));
|
this->max(1) < other.min(1) || this->min(1) > other.max(1));
|
||||||
|
@ -1095,29 +1095,48 @@ wxDEFINE_EVENT(EVT_GLCANVAS_RELOAD_FROM_DISK, SimpleEvent);
|
|||||||
|
|
||||||
const double GLCanvas3D::DefaultCameraZoomToBoxMarginFactor = 1.25;
|
const double GLCanvas3D::DefaultCameraZoomToBoxMarginFactor = 1.25;
|
||||||
|
|
||||||
static GLCanvas3D::ArrangeSettings load_arrange_settings()
|
void GLCanvas3D::load_arrange_settings()
|
||||||
{
|
{
|
||||||
GLCanvas3D::ArrangeSettings settings;
|
std::string dist_fff_str =
|
||||||
|
wxGetApp().app_config->get("arrange", "min_object_distance_fff");
|
||||||
|
|
||||||
std::string dist_str =
|
std::string dist_fff_seq_print_str =
|
||||||
wxGetApp().app_config->get("arrange", "min_object_distance");
|
wxGetApp().app_config->get("arrange", "min_object_distance_fff_seq_print");
|
||||||
|
|
||||||
std::string dist_seq_print_str =
|
std::string dist_sla_str =
|
||||||
wxGetApp().app_config->get("arrange", "min_object_distance_seq_print");
|
wxGetApp().app_config->get("arrange", "min_object_distance_sla");
|
||||||
|
|
||||||
std::string en_rot_str =
|
std::string en_rot_fff_str =
|
||||||
wxGetApp().app_config->get("arrange", "enable_rotation");
|
wxGetApp().app_config->get("arrange", "enable_rotation_fff");
|
||||||
|
|
||||||
if (!dist_str.empty())
|
std::string en_rot_fff_seqp_str =
|
||||||
settings.distance = std::stof(dist_str);
|
wxGetApp().app_config->get("arrange", "enable_rotation_fff_seq_print");
|
||||||
|
|
||||||
if (!dist_seq_print_str.empty())
|
std::string en_rot_sla_str =
|
||||||
settings.distance_seq_print = std::stof(dist_seq_print_str);
|
wxGetApp().app_config->get("arrange", "enable_rotation_sla");
|
||||||
|
|
||||||
if (!en_rot_str.empty())
|
if (!dist_fff_str.empty())
|
||||||
settings.enable_rotation = (en_rot_str == "1" || en_rot_str == "yes");
|
m_arrange_settings_fff.distance = std::stof(dist_fff_str);
|
||||||
|
|
||||||
return settings;
|
if (!dist_fff_seq_print_str.empty())
|
||||||
|
m_arrange_settings_fff_seq_print.distance = std::stof(dist_fff_seq_print_str);
|
||||||
|
|
||||||
|
if (!dist_sla_str.empty())
|
||||||
|
m_arrange_settings_sla.distance = std::stof(dist_sla_str);
|
||||||
|
|
||||||
|
if (!en_rot_fff_str.empty())
|
||||||
|
m_arrange_settings_fff.enable_rotation = (en_rot_fff_str == "1" || en_rot_fff_str == "yes");
|
||||||
|
|
||||||
|
if (!en_rot_fff_seqp_str.empty())
|
||||||
|
m_arrange_settings_fff_seq_print.enable_rotation = (en_rot_fff_seqp_str == "1" || en_rot_fff_seqp_str == "yes");
|
||||||
|
|
||||||
|
if (!en_rot_sla_str.empty())
|
||||||
|
m_arrange_settings_sla.enable_rotation = (en_rot_sla_str == "1" || en_rot_sla_str == "yes");
|
||||||
|
}
|
||||||
|
|
||||||
|
PrinterTechnology GLCanvas3D::current_printer_technology() const
|
||||||
|
{
|
||||||
|
return m_process->current_printer_technology();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
|
GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
|
||||||
@ -1162,7 +1181,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
|
|||||||
#endif // ENABLE_RETINA_GL
|
#endif // ENABLE_RETINA_GL
|
||||||
}
|
}
|
||||||
|
|
||||||
m_arrange_settings = load_arrange_settings();
|
load_arrange_settings();
|
||||||
|
|
||||||
m_selection.set_volumes(&m_volumes.volumes);
|
m_selection.set_volumes(&m_volumes.volumes);
|
||||||
}
|
}
|
||||||
@ -3908,44 +3927,60 @@ bool GLCanvas3D::_render_arrange_menu(float pos_x)
|
|||||||
imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
|
imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
|
||||||
|
|
||||||
imgui->begin(_L("Arrange options"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
|
imgui->begin(_L("Arrange options"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
|
||||||
ArrangeSettings settings = m_arrange_settings;
|
|
||||||
|
ArrangeSettings settings = get_arrange_settings();
|
||||||
|
ArrangeSettings &settings_out = get_arrange_settings();
|
||||||
|
|
||||||
auto &appcfg = wxGetApp().app_config;
|
auto &appcfg = wxGetApp().app_config;
|
||||||
|
PrinterTechnology ptech = m_process->current_printer_technology();
|
||||||
|
|
||||||
bool settings_changed = false;
|
bool settings_changed = false;
|
||||||
bool is_seq_print = m_config->opt_bool("complete_objects");
|
float dist_min = 0.f;
|
||||||
|
std::string dist_key = "min_object_distance", rot_key = "enable_rotation";
|
||||||
|
std::string postfix;
|
||||||
|
|
||||||
|
if (ptech == ptSLA) {
|
||||||
|
dist_min = 0.f;
|
||||||
|
postfix = "_sla";
|
||||||
|
} else if (ptech == ptFFF) {
|
||||||
|
auto co_opt = m_config->option<ConfigOptionBool>("complete_objects");
|
||||||
|
if (co_opt && co_opt->value) {
|
||||||
|
dist_min = float(min_object_distance(*m_config));
|
||||||
|
postfix = "_fff_seq_print";
|
||||||
|
} else {
|
||||||
|
dist_min = 0.f;
|
||||||
|
postfix = "_fff";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dist_key += postfix;
|
||||||
|
rot_key += postfix;
|
||||||
|
|
||||||
imgui->text(_L("Use CTRL+left mouse key to enter text edit mode:"));
|
imgui->text(_L("Use CTRL+left mouse key to enter text edit mode:"));
|
||||||
|
|
||||||
float &dist_val = is_seq_print ? settings.distance_seq_print : settings.distance;
|
if (imgui->slider_float(_L("Clearance size"), &settings.distance, dist_min, 100.0f, "%5.2f") || dist_min > settings.distance) {
|
||||||
float dist_min = is_seq_print ? float(min_object_distance(*m_config)) : 0.f;
|
settings.distance = std::max(dist_min, settings.distance);
|
||||||
dist_val = std::max(dist_min, dist_val);
|
settings_out.distance = settings.distance;
|
||||||
|
appcfg->set("arrange", dist_key.c_str(), std::to_string(settings_out.distance));
|
||||||
if (imgui->slider_float(_L("Clearance size"), &dist_val, dist_min, 100.0f, "%5.2f")) {
|
|
||||||
is_seq_print ? m_arrange_settings.distance_seq_print = dist_val :
|
|
||||||
m_arrange_settings.distance = dist_val;
|
|
||||||
|
|
||||||
settings_changed = true;
|
settings_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imgui->checkbox(_L("Enable rotations (slow)"), settings.enable_rotation)) {
|
if (imgui->checkbox(_L("Enable rotations (slow)"), settings.enable_rotation)) {
|
||||||
m_arrange_settings.enable_rotation = settings.enable_rotation;
|
settings_out.enable_rotation = settings.enable_rotation;
|
||||||
|
appcfg->set("arrange", rot_key.c_str(), settings_out.enable_rotation? "1" : "0");
|
||||||
settings_changed = true;
|
settings_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (imgui->button(_L("Reset"))) {
|
if (imgui->button(_L("Reset"))) {
|
||||||
m_arrange_settings = ArrangeSettings{};
|
settings_out = ArrangeSettings{};
|
||||||
|
settings_out.distance = std::max(dist_min, settings_out.distance);
|
||||||
|
appcfg->set("arrange", dist_key.c_str(), std::to_string(settings_out.distance));
|
||||||
|
appcfg->set("arrange", rot_key.c_str(), settings_out.enable_rotation? "1" : "0");
|
||||||
settings_changed = true;
|
settings_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings_changed) {
|
|
||||||
appcfg->set("arrange", "min_object_distance", std::to_string(m_arrange_settings.distance));
|
|
||||||
appcfg->set("arrange", "min_object_distance_seq_print", std::to_string(m_arrange_settings.distance_seq_print));
|
|
||||||
appcfg->set("arrange", "enable_rotation", m_arrange_settings.enable_rotation? "1" : "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
if (imgui->button(_L("Arrange"))) {
|
if (imgui->button(_L("Arrange"))) {
|
||||||
|
@ -388,7 +388,8 @@ public:
|
|||||||
struct ArrangeSettings
|
struct ArrangeSettings
|
||||||
{
|
{
|
||||||
float distance = 6.;
|
float distance = 6.;
|
||||||
float distance_seq_print = 6.; // Used when sequential print is ON
|
// float distance_seq_print = 6.; // Used when sequential print is ON
|
||||||
|
// float distance_sla = 6.;
|
||||||
float accuracy = 0.65f; // Unused currently
|
float accuracy = 0.65f; // Unused currently
|
||||||
bool enable_rotation = false;
|
bool enable_rotation = false;
|
||||||
};
|
};
|
||||||
@ -464,7 +465,35 @@ private:
|
|||||||
mutable bool m_tooltip_enabled{ true };
|
mutable bool m_tooltip_enabled{ true };
|
||||||
Slope m_slope;
|
Slope m_slope;
|
||||||
|
|
||||||
ArrangeSettings m_arrange_settings;
|
ArrangeSettings m_arrange_settings_fff, m_arrange_settings_sla,
|
||||||
|
m_arrange_settings_fff_seq_print;
|
||||||
|
|
||||||
|
PrinterTechnology current_printer_technology() const;
|
||||||
|
|
||||||
|
template<class Self>
|
||||||
|
static auto & get_arrange_settings(Self *self)
|
||||||
|
{
|
||||||
|
PrinterTechnology ptech = self->current_printer_technology();
|
||||||
|
|
||||||
|
auto *ptr = &self->m_arrange_settings_fff;
|
||||||
|
|
||||||
|
if (ptech == ptSLA) {
|
||||||
|
ptr = &self->m_arrange_settings_sla;
|
||||||
|
} else if (ptech == ptFFF) {
|
||||||
|
auto co_opt = self->m_config->template option<ConfigOptionBool>("complete_objects");
|
||||||
|
if (co_opt && co_opt->value) {
|
||||||
|
ptr = &self->m_arrange_settings_fff_seq_print;
|
||||||
|
} else {
|
||||||
|
ptr = &self->m_arrange_settings_fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrangeSettings &get_arrange_settings() { return get_arrange_settings(this); }
|
||||||
|
|
||||||
|
void load_arrange_settings();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GLCanvas3D(wxGLCanvas* canvas);
|
explicit GLCanvas3D(wxGLCanvas* canvas);
|
||||||
@ -685,7 +714,17 @@ public:
|
|||||||
void use_slope(bool use) { m_slope.use(use); }
|
void use_slope(bool use) { m_slope.use(use); }
|
||||||
void set_slope_normal_angle(float angle_in_deg) { m_slope.set_normal_angle(angle_in_deg); }
|
void set_slope_normal_angle(float angle_in_deg) { m_slope.set_normal_angle(angle_in_deg); }
|
||||||
|
|
||||||
const ArrangeSettings& get_arrange_settings() const { return m_arrange_settings; }
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _is_shown_on_screen() const;
|
bool _is_shown_on_screen() const;
|
||||||
|
@ -145,14 +145,12 @@ void ArrangeJob::process()
|
|||||||
{
|
{
|
||||||
static const auto arrangestr = _(L("Arranging"));
|
static const auto arrangestr = _(L("Arranging"));
|
||||||
|
|
||||||
GLCanvas3D::ArrangeSettings settings =
|
const GLCanvas3D::ArrangeSettings &settings =
|
||||||
m_plater->canvas3D()->get_arrange_settings();
|
static_cast<const GLCanvas3D*>(m_plater->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 = m_plater->config()->opt_bool("complete_objects") ?
|
params.min_obj_distance = scaled(settings.distance);
|
||||||
scaled(settings.distance_seq_print) :
|
|
||||||
scaled(settings.distance);
|
|
||||||
|
|
||||||
|
|
||||||
auto count = unsigned(m_selected.size() + m_unprintable.size());
|
auto count = unsigned(m_selected.size() + m_unprintable.size());
|
||||||
|
@ -29,7 +29,9 @@ void FillBedJob::prepare()
|
|||||||
for (ModelInstance *inst : model_object->instances)
|
for (ModelInstance *inst : model_object->instances)
|
||||||
if (inst->printable) {
|
if (inst->printable) {
|
||||||
ArrangePolygon ap = get_arrange_poly(PtrWrapper{inst}, m_plater);
|
ArrangePolygon ap = get_arrange_poly(PtrWrapper{inst}, m_plater);
|
||||||
++ap.priority; // need to be included in the result
|
// Existing objects need to be included in the result. Only
|
||||||
|
// the needed amount of object will be added, no more.
|
||||||
|
++ap.priority;
|
||||||
m_selected.emplace_back(ap);
|
m_selected.emplace_back(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,11 +40,18 @@ void FillBedJob::prepare()
|
|||||||
m_bedpts = get_bed_shape(*m_plater->config());
|
m_bedpts = get_bed_shape(*m_plater->config());
|
||||||
|
|
||||||
auto &objects = m_plater->model().objects;
|
auto &objects = m_plater->model().objects;
|
||||||
|
BoundingBox bedbb = get_extents(m_bedpts);
|
||||||
|
|
||||||
for (size_t idx = 0; idx < objects.size(); ++idx)
|
for (size_t idx = 0; idx < objects.size(); ++idx)
|
||||||
if (int(idx) != m_object_idx)
|
if (int(idx) != m_object_idx)
|
||||||
for (ModelInstance *mi : objects[idx]->instances) {
|
for (ModelInstance *mi : objects[idx]->instances) {
|
||||||
m_unselected.emplace_back(get_arrange_poly(PtrWrapper{mi}, m_plater));
|
ArrangePolygon ap = get_arrange_poly(PtrWrapper{mi}, m_plater);
|
||||||
m_unselected.back().bed_idx = 0;
|
auto ap_bb = ap.transformed_poly().contour.bounding_box();
|
||||||
|
|
||||||
|
if (ap.bed_idx == 0 && !bedbb.contains(ap_bb))
|
||||||
|
ap.bed_idx = arrangement::UNARRANGED;
|
||||||
|
|
||||||
|
m_unselected.emplace_back(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto wt = get_wipe_tower_arrangepoly(*m_plater))
|
if (auto wt = get_wipe_tower_arrangepoly(*m_plater))
|
||||||
@ -55,18 +64,17 @@ void FillBedJob::prepare()
|
|||||||
double unsel_area = std::accumulate(m_unselected.begin(),
|
double unsel_area = std::accumulate(m_unselected.begin(),
|
||||||
m_unselected.end(), 0.,
|
m_unselected.end(), 0.,
|
||||||
[](double s, const auto &ap) {
|
[](double s, const auto &ap) {
|
||||||
return s + ap.poly.area();
|
return s + (ap.bed_idx == 0) * ap.poly.area();
|
||||||
}) / sc;
|
}) / sc;
|
||||||
|
|
||||||
double fixed_area = unsel_area + m_selected.size() * poly_area;
|
double fixed_area = unsel_area + m_selected.size() * poly_area;
|
||||||
|
double bed_area = Polygon{m_bedpts}.area() / sc;
|
||||||
|
|
||||||
// This is the maximum range, the real number will always be close but less.
|
// This is the maximum number of items, the real number will always be close but less.
|
||||||
double bed_area = Polygon{m_bedpts}.area() / sc;
|
int needed_items = (bed_area - fixed_area) / poly_area;
|
||||||
|
|
||||||
m_status_range = (bed_area - fixed_area) / poly_area;
|
|
||||||
|
|
||||||
ModelInstance *mi = model_object->instances[0];
|
ModelInstance *mi = model_object->instances[0];
|
||||||
for (int i = 0; i < m_status_range; ++i) {
|
for (int i = 0; i < needed_items; ++i) {
|
||||||
ArrangePolygon ap;
|
ArrangePolygon ap;
|
||||||
ap.poly = m_selected.front().poly;
|
ap.poly = m_selected.front().poly;
|
||||||
ap.bed_idx = arrangement::UNARRANGED;
|
ap.bed_idx = arrangement::UNARRANGED;
|
||||||
@ -77,20 +85,28 @@ void FillBedJob::prepare()
|
|||||||
};
|
};
|
||||||
m_selected.emplace_back(ap);
|
m_selected.emplace_back(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_status_range = m_selected.size();
|
||||||
|
|
||||||
|
// The strides have to be removed from the fixed items. For the
|
||||||
|
// arrangeable (selected) items bed_idx is ignored and the
|
||||||
|
// translation is irrelevant.
|
||||||
|
double stride = bed_stride(m_plater);
|
||||||
|
for (auto &p : m_unselected)
|
||||||
|
if (p.bed_idx > 0)
|
||||||
|
p.translation(X) -= p.bed_idx * stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillBedJob::process()
|
void FillBedJob::process()
|
||||||
{
|
{
|
||||||
if (m_object_idx == -1 || m_selected.empty()) return;
|
if (m_object_idx == -1 || m_selected.empty()) return;
|
||||||
|
|
||||||
GLCanvas3D::ArrangeSettings settings =
|
const GLCanvas3D::ArrangeSettings &settings =
|
||||||
m_plater->canvas3D()->get_arrange_settings();
|
static_cast<const GLCanvas3D*>(m_plater->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 = m_plater->config()->opt_bool("complete_objects") ?
|
params.min_obj_distance = scaled(settings.distance);
|
||||||
scaled(settings.distance_seq_print) :
|
|
||||||
scaled(settings.distance);
|
|
||||||
|
|
||||||
bool do_stop = false;
|
bool do_stop = false;
|
||||||
params.stopcondition = [this, &do_stop]() {
|
params.stopcondition = [this, &do_stop]() {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/system/error_code.hpp>
|
||||||
#include <boost/filesystem/convenience.hpp>
|
#include <boost/filesystem/convenience.hpp>
|
||||||
#include <boost/process.hpp>
|
#include <boost/process.hpp>
|
||||||
#endif
|
#endif
|
||||||
@ -187,8 +188,9 @@ namespace search_for_drives_internal
|
|||||||
//if not same file system - could be removable drive
|
//if not same file system - could be removable drive
|
||||||
if (! compare_filesystem_id(path, parent_path)) {
|
if (! compare_filesystem_id(path, parent_path)) {
|
||||||
//free space
|
//free space
|
||||||
boost::filesystem::space_info si = boost::filesystem::space(path);
|
boost::system::error_code ec;
|
||||||
if (si.available != 0) {
|
boost::filesystem::space_info si = boost::filesystem::space(path, ec);
|
||||||
|
if (!ec && si.available != 0) {
|
||||||
//user id
|
//user id
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
stat(path.c_str(), &buf);
|
stat(path.c_str(), &buf);
|
||||||
|
@ -16,6 +16,12 @@
|
|||||||
#include "Plater.hpp"
|
#include "Plater.hpp"
|
||||||
#include "../Utils/MacDarkMode.hpp"
|
#include "../Utils/MacDarkMode.hpp"
|
||||||
|
|
||||||
|
#ifdef __Linux__
|
||||||
|
#define wxLinux true
|
||||||
|
#else
|
||||||
|
#define wxLinux false
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __WXGTK__// msw_menuitem_bitmaps is used for MSW and OSX
|
#ifndef __WXGTK__// msw_menuitem_bitmaps is used for MSW and OSX
|
||||||
static std::map<int, std::string> msw_menuitem_bitmaps;
|
static std::map<int, std::string> msw_menuitem_bitmaps;
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
@ -653,7 +659,7 @@ void ModeButton::focus_button(const bool focus)
|
|||||||
Slic3r::GUI::wxGetApp().normal_font();
|
Slic3r::GUI::wxGetApp().normal_font();
|
||||||
|
|
||||||
SetFont(new_font);
|
SetFont(new_font);
|
||||||
SetForegroundColour(wxSystemSettings::GetColour(focus ? wxSYS_COLOUR_BTNTEXT : wxSYS_COLOUR_BTNSHADOW));
|
SetForegroundColour(wxSystemSettings::GetColour(focus ? wxSYS_COLOUR_BTNTEXT : wxLinux ? wxSYS_COLOUR_GRAYTEXT : wxSYS_COLOUR_BTNSHADOW));
|
||||||
|
|
||||||
Refresh();
|
Refresh();
|
||||||
Update();
|
Update();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user