mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-12 18:19:13 +08:00
Merge branch 'master' into gui3-shortcuts
This commit is contained in:
commit
8a3094fe5f
@ -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.
|
||||
|
@ -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;
|
||||
|
16
t/multi.t
16
t/multi.t
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user