Fixed conflicts after merge with master

This commit is contained in:
enricoturri1966 2020-06-04 13:57:39 +02:00
commit c3d643ead3
28 changed files with 497 additions and 185 deletions

View file

@ -396,11 +396,14 @@ template<> std::function<double(const Item&)> AutoArranger<Box>::get_objfn()
double score = std::get<0>(result);
auto& fullbb = std::get<1>(result);
double miss = Placer::overfit(fullbb, m_bin);
auto bin = m_bin;
sl::offset(bin, -EPSILON * (m_bin.width() + m_bin.height()));
double miss = Placer::overfit(fullbb, bin);
miss = miss > 0? miss : 0;
score += miss*miss;
return score;
return score;
};
}

View file

@ -1334,7 +1334,28 @@ 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_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).
{
BoundingBoxf bbox(print.config().bed_shape.values);
m_placeholder_parser.set("print_bed_min", new ConfigOptionFloats({ bbox.min.x(), bbox.min.y() }));
m_placeholder_parser.set("print_bed_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() }));
m_placeholder_parser.set("print_bed_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
}
{
// 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() }));
m_placeholder_parser.set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
}
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.
this->_print_first_layer_bed_temperature(file, print, start_gcode, initial_extruder_id, true);

View file

@ -355,7 +355,7 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_
max_layer_height = std::min(max_layer_height, mlh);
}
// The Prusa3D Fast (0.35mm layer height) print profile sets a higher layer height than what is normally allowed
// by the nozzle. This is a hack and it works by increasing extrusion width.
// by the nozzle. This is a hack and it works by increasing extrusion width. See GH #3919.
max_layer_height = std::max(max_layer_height, max_object_layer_height);
for (size_t i = 0; i + 1 < m_layer_tools.size(); ++ i) {
@ -400,47 +400,21 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_
// and maybe other problems. We will therefore go through layer_tools and detect and fix this.
// So, if there is a non-object layer starting with different extruder than the last one ended with (or containing more than one extruder),
// we'll mark it with has_wipe tower.
assert(! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower);
if (! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower) {
for (size_t i = 0; i + 1 < m_layer_tools.size();) {
const LayerTools &lt = m_layer_tools[i];
assert(lt.has_wipe_tower);
assert(! lt.extruders.empty());
// Find the next layer with wipe tower or mark a layer as such.
size_t j = i + 1;
for (; j < m_layer_tools.size() && ! m_layer_tools[j].has_wipe_tower; ++ j) {
LayerTools &lt_next = m_layer_tools[j];
if (lt_next.extruders.empty()) {
//FIXME Vojtech: Lukasi, proc?
j = m_layer_tools.size();
break;
}
if (lt_next.extruders.front() != lt.extruders.back() || lt_next.extruders.size() > 1) {
// Support only layer, soluble layers? Otherwise the layer should have been already marked as having wipe tower.
assert(lt_next.has_support && ! lt_next.has_object);
lt_next.has_wipe_tower = true;
break;
}
for (unsigned int i=0; i+1<m_layer_tools.size(); ++i) {
LayerTools& lt = m_layer_tools[i];
LayerTools& lt_next = m_layer_tools[i+1];
if (lt.extruders.empty() || lt_next.extruders.empty())
break;
if (!lt_next.has_wipe_tower && (lt_next.extruders.front() != lt.extruders.back() || lt_next.extruders.size() > 1))
lt_next.has_wipe_tower = true;
// We should also check that the next wipe tower layer is no further than max_layer_height:
unsigned int j = i+1;
double last_wipe_tower_print_z = lt_next.print_z;
while (++j < m_layer_tools.size()-1 && !m_layer_tools[j].has_wipe_tower)
if (m_layer_tools[j+1].print_z - last_wipe_tower_print_z > max_layer_height + EPSILON) {
m_layer_tools[j].has_wipe_tower = true;
last_wipe_tower_print_z = m_layer_tools[j].print_z;
}
if (j == m_layer_tools.size())
// No wipe tower above layer i, therefore no need to add any wipe tower layer above i.
break;
// We should also check that the next wipe tower layer is no further than max_layer_height.
// This algorith may in theory create very thin wipe layer j if layer closely below j is marked as wipe tower.
// This may happen if printing with non-soluble break away supports.
// On the other side it should not hurt as there will be no wipe, just perimeter and sparse infill printed
// at that particular wipe tower layer without extruder change.
double last_wipe_tower_print_z = lt.print_z;
assert(m_layer_tools[j].has_wipe_tower);
for (size_t k = i + 1; k < j; ++k) {
assert(! m_layer_tools[k].has_wipe_tower);
if (m_layer_tools[k + 1].print_z - last_wipe_tower_print_z > max_layer_height + EPSILON) {
m_layer_tools[k].has_wipe_tower = true;
last_wipe_tower_print_z = m_layer_tools[k].print_z;
}
}
i = j;
}
}
// Calculate the wipe_tower_layer_height values.

View file

@ -166,6 +166,7 @@ class SupportLayer : public Layer
{
public:
// 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;
// Extrusion paths for the support base and for the support interface and contacts.
ExtrusionEntityCollection support_fills;

View file

@ -244,7 +244,6 @@ bool Print::invalidate_step(PrintStep step)
{
bool invalidated = Inherited::invalidate_step(step);
// Propagate to dependent steps.
//FIXME Why should skirt invalidate brim? Shouldn't it be vice versa?
if (step == psSkirt)
invalidated |= Inherited::invalidate_step(psBrim);
if (step != psGCodeExport)
@ -1606,6 +1605,8 @@ void Print::process()
}
if (this->set_started(psSkirt)) {
m_skirt.clear();
m_skirt_convex_hull.clear();
m_first_layer_convex_hull.points.clear();
if (this->has_skirt()) {
this->set_status(88, L("Generating skirt"));
this->_make_skirt();
@ -1614,11 +1615,15 @@ void Print::process()
}
if (this->set_started(psBrim)) {
m_brim.clear();
m_first_layer_convex_hull.points.clear();
if (m_config.brim_width > 0) {
this->set_status(88, L("Generating 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();
}
@ -1709,22 +1714,7 @@ void Print::_make_skirt()
}
// Include the wipe tower.
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 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())));
}
}
append(points, this->first_layer_wipe_tower_corners());
if (points.size() < 3)
// At least three points required for a convex hull.
@ -1808,28 +1798,19 @@ void Print::_make_skirt()
}
// Brims were generated inside out, reverse to print the outmost contour first.
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()
{
// Brim is only printed on first layer and uses perimeter extruder.
Polygons islands = this->first_layer_islands();
Polygons loops;
Flow flow = this->brim_flow();
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);
}
}
Polygons loops;
size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing()));
size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing()));
for (size_t i = 0; i < num_loops; ++ i) {
this->throw_if_canceled();
islands = offset(islands, float(flow.scaled_spacing()), jtSquare);
@ -1840,6 +1821,11 @@ void Print::_make_brim()
p.pop_back();
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())));
}
loops = union_pt_chained(loops, false);
@ -1979,6 +1965,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.
bool Print::has_wipe_tower() const
{
@ -2003,7 +2041,6 @@ const WipeTowerData& Print::wipe_tower_data(size_t extruders_cnt, double first_l
return m_wipe_tower_data;
}
void Print::_make_wipe_tower()
{
m_wipe_tower_data.clear();

View file

@ -411,6 +411,12 @@ public:
const ExtrusionEntityCollection& skirt() const { return m_skirt; }
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; }
@ -446,6 +452,12 @@ private:
void _make_skirt();
void _make_brim();
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
static void model_volume_list_update_supports(ModelObject &model_object_dst, const ModelObject &model_object_src);
@ -459,6 +471,13 @@ private:
// Ordered collections of extrusion paths to build skirt loops and brim.
ExtrusionEntityCollection m_skirt;
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.
ToolOrdering m_tool_ordering;

View file

@ -7,7 +7,7 @@
// There is an implementation of a hole-aware raycaster that was eventually
// not used in production version. It is now hidden under following define
// for possible future use.
#define SLIC3R_HOLE_RAYCASTER
// #define SLIC3R_HOLE_RAYCASTER
#ifdef SLIC3R_HOLE_RAYCASTER
#include "libslic3r/SLA/Hollowing.hpp"

View file

@ -45,6 +45,9 @@
// Enable rendering of objects using environment map
#define ENABLE_ENVIRONMENT_MAP (1 && ENABLE_2_3_0_ALPHA1)
// Enable smoothing of objects normals
#define ENABLE_SMOOTH_NORMALS (0 && ENABLE_2_3_0_ALPHA1)
// Enable G-Code viewer
#define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1)
#define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER)