Merge upstream main: belt printing, texture displacement color mixing, 3MF component cycle checks, undo blocked during background jobs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Clifford GarwoodandClaude Opus 5.5 committed 2026-10-09 07:44:12 -04:00
commit f970a607ae
227 files changed
+14506 -1079

No files matched your search

+31 -4
View File
@@ -1555,6 +1555,17 @@ void PartPlate::calc_height_limit() {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to create height limit top lines\n";
}
// The plate's icons and labels grow with its depth, but they sit in the gap to the
// next plate, which grows with its width: on a long, narrow bed (a belt) they would
// otherwise run across the neighbouring plate.
float PartPlate::icon_scale_factor() const
{
const BoundingBoxf bed_ext = get_extents(m_shape);
const double by_depth = bed_ext.size().y() / 200.;
const double by_gap = bed_ext.size().x() * LOGICAL_PART_PLATE_GAP / (PARTPLATE_ICON_SIZE + 2 * PARTPLATE_ICON_GAP_LEFT);
return float(std::min(by_depth, by_gap));
}
void PartPlate::calc_vertex_for_number(int index, bool one_number, GLModel &buffer)
{
buffer.reset();
@@ -1571,7 +1582,7 @@ void PartPlate::calc_vertex_for_number(int index, bool one_number, GLModel &buff
#else //in the bottom
auto bed_ext = get_extents(m_shape);
Vec2d p = bed_ext[1];
float factor = bed_ext.size()(1) / 200.0;
float factor = icon_scale_factor();
float size = PARTPLATE_ICON_SIZE * factor;
float offset_y = PARTPLATE_TEXT_OFFSET_Y * factor;
float offset_x = (one_number?PARTPLATE_TEXT_OFFSET_X1: PARTPLATE_TEXT_OFFSET_X2) * factor;
@@ -1593,7 +1604,7 @@ void PartPlate::calc_vertex_for_plate_name_edit_icon(GLTexture *texture, int ind
ExPolygon poly;
auto bed_ext = get_extents(m_shape);
Vec2d p = bed_ext[3];
float factor = bed_ext.size()(1) / 200.0;
float factor = icon_scale_factor();
float icon_sz = factor * PARTPLATE_EDIT_PLATE_NAME_ICON_SIZE;
float width = icon_sz;
float height = icon_sz;
@@ -1626,7 +1637,7 @@ void PartPlate::calc_vertex_for_icons(int index, PickingModel &model)
ExPolygon poly;
auto bed_ext = get_extents(m_shape);
Vec2d p = bed_ext[2];
auto factor = bed_ext.size()(1) / 200.0;
float factor = icon_scale_factor();
float size = PARTPLATE_ICON_SIZE * factor;
float gap_left = PARTPLATE_ICON_GAP_LEFT * factor;
float gap_y = PARTPLATE_ICON_GAP_Y * factor;
@@ -3569,7 +3580,7 @@ void PartPlate::generate_plate_name_texture()
ExPolygon poly;
auto bed_ext = get_extents(m_shape);
Vec2d p = bed_ext[3];
float factor = bed_ext.size()(1) / 200.0;
float factor = icon_scale_factor();
float icon_sz = factor * PARTPLATE_EDIT_PLATE_NAME_ICON_SIZE;
float width = icon_sz * m_name_texture.get_width() / m_name_texture.get_height(); // icon size * text_bb_ratio
float height = icon_sz; // scale with icon size to preserve ratio while system scaling
@@ -3775,6 +3786,7 @@ bool PartPlate::check_outside(int obj_id, int instance_id, BoundingBoxf3* boundi
BoundingBoxf3 instance_box = bounding_box? *bounding_box: object->instance_convex_hull_bounding_box(instance_id);
Polygon hull = instance->convex_hull_2d();
BoundingBoxf3 plate_box = get_plate_box();
this->open_belt_y(plate_box);
if (instance_box.max.z() > plate_box.min.z())
plate_box.min.z() += instance_box.min.z(); // not considering outsize if sinking
@@ -4479,6 +4491,19 @@ Polygon PartPlate::get_shared_printable_polygon() const
return m_extruder_areas.empty() ? Polygon::new_scale(m_shape) : get_shared_poly(m_extruder_areas);
}
bool PartPlate::belt_open_y() const
{
// Headless (CLI) plates have no plater and no wxApp behind wxGetApp(); the CLI's own belt
// handling lives in Print::validate().
if (m_plater == nullptr || wxGetApp().preset_bundle == nullptr)
return false;
const DynamicPrintConfig &printer = wxGetApp().preset_bundle->printers.get_edited_preset().config;
const auto *belt = printer.option<ConfigOptionBool>("belt_printer");
const auto *infinite_y = printer.option<ConfigOptionBool>("belt_printer_infinite_y");
return belt != nullptr && belt->value && infinite_y != nullptr && infinite_y->value;
}
bool PartPlate::contains(const Vec3d& point) const
{
return m_bounding_box.contains(point);
@@ -4498,6 +4523,7 @@ bool PartPlate::contains(const BoundingBoxf3& bb) const
print_volume.min(1) -= Slic3r::BuildVolume::BedEpsilon;
print_volume.max(0) += Slic3r::BuildVolume::BedEpsilon;
print_volume.max(1) += Slic3r::BuildVolume::BedEpsilon;
this->open_belt_y(print_volume);
return print_volume.contains(bb);
}
@@ -4510,6 +4536,7 @@ bool PartPlate::intersects(const BoundingBoxf3& bb) const
print_volume.min(1) -= Slic3r::BuildVolume::BedEpsilon;
print_volume.max(0) += Slic3r::BuildVolume::BedEpsilon;
print_volume.max(1) += Slic3r::BuildVolume::BedEpsilon;
this->open_belt_y(print_volume);
return print_volume.intersects(bb);
}