mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-07 07:41:06 +00:00
Belt printer: size the layer range from the on-bed box
The belt object height is estimated from a bounding box swept through the tilt rotation. raw_bounding_box() has the instance's Z offset removed, which did not matter while the estimate was the box's rotated Z extent (a Z shift moves every corner alike), but the frame now starts at the lowest belt-floor point under the footprint, and a point's rotated z and the floor under it move in opposite directions under a Z shift: the offset box under-estimated the height by twice the object's height above the bed, so the layers stopped at the part's diagonal and every part came out as a wedge (GUI and CLI alike; the unit tests never checked the top). Use the box of the mesh in the frame it is sliced in (trafo_centered(), Z as placed on the bed), and have the leading overhang test check that the whole part is sliced. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
dda58b07cd
commit
a2f5a8ce2b
@@ -4141,7 +4141,17 @@ void PrintObject::update_slicing_parameters()
|
||||
BeltTransformPipeline::BeltFloorParams belt_floor;
|
||||
const auto &pcfg = this->print()->config();
|
||||
if (pcfg.belt_printer.value) {
|
||||
const BoundingBoxf3 bb = this->model_object()->raw_bounding_box();
|
||||
// The box of the mesh in the frame it is sliced in: XY centred and Z as
|
||||
// placed on the bed (trafo_centered()). raw_bounding_box() has the
|
||||
// instance's Z offset removed, and the belt floor is not invariant to a
|
||||
// Z shift (a point's z and the floor under it move in opposite
|
||||
// directions under the rotation), so an offset box under-estimates the
|
||||
// height by twice the shift and the layers stop part way up the object.
|
||||
BoundingBoxf3 bb;
|
||||
const Transform3d trafo = this->trafo_centered();
|
||||
for (const ModelVolume *v : this->model_object()->volumes)
|
||||
if (v->is_model_part())
|
||||
bb.merge(v->mesh().transformed_bounding_box(trafo * v->get_matrix()));
|
||||
auto hr = BeltTransformPipeline::compute_belt_height_and_floor(pcfg, bb, object_height);
|
||||
object_height = hr.object_height;
|
||||
belt_floor = hr.floor_params;
|
||||
@@ -4202,6 +4212,13 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig &full
|
||||
BoundingBoxf3 bb = model_object.raw_bounding_box();
|
||||
object_max_z = (float)bb.size().z();
|
||||
if (print_config.belt_printer.value) {
|
||||
// Z as placed on the bed, XY around the instance origin: the belt floor
|
||||
// depends on where the box sits in Z (see update_slicing_parameters()).
|
||||
if (! model_object.instances.empty()) {
|
||||
bb = model_object.instance_bounding_box(0, false);
|
||||
const Vec3d off = model_object.instances.front()->get_offset();
|
||||
bb.translate(-off.x(), -off.y(), 0.);
|
||||
}
|
||||
auto hr = BeltTransformPipeline::compute_belt_height_and_floor(print_config, bb, object_max_z);
|
||||
object_max_z = (float)hr.object_height;
|
||||
belt_floor = hr.floor_params;
|
||||
|
||||
@@ -1305,6 +1305,22 @@ TEST_CASE("Belt supports reach the belt under a leading overhang", "[Print][belt
|
||||
|
||||
const PrintObject &object = *print.objects().front();
|
||||
REQUIRE(! object.layers().empty());
|
||||
// The whole part is sliced: the layers lean at 45 deg, so the part spans
|
||||
// (y + z) / sqrt(2) of slicing Z, and every layer in that span has geometry.
|
||||
{
|
||||
double lo = std::numeric_limits<double>::max(), hi = std::numeric_limits<double>::lowest();
|
||||
for (const stl_vertex &v : mesh.its.vertices) {
|
||||
lo = std::min<double>(lo, v.y() + v.z());
|
||||
hi = std::max<double>(hi, v.y() + v.z());
|
||||
}
|
||||
const double span = (hi - lo) / std::sqrt(2.);
|
||||
size_t nonempty = 0;
|
||||
for (const Layer *layer : object.layers())
|
||||
if (! layer->lslices.empty())
|
||||
++ nonempty;
|
||||
INFO("non-empty object layers " << nonempty << ", slicing span " << span << " mm");
|
||||
CHECK(double(nonempty) * 0.2 > span - 0.6);
|
||||
}
|
||||
BeltFloorContext floor;
|
||||
REQUIRE(floor.init(object.slicing_parameters(), print.config()));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user