OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::TimelapsePosPicker Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/GCode/TimelapsePosPicker.hpp>

Collaboration diagram for Slic3r::TimelapsePosPicker:

Public Member Functions

 TimelapsePosPicker ()=default
 ~TimelapsePosPicker ()=default
Point pick_pos (const PosPickCtx &ctx)
bool get_is_clear_to_x0 (const PosPickCtx &ctx)
void init (const Print *print, const Point &plate_offset)
void reset ()

Private Member Functions

void construct_printable_area_by_printer ()
 Constructs the printable area based on printer configuration.
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)
 Collects object slice data within a specified height range for a given layer.
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)
 Calculates the center of multiple objects.
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)
 Retrieves a list of print objects based on the provided optional set of 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 Attributes

const Print * print { nullptr }
std::vector< ExPolygons > m_extruder_printable_area
Polygon m_bed_polygon
Point m_plate_offset
int m_plate_height
int m_plate_width
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

Detailed Description

Constructor & Destructor Documentation

◆ TimelapsePosPicker()

Slic3r::TimelapsePosPicker::TimelapsePosPicker ( )
default

◆ ~TimelapsePosPicker()

Slic3r::TimelapsePosPicker::~TimelapsePosPicker ( )
default

References print.

Member Function Documentation

◆ collect_limit_areas_for_camera()

Polygons Slic3r::TimelapsePosPicker::collect_limit_areas_for_camera ( const std::vector< const PrintObject * > & object_list)
private
183 {
184 Polygons ret;
185 for (auto& obj : object_list)
186 ret.emplace_back(get_limit_area_for_camera(obj));
187 ret = union_(ret);
188 return ret;
189 }
Polygon get_limit_area_for_camera(const PrintObject *obj)
Definition TimelapsePosPicker.cpp:356
Slic3r::Polygons union_(const Slic3r::Polygons &subject)
Definition ClipperUtils.cpp:801
std::vector< Polygon, PointsAllocator< Polygon > > Polygons
Definition Polygon.hpp:22

References get_limit_area_for_camera(), and Slic3r::union_().

Referenced by pick_pos_for_all_layer(), and pick_pos_for_curr_layer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ collect_limit_areas_for_rod()

Polygons Slic3r::TimelapsePosPicker::collect_limit_areas_for_rod ( const std::vector< const PrintObject * > & object_list,
const PosPickCtx & ctx )
private
193 {
194 double rod_limit_height = m_nozzle_height_to_rod + ctx.curr_layer->print_z;
195 std::vector<const PrintObject*> rod_collision_candidates;
196 for(auto& obj : object_list){
197 if(ctx.printed_objects && obj == ctx.printed_objects->back())
198 continue;
199 auto bbox = get_real_instance_bbox(obj->instances().front());
200 if(bbox.max.z() >= rod_limit_height)
201 rod_collision_candidates.push_back(obj);
202 }
203
204 if (rod_collision_candidates.empty())
205 return {};
206
207
208 std::vector<BoundingBoxf3> collision_obj_bboxs;
209 for (auto obj : rod_collision_candidates) {
210 collision_obj_bboxs.emplace_back(
212 get_real_instance_bbox(obj->instances().front()),
214 )
215 );
216 }
217
218 std::sort(collision_obj_bboxs.begin(), collision_obj_bboxs.end(), [&](const auto& lbbox, const auto& rbbox) {
219 if (lbbox.min.y() == rbbox.min.y())
220 return lbbox.max.y() < rbbox.max.y();
221 return lbbox.min.y() < rbbox.min.y();
222 });
223
224 std::vector<std::pair<int,int>> object_y_ranges = {{0,0}};
225 for(auto& bbox : collision_obj_bboxs){
226 if( object_y_ranges.back().second >= bbox.min.y())
227 object_y_ranges.back().second = bbox.max.y();
228 else
229 object_y_ranges.emplace_back(bbox.min.y(), bbox.max.y());
230 }
231
232 if (object_y_ranges.back().second < m_plate_height)
233 object_y_ranges.emplace_back(m_plate_height, m_plate_height);
234
235 int lower_y_pos = -1, upper_y_pos =-1;
236 Point unscaled_curr_pos = {unscale_(ctx.curr_pos.x())-m_plate_offset.x(), unscale_(ctx.curr_pos.y()) - m_plate_offset.y()};
237
238 for (size_t idx = 1; idx < object_y_ranges.size(); ++idx) {
239 if (unscaled_curr_pos.y() >= object_y_ranges[idx - 1].second && unscaled_curr_pos.y() <= object_y_ranges[idx].first) {
240 lower_y_pos = object_y_ranges[idx - 1].second;
241 upper_y_pos = object_y_ranges[idx].first;
242 break;
243 }
244 }
245
246 if(lower_y_pos == -1 && upper_y_pos == -1)
247 return { m_bed_polygon };
248
249 Polygons ret;
250
251 ret.emplace_back(
252 Polygon{
253 Point{scale_(0), scale_(0)},
255 Point{scale_(m_plate_width), scale_(lower_y_pos)},
256 Point{scale_(0), scale_(lower_y_pos)}
257 }
258 );
259
260 ret.emplace_back(
261 Polygon{
262 Point{scale_(0), scale_(upper_y_pos)},
263 Point{scale_(m_plate_width), scale_(upper_y_pos)},
266 }
267 );
268 return ret;
269 }
int m_nozzle_height_to_rod
Definition TimelapsePosPicker.hpp:82
BoundingBoxf3 get_real_instance_bbox(const PrintInstance &instance)
Definition TimelapsePosPicker.cpp:336
int m_plate_height
Definition TimelapsePosPicker.hpp:77
BoundingBoxf3 expand_object_bbox(const BoundingBoxf3 &bbox, bool by_object)
Definition TimelapsePosPicker.cpp:295
PrintSequence m_print_seq
Definition TimelapsePosPicker.hpp:80
Polygon m_bed_polygon
Definition TimelapsePosPicker.hpp:75
Point m_plate_offset
Definition TimelapsePosPicker.hpp:76
int m_plate_width
Definition TimelapsePosPicker.hpp:78
#define unscale_(val)
Definition libslic3r.h:107
#define scale_(val)
Definition libslic3r.h:106
Kernel::Point_3 Point
Definition MeshRepair.cpp:81
@ ByObject
Definition PrintConfig.hpp:312

References Slic3r::ByObject, Slic3r::PosPickCtx::curr_layer, Slic3r::PosPickCtx::curr_pos, expand_object_bbox(), get_real_instance_bbox(), m_bed_polygon, m_nozzle_height_to_rod, m_plate_height, m_plate_offset, m_plate_width, m_print_seq, Slic3r::Layer::print_z, Slic3r::PosPickCtx::printed_objects, scale_, and unscale_.

Referenced by pick_pos_for_curr_layer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ collect_object_slices_data()

ExPolygons Slic3r::TimelapsePosPicker::collect_object_slices_data ( const Layer * layer,
float height_range,
const std::vector< const PrintObject * > & object_list,
bool by_object )
private

Collects object slice data within a specified height range for a given layer.

Parameters
layerThe layer for which slices are being collected.
height_rangeThe height range to consider for collecting slices.
object_listList of print objects to process.
by_objectDecides the expand length of polygon
Returns
ExPolygons representing the collected slice data.
145 {
146 auto range_intersect = [](int left1, int right1, int left2, int right2) {
147 if (left1 <= left2 && left2 <= right1)
148 return true;
149 if (left2 <= left1 && left1 <= right2)
150 return true;
151 return false;
152 };
153 ExPolygons ret;
154 float z_target = layer->print_z;
155 float z_low = height_range < 0 ? layer->print_z + height_range : layer->print_z;
156 float z_high = height_range < 0 ? layer->print_z : layer->print_z + height_range;
157 if (z_low <= 0)
158 return to_expolygons({ m_bed_polygon });
159
160 for (auto& obj : object_list) {
161 for (auto& instance : obj->instances()) {
162 auto instance_bbox = get_real_instance_bbox(instance);
163 bool higher_than_curr_layer = (layer->object() == obj) ? false : instance_bbox.max.z() > z_target;
164 if(range_intersect(instance_bbox.min.z(), instance_bbox.max.z(), z_low, z_high)){
165 ExPolygon expoly;
166 expoly.contour = {
167 {scale_(instance_bbox.min.x()), scale_(instance_bbox.min.y())},
168 {scale_(instance_bbox.max.x()), scale_(instance_bbox.min.y())},
169 {scale_(instance_bbox.max.x()), scale_(instance_bbox.max.y())},
170 {scale_(instance_bbox.min.x()), scale_(instance_bbox.max.y())}
171 };
172 expoly.contour = expand_object_projection(expoly.contour, by_object, higher_than_curr_layer);
173 ret.emplace_back(std::move(expoly));
174 }
175 }
176 }
177 ret = union_ex(ret);
178 return ret;
179 }
Polygon expand_object_projection(const Polygon &poly, bool by_object, bool higher_than_curr=true)
Definition TimelapsePosPicker.cpp:274
std::vector< ExPolygon > ExPolygons
Definition ExPolygon.hpp:20
ExPolygons to_expolygons(const Polygons &polys)
Definition ExPolygon.hpp:373
Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, PolyFillType fill_type)
Definition ClipperUtils.cpp:1011

References Slic3r::ExPolygon::contour, expand_object_projection(), get_real_instance_bbox(), m_bed_polygon, Slic3r::Layer::object(), Slic3r::Layer::print_z, scale_, Slic3r::to_expolygons(), and Slic3r::union_ex().

Referenced by pick_pos_for_curr_layer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ construct_printable_area_by_printer()

void Slic3r::TimelapsePosPicker::construct_printable_area_by_printer ( )
private

Constructs the printable area based on printer configuration.

This function initializes the bed polygon, excludes specific areas, accounts for wipe towers, and calculates the printable area for each extruder.

88 {
89 auto config = print->config();
90 size_t extruder_count = config.nozzle_diameter.size();
92 m_extruder_printable_area.resize(extruder_count);
93
94 for (size_t idx = 0; idx < config.printable_area.values.size(); ++idx)
95 m_bed_polygon.points.emplace_back(coord_t(scale_(config.printable_area.values[idx].x())), coord_t(scale_(config.printable_area.values[idx].y())));
96
97 auto bed_bbox = get_extents(m_bed_polygon);
98 m_plate_height = unscale_(bed_bbox.max.y());
99 m_plate_width = unscale_(bed_bbox.max.x());
100
101 // Timelapse positions are selected in the bed plane. Use the resolved
102 // bed-level footprints instead of the legacy flat point array, which
103 // cannot represent multiple or per-nozzle exclusion polygons.
104 const Polygons bed_exclude_areas = get_bed_excluded_area(config);
105
106 Point base_wp_pt = print->get_fake_wipe_tower().pos.cast<coord_t>();
107 base_wp_pt = Point{ scale_(base_wp_pt.x()),scale_(base_wp_pt.y()) };
108
109 auto transform_wt_pt = [base_wp_pt](const Point& pt) -> Point {
110 Point out =pt;
111 out += base_wp_pt;
112 return out;
113 };
114 auto wt_box = print->wipe_tower_data().bbx;
115 Polygon wipe_tower_area{
116 {transform_wt_pt({scale_(wt_box.min.x()),scale_(wt_box.min.y())})},
117 {transform_wt_pt({scale_(wt_box.max.x()),scale_(wt_box.min.y())})},
118 {transform_wt_pt({scale_(wt_box.max.x()),scale_(wt_box.max.y())})},
119 {transform_wt_pt({scale_(wt_box.min.x()),scale_(wt_box.max.y())})}
120 };
121 wipe_tower_area = expand_object_projection(wipe_tower_area, m_print_seq == PrintSequence::ByObject);
122
123 for (size_t idx = 0; idx < extruder_count; ++idx) {
124 ExPolygons printable_area = diff_ex(diff(Polygons{ m_bed_polygon }, bed_exclude_areas), { wipe_tower_area });
125 if (idx < config.extruder_printable_area.size()) {
126 Polygon extruder_printable_area;
127 for (size_t j = 0; j < config.extruder_printable_area.values[idx].size(); ++j)
128 extruder_printable_area.points.emplace_back(coord_t(scale_(config.extruder_printable_area.values[idx][j].x())), coord_t(scale_(config.extruder_printable_area.values[idx][j].y())));
129 printable_area = intersection_ex(printable_area, Polygons{ extruder_printable_area });
130 }
132 }
133 }
Points points
Definition MultiPoint.hpp:22
const Print * print
Definition TimelapsePosPicker.hpp:73
std::vector< ExPolygons > m_extruder_printable_area
Definition TimelapsePosPicker.hpp:74
int64_t coord_t
Definition libslic3r.h:48
zaa_minimize_perimeter_height printable_area((ConfigOptionPointsGroups, extruder_printable_area))((ConfigOptionBool
Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:831
BoundingBox get_extents(const ExPolygonsWithIds &e)
Definition Emboss.cpp:1374
Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:878
Polygons get_bed_excluded_area(const PrintConfig &cfg)
Definition PrintConfig.cpp:14376
Slic3r::Polygons diff(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:731
Slic3r::Polygon Polygon
Definition Emboss.cpp:101

References Slic3r::ByObject, Slic3r::diff(), Slic3r::diff_ex(), expand_object_projection(), Slic3r::get_bed_excluded_area(), Slic3r::get_extents(), Slic3r::intersection_ex(), m_bed_polygon, m_extruder_printable_area, m_plate_height, m_plate_width, m_print_seq, Slic3r::MultiPoint::points, print, Slic3r::printable_area(), scale_, and unscale_.

Referenced by init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ expand_object_bbox()

BoundingBoxf3 Slic3r::TimelapsePosPicker::expand_object_bbox ( const BoundingBoxf3 & bbox,
bool by_object )
private
296 {
297 float radius = 0;
298 if (by_object)
299 radius = print->config().extruder_clearance_radius.value;
300 else
301 radius = print->config().extruder_clearance_radius.value / 2;
302
303 BoundingBoxf3 ret = bbox;
304 ret.min.x() -= radius;
305 ret.min.y() -= radius;
306 ret.max.x() += radius;
307 ret.max.y() += radius;
308
309 return ret;
310 }

References Slic3r::BoundingBoxBase< PointType, std::vector< PointType > >::max, Slic3r::BoundingBoxBase< PointType, std::vector< PointType > >::min, and print.

Referenced by collect_limit_areas_for_rod().

Here is the caller graph for this function:

◆ expand_object_projection()

Polygon Slic3r::TimelapsePosPicker::expand_object_projection ( const Polygon & poly,
bool by_object,
bool higher_than_curr = true )
private
275 {
276 float radius = 0;
277 if (by_object) {
278 if (higher_than_curr) {
279 radius = scale_(print->config().extruder_clearance_radius.value);
280 }else{
281 radius = scale_(print->config().extruder_clearance_radius.value / 2);
282 }
283 }
284 else
285 radius = scale_(print->config().extruder_clearance_radius.value / 2);
286
287 // the input poly is bounding box, so we get the first offseted polygon is ok
288 auto ret = offset(poly, radius);
289 if (ret.empty())
290 return {};
291 return ret[0];
292 }
Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:582

References Slic3r::offset(), print, and scale_.

Referenced by collect_object_slices_data(), construct_printable_area_by_printer(), get_is_clear_to_x0(), and pick_pos_for_all_layer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_is_clear_to_x0()

bool Slic3r::TimelapsePosPicker::get_is_clear_to_x0 ( const PosPickCtx & ctx)
642 {
643 bool by_object = m_print_seq == PrintSequence::ByObject;
644 std::vector<const PrintObject *> object_list = get_object_list(ctx.printed_objects);
645
646 auto range_intersect = [](int left1, int right1, int left2, int right2) {
647 if (left1 <= left2 && left2 <= right1) return true;
648 if (left2 <= left1 && left1 <= right2) return true;
649 return false;
650 };
651
652 ExPolygons unclear_area;
653 const Layer *layer = ctx.curr_layer;
654 float z_target = layer->print_z;
655 float z_low = layer->print_z - 0.5;
656 float z_high = layer->print_z + 0.5;
657
658 for (auto &obj : object_list) {
659 for (auto &instance : obj->instances()) {
660 auto instance_bbox = get_real_instance_bbox(instance);
661 bool is_curr_obj = ( obj == object_list.back() ) || ( !by_object ),
662 higher_than_curr_pos = instance_bbox.max.z() > z_target;
663 if (!is_curr_obj && range_intersect(instance_bbox.min.z(), instance_bbox.max.z(), z_low, z_high)) {
664 ExPolygon expoly;
665 expoly.contour = {{scale_(instance_bbox.min.x()), scale_(instance_bbox.min.y())},
666 {scale_(instance_bbox.max.x()), scale_(instance_bbox.min.y())},
667 {scale_(instance_bbox.max.x()), scale_(instance_bbox.max.y())},
668 {scale_(instance_bbox.min.x()), scale_(instance_bbox.max.y())}};
669 expoly.contour = expand_object_projection(expoly.contour, by_object, higher_than_curr_pos);
670 unclear_area.emplace_back(std::move(expoly));
671 }
672 }
673 }
674
675 Point curr_pos_in_plate = {ctx.curr_pos.x() - scale_(m_plate_offset.x()), ctx.curr_pos.y() - scale_(m_plate_offset.y())};
676 for (const ExPolygon &expoly : unclear_area) {
677 BoundingBox bbox = expoly.contour.bounding_box();
678 if (curr_pos_in_plate.y() < bbox.min.y() || curr_pos_in_plate.y() > bbox.max.y()) continue;
679 if (bbox.min.x() <= curr_pos_in_plate.x()) return false;
680 }
681
682 return true;
683 }
std::vector< const PrintObject * > get_object_list(const std::optional< std::vector< const PrintObject * > > &printed_objects)
Retrieves a list of print objects based on the provided optional set of printed objects.
Definition TimelapsePosPicker.cpp:69

References Slic3r::ByObject, Slic3r::ExPolygon::contour, Slic3r::PosPickCtx::curr_layer, Slic3r::PosPickCtx::curr_pos, expand_object_projection(), get_object_list(), get_real_instance_bbox(), m_plate_offset, m_print_seq, Slic3r::BoundingBoxBase< PointType, APointsType >::max, Slic3r::BoundingBoxBase< PointType, APointsType >::min, Slic3r::Layer::print_z, Slic3r::PosPickCtx::printed_objects, and scale_.

Here is the call graph for this function:

◆ get_limit_area_for_camera()

Polygon Slic3r::TimelapsePosPicker::get_limit_area_for_camera ( const PrintObject * obj)
private
357 {
358 if (!obj)
359 return {};
360 auto bbox = get_real_instance_bbox(obj->instances().front());
361 float radius = m_nozzle_clearance_radius / 2;
362
363 auto offset_bbox = bbox.inflated(sqrt(2) * radius);
364 // Constrain the coordinates to the first quadrant.
365 Polygon ret = {
367 Point{std::max(scale_(offset_bbox.max.x()),0.),std::max(scale_(offset_bbox.min.y()),0.)},
368 Point{std::max(scale_(offset_bbox.max.x()),0.),std::max(scale_(offset_bbox.max.y()),0.)},
369 Point{std::max(scale_(offset_bbox.min.x()),0.),std::max(scale_(offset_bbox.max.y()),0.)}
370 };
371 return ret;
372 }
int m_nozzle_clearance_radius
Definition TimelapsePosPicker.hpp:83
const Point DefaultCameraPos
Definition TimelapsePosPicker.hpp:19

References Slic3r::DefaultCameraPos, get_real_instance_bbox(), Slic3r::PrintObject::instances(), m_nozzle_clearance_radius, and scale_.

Referenced by collect_limit_areas_for_camera().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_object_center()

Point Slic3r::TimelapsePosPicker::get_object_center ( const PrintObject * obj)
private
482 {
483 if (!obj)
484 return {};
485 // in bambu studio, each object only has one instance
486 const auto& instance = obj->instances().front();
487 auto instance_bbox = get_real_instance_bbox(instance);
488 Point min_p{ instance_bbox.min.x(),instance_bbox.min.y() };
489 Point max_p{ instance_bbox.max.x(),instance_bbox.max.y() };
490
491 return { scale_((min_p.x() + max_p.x()) / 2),scale_((min_p.y() + max_p.y()) / 2) };
492 }

References get_real_instance_bbox(), Slic3r::PrintObject::instances(), and scale_.

Referenced by pick_nearest_object_center(), and pick_pos_for_curr_layer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_object_list()

std::vector< const PrintObject * > Slic3r::TimelapsePosPicker::get_object_list ( const std::optional< std::vector< const PrintObject * > > & printed_objects)
private

Retrieves a list of print objects based on the provided optional set of printed objects.

If the optional set of printed objects is provided, it converts the set into a vector. Otherwise, it retrieves all objects from the print instance.

70 {
71 std::vector<const PrintObject*> object_list;
72 if (printed_objects.has_value()) {
73 object_list = std::vector<const PrintObject*>(printed_objects->begin(), printed_objects->end());
74 }
75 else {
76 object_list = std::vector<const PrintObject*>(print->objects().begin(), print->objects().end());
77 }
78 return object_list;
79 }

References print.

Referenced by get_is_clear_to_x0(), pick_pos_for_all_layer(), and pick_pos_for_curr_layer().

Here is the caller graph for this function:

◆ get_objects_center()

Point Slic3r::TimelapsePosPicker::get_objects_center ( const std::vector< const PrintObject * > & object_list)
private

Calculates the center of multiple objects.

This function computes the average center of all instances of the provided objects.

Parameters
object_listA vector of pointers to PrintObject instances.
Returns
Point The average center of all objects.Scaled data
564 {
565 if (object_list.empty())
566 return Point(0,0);
567 double sum_x = 0.0;
568 double sum_y = 0.0;
569 size_t total_instances = 0;
570 for (auto& obj : object_list) {
571 for (auto& instance : obj->instances()) {
572 const auto& bbox = get_real_instance_bbox(instance);
573 Point min_p{ bbox.min.x(),bbox.min.y() };
574 Point max_p{ bbox.max.x(),bbox.max.y() };
575 double center_x = (min_p.x() + max_p.x()) / 2.f;
576 double center_y = (min_p.y() + max_p.y()) / 2.f;
577 sum_x += center_x;
578 sum_y += center_y;
579 total_instances += 1;
580 }
581 }
582 return Point{ coord_t(scale_(sum_x / total_instances)),coord_t(scale_(sum_y / total_instances)) };
583 }

References get_real_instance_bbox(), and scale_.

Referenced by pick_pos_for_all_layer(), and pick_pos_for_curr_layer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_raft_height()

double Slic3r::TimelapsePosPicker::get_raft_height ( const PrintObject * obj)
private
314 {
315 if (!obj || !obj->has_raft())
316 return 0;
317 auto slice_params = obj->slicing_parameters();
318 int base_raft_layers = slice_params.base_raft_layers;
319 double base_raft_height = slice_params.base_raft_layer_height;
320 int interface_raft_layers = slice_params.interface_raft_layers;
321 double interface_raft_height = slice_params.interface_raft_layer_height;
322 double contact_raft_layer_height = slice_params.contact_raft_layer_height;
323
324 double ret = print->config().initial_layer_print_height;
325 if (base_raft_layers - 1 > 0)
326 ret += (base_raft_layers - 1) * base_raft_height;
327 if (interface_raft_layers - 1 > 0)
328 ret += (interface_raft_layers - 1) * interface_raft_height;
329 if (obj->config().raft_layers > 1)
330 ret += contact_raft_layer_height;
331
332 return ret + slice_params.gap_raft_object;
333 }

References Slic3r::SlicingParameters::base_raft_layers, Slic3r::PrintObject::config(), Slic3r::PrintObject::has_raft(), print, and Slic3r::PrintObject::slicing_parameters().

Referenced by get_real_instance_bbox().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_real_instance_bbox()

BoundingBoxf3 Slic3r::TimelapsePosPicker::get_real_instance_bbox ( const PrintInstance & instance)
private
337 {
338 auto iter = bbox_cache.find(&instance);
339 if (iter != bbox_cache.end())
340 return iter->second;
341
342 auto bbox = instance.get_bounding_box();
343 double raft_height =get_raft_height(instance.print_object);
344 bbox.max.z() += raft_height;
345 // remove plate offset
346 bbox.min.x() -= m_plate_offset.x();
347 bbox.max.x() -= m_plate_offset.x();
348 bbox.min.y() -= m_plate_offset.y();
349 bbox.max.y() -= m_plate_offset.y();
350
351 bbox_cache[&instance] = bbox;
352
353 return bbox;
354 }
double get_raft_height(const PrintObject *obj)
Definition TimelapsePosPicker.cpp:313
std::unordered_map< const PrintInstance *, BoundingBoxf3 > bbox_cache
Definition TimelapsePosPicker.hpp:87

References bbox_cache, Slic3r::PrintInstance::get_bounding_box(), get_raft_height(), m_plate_offset, and Slic3r::PrintInstance::print_object.

Referenced by collect_limit_areas_for_rod(), collect_object_slices_data(), get_is_clear_to_x0(), get_limit_area_for_camera(), get_object_center(), get_objects_center(), and pick_pos_for_all_layer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init()

void Slic3r::TimelapsePosPicker::init ( const Print * print,
const Point & plate_offset )
30 {
31 reset();
32 m_plate_offset = plate_offset;
33 print = print_;
34
35 m_nozzle_height_to_rod = print_->config().extruder_clearance_height_to_rod;
36 m_nozzle_clearance_radius = print_->config().extruder_clearance_radius;
37 if (print_->config().nozzle_diameter.size() > 1 && print_->config().extruder_printable_height.size() > 1) {
38 m_extruder_height_gap = std::abs(print_->config().extruder_printable_height.values[0] - print_->config().extruder_printable_height.values[1]);
39 m_liftable_extruder_id = print_->config().extruder_printable_height.values[0] < print_->config().extruder_printable_height.values[1] ? 0 : 1;
40 }
41 m_print_seq = print_->config().print_sequence.value;
42 m_based_on_all_layer = print_->config().timelapse_type == TimelapseType::tlSmooth;
43
45 }
std::optional< int > m_extruder_height_gap
Definition TimelapsePosPicker.hpp:85
std::optional< int > m_liftable_extruder_id
Definition TimelapsePosPicker.hpp:84
bool m_based_on_all_layer
Definition TimelapsePosPicker.hpp:81
void reset()
Definition TimelapsePosPicker.cpp:47
void construct_printable_area_by_printer()
Constructs the printable area based on printer configuration.
Definition TimelapsePosPicker.cpp:87
@ tlSmooth
Definition PrintConfig.hpp:470

References Slic3r::Print::config(), construct_printable_area_by_printer(), m_based_on_all_layer, m_extruder_height_gap, m_liftable_extruder_id, m_nozzle_clearance_radius, m_nozzle_height_to_rod, m_plate_offset, m_print_seq, print, reset(), and Slic3r::tlSmooth.

Here is the call graph for this function:

◆ pick_nearest_object_center()

Point Slic3r::TimelapsePosPicker::pick_nearest_object_center ( const Point & curr_pos,
const std::vector< const PrintObject * > & object_list )
private
496 {
497 if (object_list.empty())
498 return {};
499 const PrintObject* ptr = object_list.front();
500 double distance = std::numeric_limits<double>::max();
501 for (auto& obj : object_list) {
502 Point obj_center = get_object_center(obj);
503 double dist = (obj_center - curr_pos).cast<double>().norm();
504 if (distance > dist) {
505 distance = dist;
506 ptr = obj;
507 }
508 }
509 return get_object_center(ptr);
510 }
Point get_object_center(const PrintObject *obj)
Definition TimelapsePosPicker.cpp:481
T dist(const boost::polygon::point_data< T > &p1, const boost::polygon::point_data< T > &p2)
Definition Geometry.cpp:298
float distance(SpiralVase::SpiralPoint a, SpiralVase::SpiralPoint b)
Definition SpiralVase.cpp:19
auto cast(const BoundingBoxBase< Tin > &b)
Definition BoundingBox.hpp:299

References Slic3r::cast(), Slic3r::Geometry::dist(), and get_object_center().

Here is the call graph for this function:

◆ pick_pos()

Point Slic3r::TimelapsePosPicker::pick_pos ( const PosPickCtx & ctx)
470 {
471 Point res;
473 res = pick_pos_for_all_layer(ctx);
474 else
475 res = pick_pos_for_curr_layer(ctx);
476
477 return { unscale_(res.x()), unscale_(res.y()) };
478 }
Point pick_pos_for_all_layer(const PosPickCtx &ctx)
Definition TimelapsePosPicker.cpp:585
Point pick_pos_for_curr_layer(const PosPickCtx &ctx)
Definition TimelapsePosPicker.cpp:513

References m_based_on_all_layer, pick_pos_for_all_layer(), pick_pos_for_curr_layer(), and unscale_.

Here is the call graph for this function:

◆ pick_pos_for_all_layer()

Point Slic3r::TimelapsePosPicker::pick_pos_for_all_layer ( const PosPickCtx & ctx)
private
586 {
587 bool by_object = m_print_seq == PrintSequence::ByObject;
588 if (by_object)
589 return DefaultTimelapsePos;
590
591 float height_gap = 0;
592 if (ctx.curr_extruder_id != ctx.picture_extruder_id) {
593 if (m_liftable_extruder_id.has_value() && ctx.picture_extruder_id != m_liftable_extruder_id && m_extruder_height_gap.has_value())
594 height_gap = *m_extruder_height_gap;
595 }
596 if (ctx.curr_layer->print_z < height_gap)
597 return DefaultTimelapsePos;
598 if (m_all_layer_pos)
599 return *m_all_layer_pos;
600
601 Polygons object_projections;
602
603 auto object_list = get_object_list(std::nullopt);
604
605 for (auto& obj : object_list) {
606 for (auto& instance : obj->instances()) {
607 const auto& bbox = get_real_instance_bbox(instance);
608 Point min_p{ scale_(bbox.min.x()),scale_(bbox.min.y()) };
609 Point max_p{ scale_(bbox.max.x()),scale_(bbox.max.y()) };
610 Polygon obj_proj{ { min_p.x(),min_p.y() },
611 { max_p.x(),min_p.y() },
612 { max_p.x(),max_p.y() },
613 { min_p.x(),max_p.y() }
614 };
615 object_projections.emplace_back(expand_object_projection(obj_proj, by_object));
616 }
617 };
618
619
620 object_projections = union_(object_projections);
621 Polygons camera_limit_areas = collect_limit_areas_for_camera(object_list);
622 Polygons unplacable_area = union_(object_projections, camera_limit_areas);
623
624 ExPolygons extruder_printable_area;
625 if (m_extruder_printable_area.size() > 1)
627 else if (m_extruder_printable_area.size() == 1)
628 extruder_printable_area = m_extruder_printable_area.front();
629
630 ExPolygons safe_area = diff_ex(extruder_printable_area, unplacable_area);
631 safe_area = opening_ex(safe_area, scale_(FILTER_THRESHOLD));
632
633 Point starting_pos = get_objects_center(object_list);
634
635 m_all_layer_pos = pick_pos_internal(starting_pos, safe_area, {}, by_object);
636 return *m_all_layer_pos;
637 }
constexpr int FILTER_THRESHOLD
Definition TimelapsePosPicker.cpp:25
Point get_objects_center(const std::vector< const PrintObject * > &object_list)
Calculates the center of multiple objects.
Definition TimelapsePosPicker.cpp:563
Polygons collect_limit_areas_for_camera(const std::vector< const PrintObject * > &object_list)
Definition TimelapsePosPicker.cpp:182
std::optional< Point > m_all_layer_pos
Definition TimelapsePosPicker.hpp:89
Slic3r::ExPolygons opening_ex(const Slic3r::ExPolygons &polygons, const float delta, JoinType joinType=DefaultJoinType, double miterLimit=DefaultMiterLimit)
Definition ClipperUtils.hpp:447
const Point DefaultTimelapsePos
Definition TimelapsePosPicker.hpp:18
Point pick_pos_internal(const Point &curr_pos, const ExPolygons &safe_areas, const ExPolygons &path_collision_area, bool detect_path_collision, const std::optional< Point > &farthest_point=std::nullopt)
Selects the nearest position within the given safe areas relative to the current position.
Definition TimelapsePosPicker.cpp:385

References Slic3r::ByObject, collect_limit_areas_for_camera(), Slic3r::PosPickCtx::curr_extruder_id, Slic3r::PosPickCtx::curr_layer, Slic3r::DefaultTimelapsePos, Slic3r::diff_ex(), expand_object_projection(), FILTER_THRESHOLD, get_object_list(), get_objects_center(), get_real_instance_bbox(), Slic3r::intersection_ex(), m_all_layer_pos, m_extruder_height_gap, m_extruder_printable_area, m_liftable_extruder_id, m_print_seq, Slic3r::opening_ex(), Slic3r::pick_pos_internal(), Slic3r::PosPickCtx::picture_extruder_id, Slic3r::Layer::print_z, scale_, and Slic3r::union_().

Referenced by pick_pos().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pick_pos_for_curr_layer()

Point Slic3r::TimelapsePosPicker::pick_pos_for_curr_layer ( const PosPickCtx & ctx)
private
514 {
515 float height_gap = 0;
516 if (ctx.curr_extruder_id != ctx.picture_extruder_id) {
517 if (m_liftable_extruder_id.has_value() && ctx.picture_extruder_id != m_liftable_extruder_id && m_extruder_height_gap.has_value())
518 height_gap = -*m_extruder_height_gap;
519 }
520
521 bool by_object = m_print_seq == PrintSequence::ByObject;
522 std::vector<const PrintObject*> object_list = get_object_list(ctx.printed_objects);
523
524 ExPolygons layer_slices = collect_object_slices_data(ctx.curr_layer, height_gap, object_list, by_object);
525 Polygons camera_limit_areas = collect_limit_areas_for_camera(object_list);
526 Polygons rod_limit_areas;
527 if (by_object) {
528 rod_limit_areas = collect_limit_areas_for_rod(object_list, ctx);
529 }
530 ExPolygons unplacable_area = union_ex(union_ex(layer_slices, camera_limit_areas), rod_limit_areas);
531 ExPolygons extruder_printable_area = m_extruder_printable_area[ctx.picture_extruder_id];
532
533 ExPolygons safe_area = diff_ex(extruder_printable_area, unplacable_area);
534 safe_area = opening_ex(safe_area, scale_(FILTER_THRESHOLD));
535
536 Point center_p;
537 if (by_object && ctx.printed_objects && !ctx.printed_objects->empty())
538 center_p = get_object_center(ctx.printed_objects->back());
539 else
540 center_p = get_objects_center(object_list);
541
542 ExPolygons path_collision_area;
543 if (by_object) {
544 auto object_without_curr = ctx.printed_objects;
545 if (object_without_curr && !object_without_curr->empty())
546 object_without_curr->pop_back();
547
548 ExPolygons layer_slices_without_curr = collect_object_slices_data(ctx.curr_layer, height_gap, get_object_list(object_without_curr), by_object);
549 path_collision_area = union_ex(layer_slices_without_curr, rod_limit_areas);
550 }
551
552 return pick_pos_internal(center_p, safe_area,path_collision_area, by_object, ctx.farthest_point);
553 }
ExPolygons collect_object_slices_data(const Layer *curr_layer, float height_range, const std::vector< const PrintObject * > &object_list, bool by_object)
Collects object slice data within a specified height range for a given layer.
Definition TimelapsePosPicker.cpp:144
Polygons collect_limit_areas_for_rod(const std::vector< const PrintObject * > &object_list, const PosPickCtx &ctx)
Definition TimelapsePosPicker.cpp:192

References Slic3r::ByObject, collect_limit_areas_for_camera(), collect_limit_areas_for_rod(), collect_object_slices_data(), Slic3r::PosPickCtx::curr_extruder_id, Slic3r::PosPickCtx::curr_layer, Slic3r::diff_ex(), Slic3r::PosPickCtx::farthest_point, FILTER_THRESHOLD, get_object_center(), get_object_list(), get_objects_center(), m_extruder_height_gap, m_extruder_printable_area, m_liftable_extruder_id, m_print_seq, Slic3r::opening_ex(), Slic3r::pick_pos_internal(), Slic3r::PosPickCtx::picture_extruder_id, Slic3r::PosPickCtx::printed_objects, scale_, and Slic3r::union_ex().

Referenced by pick_pos().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reset()

void Slic3r::TimelapsePosPicker::reset ( )
48 {
49 print = nullptr;
50 m_bed_polygon.clear();
52 m_all_layer_pos = std::nullopt;
53 bbox_cache.clear();
54
58 m_liftable_extruder_id = std::nullopt;
59 m_extruder_height_gap = std::nullopt;
61 }

References bbox_cache, Slic3r::ByObject, m_all_layer_pos, m_based_on_all_layer, m_bed_polygon, m_extruder_height_gap, m_extruder_printable_area, m_liftable_extruder_id, m_nozzle_clearance_radius, m_nozzle_height_to_rod, m_print_seq, and print.

Referenced by init().

Here is the caller graph for this function:

Member Data Documentation

◆ bbox_cache

std::unordered_map<const PrintInstance*, BoundingBoxf3> Slic3r::TimelapsePosPicker::bbox_cache
private

Referenced by get_real_instance_bbox(), and reset().

◆ m_all_layer_pos

std::optional<Point> Slic3r::TimelapsePosPicker::m_all_layer_pos
private

Referenced by pick_pos_for_all_layer(), and reset().

◆ m_based_on_all_layer

bool Slic3r::TimelapsePosPicker::m_based_on_all_layer
private

Referenced by init(), pick_pos(), and reset().

◆ m_bed_polygon

Polygon Slic3r::TimelapsePosPicker::m_bed_polygon
private

◆ m_extruder_height_gap

std::optional<int> Slic3r::TimelapsePosPicker::m_extruder_height_gap
private

◆ m_extruder_printable_area

std::vector<ExPolygons> Slic3r::TimelapsePosPicker::m_extruder_printable_area
private

◆ m_liftable_extruder_id

std::optional<int> Slic3r::TimelapsePosPicker::m_liftable_extruder_id
private

◆ m_nozzle_clearance_radius

int Slic3r::TimelapsePosPicker::m_nozzle_clearance_radius
private

◆ m_nozzle_height_to_rod

int Slic3r::TimelapsePosPicker::m_nozzle_height_to_rod
private

◆ m_plate_height

int Slic3r::TimelapsePosPicker::m_plate_height
private

◆ m_plate_offset

Point Slic3r::TimelapsePosPicker::m_plate_offset
private

◆ m_plate_width

int Slic3r::TimelapsePosPicker::m_plate_width
private

◆ m_print_seq

◆ print


The documentation for this class was generated from the following files: