mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-25 09:50:59 +00:00
77 lines
3.5 KiB
C++
77 lines
3.5 KiB
C++
#ifndef slic3r_FirstLayerPlane_hpp_
|
|
#define slic3r_FirstLayerPlane_hpp_
|
|
|
|
#include "libslic3r.h"
|
|
#include "Point.hpp"
|
|
#include "BoundingBox.hpp"
|
|
#include "PrintConfig.hpp"
|
|
|
|
namespace Slic3r {
|
|
|
|
// Decides which extrusions get "first layer" treatment (no fan, slow speed,
|
|
// initial-layer accel/jerk, deferred temperature drop) by reference to a
|
|
// configurable plane in slicing-frame coordinates rather than the slicing
|
|
// layer index.
|
|
//
|
|
// On a normal flat-bed printer the plane is XY at slicing_Z = 0 and the
|
|
// evaluator is INACTIVE — every call site short-circuits back to the legacy
|
|
// `Layer::id() == 0` test. On a belt printer with a Z-from-Y shear the
|
|
// belt surface (machine_Z = 0) maps to a plane in slicing-frame coordinates
|
|
// derived from the gcode axis remap, so layer-index-based detection no
|
|
// longer matches the physical first printed surface.
|
|
//
|
|
// Plane representation: unit normal `n` (slicing frame) and offset along
|
|
// the normal such that the plane equation is `n · p == offset`. Signed
|
|
// perpendicular distance is `d(p) = n · p - offset`. Positive distance
|
|
// means "away from the belt surface", negative means "below the plane".
|
|
class FirstLayerPlane
|
|
{
|
|
public:
|
|
explicit FirstLayerPlane(const PrintConfig &config);
|
|
|
|
// Inactive when the legacy XY layer-index path should be used. This
|
|
// covers all non-belt printers and any belt printer where the user
|
|
// explicitly picked XY mode.
|
|
bool is_active() const { return m_active; }
|
|
FirstLayerPlaneMode effective_mode() const{ return m_mode; }
|
|
double band_thickness_mm() const { return m_thickness_mm; }
|
|
const Vec3d & normal() const { return m_normal; }
|
|
double plane_offset() const { return m_offset; }
|
|
|
|
// Signed perpendicular distance from a slicing-frame point to the plane.
|
|
double distance_from_plane(const Vec3d &point_slicing_mm) const;
|
|
|
|
// True if perpendicular distance < first_layer_height_mm. When the
|
|
// evaluator is inactive this returns false (call sites should fall back
|
|
// to the legacy per-layer path before reaching this function).
|
|
bool is_first_layer(const Vec3d &point_slicing_mm,
|
|
double first_layer_height_mm) const;
|
|
|
|
// floor((distance - 0) / band_thickness), clamped to [0, +inf). Used
|
|
// for "first N layers" thresholds (fan, slow_down_layers). Returns 0
|
|
// for points within the band. Returns INT_MAX/2 when inactive.
|
|
int effective_layer_index(const Vec3d &point_slicing_mm) const;
|
|
|
|
// Min effective index over a 2D bbox at a fixed slicing_Z. Used for
|
|
// layer-level decisions (e.g. temperature transition gate) where we
|
|
// don't want to walk every extrusion in the layer. For axis-aligned
|
|
// planes this is exact; for tilted planes it's a tight lower bound
|
|
// (the plane projection of the bbox's extreme corner).
|
|
int min_effective_index_for_xy_bbox(const BoundingBoxf &xy_bbox_mm,
|
|
double slicing_z_mm) const;
|
|
|
|
// Same as above but the bbox spans a Z range too.
|
|
int min_effective_index_for_bbox3(const BoundingBoxf3 &bbox_mm) const;
|
|
|
|
private:
|
|
bool m_active = false;
|
|
FirstLayerPlaneMode m_mode = FirstLayerPlaneMode::XY;
|
|
Vec3d m_normal = Vec3d::UnitZ(); // unit, slicing frame
|
|
double m_offset = 0.0; // n·p == m_offset
|
|
double m_thickness_mm = 0.0;
|
|
};
|
|
|
|
} // namespace Slic3r
|
|
|
|
#endif // slic3r_FirstLayerPlane_hpp_
|