WIP: first_layer_print_min/max, first_layer_print_convex_hull
placeholders for the G-code export.
This commit is contained in:
parent
d95c151823
commit
6529543518
4 changed files with 107 additions and 36 deletions
|
@ -1298,7 +1298,21 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
|
||||||
m_placeholder_parser.set("has_wipe_tower", has_wipe_tower);
|
m_placeholder_parser.set("has_wipe_tower", has_wipe_tower);
|
||||||
m_placeholder_parser.set("has_single_extruder_multi_material_priming", has_wipe_tower && print.config().single_extruder_multi_material_priming);
|
m_placeholder_parser.set("has_single_extruder_multi_material_priming", has_wipe_tower && print.config().single_extruder_multi_material_priming);
|
||||||
m_placeholder_parser.set("total_toolchanges", std::max(0, print.wipe_tower_data().number_of_toolchanges)); // Check for negative toolchanges (single extruder mode) and set to 0 (no tool change).
|
m_placeholder_parser.set("total_toolchanges", std::max(0, print.wipe_tower_data().number_of_toolchanges)); // Check for negative toolchanges (single extruder mode) and set to 0 (no tool change).
|
||||||
|
{
|
||||||
|
// Convex hull of the 1st layer extrusions, for bed leveling and placing the initial purge line.
|
||||||
|
// It encompasses the object extrusions, support extrusions, skirt, brim, wipe tower.
|
||||||
|
// It does NOT encompass user extrusions generated by custom G-code,
|
||||||
|
// therefore it does NOT encompass the initial purge line.
|
||||||
|
// It does NOT encompass MMU/MMU2 starting (wipe) areas.
|
||||||
|
auto pts = std::make_unique<ConfigOptionPoints>();
|
||||||
|
pts->values.reserve(print.first_layer_convex_hull().size());
|
||||||
|
for (const Point &pt : print.first_layer_convex_hull().points)
|
||||||
|
pts->values.emplace_back(unscale(pt));
|
||||||
|
BoundingBoxf bbox(pts->values);
|
||||||
|
m_placeholder_parser.set("first_layer_print_convex_hull", pts.release());
|
||||||
|
m_placeholder_parser.set("first_layer_print_min", new ConfigOptionFloats({ bbox.min.x(), bbox.min.y() }));
|
||||||
|
m_placeholder_parser.set("first_layer_print_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() }));
|
||||||
|
}
|
||||||
std::string start_gcode = this->placeholder_parser_process("start_gcode", print.config().start_gcode.value, initial_extruder_id);
|
std::string start_gcode = this->placeholder_parser_process("start_gcode", print.config().start_gcode.value, initial_extruder_id);
|
||||||
// Set bed temperature if the start G-code does not contain any bed temp control G-codes.
|
// Set bed temperature if the start G-code does not contain any bed temp control G-codes.
|
||||||
this->_print_first_layer_bed_temperature(file, print, start_gcode, initial_extruder_id, true);
|
this->_print_first_layer_bed_temperature(file, print, start_gcode, initial_extruder_id, true);
|
||||||
|
|
|
@ -166,6 +166,7 @@ class SupportLayer : public Layer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Polygons covered by the supports: base, interface and contact areas.
|
// Polygons covered by the supports: base, interface and contact areas.
|
||||||
|
// Used to suppress retraction if moving for a support extrusion over these support_islands.
|
||||||
ExPolygonCollection support_islands;
|
ExPolygonCollection support_islands;
|
||||||
// Extrusion paths for the support base and for the support interface and contacts.
|
// Extrusion paths for the support base and for the support interface and contacts.
|
||||||
ExtrusionEntityCollection support_fills;
|
ExtrusionEntityCollection support_fills;
|
||||||
|
|
|
@ -244,7 +244,6 @@ bool Print::invalidate_step(PrintStep step)
|
||||||
{
|
{
|
||||||
bool invalidated = Inherited::invalidate_step(step);
|
bool invalidated = Inherited::invalidate_step(step);
|
||||||
// Propagate to dependent steps.
|
// Propagate to dependent steps.
|
||||||
//FIXME Why should skirt invalidate brim? Shouldn't it be vice versa?
|
|
||||||
if (step == psSkirt)
|
if (step == psSkirt)
|
||||||
invalidated |= Inherited::invalidate_step(psBrim);
|
invalidated |= Inherited::invalidate_step(psBrim);
|
||||||
if (step != psGCodeExport)
|
if (step != psGCodeExport)
|
||||||
|
@ -1606,6 +1605,8 @@ void Print::process()
|
||||||
}
|
}
|
||||||
if (this->set_started(psSkirt)) {
|
if (this->set_started(psSkirt)) {
|
||||||
m_skirt.clear();
|
m_skirt.clear();
|
||||||
|
m_skirt_convex_hull.clear();
|
||||||
|
m_first_layer_convex_hull.points.clear();
|
||||||
if (this->has_skirt()) {
|
if (this->has_skirt()) {
|
||||||
this->set_status(88, L("Generating skirt"));
|
this->set_status(88, L("Generating skirt"));
|
||||||
this->_make_skirt();
|
this->_make_skirt();
|
||||||
|
@ -1614,11 +1615,15 @@ void Print::process()
|
||||||
}
|
}
|
||||||
if (this->set_started(psBrim)) {
|
if (this->set_started(psBrim)) {
|
||||||
m_brim.clear();
|
m_brim.clear();
|
||||||
|
m_first_layer_convex_hull.points.clear();
|
||||||
if (m_config.brim_width > 0) {
|
if (m_config.brim_width > 0) {
|
||||||
this->set_status(88, L("Generating brim"));
|
this->set_status(88, L("Generating brim"));
|
||||||
this->_make_brim();
|
this->_make_brim();
|
||||||
}
|
}
|
||||||
this->set_done(psBrim);
|
// Brim depends on skirt (brim lines are trimmed by the skirt lines), therefore if
|
||||||
|
// the skirt gets invalidated, brim gets invalidated as well and the following line is called.
|
||||||
|
this->finalize_first_layer_convex_hull();
|
||||||
|
this->set_done(psBrim);
|
||||||
}
|
}
|
||||||
BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info();
|
BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info();
|
||||||
}
|
}
|
||||||
|
@ -1697,22 +1702,7 @@ void Print::_make_skirt()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include the wipe tower.
|
// Include the wipe tower.
|
||||||
if (has_wipe_tower() && ! m_wipe_tower_data.tool_changes.empty()) {
|
append(points, this->first_layer_wipe_tower_corners());
|
||||||
double width = m_config.wipe_tower_width + 2*m_wipe_tower_data.brim_width;
|
|
||||||
double depth = m_wipe_tower_data.depth + 2*m_wipe_tower_data.brim_width;
|
|
||||||
Vec2d pt = Vec2d(-m_wipe_tower_data.brim_width, -m_wipe_tower_data.brim_width);
|
|
||||||
|
|
||||||
std::vector<Vec2d> pts;
|
|
||||||
pts.push_back(Vec2d(pt.x(), pt.y()));
|
|
||||||
pts.push_back(Vec2d(pt.x()+width, pt.y()));
|
|
||||||
pts.push_back(Vec2d(pt.x()+width, pt.y()+depth));
|
|
||||||
pts.push_back(Vec2d(pt.x(), pt.y()+depth));
|
|
||||||
for (Vec2d& pt : pts) {
|
|
||||||
pt = Eigen::Rotation2Dd(Geometry::deg2rad(m_config.wipe_tower_rotation_angle.value)) * pt;
|
|
||||||
pt += Vec2d(m_config.wipe_tower_x.value, m_config.wipe_tower_y.value);
|
|
||||||
points.push_back(Point(scale_(pt.x()), scale_(pt.y())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (points.size() < 3)
|
if (points.size() < 3)
|
||||||
// At least three points required for a convex hull.
|
// At least three points required for a convex hull.
|
||||||
|
@ -1796,28 +1786,19 @@ void Print::_make_skirt()
|
||||||
}
|
}
|
||||||
// Brims were generated inside out, reverse to print the outmost contour first.
|
// Brims were generated inside out, reverse to print the outmost contour first.
|
||||||
m_skirt.reverse();
|
m_skirt.reverse();
|
||||||
|
|
||||||
|
// Remember the outer edge of the last skirt line extruded as m_skirt_convex_hull.
|
||||||
|
for (Polygon &poly : offset(convex_hull, distance + 0.5f * float(scale_(spacing)), ClipperLib::jtRound, float(scale_(0.1))))
|
||||||
|
append(m_skirt_convex_hull, std::move(poly.points));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Print::_make_brim()
|
void Print::_make_brim()
|
||||||
{
|
{
|
||||||
// Brim is only printed on first layer and uses perimeter extruder.
|
// Brim is only printed on first layer and uses perimeter extruder.
|
||||||
|
Polygons islands = this->first_layer_islands();
|
||||||
|
Polygons loops;
|
||||||
Flow flow = this->brim_flow();
|
Flow flow = this->brim_flow();
|
||||||
Polygons islands;
|
size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing()));
|
||||||
for (PrintObject *object : m_objects) {
|
|
||||||
Polygons object_islands;
|
|
||||||
for (ExPolygon &expoly : object->m_layers.front()->lslices)
|
|
||||||
object_islands.push_back(expoly.contour);
|
|
||||||
if (! object->support_layers().empty())
|
|
||||||
object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON));
|
|
||||||
islands.reserve(islands.size() + object_islands.size() * object->instances().size());
|
|
||||||
for (const PrintInstance &instance : object->instances())
|
|
||||||
for (Polygon &poly : object_islands) {
|
|
||||||
islands.push_back(poly);
|
|
||||||
islands.back().translate(instance.shift);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Polygons loops;
|
|
||||||
size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing()));
|
|
||||||
for (size_t i = 0; i < num_loops; ++ i) {
|
for (size_t i = 0; i < num_loops; ++ i) {
|
||||||
this->throw_if_canceled();
|
this->throw_if_canceled();
|
||||||
islands = offset(islands, float(flow.scaled_spacing()), jtSquare);
|
islands = offset(islands, float(flow.scaled_spacing()), jtSquare);
|
||||||
|
@ -1828,6 +1809,11 @@ void Print::_make_brim()
|
||||||
p.pop_back();
|
p.pop_back();
|
||||||
poly.points = std::move(p);
|
poly.points = std::move(p);
|
||||||
}
|
}
|
||||||
|
if (i + 1 == num_loops) {
|
||||||
|
// Remember the outer edge of the last brim line extruded as m_first_layer_convex_hull.
|
||||||
|
for (Polygon &poly : islands)
|
||||||
|
append(m_first_layer_convex_hull.points, poly.points);
|
||||||
|
}
|
||||||
polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing())));
|
polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing())));
|
||||||
}
|
}
|
||||||
loops = union_pt_chained(loops, false);
|
loops = union_pt_chained(loops, false);
|
||||||
|
@ -1967,6 +1953,58 @@ void Print::_make_brim()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Polygons Print::first_layer_islands() const
|
||||||
|
{
|
||||||
|
Polygons islands;
|
||||||
|
for (PrintObject *object : m_objects) {
|
||||||
|
Polygons object_islands;
|
||||||
|
for (ExPolygon &expoly : object->m_layers.front()->lslices)
|
||||||
|
object_islands.push_back(expoly.contour);
|
||||||
|
if (! object->support_layers().empty())
|
||||||
|
object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON));
|
||||||
|
islands.reserve(islands.size() + object_islands.size() * object->instances().size());
|
||||||
|
for (const PrintInstance &instance : object->instances())
|
||||||
|
for (Polygon &poly : object_islands) {
|
||||||
|
islands.push_back(poly);
|
||||||
|
islands.back().translate(instance.shift);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return islands;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Point> Print::first_layer_wipe_tower_corners() const
|
||||||
|
{
|
||||||
|
std::vector<Point> corners;
|
||||||
|
if (has_wipe_tower() && ! m_wipe_tower_data.tool_changes.empty()) {
|
||||||
|
double width = m_config.wipe_tower_width + 2*m_wipe_tower_data.brim_width;
|
||||||
|
double depth = m_wipe_tower_data.depth + 2*m_wipe_tower_data.brim_width;
|
||||||
|
Vec2d pt0(-m_wipe_tower_data.brim_width, -m_wipe_tower_data.brim_width);
|
||||||
|
for (Vec2d pt : {
|
||||||
|
pt0,
|
||||||
|
Vec2d(pt0.x()+width, pt0.y() ),
|
||||||
|
Vec2d(pt0.x()+width, pt0.y()+depth),
|
||||||
|
Vec2d(pt0.x(), pt0.y()+depth)
|
||||||
|
}) {
|
||||||
|
pt = Eigen::Rotation2Dd(Geometry::deg2rad(m_config.wipe_tower_rotation_angle.value)) * pt;
|
||||||
|
pt += Vec2d(m_config.wipe_tower_x.value, m_config.wipe_tower_y.value);
|
||||||
|
corners.emplace_back(Point(scale_(pt.x()), scale_(pt.y())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return corners;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Print::finalize_first_layer_convex_hull()
|
||||||
|
{
|
||||||
|
append(m_first_layer_convex_hull.points, m_skirt_convex_hull);
|
||||||
|
if (m_first_layer_convex_hull.empty()) {
|
||||||
|
// Neither skirt nor brim was extruded. Collect points of printed objects from 1st layer.
|
||||||
|
for (Polygon &poly : this->first_layer_islands())
|
||||||
|
append(m_first_layer_convex_hull.points, std::move(poly.points));
|
||||||
|
}
|
||||||
|
append(m_first_layer_convex_hull.points, this->first_layer_wipe_tower_corners());
|
||||||
|
m_first_layer_convex_hull = Geometry::convex_hull(m_first_layer_convex_hull.points);
|
||||||
|
}
|
||||||
|
|
||||||
// Wipe tower support.
|
// Wipe tower support.
|
||||||
bool Print::has_wipe_tower() const
|
bool Print::has_wipe_tower() const
|
||||||
{
|
{
|
||||||
|
@ -1991,7 +2029,6 @@ const WipeTowerData& Print::wipe_tower_data(size_t extruders_cnt, double first_l
|
||||||
return m_wipe_tower_data;
|
return m_wipe_tower_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Print::_make_wipe_tower()
|
void Print::_make_wipe_tower()
|
||||||
{
|
{
|
||||||
m_wipe_tower_data.clear();
|
m_wipe_tower_data.clear();
|
||||||
|
|
|
@ -402,6 +402,12 @@ public:
|
||||||
|
|
||||||
const ExtrusionEntityCollection& skirt() const { return m_skirt; }
|
const ExtrusionEntityCollection& skirt() const { return m_skirt; }
|
||||||
const ExtrusionEntityCollection& brim() const { return m_brim; }
|
const ExtrusionEntityCollection& brim() const { return m_brim; }
|
||||||
|
// Convex hull of the 1st layer extrusions, for bed leveling and placing the initial purge line.
|
||||||
|
// It encompasses the object extrusions, support extrusions, skirt, brim, wipe tower.
|
||||||
|
// It does NOT encompass user extrusions generated by custom G-code,
|
||||||
|
// therefore it does NOT encompass the initial purge line.
|
||||||
|
// It does NOT encompass MMU/MMU2 starting (wipe) areas.
|
||||||
|
const Polygon& first_layer_convex_hull() const { return m_first_layer_convex_hull; }
|
||||||
|
|
||||||
const PrintStatistics& print_statistics() const { return m_print_statistics; }
|
const PrintStatistics& print_statistics() const { return m_print_statistics; }
|
||||||
|
|
||||||
|
@ -437,6 +443,12 @@ private:
|
||||||
void _make_skirt();
|
void _make_skirt();
|
||||||
void _make_brim();
|
void _make_brim();
|
||||||
void _make_wipe_tower();
|
void _make_wipe_tower();
|
||||||
|
void finalize_first_layer_convex_hull();
|
||||||
|
|
||||||
|
// Islands of objects and their supports extruded at the 1st layer.
|
||||||
|
Polygons first_layer_islands() const;
|
||||||
|
// Return 4 wipe tower corners in the world coordinates (shifted and rotated), including the wipe tower brim.
|
||||||
|
std::vector<Point> first_layer_wipe_tower_corners() const;
|
||||||
|
|
||||||
// Declared here to have access to Model / ModelObject / ModelInstance
|
// Declared here to have access to Model / ModelObject / ModelInstance
|
||||||
static void model_volume_list_update_supports(ModelObject &model_object_dst, const ModelObject &model_object_src);
|
static void model_volume_list_update_supports(ModelObject &model_object_dst, const ModelObject &model_object_src);
|
||||||
|
@ -450,6 +462,13 @@ private:
|
||||||
// Ordered collections of extrusion paths to build skirt loops and brim.
|
// Ordered collections of extrusion paths to build skirt loops and brim.
|
||||||
ExtrusionEntityCollection m_skirt;
|
ExtrusionEntityCollection m_skirt;
|
||||||
ExtrusionEntityCollection m_brim;
|
ExtrusionEntityCollection m_brim;
|
||||||
|
// Convex hull of the 1st layer extrusions.
|
||||||
|
// It encompasses the object extrusions, support extrusions, skirt, brim, wipe tower.
|
||||||
|
// It does NOT encompass user extrusions generated by custom G-code,
|
||||||
|
// therefore it does NOT encompass the initial purge line.
|
||||||
|
// It does NOT encompass MMU/MMU2 starting (wipe) areas.
|
||||||
|
Polygon m_first_layer_convex_hull;
|
||||||
|
Points m_skirt_convex_hull;
|
||||||
|
|
||||||
// Following section will be consumed by the GCodeGenerator.
|
// Following section will be consumed by the GCodeGenerator.
|
||||||
ToolOrdering m_tool_ordering;
|
ToolOrdering m_tool_ordering;
|
||||||
|
|
Loading…
Reference in a new issue