mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-04 05:50:47 +08:00
Do not account for bed model for spacing calculation
This commit is contained in:
parent
45eda1a00f
commit
311434382d
@ -96,14 +96,20 @@ Vec3d MultipleBeds::get_bed_translation(int id) const
|
||||
return Vec3d::Zero();
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
if (m_layout_linear)
|
||||
if (m_legacy_layout)
|
||||
x = id;
|
||||
else {
|
||||
BedsGrid::GridCoords coords{BedsGrid::index2grid_coords(id)};
|
||||
x = coords.x();
|
||||
y = coords.y();
|
||||
}
|
||||
return Vec3d(x * m_build_volume_bb_incl_model.size().x() * (1. + bed_gap_x), y * m_build_volume_bb_incl_model.size().y() * (1. + bed_gap_y), 0.);
|
||||
|
||||
// As for the m_legacy_layout switch, see comments at definition of bed_gap_relative.
|
||||
Vec2d gap = bed_gap();
|
||||
double gap_x = (m_legacy_layout ? m_build_volume_bb.size().x() * (2./10.) : gap.x());
|
||||
return Vec3d(x * (m_build_volume_bb.size().x() + gap_x),
|
||||
y * (m_build_volume_bb.size().y() + gap.y()), // When using legacy layout, y is zero anyway.
|
||||
0.);
|
||||
}
|
||||
|
||||
void MultipleBeds::clear_inst_map()
|
||||
@ -207,13 +213,12 @@ void MultipleBeds::update_shown_beds(Model& model, const BuildVolume& build_volu
|
||||
set_active_bed(m_number_of_beds != original_number_of_beds ? 0 : stash_active);
|
||||
}
|
||||
|
||||
// Beware! This function is also needed for proper update of bed when normal grid project is loaded!
|
||||
bool MultipleBeds::update_after_load_or_arrange(Model& model, const BuildVolume& build_volume, std::function<void()> update_fn)
|
||||
bool MultipleBeds::rearrange_after_load(Model& model, const BuildVolume& build_volume, std::function<void()> update_fn)
|
||||
{
|
||||
int original_number_of_beds = m_number_of_beds;
|
||||
int stash_active = get_active_bed();
|
||||
Slic3r::ScopeGuard guard([&]() {
|
||||
m_layout_linear = false;
|
||||
m_legacy_layout = false;
|
||||
m_number_of_beds = get_max_beds();
|
||||
model.update_print_volume_state(build_volume);
|
||||
int max_bed = 0;
|
||||
@ -226,8 +231,7 @@ bool MultipleBeds::update_after_load_or_arrange(Model& model, const BuildVolume&
|
||||
update_fn();
|
||||
});
|
||||
|
||||
m_layout_linear = true;
|
||||
std::swap(m_build_volume_bb, m_build_volume_bb_incl_model);
|
||||
m_legacy_layout = true;
|
||||
int abs_max = get_max_beds();
|
||||
while (true) {
|
||||
// This is to ensure that even objects on linear bed with higher than
|
||||
@ -242,10 +246,11 @@ bool MultipleBeds::update_after_load_or_arrange(Model& model, const BuildVolume&
|
||||
abs_max += get_max_beds();
|
||||
}
|
||||
m_number_of_beds = 1;
|
||||
std::swap(m_build_volume_bb, m_build_volume_bb_incl_model);
|
||||
m_legacy_layout = false;
|
||||
|
||||
int max_bed = 0;
|
||||
|
||||
// Check that no instances are out of any bed.
|
||||
std::map<ObjectID, std::pair<ModelInstance*, int>> id_to_ptr_and_bed;
|
||||
for (ModelObject* mo : model.objects) {
|
||||
for (ModelInstance* mi : mo->instances) {
|
||||
@ -267,27 +272,34 @@ bool MultipleBeds::update_after_load_or_arrange(Model& model, const BuildVolume&
|
||||
return false;
|
||||
|
||||
// All instances are on some bed, at least two are used.
|
||||
// Move everything as if its bed was in the first position.
|
||||
for (auto& [oid, mi_and_bed] : id_to_ptr_and_bed) {
|
||||
auto& [mi, bed_idx] = mi_and_bed;
|
||||
std::swap(m_build_volume_bb, m_build_volume_bb_incl_model);
|
||||
m_legacy_layout = true;
|
||||
mi->set_offset(mi->get_offset() - get_bed_translation(bed_idx));
|
||||
std::swap(m_build_volume_bb, m_build_volume_bb_incl_model);
|
||||
}
|
||||
|
||||
m_layout_linear = false;
|
||||
for (auto& [oid, mi_and_bed] : id_to_ptr_and_bed) {
|
||||
auto& [mi, bed_idx] = mi_and_bed;
|
||||
m_legacy_layout = false;
|
||||
mi->set_offset(mi->get_offset() + get_bed_translation(bed_idx));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vec2d MultipleBeds::bed_gap() const
|
||||
{
|
||||
// This is the only function that defines how far apart should the beds be. Used in scene and arrange.
|
||||
// Note that the spacing is momentarily switched to legacy value of 2/10 when a project is loaded.
|
||||
// Slicers before 2.9.0 used this value for arrange, and there are existing projects with objects spaced that way (controlled by the m_legacy_layout flag).
|
||||
|
||||
// TOUCHING THIS WILL BREAK LOADING OF EXISTING PROJECTS !!!
|
||||
|
||||
double gap = std::min(100., m_build_volume_bb.size().norm() * (3./10.));
|
||||
return Vec2d::Ones() * gap;
|
||||
}
|
||||
|
||||
|
||||
Vec2crd MultipleBeds::get_bed_gap() const {
|
||||
const Vec2d size_with_gap{
|
||||
m_build_volume_bb_incl_model.size().cwiseProduct(
|
||||
Vec2d::Ones() + Vec2d{bed_gap_x, bed_gap_y})};
|
||||
return scaled(Vec2d{(size_with_gap - m_build_volume_bb.size()) / 2.0});
|
||||
return scaled(Vec2d{bed_gap() / 2.0});
|
||||
};
|
||||
|
||||
void MultipleBeds::ensure_wipe_towers_on_beds(Model& model, const std::vector<std::unique_ptr<Print>>& prints)
|
||||
|
@ -53,15 +53,15 @@ public:
|
||||
int get_last_hovered_bed() const { return m_last_hovered_bed; }
|
||||
|
||||
void update_shown_beds(Model& model, const BuildVolume& build_volume);
|
||||
bool update_after_load_or_arrange(Model& model, const BuildVolume& build_volume, std::function<void()> update_fn);
|
||||
bool rearrange_after_load(Model& model, const BuildVolume& build_volume, std::function<void()> update_fn);
|
||||
void set_loading_project_flag(bool project) { m_loading_project = project; }
|
||||
bool get_loading_project_flag() const { return m_loading_project; }
|
||||
|
||||
void update_build_volume(const BoundingBoxf& build_volume_bb, const BoundingBoxf& build_volume_bb_incl_model) {
|
||||
void update_build_volume(const BoundingBoxf& build_volume_bb) {
|
||||
m_build_volume_bb = build_volume_bb;
|
||||
m_build_volume_bb_incl_model = build_volume_bb_incl_model;
|
||||
}
|
||||
Vec2crd get_bed_gap() const;
|
||||
Vec2d bed_gap() const;
|
||||
Vec2crd get_bed_gap() const;
|
||||
void ensure_wipe_towers_on_beds(Model& model, const std::vector<std::unique_ptr<Print>>& prints);
|
||||
|
||||
private:
|
||||
@ -75,17 +75,9 @@ private:
|
||||
std::map<PrintBase*, size_t> m_printbase_to_texture;
|
||||
int m_last_hovered_bed = -1;
|
||||
BoundingBoxf m_build_volume_bb;
|
||||
BoundingBoxf m_build_volume_bb_incl_model;
|
||||
bool m_layout_linear = false;
|
||||
bool m_legacy_layout = false;
|
||||
bool m_loading_project = false;
|
||||
|
||||
// The x value is bed gap as multiples of the actual printable area bounding box,
|
||||
// so it can be matched to how the old slicer arranged things (in SceneBuilder.cpp).
|
||||
// The y value is a multiple of the larger of printable area BB and bed model BB -
|
||||
// this is to make sure that the bed models do not overlap.
|
||||
const double bed_gap_x = 2./10;
|
||||
const double bed_gap_y = 2./10;
|
||||
|
||||
};
|
||||
|
||||
extern MultipleBeds s_multiple_beds;
|
||||
|
@ -102,9 +102,18 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c
|
||||
init_internal_model_from_file();
|
||||
init_triangles();
|
||||
|
||||
BoundingBoxf bb = m_build_volume.bounding_volume2d();
|
||||
bb.max = Vec2d(bb.max.x() + std::max(0., m_model.model.get_bounding_box().size().x() - bb.size().x()), bb.max.y() + std::max(0., m_model.model.get_bounding_box().size().y() - bb.size().y()));
|
||||
s_multiple_beds.update_build_volume(m_build_volume.bounding_volume2d(), bb);
|
||||
s_multiple_beds.update_build_volume(m_build_volume.bounding_volume2d());
|
||||
|
||||
m_models_overlap = false;
|
||||
if (! m_model_filename.empty()) {
|
||||
// Calculate bb of the bed model and figure out if the models would overlap when rendered next to each other.
|
||||
const BoundingBoxf3& mdl_bb3 = m_model.model.get_bounding_box();
|
||||
const BoundingBoxf model_bb(Vec2d(mdl_bb3.min.x(), mdl_bb3.min.y()), Vec2d(mdl_bb3.max.x(), mdl_bb3.max.y()));
|
||||
BoundingBoxf bed_bb = m_build_volume.bounding_volume2d();
|
||||
bed_bb.translate(-m_model_offset.x(), -m_model_offset.y());
|
||||
Vec2d gap = unscale(s_multiple_beds.get_bed_gap());
|
||||
m_models_overlap = (model_bb.size().x() - bed_bb.size().x() > 2 * gap.x() || model_bb.size().y() - bed_bb.size().y() > 2 * gap.y());
|
||||
}
|
||||
|
||||
// Set the origin and size for rendering the coordinate system axes.
|
||||
m_axes.set_origin({ 0.0, 0.0, static_cast<double>(GROUND_Z) });
|
||||
@ -345,6 +354,11 @@ void Bed3D::render_axes()
|
||||
|
||||
void Bed3D::render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture, bool is_active)
|
||||
{
|
||||
if (m_models_overlap && s_multiple_beds.get_number_of_beds() + int(s_multiple_beds.should_show_next_bed()) > 1) {
|
||||
render_default(bottom, false, show_texture, view_matrix, projection_matrix);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bottom)
|
||||
render_model(view_matrix, projection_matrix);
|
||||
|
||||
@ -507,7 +521,8 @@ void Bed3D::render_model(const Transform3d& view_matrix, const Transform3d& proj
|
||||
|
||||
void Bed3D::render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture, bool picking, bool is_active)
|
||||
{
|
||||
if (m_texture_filename.empty() && m_model_filename.empty()) {
|
||||
if ((m_texture_filename.empty() && m_model_filename.empty())
|
||||
|| (m_models_overlap && s_multiple_beds.get_number_of_beds() + int(s_multiple_beds.should_show_next_bed()) > 1)) {
|
||||
render_default(bottom, picking, show_texture, view_matrix, projection_matrix);
|
||||
return;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ private:
|
||||
Type m_type{ Type::Custom };
|
||||
std::string m_texture_filename;
|
||||
std::string m_model_filename;
|
||||
bool m_models_overlap;
|
||||
// Print volume bounding box exteded with axes and model.
|
||||
BoundingBoxf3 m_extended_bounding_box;
|
||||
// Print bed polygon
|
||||
|
@ -1600,7 +1600,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
GLGizmoSimplify::add_simplify_suggestion_notification(
|
||||
obj_idxs, model.objects, *notification_manager);
|
||||
|
||||
if (s_multiple_beds.update_after_load_or_arrange(model, q->build_volume(), [this]() {
|
||||
if (s_multiple_beds.rearrange_after_load(model, q->build_volume(), [this]() {
|
||||
q->canvas3D()->check_volumes_outside_state();
|
||||
s_multiple_beds.ensure_wipe_towers_on_beds(model, fff_prints);
|
||||
}))
|
||||
@ -4207,11 +4207,11 @@ void Plater::load_project(const wxString& filename)
|
||||
// Take the Undo / Redo snapshot.
|
||||
Plater::TakeSnapshot snapshot(this, _L("Load Project") + ": " + wxString::FromUTF8(into_path(filename).stem().string().c_str()), UndoRedo::SnapshotType::ProjectSeparator);
|
||||
|
||||
p->reset();
|
||||
|
||||
s_multiple_beds.set_loading_project_flag(true);
|
||||
ScopeGuard guard([](){ s_multiple_beds.set_loading_project_flag(false);});
|
||||
|
||||
p->reset();
|
||||
|
||||
if (! load_files({ into_path(filename) }).empty()) {
|
||||
// At least one file was loaded.
|
||||
p->set_project_filename(filename);
|
||||
|
Loading…
x
Reference in New Issue
Block a user