Merge branch 'master' into gui3-shortcuts

This commit is contained in:
Alessandro Ranellucci 2017-05-21 20:03:57 +02:00
commit 8a3094fe5f
13 changed files with 101 additions and 46 deletions

View File

@ -58,8 +58,7 @@ Sure! You can do the following to find things that are available to help with:
* Development
* [Low Effort tasks](https://github.com/alexrj/Slic3r/labels/Low%20Effort): pick one of them!
* [More available tasks](https://github.com/alexrj/Slic3r/milestone/31): let's discuss together before you start working on them
* Please comment in the related github issue that you are working on it so that other people know.
* Please comment in the related GitHub issue that you are working on it so that other people know.
* Please comment in the related GitHub issue that you are working on it so that other people know.
* Contribute to the [Manual](http://manual.slic3r.org/)! (see its [GitHub repository](https://github.com/alexrj/Slic3r-Manual))
* You can also find us in #slic3r on [FreeNode](https://webchat.freenode.net): talk to _Sound_, _LoH_ or the other members of the Slic3r community.
* Add an [issue](https://github.com/alexrj/Slic3r/issues) to the GitHub tracker if it isn't already present.

View File

@ -136,6 +136,10 @@ sub export {
# prepare the helper object for replacing placeholders in custom G-code and output filename
$self->placeholder_parser->update_timestamp;
# GCode sets this automatically whenever we call change_layer(),
# but we need it for skirt/brim too
$gcodegen->set_first_layer(1);
# disable fan
print $fh $gcodegen->writer->set_fan(0, 1)
if $self->config->cooling && $self->config->disable_fan_first_layers;

View File

@ -16,6 +16,8 @@ use Slic3r::Test;
{
my $config = Slic3r::Config->new_from_defaults;
$config->set('layer_height', 0.3);
$config->set('first_layer_height', 0.35);
$config->set('raft_layers', 2);
$config->set('infill_extruder', 2);
$config->set('solid_infill_extruder', 3);
@ -24,7 +26,9 @@ use Slic3r::Test;
$config->set('extruder_offset', [ [0,0], [20,0], [0,20], [20,20] ]);
$config->set('temperature', [200, 180, 170, 160]);
$config->set('first_layer_temperature', [206, 186, 166, 156]);
$config->set('standby_temperature_delta', -5);
$config->set('toolchange_gcode', ';toolchange'); # test that it doesn't crash when this is supplied
$config->set('skirts', 2); # test correct temperatures are applied to skirt as well
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
@ -57,6 +61,18 @@ use Slic3r::Test;
} elsif ($cmd eq 'G1' && $info->{extruding} && $info->{dist_XY} > 0) {
push @extrusion_points, my $point = Slic3r::Point->new_scale($args->{X}, $args->{Y});
$point->translate(map +scale($_), @{ $config->extruder_offset->[$tool] });
# check temperature (we don't do it at M104/M109 because that may be
# issued before layer change)
if ($self->Z == $config->first_layer_height) {
fail 'unexpected temperature in first layer'
unless $tool_temp[$tool] == ($config->first_layer_temperature->[$tool] + $config->standby_temperature_delta)
|| $tool_temp[$tool] == $config->first_layer_temperature->[$tool];
} else {
fail 'unexpected temperature'
unless $tool_temp[$tool] == ($config->temperature->[$tool] + $config->standby_temperature_delta)
|| $tool_temp[$tool] == $config->temperature->[$tool];
}
}
});
my $convex_hull = convex_hull(\@extrusion_points);

View File

@ -836,10 +836,6 @@ FILE_PATTERNS = *.c \
*.h++ \
*.cs \
*.d \
*.php \
*.php4 \
*.php5 \
*.phtml \
*.inc \
*.m \
*.markdown \
@ -855,8 +851,6 @@ FILE_PATTERNS = *.c \
*.f \
*.for \
*.tcl \
*.vhd \
*.vhdl \
*.ucf \
*.qsf
@ -864,7 +858,7 @@ FILE_PATTERNS = *.c \
# be searched for input files as well.
# The default value is: NO.
RECURSIVE = NO
RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a

View File

@ -10,15 +10,15 @@ namespace Slic3r {
class BridgeDetector {
public:
// The non-grown hole.
/// The non-grown hole.
ExPolygon expolygon;
// Lower slices, all regions.
/// Lower slices, all regions.
ExPolygonCollection lower_slices;
// Scaled extrusion width of the infill.
/// Scaled extrusion width of the infill.
coord_t extrusion_width;
// Angle resolution for the brute force search of the best bridging angle.
/// Angle resolution for the brute force search of the best bridging angle.
double resolution;
// The final optimal angle.
/// The final optimal angle.
double angle;
BridgeDetector(const ExPolygon &_expolygon, const ExPolygonCollection &_lower_slices, coord_t _extrusion_width);
@ -28,15 +28,15 @@ public:
Polylines unsupported_edges(double angle = -1) const;
private:
// Open lines representing the supporting edges.
/// Open lines representing the supporting edges.
Polylines _edges;
// Closed polygons representing the supporting areas.
/// Closed polygons representing the supporting areas.
ExPolygons _anchors;
class BridgeDirection {
public:
BridgeDirection(double a = -1.) : angle(a), coverage(0.), max_length(0.) {}
// the best direction is the one causing most lines to be bridged (thus most coverage)
/// the best direction is the one causing most lines to be bridged (thus most coverage)
bool operator<(const BridgeDirection &other) const {
// Initial sort by coverage only - comparator must obey strict weak ordering
return this->coverage > other.coverage;

View File

@ -39,13 +39,14 @@ Extruder::extrude(double dE)
return dE;
}
/* This method makes sure the extruder is retracted by the specified amount
/** This method makes sure the extruder is retracted by the specified amount
of filament and returns the amount of filament retracted.
If the extruder is already retracted by the same or a greater amount,
this method is a no-op.
The restart_extra argument sets the extra length to be used for
unretraction. If we're actually performing a retraction, any restart_extra
value supplied will overwrite the previous one if any. */
value supplied will overwrite the previous one if any.
*/
double
Extruder::retract(double length, double restart_extra)
{

View File

@ -10,6 +10,7 @@ namespace Slic3r {
class Extruder
{
public:
/// ID of current object.
unsigned int id;
double E;
double absolute_E;
@ -21,16 +22,23 @@ class Extruder
Extruder(unsigned int id, GCodeConfig *config);
virtual ~Extruder() {}
void reset();
/// Calculate the amount extruded for relative or absolute moves.
double extrude(double dE);
double retract(double length, double restart_extra);
double unretract();
double e_per_mm(double mm3_per_mm) const;
double extruded_volume() const;
double used_filament() const;
/// Calculate amount of filament used for current Extruder object.
double used_filament() const;
/// Retrieve the filament diameter for this Extruder from config.
double filament_diameter() const;
/// Retrieve the filament density for this Extruder from config.
double filament_density() const;
/// Retrieve the filament cost for this Extruder from config.
double filament_cost() const;
/// Retrieve the extrustion multiplier for this Extruder from config.
double extrusion_multiplier() const;
double retract_length() const;
double retract_lift() const;

View File

@ -11,7 +11,8 @@ class ExPolygonCollection;
class ExtrusionEntityCollection;
class Extruder;
/* Each ExtrusionRole value identifies a distinct set of { extruder, speed } */
/** \brief Each ExtrusionRole value identifies a distinct set of { extruder, speed }
*/
enum ExtrusionRole {
erNone,
erPerimeter,
@ -27,7 +28,7 @@ enum ExtrusionRole {
erSupportMaterialInterface,
};
/* Special flags describing loop */
/** \brief Special flags describing loop */
enum ExtrusionLoopRole {
elrDefault,
elrContourInternalPerimeter,
@ -45,9 +46,9 @@ public:
virtual void reverse() = 0;
virtual Point first_point() const = 0;
virtual Point last_point() const = 0;
// Produce a list of 2D polygons covered by the extruded path.
/// Produce a list of 2D polygons covered by the extruded path.
virtual Polygons grow() const = 0;
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
/// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
virtual double min_mm3_per_mm() const = 0;
virtual Polyline as_polyline() const = 0;
virtual double length() const { return 0; };
@ -60,11 +61,11 @@ class ExtrusionPath : public ExtrusionEntity
public:
Polyline polyline;
ExtrusionRole role;
// Volumetric velocity. mm^3 of plastic per mm of linear head motion
/// Volumetric velocity. mm^3 of plastic per mm of linear head motion
double mm3_per_mm;
// Width of the extrusion.
/// Width of the extrusion.
float width;
// Height of the extrusion.
/// Height of the extrusion.
float height;
ExtrusionPath(ExtrusionRole role) : role(role), mm3_per_mm(-1), width(-1), height(-1) {};
@ -74,11 +75,11 @@ public:
void reverse() { this->polyline.reverse(); }
Point first_point() const { return this->polyline.points.front(); }
Point last_point() const { return this->polyline.points.back(); }
// Produce a list of extrusion paths into retval by clipping this path by ExPolygonCollection.
// Currently not used.
/// Produce a list of extrusion paths into retval by clipping this path by ExPolygonCollection.
/// Currently not used.
void intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const;
// Produce a list of extrusion paths into retval by removing parts of this path by ExPolygonCollection.
// Currently not used.
/// Produce a list of extrusion paths into retval by removing parts of this path by ExPolygonCollection.
/// Currently not used.
void subtract_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const;
void clip_end(double distance);
void simplify(double tolerance);
@ -103,9 +104,9 @@ public:
return this->role == erBridgeInfill
|| this->role == erOverhangPerimeter;
};
// Produce a list of 2D polygons covered by the extruded path.
/// Produce a list of 2D polygons covered by the extruded path.
Polygons grow() const;
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
/// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
double min_mm3_per_mm() const { return this->mm3_per_mm; }
Polyline as_polyline() const { return this->polyline; }
@ -141,7 +142,7 @@ class ExtrusionLoop : public ExtrusionEntity
bool split_at_vertex(const Point &point);
void split_at(const Point &point, bool prefer_non_overhang = false);
void clip_end(double distance, ExtrusionPaths* paths) const;
// Test, whether the point is extruded by a bridging flow.
/// Test, whether the point is extruded by a bridging flow.
bool has_overhang_point(const Point &point) const;
bool is_perimeter() const {
return this->paths.front().role == erPerimeter
@ -159,9 +160,9 @@ class ExtrusionLoop : public ExtrusionEntity
|| this->paths.front().role == erSolidInfill
|| this->paths.front().role == erTopSolidInfill;
}
// Produce a list of 2D polygons covered by the extruded path.
/// Produce a list of 2D polygons covered by the extruded path.
Polygons grow() const;
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
/// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
double min_mm3_per_mm() const;
Polyline as_polyline() const { return this->polygon().split_at_first_point(); }
void append(const ExtrusionPath &path) {

View File

@ -120,11 +120,11 @@ Flow::_width_from_spacing(float spacing, float nozzle_diameter, float height, bo
return spacing + OVERLAP_FACTOR * height * (1 - PI/4.0);
}
// Calculate a new spacing to fill width with possibly integer number of lines,
// the first and last line being centered at the interval ends.
// This function possibly increases the spacing, never decreases,
// and for a narrow width the increase in spacing may become severe,
// therefore the adjustment is limited to 20% increase.
/// Calculate a new spacing to fill width with possibly integer number of lines,
/// the first and last line being centered at the interval ends.
/// This function possibly increases the spacing, never decreases,
/// and for a narrow width the increase in spacing may become severe,
/// therefore the adjustment is limited to 20% increase.
template <class T>
T
Flow::solid_spacing(const T total_width, const T spacing)

View File

@ -10,6 +10,7 @@ namespace Slic3r {
constexpr auto BRIDGE_EXTRA_SPACING = 0.05;
constexpr auto OVERLAP_FACTOR = 1.0;
/// Enumeration for different flow roles
enum FlowRole {
frExternalPerimeter,
frPerimeter,
@ -20,6 +21,8 @@ enum FlowRole {
frSupportMaterialInterface,
};
/// Represents material flow; provides methods to predict material spacing.
class Flow
{
public:
@ -28,7 +31,13 @@ class Flow
Flow(float _w, float _h, float _nd, bool _bridge = false)
: width(_w), height(_h), nozzle_diameter(_nd), bridge(_bridge) {};
/// Return the centerline spacing between two adjacent extrusions that have the same properties (width, etc).
/// Models as a rectangle with semicircles at the ends.
float spacing() const;
/// Return the centerline spacing between two Flow objects (current and some other flow).
/// \remark this->spacing(other) == other.spacing(this)
float spacing(const Flow &other) const;
void set_spacing(float spacing);
void set_solid_spacing(const coord_t total_width) {
@ -48,12 +57,18 @@ class Flow
return scale_(this->spacing(other));
};
/// Static method to build a Flow object from an extrusion width config setting and some other context properties
static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float bridge_flow_ratio);
/// Static method to build a Flow object from a specified centerline spacing (center-to-center).
static Flow new_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge);
template <class T> static T solid_spacing(const T total_width, const T spacing);
private:
static float _bridge_width(float nozzle_diameter, float bridge_flow_ratio);
/// Calculate a relatively sane extrusion width, based on height and nozzle diameter.
/// Algorithm used does not play nice with layer heights < 0.1mm.
static float _auto_width(FlowRole role, float nozzle_diameter, float height);
static float _width_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge);
};

View File

@ -119,7 +119,7 @@ OozePrevention::post_toolchange(GCode &gcodegen)
int
OozePrevention::_get_temp(GCode &gcodegen)
{
return (gcodegen.layer != NULL && gcodegen.layer->id() == 0)
return gcodegen.first_layer
? gcodegen.config.first_layer_temperature.get_at(gcodegen.writer.extruder()->id)
: gcodegen.config.temperature.get_at(gcodegen.writer.extruder()->id);
}

View File

@ -738,7 +738,7 @@ template <Axis A>
void
TriangleMeshSlicer<A>::slice(const std::vector<float> &z, std::vector<Polygons>* layers) const
{
/*
/**
This method gets called with a list of unscaled Z coordinates and outputs
a vector pointer having the same number of items as the original list.
Each item is a vector of polygons created by slicing our mesh at the
@ -1160,14 +1160,14 @@ template <Axis A>
void
TriangleMeshSlicer<A>::make_expolygons(const Polygons &loops, ExPolygons* slices) const
{
/*
/**
Input loops are not suitable for evenodd nor nonzero fill types, as we might get
two consecutive concentric loops having the same winding order - and we have to
respect such order. In that case, evenodd would create wrong inversions, and nonzero
would ignore holes inside two concentric contours.
So we're ordering loops and collapse consecutive concentric loops having the same
winding order.
TODO: find a faster algorithm for this, maybe with some sort of binary search.
\todo find a faster algorithm for this, maybe with some sort of binary search.
If we computed a "nesting tree" we could also just remove the consecutive loops
having the same winding order, and remove the extra one(s) so that we could just
supply everything to offset() instead of performing several union/diff calls.

View File

@ -60,12 +60,23 @@ class TriangleMesh
void extrude_tin(float offset);
void require_shared_vertices();
void reverse_normals();
/// Generate a mesh representing a cube with dimensions (x, y, z), with one corner at (0,0,0).
static TriangleMesh make_cube(double x, double y, double z);
/// Generate a mesh representing a cylinder of radius r and height h, with the base at (0,0,0).
/// param[in] r Radius
/// param[in] h Height
/// param[in] fa Facet angle. A smaller angle produces more facets. Default value is 2pi / 360.
static TriangleMesh make_cylinder(double r, double h, double fa=(2*PI/360));
/// Generate a mesh representing a sphere of radius rho, centered about (0,0,0).
/// param[in] rho Distance from center to the shell of the sphere.
/// param[in] fa Facet angle. A smaller angle produces more facets. Default value is 2pi / 360.
static TriangleMesh make_sphere(double rho, double fa=(2*PI/360));
stl_file stl;
/// Whether or not this mesh has been repaired.
bool repaired;
private:
@ -98,6 +109,8 @@ class IntersectionLine : public Line
typedef std::vector<IntersectionLine> IntersectionLines;
typedef std::vector<IntersectionLine*> IntersectionLinePtrs;
/// \brief Class for processing TriangleMesh objects.
template <Axis A>
class TriangleMeshSlicer
{
@ -112,6 +125,10 @@ class TriangleMeshSlicer
const float &min_z, const float &max_z, std::vector<IntersectionLine>* lines,
boost::mutex* lines_mutex = NULL) const;
/// \brief Splits the current mesh into two parts.
/// \param[in] z Coordinate plane to cut along.
/// \param[out] upper TriangleMesh object to add the mesh > z. NULL suppresses saving this.
/// \param[out] lower TriangleMesh object to save the mesh < z. NULL suppresses saving this.
void cut(float z, TriangleMesh* upper, TriangleMesh* lower) const;
private: