Prepare view: drop the dormant tilted-bed rendering

Plater::set_bed_shape read the belt keys from the plater's own config, which
never carries them, so the branch that tilted the bed model, drew the slicing
arrow and plane and switched the build volume to belt mode never ran. The
Prepare view shows the bed as the slicing pipeline treats it, flat; the
gravity arrow from build_plate_tilt stays, as does the preview's belt view,
which takes its angle from the G-code header.
This commit is contained in:
harrierpigeon
2026-10-03 13:12:41 -05:00
parent 2782374d8d
commit 82c462ab2a
6 changed files with 3 additions and 219 deletions
-30
View File
@@ -180,31 +180,6 @@ BuildVolume::BuildVolume(const std::vector<Vec2d> &printable_area, const double
BOOST_LOG_TRIVIAL(debug) << "BuildVolume printable_area clasified as: " << this->type_name();
}
void BuildVolume::set_belt_printer(bool enabled, double angle_deg, bool infinite_y)
{
m_is_belt_printer = enabled;
m_belt_angle = angle_deg;
m_belt_infinite_y = infinite_y;
// Restart from the unmodified bbox each call. Without this, toggling
// belt mode off (or switching infinite_y true→false) would leave the
// extents inflated and break collision / object_state checks.
BoundingBoxf bboxf = get_extents(m_bed_shape);
m_bboxf = BoundingBoxf3{ to_3d(bboxf.min, 0.), to_3d(bboxf.max, m_max_print_height) };
if (enabled) {
if (infinite_y) {
// Extend the Y bound to a very large value for infinite belt.
m_bboxf.max.y() = 100000.;
}
// Belt printer: the Z extent already equals printable_height (set above), which
// is the usable vertical clearance above the belt. The gantry's axis range is
// sized to reach height/cos(tilt), so no diagonal scaling is applied here — this
// keeps the live "outside build volume" highlight in agreement with Print::validate().
(void) angle_deg;
}
}
#if 0
// Tests intersections of projected triangles, not just their vertices against a bounding box.
// This test also correctly evaluates collision of a non-convex object with the bounding box.
@@ -413,11 +388,6 @@ BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set& i
build_volume.max.z() = std::numeric_limits<double>::max();
if (ignore_bottom)
build_volume.min.z() = -std::numeric_limits<double>::max();
// Belt printer: extend Y bounds for infinite Y.
if (m_is_belt_printer && m_belt_infinite_y) {
build_volume.min.y() = -std::numeric_limits<double>::max();
build_volume.max.y() = std::numeric_limits<double>::max();
}
BoundingBox3Base<Vec3f> build_volumef(build_volume.min.cast<float>(), build_volume.max.cast<float>());
// The following test correctly interprets intersection of a non-convex object with a rectangular build volume.
//return rectangle_test(its, trafo, to_2d(build_volume.min), to_2d(build_volume.max), build_volume.max.z());
-8
View File
@@ -57,10 +57,6 @@ public:
// Initialize from PrintConfig::printable_area and PrintConfig::printable_height
BuildVolume(const std::vector<Vec2d> &printable_area, const double printable_height, const std::vector<std::vector<Vec2d>> &extruder_areas, const std::vector<double>& extruder_printable_heights);
// Belt printer configuration.
void set_belt_printer(bool enabled, double angle_deg, bool infinite_y);
bool is_belt_printer() const { return m_is_belt_printer; }
// Source data, unscaled coordinates.
const std::vector<Vec2d>& printable_area() const { return m_bed_shape; }
double printable_height() const { return m_max_print_height; }
@@ -143,10 +139,6 @@ private:
// Source definition of the print volume height (PrintConfig::printable_height)
double m_max_print_height { 0.f };
std::vector<double> m_extruder_printable_height;
// Belt printer state.
bool m_is_belt_printer { false };
double m_belt_angle { 0. };
bool m_belt_infinite_y { false };
// Derived values.
BuildVolume_Type m_type { BuildVolume_Type::Invalid };
+1 -128
View File
@@ -387,9 +387,6 @@ void Bed3D::render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix,
m_model.set_color(m_is_dark ? DEFAULT_MODEL_COLOR_DARK : DEFAULT_MODEL_COLOR);
// Belt printer: bed rotation is applied inside render_model() and render_default()
// using m_is_belt_printer and m_belt_angle members.
switch (m_type)
{
case Type::System: { render_system(canvas, view_matrix, projection_matrix, bottom); break; }
@@ -398,8 +395,6 @@ void Bed3D::render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix,
}
render_gravity_arrow(view_matrix, projection_matrix);
render_slicing_arrow(view_matrix, projection_matrix);
render_slicing_plane(view_matrix, projection_matrix);
glsafe(::glDisable(GL_DEPTH_TEST));
}
@@ -700,12 +695,6 @@ void Bed3D::render_model(const Transform3d& view_matrix, const Transform3d& proj
shader->start_using();
shader->set_uniform("emission_factor", 0.0f);
Transform3d model_matrix = Geometry::assemble_transform(m_model_offset);
// Belt printer: rotate the bed model about the tilt axis so the belt tilt
// is visible. Negative angle: belt surface tilts downward away from the nozzle.
if (m_is_belt_printer && m_belt_angle > 0.f) {
double angle_rad = Geometry::deg2rad(static_cast<double>(m_belt_angle));
model_matrix = Eigen::AngleAxisd(-angle_rad, belt_tilt_unit_axis()) * model_matrix;
}
shader->set_uniform("volume_world_matrix", model_matrix);
shader->set_uniform("view_model_matrix", view_matrix * model_matrix);
shader->set_uniform("projection_matrix", projection_matrix);
@@ -797,114 +786,6 @@ void Bed3D::render_gravity_arrow(const Transform3d& view_matrix, const Transform
shader->stop_using();
}
void Bed3D::render_slicing_arrow(const Transform3d& view_matrix, const Transform3d& projection_matrix)
{
if (!m_is_belt_printer || m_belt_angle <= 0.f)
return;
// Build the arrow model: shorter and wider than the gravity arrow.
if (!m_slicing_arrow.is_initialized()) {
const float stem_length = 15.0f; // shorter than gravity arrow (25)
const float stem_radius = 1.0f; // wider than gravity arrow (~0.33)
const float tip_radius = 3.0f; // wider tip
const float tip_length = 5.0f;
m_slicing_arrow.init_from(stilized_arrow(16, tip_radius, tip_length, stem_radius, stem_length));
}
// The slicing direction: layers stack along the gantry normal, i.e. the image of
// +Z under the mesh rotation about the tilt axis. Use the same AngleAxis as the
// slicing pipeline so the arrow matches whichever tilt axis is configured.
double angle_rad = Geometry::deg2rad(static_cast<double>(m_belt_angle));
Vec3d slice_dir = (Eigen::AngleAxisd(angle_rad, belt_tilt_unit_axis()).toRotationMatrix()
* Vec3d::UnitZ()).normalized();
// Compute rotation to align +Z (arrow default) with slice_dir.
Vec3d from = Vec3d::UnitZ();
double dot = from.dot(slice_dir);
Transform3d rot = Transform3d::Identity();
if (dot < -0.9999) {
rot = Eigen::AngleAxisd(M_PI, Vec3d::UnitX()) * rot;
} else if (dot < 0.9999) {
Vec3d axis = from.cross(slice_dir).normalized();
double angle = std::acos(std::clamp(dot, -1.0, 1.0));
rot = Eigen::AngleAxisd(angle, axis) * rot;
}
GLShaderProgram* shader = wxGetApp().get_shader("flat");
if (shader == nullptr)
return;
// Disable depth test so the arrow is always visible (not occluded by the tilted bed).
glsafe(::glDisable(GL_DEPTH_TEST));
shader->start_using();
const Camera& camera = wxGetApp().plater()->get_camera();
Transform3d model_matrix = rot;
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * model_matrix);
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
m_slicing_arrow.set_color({ 1.0f, 0.2f, 0.6f, 1.0f }); // pink
m_slicing_arrow.render();
shader->stop_using();
glsafe(::glEnable(GL_DEPTH_TEST));
}
void Bed3D::render_slicing_plane(const Transform3d& view_matrix, const Transform3d& projection_matrix)
{
if (!m_is_belt_printer || m_belt_angle <= 0.f)
return;
// Build a quad in the XZ plane (world frame) representing the belt slicing plane.
// The plane is tilted at belt_angle from horizontal, with normal (0, -sin(a), cos(a)).
// We render it as a semi-transparent quad centered on the build plate.
if (!m_slicing_plane.is_initialized()) {
const float half_size = 120.f; // mm, large enough to be visible
GLModel::Geometry init_data;
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
init_data.reserve_vertices(4);
init_data.reserve_indices(2); // 2 triangles
// Quad corners in local frame (XY plane, will be rotated to match slicing plane)
Vec3f n = Vec3f::UnitZ();
init_data.add_vertex(Vec3f(-half_size, -half_size, 0.f), n);
init_data.add_vertex(Vec3f( half_size, -half_size, 0.f), n);
init_data.add_vertex(Vec3f( half_size, half_size, 0.f), n);
init_data.add_vertex(Vec3f(-half_size, half_size, 0.f), n);
init_data.add_triangle(0, 1, 2);
init_data.add_triangle(0, 2, 3);
m_slicing_plane.init_from(std::move(init_data));
}
GLShaderProgram* shader = wxGetApp().get_shader("flat");
if (shader == nullptr)
return;
glsafe(::glEnable(GL_DEPTH_TEST));
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
shader->start_using();
// Show a tilted plane representing the slicing direction.
// The slicing plane is rotated by belt_angle about the tilt axis from horizontal.
// Raise it slightly so it's visible above the bed surface.
double angle_rad = Geometry::deg2rad(static_cast<double>(m_belt_angle));
Transform3d model_matrix = Transform3d::Identity();
model_matrix.translate(Vec3d(0., 0., 30.));
model_matrix.rotate(Eigen::AngleAxisd(angle_rad, belt_tilt_unit_axis()));
shader->set_uniform("view_model_matrix", view_matrix * model_matrix);
shader->set_uniform("projection_matrix", projection_matrix);
m_slicing_plane.set_color({ 0.2f, 0.6f, 1.0f, 0.3f }); // semi-transparent blue
m_slicing_plane.render();
glsafe(::glDisable(GL_BLEND));
shader->stop_using();
}
void Bed3D::render_default(bool bottom, const Transform3d& view_matrix, const Transform3d& projection_matrix)
{
// m_texture.reset();
@@ -915,15 +796,7 @@ void Bed3D::render_default(bool bottom, const Transform3d& view_matrix, const Tr
if (shader != nullptr) {
shader->start_using();
// Belt printer: rotate the default bed about X so the belt tilt is visible.
Transform3d view_model_matrix = view_matrix;
if (m_is_belt_printer && m_belt_angle > 0.f) {
double angle_rad = Geometry::deg2rad(static_cast<double>(m_belt_angle));
Transform3d belt_rotation = Transform3d::Identity();
belt_rotation.rotate(Eigen::AngleAxisd(-angle_rad, Vec3d::UnitX()));
view_model_matrix = view_matrix * belt_rotation;
}
shader->set_uniform("view_model_matrix", view_model_matrix);
shader->set_uniform("view_model_matrix", view_matrix);
shader->set_uniform("projection_matrix", projection_matrix);
glsafe(::glEnable(GL_DEPTH_TEST));
-18
View File
@@ -111,8 +111,6 @@ private:
GLModel m_model;
Vec3d m_model_offset{ Vec3d::Zero() };
GLModel m_gravity_arrow;
GLModel m_slicing_arrow; // Pink arrow showing the effective slicing direction
GLModel m_slicing_plane; // Debug: shows the intended slicing plane direction
Axes m_axes;
float m_scale_factor{ 1.0f };
@@ -122,11 +120,6 @@ private:
std::vector<std::vector<Vec2d>> m_extruder_shapes;
std::vector<double> m_extruder_heights;
bool m_is_dark = false;
// Belt printer state for rendering.
bool m_is_belt_printer = false;
float m_belt_angle = 0.f;
// Tilt axis: 0 = X (belt travels along Y, the common case), 1 = Y.
int m_belt_tilt_axis = 0;
public:
Bed3D() = default;
@@ -148,15 +141,6 @@ public:
const BuildVolume& build_volume() const { return m_build_volume; }
BuildVolume& build_volume() { return m_build_volume; }
// Belt printer bed settings. tilt_axis: 0 = X (belt along Y), 1 = Y.
void set_belt_printer(bool enabled, float angle_deg, int tilt_axis = 0) {
m_is_belt_printer = enabled; m_belt_angle = angle_deg; m_belt_tilt_axis = tilt_axis;
}
bool is_belt_printer() const { return m_is_belt_printer; }
float belt_angle() const { return m_belt_angle; }
// Unit vector of the tilt axis in bed space.
Vec3d belt_tilt_unit_axis() const { return m_belt_tilt_axis == 1 ? Vec3d::UnitY() : Vec3d::UnitX(); }
// Was the model provided, or was it generated procedurally?
Type get_type() const { return m_type; }
// Was the model generated procedurally?
@@ -196,8 +180,6 @@ private:
void render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom);
void render_default(bool bottom, const Transform3d& view_matrix, const Transform3d& projection_matrix);
void render_gravity_arrow(const Transform3d& view_matrix, const Transform3d& projection_matrix);
void render_slicing_arrow(const Transform3d& view_matrix, const Transform3d& projection_matrix);
void render_slicing_plane(const Transform3d& view_matrix, const Transform3d& projection_matrix);
// BBS: remove the bed picking logic
// void register_raycasters_for_picking(const GLModel::Geometry& geometry, const Transform3d& trafo);
+2 -4
View File
@@ -1223,10 +1223,8 @@ void GCodeViewer::load_as_gcode(const GCodeProcessorResult& gcode_result, const
m_loaded_as_preview = false;
// Belt printers: drive the designed/raw view UI (legend checkbox, hotkey B, canvas-toolbar
// menu item) from the loaded print here. Plater::set_bed_shape also calls set_belt_printer(),
// but only on bed-shape changes — not reliably on every slice/preview load — so the UI was
// staying hidden even though the (config-driven) designed view rendered. The tilt magnitude
// comes from the G-code header (gcode_result.belt_tilt_angle, abs of the slicing rotation).
// menu item) from the loaded print. The tilt magnitude comes from the G-code header
// (gcode_result.belt_tilt_angle, abs of the slicing rotation).
m_belt_view_enabled = print.config().belt_printer.value;
m_belt_angle_deg = gcode_result.belt_tilt_angle;
-31
View File
@@ -14145,37 +14145,6 @@ void Plater::priv::set_bed_shape(const Pointfs &shape,
Vec2d shape_position = partplate_list.get_current_shape_position();
bool new_shape = bed.set_shape(shape, printable_height, extruder_areas, extruder_heights, custom_model, force_as_custom, shape_position);
// Belt printer: configure build volume and bed rendering for belt mode.
{
const auto *belt_opt = config->option<ConfigOptionBool>("belt_printer");
bool is_belt = belt_opt && belt_opt->value;
if (is_belt) {
// The slicing rotation is the single source of truth for the belt tilt:
// its magnitude is the physical tilt angle and its axis is the tilt axis.
auto rot_axis = config->option<ConfigOptionEnum<BeltRotationAxis>>("belt_slice_rotation")->value;
double rot_angle = config->opt_float("belt_slice_rotation_angle");
double belt_angle = std::abs(rot_angle); // physical tilt magnitude
int tilt_axis = (rot_axis == BeltRotationAxis::Y) ? 1 : 0;
bool infinite_y = config->opt_bool("belt_printer_infinite_y");
bed.build_volume().set_belt_printer(true, belt_angle, infinite_y);
bed.set_belt_printer(true, static_cast<float>(belt_angle), tilt_axis);
if (preview)
preview->get_canvas3d()->get_gcode_viewer().set_belt_printer(true, static_cast<float>(belt_angle));
// The belt "designed view" back-transform is rebuilt from the print config at
// G-code load time (GCodeViewer::compute_belt_back_transform), so no mesh-side
// inverse needs to be pushed to the viewer here.
} else {
// Reset the BuildVolume belt state too: Bed3D::set_shape early-returns when
// the bed params are unchanged, so a belt->normal switch (or toggling belt off
// on the same printer) would otherwise leave the BuildVolume with
// m_is_belt_printer=true and an inflated Y bbox, wrongly treating out-of-bounds
// objects as printable. Idempotent for a printer that was never belt.
bed.build_volume().set_belt_printer(false, 0., false);
bed.set_belt_printer(false, 0.f);
if (preview)
preview->get_canvas3d()->get_gcode_viewer().set_belt_printer(false, 0.f);
}
}
float prev_height_lid, prev_height_rod;
partplate_list.get_height_limits(prev_height_lid, prev_height_rod);