Precise Seam: slice modifiers in the belt slicing frame

slice_single_volume_regions() sliced Precise Seam modifiers with
trafo_centered(), but a belt printer slices its layers with
trafo_sliced(): the belt rotation, any pre-slice remap and the lift off
the plate on top. On a belt print the modifier regions landed in the
unrotated frame, away from the walls they were meant to place the seam
on. Slice them with trafo_sliced(), as the support volumes and the seam
enforcers already are. It equals trafo_centered() off a belt printer.
This commit is contained in:
harrierpigeon
2026-10-04 19:22:42 -05:00
parent e8a499df7b
commit 1b4153f0cd
2 changed files with 45 additions and 2 deletions
+3 -2
View File
@@ -1832,10 +1832,11 @@ std::vector<ExPolygons> PrintObject::slice_single_volume_regions(const ModelVolu
{
if (volume == nullptr)
return {};
// Match the existing slicing heights and centered transform without flattening holes.
// Match the existing slicing heights and the frame the layers were sliced in (belt
// pre-slice transforms included) without flattening holes.
const std::vector<float> zs = zs_from_layers(this->layers());
MeshSlicingParamsEx params;
params.trafo = this->trafo_centered();
params.trafo = this->trafo_sliced();
const Print *print = this->print();
return slice_volume(*volume, zs, params, [print]() { print->throw_if_canceled(); });
}
+42
View File
@@ -1426,3 +1426,45 @@ TEST_CASE("Full containment warns for Blocked but not for Enforced", "[PreciseSe
else
CHECK(fixture.warning().empty());
}
TEST_CASE("Belt printers slice Precise Seam modifiers in the frame the object was sliced in", "[PreciseSeam][belt]")
{
Model model;
Print print;
Test::init_print({Test::cube(20)}, print, model, {
{ "belt_printer", 1 },
{ "belt_slice_rotation", "x" },
{ "belt_slice_rotation_angle", 45 },
{ "belt_slice_rotation_global", 1 },
{ "layer_height", 0.2 },
{ "initial_layer_print_height", 0.2 },
{ "skirt_loops", 0 },
// Keep the first layer's islands the raw slice, like the modifier's.
{ "elefant_foot_compensation", 0 },
});
print.process();
const PrintObject *object = print.get_object(0);
REQUIRE(object->layer_count() > 0);
// A modifier with the object's own mesh and placement must slice to the object's own islands
// on every layer. Sliced without the belt rotation it would give 20 mm squares on the lower
// layers and nothing above 20 mm, while the tilted cube reaches about 28 mm.
Model modifiers;
ModelVolume *modifier = modifiers.add_object()->add_volume(*model.objects.front()->volumes.front());
modifier->set_type(ModelVolumeType::PRECISE_SEAM_BLOCKED);
const std::vector<ExPolygons> slices = object->slice_single_volume_regions(modifier);
REQUIRE(slices.size() == object->layer_count());
const double tolerance = scale_(0.05) * scale_(20.);
for (size_t i = 0; i < slices.size(); ++i) {
CAPTURE(i, object->get_layer(int(i))->slice_z);
const ExPolygons &islands = object->get_layer(int(i))->lslices;
double object_area = 0., modifier_area = 0.;
for (const ExPolygon &island : islands)
object_area += island.area();
for (const ExPolygon &region : slices[i])
modifier_area += region.area();
CHECK(std::abs(modifier_area - object_area) < tolerance);
CHECK(get_extents(slices[i]).inflated(scale_(0.05)).contains(get_extents(islands)));
}
}