Merge upstream/main into belt/rebase/may-18

Reconciles the belt-printer branch with upstream PRs through #13723. Six
files had conflicts; three additional files needed manual follow-up fixes
where the auto-merge produced code that referenced upstream-renamed fields
or changed function signatures.

Notable reconciliations:
- TreeSupport.cpp: kept belt-floor early-exit branches around HEAD's
  drop-down logic, folded upstream's `(distance_to_top > 0 ? 1 : 0)`
  formula into the non-belt-floor path (upstream PR #11812). Dropped dead
  `roof_enabled`/`force_tip_to_roof` locals.
- TreeSupport3D.cpp: combined upstream's safety-offset + remove_small
  changes with HEAD's belt-floor clip in the per-slice trim loop. Dropped
  HEAD's `else` block (superseded by upstream's rewritten bottom-contact
  propagation) and re-added the belt-floor clip into the new propagation
  loop. Gated the propagation on belt printers to prevent OOM when
  belt-floor clipping produces empty initial slices.
- TriangleSelector.{cpp,hpp}: merged both new `select_patch` parameters
  (HEAD's `up_direction` and upstream's `select_partially`); body uses
  `dot(up_direction)` for the overhang angle check and forwards
  `select_partially` to `select_triangle`.
- SupportMaterial.cpp: `slicing_params.soluble_interface` →
  `zero_gap_interface_bottom` in HEAD's `detect_belt_floor_bottom_contacts`,
  matching upstream's same-purpose rename at line 2495.
- Custom.json, GCodeWriter.cpp: simple additive merges (kept entries /
  includes from both sides).

Verified by building OrcaSlicer (RelWithDebInfo) after a full deps
rebuild (Eigen v5.0.1, libigl v2.6.0 are now managed deps) and slicing
a scaled Benchy on the NORMALIZER belt-printer profile without OOM.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
harrierpigeon
2026-05-18 21:53:24 -05:00
co-authored by Claude Opus 4.7
2143 changed files with 130163 additions and 174147 deletions
+10 -10
View File
@@ -1795,7 +1795,7 @@ static inline std::pair<SupportGeneratorLayer*, SupportGeneratorLayer*> new_cont
print_z = slicing_params.raft_contact_top_z;
bottom_z = slicing_params.raft_interface_top_z;
height = slicing_params.contact_raft_layer_height;
} else if (slicing_params.soluble_interface) {
} else if (slicing_params.zero_gap_interface_top) {
// Align the contact surface height with a layer immediately below the supported layer.
// Interface layer will be synchronized with the object.
print_z = layer.bottom_z();
@@ -1918,7 +1918,7 @@ static inline void fill_contact_layer(
#endif // SLIC3R_DEBUG
));
// 2) infill polygons, expand them by half the extrusion width + a tiny bit of extra.
bool reduce_interfaces = object_config.support_style.value != smsSnug && layer_id > 0 && !slicing_params.soluble_interface;
bool reduce_interfaces = object_config.support_style.value != smsSnug && layer_id > 0 && !slicing_params.zero_gap_interface_top;
if (reduce_interfaces) {
// Reduce the amount of dense interfaces: Do not generate dense interfaces below overhangs with 60% overhang of the extrusions.
Polygons dense_interface_polygons = diff(overhang_polygons, lower_layer_polygons_for_dense_interface());
@@ -2477,12 +2477,12 @@ static inline SupportGeneratorLayer* detect_bottom_contacts(
Layer* upper_layer = layer.upper_layer;
if (object.print()->config().independent_support_layer_height) {
// If the layer is extruded with no bridging flow, support just the normal extrusions.
layer_new.height = slicing_params.soluble_interface ?
layer_new.height = slicing_params.zero_gap_interface_bottom ?
// Align the interface layer with the object's layer height.
upper_layer->height :
// Place a bridge flow interface layer or the normal flow interface layer over the top surface.
support_params.support_material_bottom_interface_flow.height();
layer_new.print_z = slicing_params.soluble_interface ? upper_layer->print_z :
layer_new.print_z = slicing_params.zero_gap_interface_bottom ? upper_layer->print_z :
layer.print_z + layer_new.height + slicing_params.gap_object_support;
}
else {
@@ -2492,11 +2492,11 @@ static inline SupportGeneratorLayer* detect_bottom_contacts(
}
layer_new.bottom_z = layer.print_z;
layer_new.idx_object_layer_below = layer_id;
layer_new.bridging = !slicing_params.soluble_interface && object.config().thick_bridges;
layer_new.bridging = !slicing_params.zero_gap_interface_bottom && object.config().thick_bridges;
//FIXME how much to inflate the bottom surface, as it is being extruded with a bridging flow? The following line uses a normal flow.
layer_new.polygons = expand(touching, float(support_params.support_material_flow.scaled_width()), SUPPORT_SURFACES_OFFSET_PARAMETERS);
if (! slicing_params.soluble_interface) {
if (!slicing_params.zero_gap_interface_bottom) {
// Walk the top surfaces, snap the top of the new bottom surface to the closest top of the top surface,
// so there will be no support surfaces generated with thickness lower than m_support_layer_height_min.
for (size_t top_idx = size_t(std::max<int>(0, contact_idx));
@@ -2598,10 +2598,10 @@ static inline SupportGeneratorLayer* detect_belt_floor_bottom_contacts(
layer_new.print_z = layer.print_z + layer_new.height + slicing_params.gap_object_support;
layer_new.bottom_z = layer.print_z;
layer_new.idx_object_layer_below = layer_id;
layer_new.bridging = ! slicing_params.soluble_interface && object.config().thick_bridges;
layer_new.bridging = ! slicing_params.zero_gap_interface_bottom && object.config().thick_bridges;
layer_new.polygons = expand(touching, float(support_params.support_material_flow.scaled_width()), SUPPORT_SURFACES_OFFSET_PARAMETERS);
if (! slicing_params.soluble_interface) {
if (! slicing_params.zero_gap_interface_bottom) {
// Snap to nearby top contact layers to avoid very thin support layers.
for (size_t top_idx = size_t(std::max<int>(0, int(contact_idx)));
top_idx < top_contacts.size() && top_contacts[top_idx]->print_z < layer_new.print_z + support_params.support_layer_height_min + EPSILON;
@@ -3071,7 +3071,7 @@ SupportGeneratorLayersPtr PrintObjectSupportMaterial::raft_and_intermediate_supp
// Continue printing the other layers up to extr2z.
step = dist / coordf_t(n_layers_extra);
}
if (! m_slicing_params.soluble_interface && extr2->layer_type == SupporLayerType::TopContact) {
if (!m_slicing_params.zero_gap_interface_top && extr2->layer_type == SupporLayerType::TopContact) {
// This is a top interface layer, which does not have a height assigned yet. Do it now.
assert(extr2->height == 0.);
assert(extr1z > m_slicing_params.first_print_layer_height - EPSILON);
@@ -3359,7 +3359,7 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object(
polygons_append(polygons_trimming, offset({ expoly }, trimming_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS));
}
}
if (! m_slicing_params.soluble_interface && m_object_config->thick_bridges) {
if (!m_slicing_params.zero_gap_interface_top && m_object_config->thick_bridges) {
// Collect all bottom surfaces, which will be extruded with a bridging flow.
for (; i < object.layers().size(); ++ i) {
const Layer &object_layer = *object.layers()[i];