Files
OrcaSlicer/src/libslic3r/GCode/TimelapsePosPicker.hpp
SoftFever 237ef41b06 feat(libslic3r): multi-nozzle slicing engine for H2C/A2L
Port BambuStudio's dual-nozzle slicing core: H2C-era config keys, filament-to-nozzle grouping with per-layer dynamic regrouping, filament/nozzle/hotend gcode placeholder vocabulary, multi-nozzle wipe tower pre-heat/pre-cool, the two-pass pre-cooling injector, and corexy farthest-point timelapse.
2026-07-09 01:16:25 +08:00

87 lines
3.4 KiB
C++

#ifndef TIMELAPSE_POS_PICKER_HPP
#define TIMELAPSE_POS_PICKER_HPP
#include <vector>
#include "libslic3r/Point.hpp"
#include "libslic3r/ExPolygon.hpp"
#include "libslic3r/Print.hpp"
#include "libslic3r/PrintConfig.hpp"
namespace Slic3r {
const Point DefaultTimelapsePos = Point(0, 0);
const Point DefaultCameraPos = Point(0, 0);
class Layer;
class Print;
struct PosPickCtx
{
Point curr_pos;
const Layer* curr_layer;
int picture_extruder_id; // the extruder id to take picture
int curr_extruder_id;
std::optional<std::vector<const PrintObject*>> printed_objects; // printed objects, only have value in by object mode
// Farthest-point timelapse: plate-relative scaled point; when set, pick_pos_internal
// biases the picked snapshot position toward this point (nullopt → legacy camera-occlusion loss).
std::optional<Point> farthest_point;
};
// data are stored without plate offset
class TimelapsePosPicker
{
public:
TimelapsePosPicker() = default;
~TimelapsePosPicker() = default;
Point pick_pos(const PosPickCtx& ctx);
// Is the path to X0 clear of other (taller) instances? Drives the
// `clear_to_x0` timelapse-gcode variable (g39 clamping detection).
bool get_is_clear_to_x0(const PosPickCtx& ctx);
void init(const Print* print, const Point& plate_offset);
void reset();
private:
void construct_printable_area_by_printer();
Point pick_pos_for_curr_layer(const PosPickCtx& ctx);
Point pick_pos_for_all_layer(const PosPickCtx& ctx);
ExPolygons collect_object_slices_data(const Layer* curr_layer, float height_range, const std::vector<const PrintObject*>& object_list,bool by_object);
Polygons collect_limit_areas_for_camera(const std::vector<const PrintObject*>& object_list);
Polygons collect_limit_areas_for_rod(const std::vector<const PrintObject*>& object_list, const PosPickCtx& ctx);
Polygon expand_object_projection(const Polygon &poly, bool by_object, bool higher_than_curr = true);
BoundingBoxf3 expand_object_bbox(const BoundingBoxf3& bbox, bool by_object);
Point pick_nearest_object_center(const Point& curr_pos, const std::vector<const PrintObject*>& object_list);
Point get_objects_center(const std::vector<const PrintObject*>& object_list);
Polygon get_limit_area_for_camera(const PrintObject* obj);
std::vector<const PrintObject*> get_object_list(const std::optional<std::vector<const PrintObject*>>& printed_objects);
double get_raft_height(const PrintObject* obj);
BoundingBoxf3 get_real_instance_bbox(const PrintInstance& instance);
Point get_object_center(const PrintObject* obj);
private:
const Print* print{ nullptr };
std::vector<ExPolygons> m_extruder_printable_area; //scaled data
Polygon m_bed_polygon; //scaled_data
Point m_plate_offset; // unscaled data
int m_plate_height; // unscaled data
int m_plate_width; // unscaled data
PrintSequence m_print_seq;
bool m_based_on_all_layer;
int m_nozzle_height_to_rod;
int m_nozzle_clearance_radius;
std::optional<int> m_liftable_extruder_id;
std::optional<int> m_extruder_height_gap;
std::unordered_map<const PrintInstance*, BoundingBoxf3> bbox_cache;
std::optional<Point> m_all_layer_pos;
};
}
#endif