Merge newest master

This commit is contained in:
tamasmeszaros 2018-07-18 10:26:03 +02:00
commit eeeced1d6b
14 changed files with 297 additions and 237 deletions

View file

@ -613,6 +613,9 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
m_cooling_buffer->set_current_extruder(initial_extruder_id);
// Emit machine envelope limits for the Marlin firmware.
this->print_machine_envelope(file, print);
// Disable fan.
if (! print.config.cooling.get_at(initial_extruder_id) || print.config.disable_fan_first_layers.get_at(initial_extruder_id))
_write(file, m_writer.set_fan(0, true));
@ -968,6 +971,35 @@ static bool custom_gcode_sets_temperature(const std::string &gcode, const int mc
return temp_set_by_gcode;
}
// Print the machine envelope G-code for the Marlin firmware based on the "machine_max_xxx" parameters.
// Do not process this piece of G-code by the time estimator, it already knows the values through another sources.
void GCode::print_machine_envelope(FILE *file, Print &print)
{
if (print.config.gcode_flavor.value == gcfMarlin) {
fprintf(file, "M201 X%d Y%d Z%d E%d ; sets maximum accelerations, mm/sec^2\n",
int(print.config.machine_max_acceleration_x.values.front() + 0.5),
int(print.config.machine_max_acceleration_y.values.front() + 0.5),
int(print.config.machine_max_acceleration_z.values.front() + 0.5),
int(print.config.machine_max_acceleration_e.values.front() + 0.5));
fprintf(file, "M203 X%d Y%d Z%d E%d ; sets maximum feedrates, mm/sec\n",
int(print.config.machine_max_feedrate_x.values.front() + 0.5),
int(print.config.machine_max_feedrate_y.values.front() + 0.5),
int(print.config.machine_max_feedrate_z.values.front() + 0.5),
int(print.config.machine_max_feedrate_e.values.front() + 0.5));
fprintf(file, "M204 S%d T%d ; sets acceleration (S) and retract acceleration (T), mm/sec^2\n",
int(print.config.machine_max_acceleration_extruding.values.front() + 0.5),
int(print.config.machine_max_acceleration_retracting.values.front() + 0.5));
fprintf(file, "M205 X%.2lf Y%.2lf Z%.2lf E%.2lf ; sets the jerk limits, mm/sec\n",
print.config.machine_max_jerk_x.values.front(),
print.config.machine_max_jerk_y.values.front(),
print.config.machine_max_jerk_z.values.front(),
print.config.machine_max_jerk_e.values.front());
fprintf(file, "M205 S%d T%d ; sets the minimum extruding and travel feed rate, mm/sec\n",
int(print.config.machine_min_extruding_rate.values.front() + 0.5),
int(print.config.machine_min_travel_rate.values.front() + 0.5));
}
}
// Write 1st layer bed temperatures into the G-code.
// Only do that if the start G-code does not already contain any M-code controlling an extruder temperature.
// M140 - Set Extruder Temperature

View file

@ -327,6 +327,7 @@ protected:
void _write_format(FILE* file, const char* format, ...);
std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1);
void print_machine_envelope(FILE *file, Print &print);
void _print_first_layer_bed_temperature(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
void _print_first_layer_extruder_temperatures(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
// this flag triggers first layer speeds

View file

@ -19,7 +19,6 @@
#include <boost/nowide/iostream.hpp>
#include <boost/algorithm/string/replace.hpp>
// #include <benchmark.h>
#include "SVG.hpp"
#include <Eigen/Dense>
@ -309,7 +308,7 @@ namespace arr {
using namespace libnest2d;
std::string toString(const Model& model) {
std::string toString(const Model& model, bool holes = true) {
std::stringstream ss;
ss << "{\n";
@ -348,17 +347,17 @@ std::string toString(const Model& model) {
// Holes:
ss << "\t\t{\n";
// for(auto h : expoly.holes) {
// ss << "\t\t\t{\n";
// for(auto v : h.points) ss << "\t\t\t\t{"
// << v.x << ", "
// << v.y << "},\n";
// {
// auto v = h.points.front();
// ss << "\t\t\t\t{" << v.x << ", " << v.y << "},\n";
// }
// ss << "\t\t\t},\n";
// }
if(holes) for(auto h : expoly.holes) {
ss << "\t\t\t{\n";
for(auto v : h.points) ss << "\t\t\t\t{"
<< v.x << ", "
<< v.y << "},\n";
{
auto v = h.points.front();
ss << "\t\t\t\t{" << v.x << ", " << v.y << "},\n";
}
ss << "\t\t\t},\n";
}
ss << "\t\t},\n";
ss << "\t},\n";
@ -477,58 +476,21 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
// Create the arranger config
auto min_obj_distance = static_cast<Coord>(dist/SCALING_FACTOR);
// Benchmark bench;
// std::cout << "Creating model siluett..." << std::endl;
// bench.start();
// Get the 2D projected shapes with their 3D model instance pointers
auto shapemap = arr::projectModelFromTop(model);
// bench.stop();
// std::cout << "Model siluett created in " << bench.getElapsedSec()
// << " seconds. " << "Min object distance = " << min_obj_distance << std::endl;
// std::cout << "{" << std::endl;
// std::for_each(shapemap.begin(), shapemap.end(),
// [] (ShapeData2D::value_type& it)
// {
// std::cout << "\t{" << std::endl;
// Item& item = it.second;
// for(auto& v : item) {
// std::cout << "\t\t" << "{" << getX(v)
// << ", " << getY(v) << "},\n";
// }
// std::cout << "\t}," << std::endl;
// });
// std::cout << "}" << std::endl;
// return true;
bool hasbin = bb != nullptr && bb->defined;
double area_max = 0;
Item *biggest = nullptr;
// Copy the references for the shapes only as the arranger expects a
// sequence of objects convertible to Item or ClipperPolygon
std::vector<std::reference_wrapper<Item>> shapes;
shapes.reserve(shapemap.size());
std::for_each(shapemap.begin(), shapemap.end(),
[&shapes, min_obj_distance, &area_max, &biggest,hasbin]
[&shapes, min_obj_distance, &area_max, hasbin]
(ShapeData2D::value_type& it)
{
if(!hasbin) {
Item& item = it.second;
item.addOffset(min_obj_distance);
auto b = ShapeLike::boundingBox(item.transformedShape());
auto a = b.width()*b.height();
if(area_max < a) {
area_max = static_cast<double>(a);
biggest = &item;
}
}
shapes.push_back(std::ref(it.second));
});
Box bin;
@ -546,9 +508,6 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
static_cast<libnest2d::Coord>(bbb.max.x),
static_cast<libnest2d::Coord>(bbb.max.y)
});
} else {
// Just take the biggest item as bin... ?
bin = ShapeLike::boundingBox(biggest->transformedShape());
}
// Will use the DJD selection heuristic with the BottomLeft placement
@ -563,20 +522,22 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
// Align the arranged pile into the center of the bin
pcfg.alignment = PConf::Alignment::CENTER;
// Start placing the items from the center of the print bed
pcfg.starting_point = PConf::Alignment::CENTER;
// TODO cannot use rotations until multiple objects of same geometry can
// handle different rotations
// arranger.useMinimumBoundigBoxRotation();
pcfg.rotations = { 0.0 };
// Magic: we will specify what is the goal of arrangement...
// In this case we override the default object function because we
// (apparently) don't care about pack efficiency and all we care is that the
// larger items go into the center of the pile and smaller items orbit it
// so the resulting pile has a circle-like shape.
// This is good for the print bed's heat profile.
// As a side effect, the arrange procedure is a lot faster (we do not need
// to calculate the convex hulls)
pcfg.object_function = [&bin](
// In this case we override the default object to make the larger items go
// into the center of the pile and smaller items orbit it so the resulting
// pile has a circle-like shape. This is good for the print bed's heat
// profile. We alse sacrafice a bit of pack efficiency for this to work. As
// a side effect, the arrange procedure is a lot faster (we do not need to
// calculate the convex hulls)
pcfg.object_function = [bin, hasbin](
NfpPlacer::Pile pile, // The currently arranged pile
double /*area*/, // Sum area of items (not needed)
double norm, // A norming factor for physical dimensions
@ -584,14 +545,25 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
{
auto bb = ShapeLike::boundingBox(pile);
// We will optimize to the diameter of the circle around the bounding
// box and use the norming factor to get rid of the physical dimensions
double score = PointLike::distance(bb.minCorner(),
bb.maxCorner()) / norm;
// We get the current item that's being evaluated.
auto& sh = pile.back();
// We retrieve the reference point of this item
auto rv = Nfp::referenceVertex(sh);
// We get the distance of the reference point from the center of the
// heat bed
auto c = bin.center();
auto d = PointLike::distance(rv, c);
// The score will be the normalized distance which will be minimized,
// effectively creating a circle shaped pile of items
double score = double(d)/norm;
// If it does not fit into the print bed we will beat it
// with a large penality
if(!NfpPlacer::wouldFit(bb, bin)) score = 2*penality - score;
// with a large penality. If we would not do this, there would be only
// one big pile that doesn't care whether it fits onto the print bed.
if(hasbin && !NfpPlacer::wouldFit(bb, bin)) score = 2*penality - score;
return score;
};
@ -602,18 +574,10 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
// Set the progress indicator for the arranger.
arranger.progressIndicator(progressind);
// std::cout << "Arranging model..." << std::endl;
// bench.start();
// Arrange and return the items with their respective indices within the
// input sequence.
auto result = arranger.arrangeIndexed(shapes.begin(), shapes.end());
// bench.stop();
// std::cout << "Model arranged in " << bench.getElapsedSec()
// << " seconds." << std::endl;
auto applyResult = [&shapemap](ArrangeResult::value_type& group,
Coord batch_offset)
{
@ -637,8 +601,6 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
}
};
// std::cout << "Applying result..." << std::endl;
// bench.start();
if(first_bin_only) {
applyResult(result.front(), 0);
} else {
@ -658,9 +620,6 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
batch_offset += stride;
}
}
// bench.stop();
// std::cout << "Result applied in " << bench.getElapsedSec()
// << " seconds." << std::endl;
for(auto objptr : model.objects) objptr->invalidate_bounding_box();
@ -675,16 +634,11 @@ bool Model::arrange_objects(coordf_t dist, const BoundingBoxf* bb,
{
bool ret = false;
if(bb != nullptr && bb->defined) {
// Despite the new arrange is able to run without a specified bin,
// the perl testsuit still fails for this case. For now the safest
// thing to do is to use the new arrange only when a proper bin is
// specified.
ret = arr::arrange(*this, dist, bb, false, progressind);
// std::fstream out("out.cpp", std::fstream::out);
// if(out.good()) {
// out << "const TestData OBJECTS = \n";
// out << arr::toString(*this);
// }
// out.close();
// SVG svg("out.svg");
// arr::toSVG(svg, *this);
// svg.Close();
} else {
// get the (transformed) size of each instance so that we take
// into account their different transformations when packing

View file

@ -772,7 +772,7 @@ PrintConfigDef::PrintConfigDef()
def->enum_labels.push_back("Machinekit");
def->enum_labels.push_back("Smoothie");
def->enum_labels.push_back(L("No extrusion"));
def->default_value = new ConfigOptionEnum<GCodeFlavor>(gcfMarlin);
def->default_value = new ConfigOptionEnum<GCodeFlavor>(gcfRepRap);
def = this->add("infill_acceleration", coFloat);
def->label = L("Infill");
@ -907,10 +907,10 @@ PrintConfigDef::PrintConfigDef()
};
std::vector<AxisDefault> axes {
// name, max_feedrate, max_acceleration, max_jerk
{ "x", { 500., 200. }, { 9000., 1000. }, { 10., 10. } },
{ "y", { 500., 200. }, { 9000., 1000. }, { 10., 10. } },
{ "z", { 12., 12. }, { 500., 200. }, { 0.2, 0.4 } },
{ "e", { 120., 120. }, { 10000., 5000. }, { 2.5, 2.5 } }
{ "x", { 500., 200. }, { 9000., 1000. }, { 10. , 10. } },
{ "y", { 500., 200. }, { 9000., 1000. }, { 10. , 10. } },
{ "z", { 12., 12. }, { 500., 200. }, { 0.2, 0.4 } },
{ "e", { 120., 120. }, { 10000., 5000. }, { 2.5, 2.5 } }
};
for (const AxisDefault &axis : axes) {
std::string axis_upper = boost::to_upper_copy<std::string>(axis.name);

View file

@ -14,7 +14,7 @@
#include <boost/thread.hpp>
#define SLIC3R_FORK_NAME "Slic3r Prusa Edition"
#define SLIC3R_VERSION "1.40.1"
#define SLIC3R_VERSION "1.41.0-alpha"
#define SLIC3R_BUILD "UNKNOWN"
typedef int32_t coord_t;