mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-16 21:42:43 +00:00
Close the Steps of Sloped Surfaces in the Shell and Size Layers by Projection
On a dome or a cone the shell showed holes: dashes of inner wall and overhang wall through gaps, and darkness behind them. Each layer's ring on a slope is inset from the one below by less than a grid cell, so the height map cannot see the step, and the interior of the lower layer that fills it, its first inner wall above all, had been left out. Inner wall segments whose midpoint lies within a line and a half of an outer wall segment of the same layer now stay on the shell, found by exact distance against the outer walls bucketed by cell, and a segment counts as visible from above or below when any of its cells is the topmost or bottommost occupant, since the exposed band is narrower than the chords that cross it. Interior roles that are visible that way stay too. The layer stride at rest was sized from the camera's zoom value and tilt, which does not describe a perspective view: zoomed in on the test project it reached 64, so each kept ring stood 6 mm tall while the surface curved away under it. One layer's height is now projected through the camera's own matrices, at the centre of the toolpaths and at the camera target, and the stride follows that. On the test project the shell at rest gains 43 k segments for the first inner walls, 171 k to 214 k, and the dome and cone draw closed. The nine-cube plate draws 96 k at the default view and 12 k from above.
This commit is contained in:
@@ -1947,10 +1947,22 @@ void GCodeViewer::update_rest_layer_stride()
|
||||
return;
|
||||
static constexpr double MERGE_BELOW_PX = 2.0;
|
||||
static constexpr unsigned int MAX_STRIDE = 64;
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const double dz = std::abs(camera.get_dir_forward().z());
|
||||
const double tilt = std::sqrt(std::max(0.0, 1.0 - dz * dz));
|
||||
const double layer_px = static_cast<double>(m_typical_layer_height) * camera.get_zoom() * tilt;
|
||||
Camera& camera = wxGetApp().plater()->get_camera();
|
||||
// how tall one layer is on screen: a step of one layer height projected through the camera's
|
||||
// own matrices at the centre of the toolpaths and at the point the camera looks at, whichever
|
||||
// is taller. Perspective makes the near corners of a tall print larger than that, but merging
|
||||
// is judged where the user looks, not at the worst corner.
|
||||
const Matrix4d view_projection = camera.get_projection_matrix().matrix() * camera.get_view_matrix().matrix();
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
const auto to_pixels = [&](const Vec3d& p) {
|
||||
const Vec4d clip = view_projection * Vec4d(p.x(), p.y(), p.z(), 1.0);
|
||||
const double w = (std::abs(clip.w()) < 1e-9) ? 1e-9 : clip.w();
|
||||
return Vec2d(0.5 * viewport[2] * clip.x() / w, 0.5 * viewport[3] * clip.y() / w);
|
||||
};
|
||||
const Vec3d step(0.0, 0.0, static_cast<double>(m_typical_layer_height));
|
||||
double layer_px = 0.0;
|
||||
for (const Vec3d& p : { m_paths_bounding_box.center(), camera.get_target() })
|
||||
layer_px = std::max(layer_px, (to_pixels(p + step) - to_pixels(p)).norm());
|
||||
const unsigned int stride = (layer_px * MAX_STRIDE <= MERGE_BELOW_PX) ? MAX_STRIDE :
|
||||
std::clamp(static_cast<unsigned int>(MERGE_BELOW_PX / layer_px), 1u, MAX_STRIDE);
|
||||
m_viewer.set_rest_layer_stride(stride);
|
||||
|
||||
Reference in New Issue
Block a user