mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-22 00:01:09 -06:00
Ported the G-code generator from Perl to C++.
Removed GCode.pm Removed the Perl bindigns for AvoidCrossingPerimeters, OozePrevention, SpiralVase, Wipe Changed the std::set of extruder IDs to vector of IDs. Removed some MSVC compiler warnings, removed obnoxious compiler warnings when compiling the Perl bindings.
This commit is contained in:
parent
72ae3585e4
commit
e90279c513
52 changed files with 1362 additions and 1632 deletions
|
@ -514,7 +514,6 @@ xsp/Flow.xsp
|
|||
xsp/GCode.xsp
|
||||
xsp/GCodeSender.xsp
|
||||
xsp/GCodeWriter.xsp
|
||||
xsp/GCodePressureEqualizer.xsp
|
||||
xsp/Geometry.xsp
|
||||
xsp/GUI.xsp
|
||||
xsp/GUI_3DScene.xsp
|
||||
|
|
|
@ -278,10 +278,7 @@ for my $class (qw(
|
|||
Slic3r::Filler
|
||||
Slic3r::Flow
|
||||
Slic3r::GCode
|
||||
Slic3r::GCode::AvoidCrossingPerimeters
|
||||
Slic3r::GCode::OozePrevention
|
||||
Slic3r::GCode::PlaceholderParser
|
||||
Slic3r::GCode::Wipe
|
||||
Slic3r::GCode::Writer
|
||||
Slic3r::Geometry::BoundingBox
|
||||
Slic3r::Geometry::BoundingBoxf
|
||||
|
|
|
@ -37,6 +37,9 @@ public:
|
|||
Polylines unsupported_edges(double angle = -1) const;
|
||||
|
||||
private:
|
||||
// Suppress warning "assignment operator could not be generated"
|
||||
BridgeDetector& operator=(const BridgeDetector &);
|
||||
|
||||
void initialize();
|
||||
|
||||
struct BridgeDirection {
|
||||
|
|
|
@ -34,7 +34,7 @@ class ConfigOption {
|
|||
virtual int getInt() const { return 0; };
|
||||
virtual double getFloat() const { return 0; };
|
||||
virtual bool getBool() const { return false; };
|
||||
virtual void setInt(int val) {};
|
||||
virtual void setInt(int /* val */) { };
|
||||
friend bool operator== (const ConfigOption &a, const ConfigOption &b);
|
||||
friend bool operator!= (const ConfigOption &a, const ConfigOption &b);
|
||||
};
|
||||
|
@ -142,7 +142,7 @@ class ConfigOptionInt : public ConfigOptionSingle<int>
|
|||
{
|
||||
public:
|
||||
ConfigOptionInt() : ConfigOptionSingle<int>(0) {};
|
||||
ConfigOptionInt(double _value) : ConfigOptionSingle<int>(_value) {};
|
||||
ConfigOptionInt(double _value) : ConfigOptionSingle<int>(int(floor(_value + 0.5))) {};
|
||||
|
||||
int getInt() const { return this->value; };
|
||||
void setInt(int val) { this->value = val; };
|
||||
|
|
|
@ -326,7 +326,7 @@ namespace boost { namespace polygon {
|
|||
}
|
||||
|
||||
// Get the winding direction of the polygon
|
||||
static inline winding_direction winding(const Slic3r::ExPolygon& t) {
|
||||
static inline winding_direction winding(const Slic3r::ExPolygon& /* t */) {
|
||||
return unknown_winding;
|
||||
}
|
||||
};
|
||||
|
@ -391,8 +391,8 @@ namespace boost { namespace polygon {
|
|||
}
|
||||
|
||||
//don't worry about these, just return false from them
|
||||
static inline bool clean(const Slic3r::ExPolygons& polygon_set) { return false; }
|
||||
static inline bool sorted(const Slic3r::ExPolygons& polygon_set) { return false; }
|
||||
static inline bool clean(const Slic3r::ExPolygons& /* polygon_set */) { return false; }
|
||||
static inline bool sorted(const Slic3r::ExPolygons& /* polygon_set */) { return false; }
|
||||
};
|
||||
|
||||
template <>
|
||||
|
|
|
@ -4,12 +4,12 @@ namespace Slic3r {
|
|||
|
||||
Extruder::Extruder(unsigned int id, GCodeConfig *config)
|
||||
: id(id),
|
||||
config(config)
|
||||
m_config(config)
|
||||
{
|
||||
reset();
|
||||
|
||||
// cache values that are going to be called often
|
||||
if (config->use_volumetric_e) {
|
||||
if (m_config->use_volumetric_e) {
|
||||
this->e_per_mm3 = this->extrusion_multiplier();
|
||||
} else {
|
||||
this->e_per_mm3 = this->extrusion_multiplier()
|
||||
|
@ -31,7 +31,7 @@ double
|
|||
Extruder::extrude(double dE)
|
||||
{
|
||||
// in case of relative E distances we always reset to 0 before any output
|
||||
if (this->config->use_relative_e_distances)
|
||||
if (m_config->use_relative_e_distances)
|
||||
this->E = 0;
|
||||
|
||||
this->E += dE;
|
||||
|
@ -50,7 +50,7 @@ double
|
|||
Extruder::retract(double length, double restart_extra)
|
||||
{
|
||||
// in case of relative E distances we always reset to 0 before any output
|
||||
if (this->config->use_relative_e_distances)
|
||||
if (m_config->use_relative_e_distances)
|
||||
this->E = 0;
|
||||
|
||||
double to_retract = length - this->retracted;
|
||||
|
@ -84,7 +84,7 @@ Extruder::e_per_mm(double mm3_per_mm) const
|
|||
double
|
||||
Extruder::extruded_volume() const
|
||||
{
|
||||
if (this->config->use_volumetric_e) {
|
||||
if (m_config->use_volumetric_e) {
|
||||
// Any current amount of retraction should not affect used filament, since
|
||||
// it represents empty volume in the nozzle. We add it back to E.
|
||||
return this->absolute_E + this->retracted;
|
||||
|
@ -96,7 +96,7 @@ Extruder::extruded_volume() const
|
|||
double
|
||||
Extruder::used_filament() const
|
||||
{
|
||||
if (this->config->use_volumetric_e) {
|
||||
if (m_config->use_volumetric_e) {
|
||||
return this->extruded_volume() / (this->filament_diameter() * this->filament_diameter() * PI/4);
|
||||
}
|
||||
|
||||
|
@ -108,61 +108,61 @@ Extruder::used_filament() const
|
|||
double
|
||||
Extruder::filament_diameter() const
|
||||
{
|
||||
return this->config->filament_diameter.get_at(this->id);
|
||||
return m_config->filament_diameter.get_at(this->id);
|
||||
}
|
||||
|
||||
double
|
||||
Extruder::filament_density() const
|
||||
{
|
||||
return this->config->filament_density.get_at(this->id);
|
||||
return m_config->filament_density.get_at(this->id);
|
||||
}
|
||||
|
||||
double
|
||||
Extruder::filament_cost() const
|
||||
{
|
||||
return this->config->filament_cost.get_at(this->id);
|
||||
return m_config->filament_cost.get_at(this->id);
|
||||
}
|
||||
|
||||
double
|
||||
Extruder::extrusion_multiplier() const
|
||||
{
|
||||
return this->config->extrusion_multiplier.get_at(this->id);
|
||||
return m_config->extrusion_multiplier.get_at(this->id);
|
||||
}
|
||||
|
||||
double
|
||||
Extruder::retract_length() const
|
||||
{
|
||||
return this->config->retract_length.get_at(this->id);
|
||||
return m_config->retract_length.get_at(this->id);
|
||||
}
|
||||
|
||||
double
|
||||
Extruder::retract_lift() const
|
||||
{
|
||||
return this->config->retract_lift.get_at(this->id);
|
||||
return m_config->retract_lift.get_at(this->id);
|
||||
}
|
||||
|
||||
int
|
||||
Extruder::retract_speed() const
|
||||
{
|
||||
return this->config->retract_speed.get_at(this->id);
|
||||
return m_config->retract_speed.get_at(this->id);
|
||||
}
|
||||
|
||||
double
|
||||
Extruder::retract_restart_extra() const
|
||||
{
|
||||
return this->config->retract_restart_extra.get_at(this->id);
|
||||
return m_config->retract_restart_extra.get_at(this->id);
|
||||
}
|
||||
|
||||
double
|
||||
Extruder::retract_length_toolchange() const
|
||||
{
|
||||
return this->config->retract_length_toolchange.get_at(this->id);
|
||||
return m_config->retract_length_toolchange.get_at(this->id);
|
||||
}
|
||||
|
||||
double
|
||||
Extruder::retract_restart_extra_toolchange() const
|
||||
{
|
||||
return this->config->retract_restart_extra_toolchange.get_at(this->id);
|
||||
return m_config->retract_restart_extra_toolchange.get_at(this->id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Slic3r {
|
|||
|
||||
class Extruder
|
||||
{
|
||||
public:
|
||||
public:
|
||||
unsigned int id;
|
||||
double E;
|
||||
double absolute_E;
|
||||
|
@ -17,10 +17,11 @@ class Extruder
|
|||
double restart_extra;
|
||||
double e_per_mm3;
|
||||
double retract_speed_mm_min;
|
||||
|
||||
|
||||
Extruder(unsigned int id, GCodeConfig *config);
|
||||
virtual ~Extruder() {}
|
||||
void reset();
|
||||
|
||||
void reset();
|
||||
double extrude(double dE);
|
||||
double retract(double length, double restart_extra);
|
||||
double unretract();
|
||||
|
@ -34,15 +35,26 @@ class Extruder
|
|||
double extrusion_multiplier() const;
|
||||
double retract_length() const;
|
||||
double retract_lift() const;
|
||||
int retract_speed() const;
|
||||
int retract_speed() const;
|
||||
double retract_restart_extra() const;
|
||||
double retract_length_toolchange() const;
|
||||
double retract_restart_extra_toolchange() const;
|
||||
|
||||
private:
|
||||
GCodeConfig *config;
|
||||
|
||||
static Extruder key(unsigned int id) { return Extruder(id); }
|
||||
|
||||
private:
|
||||
// Private constructor to create a key for a search in std::set.
|
||||
Extruder(unsigned int id) : id(id) {}
|
||||
|
||||
GCodeConfig *m_config;
|
||||
};
|
||||
|
||||
// Sort Extruder objects by the extruder id by default.
|
||||
inline bool operator==(const Extruder &e1, const Extruder &e2) { return e1.id == e2.id; }
|
||||
inline bool operator!=(const Extruder &e1, const Extruder &e2) { return e1.id != e2.id; }
|
||||
inline bool operator< (const Extruder &e1, const Extruder &e2) { return e1.id < e2.id; }
|
||||
inline bool operator> (const Extruder &e1, const Extruder &e2) { return e1.id > e2.id; }
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -59,7 +59,7 @@ void ExtrusionPath::polygons_covered_by_spacing(Polygons &out, const float scale
|
|||
{
|
||||
// Instantiating the Flow class to get the line spacing.
|
||||
// Don't know the nozzle diameter, setting to zero. It shall not matter it shall be optimized out by the compiler.
|
||||
Flow flow(this->width, this->height, 0.f, this->is_bridge());
|
||||
Flow flow(this->width, this->height, 0.f, is_bridge(this->role()));
|
||||
polygons_append(out, offset(this->polyline, 0.5f * float(flow.scaled_spacing()) + scaled_epsilon));
|
||||
}
|
||||
|
||||
|
@ -226,7 +226,7 @@ void ExtrusionLoop::split_at(const Point &point, bool prefer_non_overhang)
|
|||
min = dist;
|
||||
path_idx = path - this->paths.begin();
|
||||
}
|
||||
if (prefer_non_overhang && ! path->is_bridge() && dist < min_non_overhang) {
|
||||
if (prefer_non_overhang && ! is_bridge(path->role()) && dist < min_non_overhang) {
|
||||
p_non_overhang = p_tmp;
|
||||
min_non_overhang = dist;
|
||||
path_idx_non_overhang = path - this->paths.begin();
|
||||
|
@ -291,7 +291,7 @@ ExtrusionLoop::has_overhang_point(const Point &point) const
|
|||
if (pos != -1) {
|
||||
// point belongs to this path
|
||||
// we consider it overhang only if it's not an endpoint
|
||||
return (path->is_bridge() && pos > 0 && pos != (int)(path->polyline.points.size())-1);
|
||||
return (is_bridge(path->role()) && pos > 0 && pos != (int)(path->polyline.points.size())-1);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -29,6 +29,33 @@ enum ExtrusionRole {
|
|||
erMixed,
|
||||
};
|
||||
|
||||
inline bool is_perimeter(ExtrusionRole role)
|
||||
{
|
||||
return role == erPerimeter
|
||||
|| role == erExternalPerimeter
|
||||
|| role == erOverhangPerimeter;
|
||||
}
|
||||
|
||||
inline bool is_infill(ExtrusionRole role)
|
||||
{
|
||||
return role == erBridgeInfill
|
||||
|| role == erInternalInfill
|
||||
|| role == erSolidInfill
|
||||
|| role == erTopSolidInfill;
|
||||
}
|
||||
|
||||
inline bool is_solid_infill(ExtrusionRole role)
|
||||
{
|
||||
return role == erBridgeInfill
|
||||
|| role == erSolidInfill
|
||||
|| role == erTopSolidInfill;
|
||||
}
|
||||
|
||||
inline bool is_bridge(ExtrusionRole role) {
|
||||
return role == erBridgeInfill
|
||||
|| role == erOverhangPerimeter;
|
||||
}
|
||||
|
||||
/* Special flags describing loop */
|
||||
enum ExtrusionLoopRole {
|
||||
elrDefault,
|
||||
|
@ -101,26 +128,6 @@ public:
|
|||
void simplify(double tolerance);
|
||||
virtual double length() const;
|
||||
virtual ExtrusionRole role() const { return m_role; }
|
||||
bool is_perimeter() const {
|
||||
return this->m_role == erPerimeter
|
||||
|| this->m_role == erExternalPerimeter
|
||||
|| this->m_role == erOverhangPerimeter;
|
||||
}
|
||||
bool is_infill() const {
|
||||
return this->m_role == erBridgeInfill
|
||||
|| this->m_role == erInternalInfill
|
||||
|| this->m_role == erSolidInfill
|
||||
|| this->m_role == erTopSolidInfill;
|
||||
}
|
||||
bool is_solid_infill() const {
|
||||
return this->m_role == erBridgeInfill
|
||||
|| this->m_role == erSolidInfill
|
||||
|| this->m_role == erTopSolidInfill;
|
||||
}
|
||||
bool is_bridge() const {
|
||||
return this->m_role == erBridgeInfill
|
||||
|| this->m_role == erOverhangPerimeter;
|
||||
}
|
||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const;
|
||||
|
@ -167,22 +174,6 @@ public:
|
|||
Point last_point() const { return this->paths.back().polyline.points.back(); }
|
||||
virtual double length() const;
|
||||
virtual ExtrusionRole role() const { return this->paths.empty() ? erNone : this->paths.front().role(); }
|
||||
bool is_perimeter() const {
|
||||
return this->paths.front().role() == erPerimeter
|
||||
|| this->paths.front().role() == erExternalPerimeter
|
||||
|| this->paths.front().role() == erOverhangPerimeter;
|
||||
}
|
||||
bool is_infill() const {
|
||||
return this->paths.front().role() == erBridgeInfill
|
||||
|| this->paths.front().role() == erInternalInfill
|
||||
|| this->paths.front().role() == erSolidInfill
|
||||
|| this->paths.front().role() == erTopSolidInfill;
|
||||
}
|
||||
bool is_solid_infill() const {
|
||||
return this->paths.front().role() == erBridgeInfill
|
||||
|| this->paths.front().role() == erSolidInfill
|
||||
|| this->paths.front().role() == erTopSolidInfill;
|
||||
}
|
||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const;
|
||||
|
@ -230,22 +221,6 @@ public:
|
|||
bool has_overhang_point(const Point &point) const;
|
||||
virtual ExtrusionRole role() const { return this->paths.empty() ? erNone : this->paths.front().role(); }
|
||||
ExtrusionLoopRole loop_role() const { return m_loop_role; }
|
||||
bool is_perimeter() const {
|
||||
return this->paths.front().role() == erPerimeter
|
||||
|| this->paths.front().role() == erExternalPerimeter
|
||||
|| this->paths.front().role() == erOverhangPerimeter;
|
||||
}
|
||||
bool is_infill() const {
|
||||
return this->paths.front().role() == erBridgeInfill
|
||||
|| this->paths.front().role() == erInternalInfill
|
||||
|| this->paths.front().role() == erSolidInfill
|
||||
|| this->paths.front().role() == erTopSolidInfill;
|
||||
}
|
||||
bool is_solid_infill() const {
|
||||
return this->paths.front().role() == erBridgeInfill
|
||||
|| this->paths.front().role() == erSolidInfill
|
||||
|| this->paths.front().role() == erTopSolidInfill;
|
||||
}
|
||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const;
|
||||
|
|
|
@ -95,8 +95,14 @@ ExtrusionEntityCollection::chained_path(ExtrusionEntityCollection* retval, bool
|
|||
this->chained_path_from(this->entities.front()->first_point(), retval, no_reverse, role, orig_indices);
|
||||
}
|
||||
|
||||
void
|
||||
ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEntityCollection* retval, bool no_reverse, ExtrusionRole role, std::vector<size_t>* orig_indices) const
|
||||
ExtrusionEntityCollection ExtrusionEntityCollection::chained_path_from(Point start_near, bool no_reverse, ExtrusionRole role) const
|
||||
{
|
||||
ExtrusionEntityCollection coll;
|
||||
this->chained_path_from(start_near, &coll, no_reverse, role);
|
||||
return coll;
|
||||
}
|
||||
|
||||
void ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEntityCollection* retval, bool no_reverse, ExtrusionRole role, std::vector<size_t>* orig_indices) const
|
||||
{
|
||||
if (this->no_sort) {
|
||||
*retval = *this;
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
void remove(size_t i);
|
||||
ExtrusionEntityCollection chained_path(bool no_reverse = false, ExtrusionRole role = erMixed) const;
|
||||
void chained_path(ExtrusionEntityCollection* retval, bool no_reverse = false, ExtrusionRole role = erMixed, std::vector<size_t>* orig_indices = nullptr) const;
|
||||
ExtrusionEntityCollection chained_path_from(Point start_near, bool no_reverse = false, ExtrusionRole role = erMixed) const;
|
||||
void chained_path_from(Point start_near, ExtrusionEntityCollection* retval, bool no_reverse = false, ExtrusionRole role = erMixed, std::vector<size_t>* orig_indices = nullptr) const;
|
||||
void reverse();
|
||||
Point first_point() const { return this->entities.front()->first_point(); }
|
||||
|
@ -78,6 +79,8 @@ public:
|
|||
void flatten(ExtrusionEntityCollection* retval) const;
|
||||
ExtrusionEntityCollection flatten() const;
|
||||
double min_mm3_per_mm() const;
|
||||
|
||||
// Following methods shall never be called on an ExtrusionEntityCollection.
|
||||
Polyline as_polyline() const {
|
||||
CONFESS("Calling as_polyline() on a ExtrusionEntityCollection");
|
||||
return Polyline();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "Flow.hpp"
|
||||
#include "Print.hpp"
|
||||
#include <cmath>
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -113,4 +114,39 @@ float Flow::_width_from_spacing(float spacing, float nozzle_diameter, float heig
|
|||
#endif
|
||||
}
|
||||
|
||||
Flow support_material_flow(const PrintObject *object, float layer_height)
|
||||
{
|
||||
return Flow::new_from_config_width(
|
||||
frSupportMaterial,
|
||||
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
|
||||
(object->config.support_material_extrusion_width.value > 0) ? object->config.support_material_extrusion_width : object->config.extrusion_width,
|
||||
// if object->config.support_material_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
|
||||
float(object->print()->config.nozzle_diameter.get_at(object->config.support_material_extruder-1)),
|
||||
(layer_height > 0.f) ? layer_height : float(object->config.layer_height.value),
|
||||
false);
|
||||
}
|
||||
|
||||
Flow support_material_1st_layer_flow(const PrintObject *object, float layer_height)
|
||||
{
|
||||
return Flow::new_from_config_width(
|
||||
frSupportMaterial,
|
||||
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
|
||||
(object->print()->config.first_layer_extrusion_width.value > 0) ? object->print()->config.first_layer_extrusion_width : object->config.support_material_extrusion_width,
|
||||
float(object->print()->config.nozzle_diameter.get_at(object->config.support_material_extruder-1)),
|
||||
(layer_height > 0.f) ? layer_height : object->config.first_layer_height.get_abs_value(object->config.layer_height.value),
|
||||
false);
|
||||
}
|
||||
|
||||
Flow support_material_interface_flow(const PrintObject *object, float layer_height)
|
||||
{
|
||||
return Flow::new_from_config_width(
|
||||
frSupportMaterialInterface,
|
||||
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
|
||||
(object->config.support_material_extrusion_width > 0) ? object->config.support_material_extrusion_width : object->config.extrusion_width,
|
||||
// if object->config.support_material_interface_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
|
||||
float(object->print()->config.nozzle_diameter.get_at(object->config.support_material_interface_extruder-1)),
|
||||
(layer_height > 0.f) ? layer_height : float(object->config.layer_height.value),
|
||||
false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
class PrintObject;
|
||||
|
||||
// Extra spacing of bridge threads, in mm.
|
||||
#define BRIDGE_EXTRA_SPACING 0.05
|
||||
|
||||
|
@ -59,6 +61,10 @@ public:
|
|||
static float _spacing(float width, float nozzle_diameter, float height, float bridge_flow_ratio);
|
||||
};
|
||||
|
||||
extern Flow support_material_flow(const PrintObject *object, float layer_height = 0.f);
|
||||
extern Flow support_material_1st_layer_flow(const PrintObject *object, float layer_height = 0.f);
|
||||
extern Flow support_material_interface_flow(const PrintObject *object, float layer_height = 0.f);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -147,6 +147,9 @@ struct AMFParserContext
|
|||
Instance *m_instance;
|
||||
// Generic string buffer for vertices, face indices, metadata etc.
|
||||
std::string m_value[3];
|
||||
|
||||
private:
|
||||
AMFParserContext& operator=(AMFParserContext&);
|
||||
};
|
||||
|
||||
void AMFParserContext::startElement(const char *name, const char **atts)
|
||||
|
@ -307,7 +310,7 @@ void AMFParserContext::characters(const XML_Char *s, int len)
|
|||
}
|
||||
}
|
||||
|
||||
void AMFParserContext::endElement(const char *name)
|
||||
void AMFParserContext::endElement(const char * /* name */)
|
||||
{
|
||||
switch (m_path.back()) {
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,16 +10,20 @@
|
|||
#include "PlaceholderParser.hpp"
|
||||
#include "Print.hpp"
|
||||
#include "PrintConfig.hpp"
|
||||
#include "GCode/CoolingBuffer.hpp"
|
||||
#include "GCode/PressureEqualizer.hpp"
|
||||
#include "GCode/SpiralVase.hpp"
|
||||
#include "EdgeGrid.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
// Forward declarations.
|
||||
class GCode;
|
||||
namespace EdgeGrid { class Grid; }
|
||||
|
||||
class AvoidCrossingPerimeters {
|
||||
public:
|
||||
public:
|
||||
|
||||
// this flag triggers the use of the external configuration space
|
||||
bool use_external_mp;
|
||||
|
@ -35,7 +39,7 @@ class AvoidCrossingPerimeters {
|
|||
void init_layer_mp(const ExPolygons &islands);
|
||||
Polyline travel_to(GCode &gcodegen, Point point);
|
||||
|
||||
private:
|
||||
private:
|
||||
MotionPlanner* _external_mp;
|
||||
MotionPlanner* _layer_mp;
|
||||
};
|
||||
|
@ -65,76 +69,141 @@ public:
|
|||
};
|
||||
|
||||
class GCode {
|
||||
public:
|
||||
|
||||
public:
|
||||
GCode() :
|
||||
m_enable_loop_clipping(true),
|
||||
m_enable_cooling_markers(false),
|
||||
m_enable_extrusion_role_markers(false),
|
||||
m_enable_analyzer_markers(false),
|
||||
m_layer_count(0),
|
||||
m_layer_index(-1),
|
||||
m_layer(nullptr),
|
||||
m_first_layer(false),
|
||||
m_elapsed_time(0.0),
|
||||
m_volumetric_speed(0),
|
||||
m_last_pos_defined(false),
|
||||
m_last_extrusion_role(erNone),
|
||||
m_brim_done(false),
|
||||
m_second_layer_things_done(false),
|
||||
m_last_obj_copy(Point(std::numeric_limits<coord_t>::max(), std::numeric_limits<coord_t>::max()))
|
||||
{}
|
||||
~GCode() {}
|
||||
|
||||
bool do_export(FILE *file, Print &print);
|
||||
|
||||
// Exported for the helper classes (OozePrevention, Wipe) and for the Perl binding for unit tests.
|
||||
const Pointf& origin() const { return m_origin; }
|
||||
void set_origin(const Pointf &pointf);
|
||||
void set_origin(const coordf_t x, const coordf_t y) { this->set_origin(Pointf(x, y)); }
|
||||
const Point& last_pos() const { return m_last_pos; }
|
||||
Pointf point_to_gcode(const Point &point) const;
|
||||
const FullPrintConfig &config() const { return m_config; }
|
||||
const Layer* layer() const { return m_layer; }
|
||||
GCodeWriter& writer() { return m_writer; }
|
||||
bool enable_cooling_markers() const { return m_enable_cooling_markers; }
|
||||
float get_reset_elapsed_time() { float t = m_elapsed_time; m_elapsed_time = 0.f; return t; }
|
||||
|
||||
// For Perl bindings, to be used exclusively by unit tests.
|
||||
unsigned int layer_count() const { return m_layer_count; }
|
||||
void set_layer_count(unsigned int value) { m_layer_count = value; }
|
||||
float elapsed_time() const { return m_elapsed_time; }
|
||||
void set_elapsed_time(float value) { m_elapsed_time = value; }
|
||||
void apply_print_config(const PrintConfig &print_config);
|
||||
|
||||
private:
|
||||
void process_layer(FILE *file, const Print &print, const Layer &layer, const Points &object_copies);
|
||||
|
||||
void set_last_pos(const Point &pos) { m_last_pos = pos; m_last_pos_defined = true; }
|
||||
bool last_pos_defined() const { return m_last_pos_defined; }
|
||||
void set_extruders(const std::vector<unsigned int> &extruder_ids);
|
||||
std::string preamble();
|
||||
std::string change_layer(const Layer &layer);
|
||||
std::string extrude(const ExtrusionEntity &entity, std::string description = "", double speed = -1);
|
||||
std::string extrude(ExtrusionLoop loop, std::string description = "", double speed = -1);
|
||||
std::string extrude(ExtrusionMultiPath multipath, std::string description = "", double speed = -1);
|
||||
std::string extrude(ExtrusionPath path, std::string description = "", double speed = -1);
|
||||
|
||||
struct ByExtruder
|
||||
{
|
||||
struct ToExtrude {
|
||||
ExtrusionEntityCollection perimeters;
|
||||
ExtrusionEntityCollection infills;
|
||||
};
|
||||
std::vector<ToExtrude> by_region;
|
||||
};
|
||||
std::string extrude_perimeters(const Print &print, const std::vector<ByExtruder::ToExtrude> &by_region);
|
||||
std::string extrude_infill(const Print &print, const std::vector<ByExtruder::ToExtrude> &by_region);
|
||||
std::string extrude_support(const ExtrusionEntityCollection &support_fills, unsigned int extruder_id);
|
||||
|
||||
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
|
||||
bool needs_retraction(const Polyline &travel, ExtrusionRole role = erNone);
|
||||
std::string retract(bool toolchange = false);
|
||||
std::string unretract();
|
||||
std::string set_extruder(unsigned int extruder_id);
|
||||
|
||||
/* Origin of print coordinates expressed in unscaled G-code coordinates.
|
||||
This affects the input arguments supplied to the extrude*() and travel_to()
|
||||
methods. */
|
||||
Pointf origin;
|
||||
FullPrintConfig config;
|
||||
GCodeWriter writer;
|
||||
PlaceholderParser* placeholder_parser;
|
||||
OozePrevention ooze_prevention;
|
||||
Wipe wipe;
|
||||
AvoidCrossingPerimeters avoid_crossing_perimeters;
|
||||
bool enable_loop_clipping;
|
||||
Pointf m_origin;
|
||||
FullPrintConfig m_config;
|
||||
GCodeWriter m_writer;
|
||||
PlaceholderParser m_placeholder_parser;
|
||||
OozePrevention m_ooze_prevention;
|
||||
Wipe m_wipe;
|
||||
AvoidCrossingPerimeters m_avoid_crossing_perimeters;
|
||||
bool m_enable_loop_clipping;
|
||||
// If enabled, the G-code generator will put following comments at the ends
|
||||
// of the G-code lines: _EXTRUDE_SET_SPEED, _WIPE, _BRIDGE_FAN_START, _BRIDGE_FAN_END
|
||||
// Those comments are received and consumed (removed from the G-code) by the CoolingBuffer.pm Perl module.
|
||||
bool enable_cooling_markers;
|
||||
bool m_enable_cooling_markers;
|
||||
// Markers for the Pressure Equalizer to recognize the extrusion type.
|
||||
// The Pressure Equalizer removes the markers from the final G-code.
|
||||
bool enable_extrusion_role_markers;
|
||||
bool m_enable_extrusion_role_markers;
|
||||
// Extended markers for the G-code Analyzer.
|
||||
// The G-code Analyzer will remove these comments from the final G-code.
|
||||
bool enable_analyzer_markers;
|
||||
bool m_enable_analyzer_markers;
|
||||
// How many times will change_layer() be called?
|
||||
// change_layer() will update the progress bar.
|
||||
size_t layer_count;
|
||||
unsigned int m_layer_count;
|
||||
// Progress bar indicator. Increments from -1 up to layer_count.
|
||||
int layer_index;
|
||||
int m_layer_index;
|
||||
// Current layer processed. Insequential printing mode, only a single copy will be printed.
|
||||
// In non-sequential mode, all its copies will be printed.
|
||||
const Layer* layer;
|
||||
std::map<const PrintObject*,Point> _seam_position;
|
||||
const Layer* m_layer;
|
||||
std::map<const PrintObject*,Point> m_seam_position;
|
||||
// Distance Field structure to
|
||||
EdgeGrid::Grid *_lower_layer_edge_grid;
|
||||
bool first_layer; // this flag triggers first layer speeds
|
||||
// Used by the CoolingBuffer.pm Perl module to calculate time spent per layer change.
|
||||
std::unique_ptr<EdgeGrid::Grid> m_lower_layer_edge_grid;
|
||||
// this flag triggers first layer speeds
|
||||
bool m_first_layer;
|
||||
// Used by the CoolingBuffer G-code filter to calculate time spent per layer change.
|
||||
// This value is not quite precise. First it only accouts for extrusion moves and travel moves,
|
||||
// it does not account for wipe, retract / unretract moves.
|
||||
// second it does not account for the velocity profiles of the printer.
|
||||
float elapsed_time; // seconds
|
||||
double volumetric_speed;
|
||||
float m_elapsed_time; // seconds
|
||||
double m_volumetric_speed;
|
||||
// Support for the extrusion role markers. Which marker is active?
|
||||
ExtrusionRole _last_extrusion_role;
|
||||
|
||||
GCode();
|
||||
~GCode();
|
||||
const Point& last_pos() const;
|
||||
void set_last_pos(const Point &pos);
|
||||
bool last_pos_defined() const;
|
||||
void apply_print_config(const PrintConfig &print_config);
|
||||
void set_extruders(const std::vector<unsigned int> &extruder_ids);
|
||||
void set_origin(const Pointf &pointf);
|
||||
std::string preamble();
|
||||
std::string change_layer(const Layer &layer);
|
||||
std::string extrude(const ExtrusionEntity &entity, std::string description = "", double speed = -1);
|
||||
std::string extrude(ExtrusionLoop loop, std::string description = "", double speed = -1);
|
||||
std::string extrude(ExtrusionMultiPath multipath, std::string description = "", double speed = -1);
|
||||
std::string extrude(ExtrusionPath path, std::string description = "", double speed = -1);
|
||||
std::string extrude_support(const ExtrusionEntityCollection *support_fills, unsigned int extruder_id);
|
||||
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
|
||||
bool needs_retraction(const Polyline &travel, ExtrusionRole role = erNone);
|
||||
std::string retract(bool toolchange = false);
|
||||
std::string unretract();
|
||||
std::string set_extruder(unsigned int extruder_id);
|
||||
Pointf point_to_gcode(const Point &point);
|
||||
|
||||
private:
|
||||
Point _last_pos;
|
||||
bool _last_pos_defined;
|
||||
ExtrusionRole m_last_extrusion_role;
|
||||
|
||||
Point m_last_pos;
|
||||
bool m_last_pos_defined;
|
||||
|
||||
std::unique_ptr<CoolingBuffer> m_cooling_buffer;
|
||||
std::unique_ptr<SpiralVase> m_spiral_vase;
|
||||
std::unique_ptr<PressureEqualizer> m_pressure_equalizer;
|
||||
|
||||
// Heights at which the skirt has already been extruded.
|
||||
std::set<coordf_t> m_skirt_done;
|
||||
// Has the brim been extruded already? Brim is being extruded only for the first object of a multi-object print.
|
||||
bool m_brim_done;
|
||||
// Flag indicating whether the nozzle temperature changes from 1st to 2nd layer were performed.
|
||||
bool m_second_layer_things_done;
|
||||
// Index of a last object copy extruded. -1 for not set yet.
|
||||
Point m_last_obj_copy;
|
||||
|
||||
std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1);
|
||||
void _print_first_layer_extruder_temperatures(FILE *file, Print &print, bool wait);
|
||||
|
||||
std::string filter(std::string &&gcode, bool flush);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ static inline int parse_int(const char *&line)
|
|||
char *endptr = NULL;
|
||||
long result = strtol(line, &endptr, 10);
|
||||
if (endptr == NULL || !is_ws_or_eol(*endptr))
|
||||
throw std::runtime_error("GCodePressureEqualizer: Error parsing an int");
|
||||
throw std::runtime_error("GCodeAnalyzer: Error parsing an int");
|
||||
line = endptr;
|
||||
return int(result);
|
||||
};
|
||||
|
@ -102,7 +102,7 @@ static inline float parse_float(const char *&line)
|
|||
char *endptr = NULL;
|
||||
float result = strtof(line, &endptr);
|
||||
if (endptr == NULL || !is_ws_or_eol(*endptr))
|
||||
throw std::runtime_error("GCodePressureEqualizer: Error parsing a float");
|
||||
throw std::runtime_error("GCodeAnalyzer: Error parsing a float");
|
||||
line = endptr;
|
||||
return result;
|
||||
};
|
||||
|
@ -171,7 +171,7 @@ bool GCodeAnalyzer::process_line(const char *line, const size_t len)
|
|||
assert(false);
|
||||
}
|
||||
if (i == -1)
|
||||
throw std::runtime_error(std::string("GCodePressureEqualizer: Invalid axis for G0/G1: ") + axis);
|
||||
throw std::runtime_error(std::string("GCodeAnalyzer: Invalid axis for G0/G1: ") + axis);
|
||||
buf.pos_provided[i] = true;
|
||||
new_pos[i] = parse_float(line);
|
||||
if (i == 3 && m_config->use_relative_e_distances.value)
|
||||
|
@ -235,7 +235,7 @@ bool GCodeAnalyzer::process_line(const char *line, const size_t len)
|
|||
set = true;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error(std::string("GCodePressureEqualizer: Incorrect axis in a G92 G-code: ") + axis);
|
||||
throw std::runtime_error(std::string("GCodeAnalyzer: Incorrect axis in a G92 G-code: ") + axis);
|
||||
}
|
||||
eatws(line);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "../GCode.hpp"
|
||||
#include "CoolingBuffer.hpp"
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
@ -5,28 +6,26 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
std::string
|
||||
CoolingBuffer::append(const std::string &gcode, std::string obj_id, size_t layer_id, float print_z)
|
||||
std::string CoolingBuffer::append(const std::string &gcode, size_t object_id, size_t layer_id, bool is_support)
|
||||
{
|
||||
std::string out;
|
||||
if (this->_last_z.find(obj_id) != this->_last_z.end()) {
|
||||
// A layer was finished, Z of the object's layer changed. Process the layer.
|
||||
size_t signature = object_id * 2 + is_support ? 1 : 0;
|
||||
if (m_object_ids_visited.find(signature) != m_object_ids_visited.end())
|
||||
// For a single print_z, a combination of (object_id, is_support) could repeat once only.
|
||||
// If the combination of (object_id, is_support) reappears, this must be for another print_z,
|
||||
// therefore a layer has to be finalized.
|
||||
out = this->flush();
|
||||
}
|
||||
|
||||
this->_layer_id = layer_id;
|
||||
this->_last_z[obj_id] = print_z;
|
||||
this->_gcode += gcode;
|
||||
|
||||
m_object_ids_visited.insert(signature);
|
||||
m_layer_id = layer_id;
|
||||
m_gcode += gcode;
|
||||
// This is a very rough estimate of the print time,
|
||||
// not taking into account the acceleration curves generated by the printer firmware.
|
||||
this->_elapsed_time += this->_gcodegen->elapsed_time;
|
||||
this->_gcodegen->elapsed_time = 0;
|
||||
|
||||
m_elapsed_time += m_gcodegen.get_reset_elapsed_time();
|
||||
return out;
|
||||
}
|
||||
|
||||
void
|
||||
apply_speed_factor(std::string &line, float speed_factor, float min_print_speed)
|
||||
void apply_speed_factor(std::string &line, float speed_factor, float min_print_speed)
|
||||
{
|
||||
// find pos of F
|
||||
size_t pos = line.find_first_of('F');
|
||||
|
@ -51,36 +50,34 @@ apply_speed_factor(std::string &line, float speed_factor, float min_print_speed)
|
|||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
CoolingBuffer::flush()
|
||||
std::string CoolingBuffer::flush()
|
||||
{
|
||||
GCode &gg = *this->_gcodegen;
|
||||
const FullPrintConfig &config = m_gcodegen.config();
|
||||
|
||||
std::string gcode = this->_gcode;
|
||||
float elapsed = this->_elapsed_time;
|
||||
this->_gcode = "";
|
||||
this->_elapsed_time = 0;
|
||||
this->_last_z.clear(); // reset the whole table otherwise we would compute overlapping times
|
||||
|
||||
int fan_speed = gg.config.fan_always_on ? gg.config.min_fan_speed.value : 0;
|
||||
std::string gcode = m_gcode;
|
||||
float elapsed = m_elapsed_time;
|
||||
m_gcode.clear();
|
||||
m_elapsed_time = 0.;
|
||||
|
||||
int fan_speed = config.fan_always_on ? config.min_fan_speed.value : 0;
|
||||
|
||||
float speed_factor = 1.0;
|
||||
|
||||
if (gg.config.cooling) {
|
||||
if (config.cooling) {
|
||||
#ifdef SLIC3R_DEBUG
|
||||
printf("Layer %zu estimated printing time: %f seconds\n", this->_layer_id, elapsed);
|
||||
printf("Layer %zu estimated printing time: %f seconds\n", m_layer_id, elapsed);
|
||||
#endif
|
||||
if (elapsed < (float)gg.config.slowdown_below_layer_time) {
|
||||
if (elapsed < (float)config.slowdown_below_layer_time) {
|
||||
// Layer time very short. Enable the fan to a full throttle and slow down the print
|
||||
// (stretch the layer print time to slowdown_below_layer_time).
|
||||
fan_speed = gg.config.max_fan_speed;
|
||||
speed_factor = elapsed / (float)gg.config.slowdown_below_layer_time;
|
||||
} else if (elapsed < (float)gg.config.fan_below_layer_time) {
|
||||
fan_speed = config.max_fan_speed;
|
||||
speed_factor = elapsed / (float)config.slowdown_below_layer_time;
|
||||
} else if (elapsed < (float)config.fan_below_layer_time) {
|
||||
// Layer time quite short. Enable the fan proportionally according to the current layer time.
|
||||
fan_speed = gg.config.max_fan_speed
|
||||
- (gg.config.max_fan_speed - gg.config.min_fan_speed)
|
||||
* (elapsed - (float)gg.config.slowdown_below_layer_time)
|
||||
/ (gg.config.fan_below_layer_time - gg.config.slowdown_below_layer_time);
|
||||
fan_speed = config.max_fan_speed
|
||||
- (config.max_fan_speed - config.min_fan_speed)
|
||||
* (elapsed - (float)config.slowdown_below_layer_time)
|
||||
/ (config.fan_below_layer_time - config.slowdown_below_layer_time);
|
||||
}
|
||||
|
||||
#ifdef SLIC3R_DEBUG
|
||||
|
@ -94,13 +91,14 @@ CoolingBuffer::flush()
|
|||
std::string new_gcode;
|
||||
std::istringstream ss(gcode);
|
||||
std::string line;
|
||||
bool bridge_fan_start = false;
|
||||
bool bridge_fan_start = false;
|
||||
float min_print_speed = float(config.min_print_speed * 60.);
|
||||
while (std::getline(ss, line)) {
|
||||
if (boost::starts_with(line, "G1")
|
||||
&& boost::contains(line, ";_EXTRUDE_SET_SPEED")
|
||||
&& !boost::contains(line, ";_WIPE")
|
||||
&& !bridge_fan_start) {
|
||||
apply_speed_factor(line, speed_factor, this->_min_print_speed);
|
||||
apply_speed_factor(line, speed_factor, min_print_speed);
|
||||
boost::replace_first(line, ";_EXTRUDE_SET_SPEED", "");
|
||||
}
|
||||
bridge_fan_start = boost::contains(line, ";_BRIDGE_FAN_START");
|
||||
|
@ -109,22 +107,23 @@ CoolingBuffer::flush()
|
|||
gcode = new_gcode;
|
||||
}
|
||||
}
|
||||
if (this->_layer_id < gg.config.disable_fan_first_layers)
|
||||
if (m_layer_id < config.disable_fan_first_layers)
|
||||
fan_speed = 0;
|
||||
|
||||
gcode = gg.writer.set_fan(fan_speed) + gcode;
|
||||
gcode = m_gcodegen.writer().set_fan(fan_speed) + gcode;
|
||||
|
||||
// bridge fan speed
|
||||
if (!gg.config.cooling || gg.config.bridge_fan_speed == 0 || this->_layer_id < gg.config.disable_fan_first_layers) {
|
||||
if (!config.cooling || config.bridge_fan_speed == 0 || m_layer_id < config.disable_fan_first_layers) {
|
||||
boost::replace_all(gcode, ";_BRIDGE_FAN_START", "");
|
||||
boost::replace_all(gcode, ";_BRIDGE_FAN_END", "");
|
||||
} else {
|
||||
boost::replace_all(gcode, ";_BRIDGE_FAN_START", gg.writer.set_fan(gg.config.bridge_fan_speed, true));
|
||||
boost::replace_all(gcode, ";_BRIDGE_FAN_END", gg.writer.set_fan(fan_speed, true));
|
||||
boost::replace_all(gcode, ";_BRIDGE_FAN_START", m_gcodegen.writer().set_fan(config.bridge_fan_speed, true));
|
||||
boost::replace_all(gcode, ";_BRIDGE_FAN_END", m_gcodegen.writer().set_fan(fan_speed, true));
|
||||
}
|
||||
boost::replace_all(gcode, ";_WIPE", "");
|
||||
boost::replace_all(gcode, ";_EXTRUDE_SET_SPEED", "");
|
||||
|
||||
m_object_ids_visited.clear();
|
||||
return gcode;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
#define slic3r_CoolingBuffer_hpp_
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "GCode.hpp"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class GCode;
|
||||
class Layer;
|
||||
|
||||
/*
|
||||
A standalone G-code filter, to control cooling of the print.
|
||||
The G-code is processed per layer. Once a layer is collected, fan start / stop commands are edited
|
||||
|
@ -15,23 +17,20 @@ and the print is modified to stretch over a minimum layer time.
|
|||
*/
|
||||
|
||||
class CoolingBuffer {
|
||||
public:
|
||||
CoolingBuffer(GCode &gcodegen)
|
||||
: _gcodegen(&gcodegen), _elapsed_time(0.), _layer_id(0)
|
||||
{
|
||||
this->_min_print_speed = this->_gcodegen->config.min_print_speed * 60;
|
||||
};
|
||||
std::string append(const std::string &gcode, std::string obj_id, size_t layer_id, float print_z);
|
||||
public:
|
||||
CoolingBuffer(GCode &gcodegen) : m_gcodegen(gcodegen), m_elapsed_time(0.), m_layer_id(0) {}
|
||||
std::string append(const std::string &gcode, size_t object_id, size_t layer_id, bool is_support);
|
||||
std::string flush();
|
||||
GCode* gcodegen() { return this->_gcodegen; };
|
||||
GCode* gcodegen() { return &m_gcodegen; };
|
||||
|
||||
private:
|
||||
GCode* _gcodegen;
|
||||
std::string _gcode;
|
||||
float _elapsed_time;
|
||||
size_t _layer_id;
|
||||
std::map<std::string,float> _last_z;
|
||||
float _min_print_speed;
|
||||
private:
|
||||
CoolingBuffer& operator=(const CoolingBuffer&);
|
||||
|
||||
GCode& m_gcodegen;
|
||||
std::string m_gcode;
|
||||
float m_elapsed_time;
|
||||
size_t m_layer_id;
|
||||
std::set<size_t> m_object_ids_visited;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -9,17 +9,17 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
GCodePressureEqualizer::GCodePressureEqualizer(const Slic3r::GCodeConfig *config) :
|
||||
PressureEqualizer::PressureEqualizer(const Slic3r::GCodeConfig *config) :
|
||||
m_config(config)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
GCodePressureEqualizer::~GCodePressureEqualizer()
|
||||
PressureEqualizer::~PressureEqualizer()
|
||||
{
|
||||
}
|
||||
|
||||
void GCodePressureEqualizer::reset()
|
||||
void PressureEqualizer::reset()
|
||||
{
|
||||
circular_buffer_pos = 0;
|
||||
circular_buffer_size = 100;
|
||||
|
@ -69,7 +69,7 @@ void GCodePressureEqualizer::reset()
|
|||
line_idx = 0;
|
||||
}
|
||||
|
||||
const char* GCodePressureEqualizer::process(const char *szGCode, bool flush)
|
||||
const char* PressureEqualizer::process(const char *szGCode, bool flush)
|
||||
{
|
||||
// Reset length of the output_buffer.
|
||||
output_buffer_length = 0;
|
||||
|
@ -147,7 +147,7 @@ static inline int parse_int(const char *&line)
|
|||
char *endptr = NULL;
|
||||
long result = strtol(line, &endptr, 10);
|
||||
if (endptr == NULL || !is_ws_or_eol(*endptr))
|
||||
throw std::runtime_error("GCodePressureEqualizer: Error parsing an int");
|
||||
throw std::runtime_error("PressureEqualizer: Error parsing an int");
|
||||
line = endptr;
|
||||
return int(result);
|
||||
};
|
||||
|
@ -159,13 +159,13 @@ static inline float parse_float(const char *&line)
|
|||
char *endptr = NULL;
|
||||
float result = strtof(line, &endptr);
|
||||
if (endptr == NULL || !is_ws_or_eol(*endptr))
|
||||
throw std::runtime_error("GCodePressureEqualizer: Error parsing a float");
|
||||
throw std::runtime_error("PressureEqualizer: Error parsing a float");
|
||||
line = endptr;
|
||||
return result;
|
||||
};
|
||||
|
||||
#define EXTRUSION_ROLE_TAG ";_EXTRUSION_ROLE:"
|
||||
bool GCodePressureEqualizer::process_line(const char *line, const size_t len, GCodeLine &buf)
|
||||
bool PressureEqualizer::process_line(const char *line, const size_t len, GCodeLine &buf)
|
||||
{
|
||||
if (strncmp(line, EXTRUSION_ROLE_TAG, strlen(EXTRUSION_ROLE_TAG)) == 0) {
|
||||
line += strlen(EXTRUSION_ROLE_TAG);
|
||||
|
@ -228,7 +228,7 @@ bool GCodePressureEqualizer::process_line(const char *line, const size_t len, GC
|
|||
assert(false);
|
||||
}
|
||||
if (i == -1)
|
||||
throw std::runtime_error(std::string("GCodePressureEqualizer: Invalid axis for G0/G1: ") + axis);
|
||||
throw std::runtime_error(std::string("GCode::PressureEqualizer: Invalid axis for G0/G1: ") + axis);
|
||||
buf.pos_provided[i] = true;
|
||||
new_pos[i] = parse_float(line);
|
||||
if (i == 3 && m_config->use_relative_e_distances.value)
|
||||
|
@ -297,7 +297,7 @@ bool GCodePressureEqualizer::process_line(const char *line, const size_t len, GC
|
|||
set = true;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error(std::string("GCodePressureEqualizer: Incorrect axis in a G92 G-code: ") + axis);
|
||||
throw std::runtime_error(std::string("GCode::PressureEqualizer: Incorrect axis in a G92 G-code: ") + axis);
|
||||
}
|
||||
eatws(line);
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ bool GCodePressureEqualizer::process_line(const char *line, const size_t len, GC
|
|||
return true;
|
||||
}
|
||||
|
||||
void GCodePressureEqualizer::output_gcode_line(GCodeLine &line)
|
||||
void PressureEqualizer::output_gcode_line(GCodeLine &line)
|
||||
{
|
||||
if (! line.modified) {
|
||||
push_to_output(line.raw.data(), line.raw_length, true);
|
||||
|
@ -453,7 +453,7 @@ void GCodePressureEqualizer::output_gcode_line(GCodeLine &line)
|
|||
}
|
||||
}
|
||||
|
||||
void GCodePressureEqualizer::adjust_volumetric_rate()
|
||||
void PressureEqualizer::adjust_volumetric_rate()
|
||||
{
|
||||
if (circular_buffer_items < 2)
|
||||
return;
|
||||
|
@ -563,7 +563,7 @@ void GCodePressureEqualizer::adjust_volumetric_rate()
|
|||
}
|
||||
}
|
||||
|
||||
void GCodePressureEqualizer::push_axis_to_output(const char axis, const float value, bool add_eol)
|
||||
void PressureEqualizer::push_axis_to_output(const char axis, const float value, bool add_eol)
|
||||
{
|
||||
char buf[2048];
|
||||
int len = sprintf(buf,
|
||||
|
@ -572,7 +572,7 @@ void GCodePressureEqualizer::push_axis_to_output(const char axis, const float va
|
|||
push_to_output(buf, len, add_eol);
|
||||
}
|
||||
|
||||
void GCodePressureEqualizer::push_to_output(const char *text, const size_t len, bool add_eol)
|
||||
void PressureEqualizer::push_to_output(const char *text, const size_t len, bool add_eol)
|
||||
{
|
||||
// New length of the output buffer content.
|
||||
size_t len_new = output_buffer_length + len + 1;
|
||||
|
@ -604,7 +604,7 @@ void GCodePressureEqualizer::push_to_output(const char *text, const size_t len,
|
|||
output_buffer[output_buffer_length] = 0;
|
||||
}
|
||||
|
||||
void GCodePressureEqualizer::push_line_to_output(const GCodeLine &line, const float new_feedrate, const char *comment)
|
||||
void PressureEqualizer::push_line_to_output(const GCodeLine &line, const float new_feedrate, const char *comment)
|
||||
{
|
||||
push_to_output("G1", 2, false);
|
||||
for (char i = 0; i < 3; ++ i)
|
||||
|
|
|
@ -9,11 +9,11 @@ namespace Slic3r {
|
|||
|
||||
// Processes a G-code. Finds changes in the volumetric extrusion speed and adjusts the transitions
|
||||
// between these paths to limit fast changes in the volumetric extrusion speed.
|
||||
class GCodePressureEqualizer
|
||||
class PressureEqualizer
|
||||
{
|
||||
public:
|
||||
GCodePressureEqualizer(const Slic3r::GCodeConfig *config);
|
||||
~GCodePressureEqualizer();
|
||||
PressureEqualizer(const Slic3r::GCodeConfig *config);
|
||||
~PressureEqualizer();
|
||||
|
||||
void reset();
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "SpiralVase.hpp"
|
||||
#include "GCode.hpp"
|
||||
#include <sstream>
|
||||
|
||||
namespace Slic3r {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define slic3r_SpiralVase_hpp_
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "GCode.hpp"
|
||||
#include "GCodeReader.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
|
|
@ -23,8 +23,8 @@ GCodeWriter::apply_print_config(const PrintConfig &print_config)
|
|||
void
|
||||
GCodeWriter::set_extruders(const std::vector<unsigned int> &extruder_ids)
|
||||
{
|
||||
for (std::vector<unsigned int>::const_iterator i = extruder_ids.begin(); i != extruder_ids.end(); ++i)
|
||||
this->extruders.insert( std::pair<unsigned int,Extruder>(*i, Extruder(*i, &this->config)) );
|
||||
for (unsigned int extruder_id : extruder_ids)
|
||||
this->extruders.insert(Extruder(extruder_id, &this->config));
|
||||
|
||||
/* we enable support for multiple extruder if any extruder greater than 0 is used
|
||||
(even if prints only uses that one) since we need to output Tx commands
|
||||
|
@ -194,11 +194,12 @@ GCodeWriter::reset_e(bool force)
|
|||
|| FLAVOR_IS(gcfSailfish))
|
||||
return "";
|
||||
|
||||
if (this->_extruder != NULL) {
|
||||
if (this->_extruder->E == 0 && !force) return "";
|
||||
this->_extruder->E = 0;
|
||||
if (this->_extruder != nullptr) {
|
||||
if (this->_extruder->E == 0. && ! force)
|
||||
return "";
|
||||
this->_extruder->E = 0.;
|
||||
}
|
||||
|
||||
|
||||
if (!this->_extrusion_axis.empty() && !this->config.use_relative_e_distances) {
|
||||
std::ostringstream gcode;
|
||||
gcode << "G92 " << this->_extrusion_axis << "0";
|
||||
|
@ -226,25 +227,10 @@ GCodeWriter::update_progress(unsigned int num, unsigned int tot, bool allow_100)
|
|||
return gcode.str();
|
||||
}
|
||||
|
||||
bool
|
||||
GCodeWriter::need_toolchange(unsigned int extruder_id) const
|
||||
{
|
||||
// return false if this extruder was already selected
|
||||
return (this->_extruder == NULL) || (this->_extruder->id != extruder_id);
|
||||
}
|
||||
|
||||
std::string
|
||||
GCodeWriter::set_extruder(unsigned int extruder_id)
|
||||
{
|
||||
if (!this->need_toolchange(extruder_id)) return "";
|
||||
return this->toolchange(extruder_id);
|
||||
}
|
||||
|
||||
std::string
|
||||
GCodeWriter::toolchange(unsigned int extruder_id)
|
||||
std::string GCodeWriter::toolchange(unsigned int extruder_id)
|
||||
{
|
||||
// set the new extruder
|
||||
this->_extruder = &this->extruders.find(extruder_id)->second;
|
||||
this->_extruder = const_cast<Extruder*>(&*this->extruders.find(Extruder::key(extruder_id)));
|
||||
|
||||
// return the toolchange command
|
||||
// if we are running a single-extruder setup, just set the extruder and return nothing
|
||||
|
|
|
@ -12,17 +12,25 @@ namespace Slic3r {
|
|||
class GCodeWriter {
|
||||
public:
|
||||
GCodeConfig config;
|
||||
std::map<unsigned int,Extruder> extruders;
|
||||
std::set<Extruder> extruders;
|
||||
bool multiple_extruders;
|
||||
|
||||
GCodeWriter()
|
||||
: multiple_extruders(false), _extrusion_axis("E"), _extruder(NULL),
|
||||
_last_acceleration(0), _last_fan_speed(0), _lifted(0)
|
||||
{};
|
||||
Extruder* extruder() const { return this->_extruder; }
|
||||
GCodeWriter() :
|
||||
multiple_extruders(false), _extrusion_axis("E"), _extruder(nullptr),
|
||||
_last_acceleration(0), _last_fan_speed(0), _lifted(0)
|
||||
{}
|
||||
Extruder* extruder() { return this->_extruder; }
|
||||
const Extruder* extruder() const { return this->_extruder; }
|
||||
std::string extrusion_axis() const { return this->_extrusion_axis; }
|
||||
void apply_print_config(const PrintConfig &print_config);
|
||||
void set_extruders(const std::vector<unsigned int> &extruder_ids);
|
||||
void apply_print_config(const PrintConfig &print_config);
|
||||
void set_extruders(const std::vector<unsigned int> &extruder_ids);
|
||||
std::vector<unsigned int> extruder_ids() const {
|
||||
std::vector<unsigned int> out;
|
||||
out.reserve(extruders.size());
|
||||
for (const auto e : extruders)
|
||||
out.push_back(e.id);
|
||||
return out;
|
||||
}
|
||||
std::string preamble();
|
||||
std::string postamble() const;
|
||||
std::string set_temperature(unsigned int temperature, bool wait = false, int tool = -1) const;
|
||||
|
@ -31,14 +39,17 @@ public:
|
|||
std::string set_acceleration(unsigned int acceleration);
|
||||
std::string reset_e(bool force = false);
|
||||
std::string update_progress(unsigned int num, unsigned int tot, bool allow_100 = false) const;
|
||||
bool need_toolchange(unsigned int extruder_id) const;
|
||||
std::string set_extruder(unsigned int extruder_id);
|
||||
// return false if this extruder was already selected
|
||||
bool need_toolchange(unsigned int extruder_id) const
|
||||
{ return (this->_extruder == nullptr) || (this->_extruder->id != extruder_id); }
|
||||
std::string set_extruder(unsigned int extruder_id)
|
||||
{ return this->need_toolchange(extruder_id) ? this->toolchange(extruder_id) : ""; }
|
||||
std::string toolchange(unsigned int extruder_id);
|
||||
std::string set_speed(double F, const std::string &comment = std::string(), const std::string &cooling_marker = std::string()) const;
|
||||
std::string travel_to_xy(const Pointf &point, const std::string &comment = std::string());
|
||||
std::string travel_to_xyz(const Pointf3 &point, const std::string &comment = std::string());
|
||||
std::string travel_to_z(double z, const std::string &comment = std::string());
|
||||
bool will_move_z(double z) const;
|
||||
bool will_move_z(double z) const;
|
||||
std::string extrude_to_xy(const Pointf &point, double dE, const std::string &comment = std::string());
|
||||
std::string extrude_to_xyz(const Pointf3 &point, double dE, const std::string &comment = std::string());
|
||||
std::string retract();
|
||||
|
@ -46,14 +57,15 @@ public:
|
|||
std::string unretract();
|
||||
std::string lift();
|
||||
std::string unlift();
|
||||
Pointf3 get_position() const { return this->_pos; }
|
||||
Pointf3 get_position() const { return this->_pos; }
|
||||
|
||||
private:
|
||||
std::string _extrusion_axis;
|
||||
Extruder* _extruder;
|
||||
unsigned int _last_acceleration;
|
||||
unsigned int _last_fan_speed;
|
||||
double _lifted;
|
||||
Pointf3 _pos;
|
||||
std::string _extrusion_axis;
|
||||
Extruder* _extruder;
|
||||
unsigned int _last_acceleration;
|
||||
unsigned int _last_fan_speed;
|
||||
double _lifted;
|
||||
Pointf3 _pos;
|
||||
|
||||
std::string _travel_to_z(double z, const std::string &comment);
|
||||
std::string _retract(double length, double restart_extra, const std::string &comment);
|
||||
|
|
|
@ -97,23 +97,34 @@ PlaceholderParser::apply_env_variables()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
PlaceholderParser::set(const std::string &key, const std::string &value)
|
||||
void PlaceholderParser::set(const std::string &key, const std::string &value)
|
||||
{
|
||||
this->_single[key] = value;
|
||||
this->_multiple.erase(key);
|
||||
}
|
||||
|
||||
void
|
||||
PlaceholderParser::set(const std::string &key, int value)
|
||||
void PlaceholderParser::set(const std::string &key, int value)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << value;
|
||||
this->set(key, ss.str());
|
||||
}
|
||||
|
||||
void
|
||||
PlaceholderParser::set(const std::string &key, std::vector<std::string> values)
|
||||
void PlaceholderParser::set(const std::string &key, unsigned int value)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << value;
|
||||
this->set(key, ss.str());
|
||||
}
|
||||
|
||||
void PlaceholderParser::set(const std::string &key, double value)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << value;
|
||||
this->set(key, ss.str());
|
||||
}
|
||||
|
||||
void PlaceholderParser::set(const std::string &key, std::vector<std::string> values)
|
||||
{
|
||||
if (values.empty()) {
|
||||
this->_multiple.erase(key);
|
||||
|
@ -124,8 +135,7 @@ PlaceholderParser::set(const std::string &key, std::vector<std::string> values)
|
|||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
PlaceholderParser::process(std::string str) const
|
||||
std::string PlaceholderParser::process(std::string str) const
|
||||
{
|
||||
// replace single options, like [foo]
|
||||
for (t_strstr_map::const_iterator it = this->_single.begin(); it != this->_single.end(); ++it) {
|
||||
|
@ -154,8 +164,7 @@ PlaceholderParser::process(std::string str) const
|
|||
return str;
|
||||
}
|
||||
|
||||
bool
|
||||
PlaceholderParser::find_and_replace(std::string &source, std::string const &find, std::string const &replace) const
|
||||
bool PlaceholderParser::find_and_replace(std::string &source, std::string const &find, std::string const &replace) const
|
||||
{
|
||||
bool found = false;
|
||||
for (std::string::size_type i = 0; (i = source.find(find, i)) != std::string::npos; ) {
|
||||
|
|
|
@ -15,7 +15,7 @@ typedef std::map<std::string, std::vector<std::string> > t_strstrs_map;
|
|||
|
||||
class PlaceholderParser
|
||||
{
|
||||
public:
|
||||
public:
|
||||
t_strstr_map _single;
|
||||
t_strstrs_map _multiple;
|
||||
|
||||
|
@ -25,10 +25,12 @@ class PlaceholderParser
|
|||
void apply_env_variables();
|
||||
void set(const std::string &key, const std::string &value);
|
||||
void set(const std::string &key, int value);
|
||||
void set(const std::string &key, unsigned int value);
|
||||
void set(const std::string &key, double value);
|
||||
void set(const std::string &key, std::vector<std::string> values);
|
||||
std::string process(std::string str) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
bool find_and_replace(std::string &source, std::string const &find, std::string const &replace) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class Point
|
|||
coord_t y;
|
||||
Point(coord_t _x = 0, coord_t _y = 0): x(_x), y(_y) {};
|
||||
Point(int _x, int _y): x(_x), y(_y) {};
|
||||
Point(long long _x, long long _y): x(_x), y(_y) {}; // for Clipper
|
||||
Point(long long _x, long long _y): x(coord_t(_x)), y(coord_t(_y)) {}; // for Clipper
|
||||
Point(double x, double y);
|
||||
static Point new_scale(coordf_t x, coordf_t y) {
|
||||
return Point(scale_(x), scale_(y));
|
||||
|
|
|
@ -93,6 +93,23 @@ inline void polygons_rotate(Polygons &polys, double angle)
|
|||
p->rotate(angle);
|
||||
}
|
||||
|
||||
inline Points to_points(const Polygon &poly)
|
||||
{
|
||||
return poly.points;
|
||||
}
|
||||
|
||||
inline Points to_points(const Polygons &polys)
|
||||
{
|
||||
size_t n_points = 0;
|
||||
for (size_t i = 0; i < polys.size(); ++ i)
|
||||
n_points += polys[i].points.size();
|
||||
Points points;
|
||||
points.reserve(n_points);
|
||||
for (const Polygon &poly : polys)
|
||||
append(points, poly.points);
|
||||
return points;
|
||||
}
|
||||
|
||||
inline Lines to_lines(const Polygon &poly)
|
||||
{
|
||||
Lines lines;
|
||||
|
@ -179,7 +196,7 @@ namespace boost { namespace polygon {
|
|||
}
|
||||
|
||||
// Get the winding direction of the polygon
|
||||
static inline winding_direction winding(const Slic3r::Polygon& t) {
|
||||
static inline winding_direction winding(const Slic3r::Polygon& /* t */) {
|
||||
return unknown_winding;
|
||||
}
|
||||
};
|
||||
|
@ -220,8 +237,8 @@ namespace boost { namespace polygon {
|
|||
}
|
||||
|
||||
//don't worry about these, just return false from them
|
||||
static inline bool clean(const Slic3r::Polygons& polygon_set) { return false; }
|
||||
static inline bool sorted(const Slic3r::Polygons& polygon_set) { return false; }
|
||||
static inline bool clean(const Slic3r::Polygons& /* polygon_set */) { return false; }
|
||||
static inline bool sorted(const Slic3r::Polygons& /* polygon_set */) { return false; }
|
||||
};
|
||||
|
||||
template <>
|
||||
|
|
|
@ -30,7 +30,7 @@ Print::~Print()
|
|||
void
|
||||
Print::clear_objects()
|
||||
{
|
||||
for (int i = this->objects.size()-1; i >= 0; --i)
|
||||
for (int i = int(this->objects.size())-1; i >= 0; --i)
|
||||
this->delete_object(i);
|
||||
|
||||
this->clear_regions();
|
||||
|
@ -255,70 +255,65 @@ Print::step_done(PrintObjectStep step) const
|
|||
}
|
||||
|
||||
// returns 0-based indices of used extruders
|
||||
std::set<size_t>
|
||||
Print::object_extruders() const
|
||||
std::vector<unsigned int> Print::object_extruders() const
|
||||
{
|
||||
std::set<size_t> extruders;
|
||||
std::vector<unsigned int> extruders;
|
||||
|
||||
FOREACH_REGION(this, region) {
|
||||
// these checks reflect the same logic used in the GUI for enabling/disabling
|
||||
// extruder selection fields
|
||||
if ((*region)->config.perimeters.value > 0 || this->config.brim_width.value > 0)
|
||||
extruders.insert((*region)->config.perimeter_extruder - 1);
|
||||
|
||||
extruders.push_back((*region)->config.perimeter_extruder - 1);
|
||||
if ((*region)->config.fill_density.value > 0)
|
||||
extruders.insert((*region)->config.infill_extruder - 1);
|
||||
|
||||
extruders.push_back((*region)->config.infill_extruder - 1);
|
||||
if ((*region)->config.top_solid_layers.value > 0 || (*region)->config.bottom_solid_layers.value > 0)
|
||||
extruders.insert((*region)->config.solid_infill_extruder - 1);
|
||||
extruders.push_back((*region)->config.solid_infill_extruder - 1);
|
||||
}
|
||||
|
||||
std::sort(extruders.begin(), extruders.end());
|
||||
extruders.erase(std::unique(extruders.begin(), extruders.end()), extruders.end());
|
||||
return extruders;
|
||||
}
|
||||
|
||||
// returns 0-based indices of used extruders
|
||||
std::set<size_t>
|
||||
Print::support_material_extruders() const
|
||||
std::vector<unsigned int> Print::support_material_extruders() const
|
||||
{
|
||||
std::set<size_t> extruders;
|
||||
std::vector<unsigned int> extruders;
|
||||
bool support_uses_current_extruder = false;
|
||||
|
||||
FOREACH_OBJECT(this, object) {
|
||||
if ((*object)->has_support_material()) {
|
||||
if ((*object)->config.support_material_extruder == 0)
|
||||
for (PrintObject *object : this->objects) {
|
||||
if (object->has_support_material()) {
|
||||
if (object->config.support_material_extruder == 0)
|
||||
support_uses_current_extruder = true;
|
||||
else
|
||||
extruders.insert((*object)->config.support_material_extruder - 1);
|
||||
if ((*object)->config.support_material_interface_extruder == 0)
|
||||
extruders.push_back(object->config.support_material_extruder - 1);
|
||||
if (object->config.support_material_interface_extruder == 0)
|
||||
support_uses_current_extruder = true;
|
||||
else
|
||||
extruders.insert((*object)->config.support_material_interface_extruder - 1);
|
||||
extruders.push_back(object->config.support_material_interface_extruder - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (support_uses_current_extruder) {
|
||||
if (support_uses_current_extruder)
|
||||
// Add all object extruders to the support extruders as it is not know which one will be used to print supports.
|
||||
std::set<size_t> object_extruders = this->object_extruders();
|
||||
extruders.insert(object_extruders.begin(), object_extruders.end());
|
||||
}
|
||||
append(extruders, this->object_extruders());
|
||||
|
||||
std::sort(extruders.begin(), extruders.end());
|
||||
extruders.erase(std::unique(extruders.begin(), extruders.end()), extruders.end());
|
||||
return extruders;
|
||||
}
|
||||
|
||||
// returns 0-based indices of used extruders
|
||||
std::set<size_t>
|
||||
Print::extruders() const
|
||||
std::vector<unsigned int> Print::extruders() const
|
||||
{
|
||||
std::set<size_t> extruders = this->object_extruders();
|
||||
|
||||
std::set<size_t> s_extruders = this->support_material_extruders();
|
||||
extruders.insert(s_extruders.begin(), s_extruders.end());
|
||||
|
||||
std::vector<unsigned int> extruders = this->object_extruders();
|
||||
append(extruders, this->support_material_extruders());
|
||||
std::sort(extruders.begin(), extruders.end());
|
||||
extruders.erase(std::unique(extruders.begin(), extruders.end()), extruders.end());
|
||||
return extruders;
|
||||
}
|
||||
|
||||
void
|
||||
Print::_simplify_slices(double distance)
|
||||
void Print::_simplify_slices(double distance)
|
||||
{
|
||||
FOREACH_OBJECT(this, object) {
|
||||
FOREACH_LAYER(*object, layer) {
|
||||
|
@ -330,23 +325,17 @@ Print::_simplify_slices(double distance)
|
|||
}
|
||||
}
|
||||
|
||||
double
|
||||
Print::max_allowed_layer_height() const
|
||||
double Print::max_allowed_layer_height() const
|
||||
{
|
||||
std::vector<double> nozzle_diameter;
|
||||
|
||||
std::set<size_t> extruders = this->extruders();
|
||||
for (std::set<size_t>::const_iterator e = extruders.begin(); e != extruders.end(); ++e) {
|
||||
nozzle_diameter.push_back(this->config.nozzle_diameter.get_at(*e));
|
||||
}
|
||||
|
||||
return *std::max_element(nozzle_diameter.begin(), nozzle_diameter.end());
|
||||
double nozzle_diameter_max = 0.;
|
||||
for (unsigned int extruder_id : this->extruders())
|
||||
nozzle_diameter_max = std::max(nozzle_diameter_max, this->config.nozzle_diameter.get_at(extruder_id));
|
||||
return nozzle_diameter_max;
|
||||
}
|
||||
|
||||
/* Caller is responsible for supplying models whose objects don't collide
|
||||
and have explicit instance positions */
|
||||
void
|
||||
Print::add_model_object(ModelObject* model_object, int idx)
|
||||
void Print::add_model_object(ModelObject* model_object, int idx)
|
||||
{
|
||||
DynamicPrintConfig object_config = model_object->config; // clone
|
||||
object_config.normalize();
|
||||
|
@ -617,9 +606,9 @@ Print::validate() const
|
|||
convex_hull = offset(convex_hull, scale_(this->config.extruder_clearance_radius.value)/2, jtRound, scale_(0.1)).front();
|
||||
|
||||
// now we check that no instance of convex_hull intersects any of the previously checked object instances
|
||||
for (Points::const_iterator copy = object->_shifted_copies.begin(); copy != object->_shifted_copies.end(); ++copy) {
|
||||
for (const Point © : object->_shifted_copies) {
|
||||
Polygon p = convex_hull;
|
||||
p.translate(*copy);
|
||||
p.translate(copy);
|
||||
if (! intersection(a, p).empty())
|
||||
return "Some objects are too close; your extruder will collide with them.";
|
||||
polygons_append(a, p);
|
||||
|
@ -654,13 +643,13 @@ Print::validate() const
|
|||
|
||||
{
|
||||
// find the smallest nozzle diameter
|
||||
std::set<size_t> extruders = this->extruders();
|
||||
std::vector<unsigned int> extruders = this->extruders();
|
||||
if (extruders.empty())
|
||||
return "The supplied settings will cause an empty print.";
|
||||
|
||||
std::set<double> nozzle_diameters;
|
||||
for (std::set<size_t>::iterator it = extruders.begin(); it != extruders.end(); ++it)
|
||||
nozzle_diameters.insert(this->config.nozzle_diameter.get_at(*it));
|
||||
std::vector<double> nozzle_diameters;
|
||||
for (unsigned int extruder_id : extruders)
|
||||
nozzle_diameters.push_back(this->config.nozzle_diameter.get_at(extruder_id));
|
||||
double min_nozzle_diameter = *std::min_element(nozzle_diameters.begin(), nozzle_diameters.end());
|
||||
|
||||
FOREACH_OBJECT(this, i_object) {
|
||||
|
|
|
@ -117,7 +117,7 @@ public:
|
|||
ModelObject* model_object() { return this->_model_object; }
|
||||
const ModelObject* model_object() const { return this->_model_object; }
|
||||
|
||||
Points copies() const { return this->_copies; }
|
||||
const Points& copies() const { return this->_copies; }
|
||||
bool add_copy(const Pointf &point);
|
||||
bool delete_last_copy();
|
||||
bool delete_all_copies();
|
||||
|
@ -249,9 +249,9 @@ public:
|
|||
Flow brim_flow() const;
|
||||
Flow skirt_flow() const;
|
||||
|
||||
std::set<size_t> object_extruders() const;
|
||||
std::set<size_t> support_material_extruders() const;
|
||||
std::set<size_t> extruders() const;
|
||||
std::vector<unsigned int> object_extruders() const;
|
||||
std::vector<unsigned int> support_material_extruders() const;
|
||||
std::vector<unsigned int> extruders() const;
|
||||
void _simplify_slices(double distance);
|
||||
double max_allowed_layer_height() const;
|
||||
bool has_support_material() const;
|
||||
|
|
|
@ -44,7 +44,7 @@ SlicingParameters SlicingParameters::create_from_config(
|
|||
const PrintConfig &print_config,
|
||||
const PrintObjectConfig &object_config,
|
||||
coordf_t object_height,
|
||||
const std::set<size_t> &object_extruders)
|
||||
const std::vector<unsigned int> &object_extruders)
|
||||
{
|
||||
coordf_t first_layer_height = (object_config.first_layer_height.value <= 0) ?
|
||||
object_config.layer_height.value :
|
||||
|
@ -84,9 +84,9 @@ SlicingParameters SlicingParameters::create_from_config(
|
|||
params.min_layer_height = std::max(params.min_layer_height, min_layer_height_from_nozzle(print_config, 0));
|
||||
params.max_layer_height = std::min(params.max_layer_height, max_layer_height_from_nozzle(print_config, 0));
|
||||
} else {
|
||||
for (std::set<size_t>::const_iterator it_extruder = object_extruders.begin(); it_extruder != object_extruders.end(); ++ it_extruder) {
|
||||
params.min_layer_height = std::max(params.min_layer_height, min_layer_height_from_nozzle(print_config, *it_extruder));
|
||||
params.max_layer_height = std::min(params.max_layer_height, max_layer_height_from_nozzle(print_config, *it_extruder));
|
||||
for (unsigned int extruder_id : object_extruders) {
|
||||
params.min_layer_height = std::max(params.min_layer_height, min_layer_height_from_nozzle(print_config, extruder_id));
|
||||
params.max_layer_height = std::min(params.max_layer_height, max_layer_height_from_nozzle(print_config, extruder_id));
|
||||
}
|
||||
}
|
||||
params.min_layer_height = std::min(params.min_layer_height, params.layer_height);
|
||||
|
@ -113,8 +113,8 @@ SlicingParameters SlicingParameters::create_from_config(
|
|||
//FIXME It is expected, that the 1st layer of the object is printed with a bridging flow over a full raft. Shall it not be vice versa?
|
||||
coordf_t average_object_extruder_dmr = 0.;
|
||||
if (! object_extruders.empty()) {
|
||||
for (std::set<size_t>::const_iterator it_extruder = object_extruders.begin(); it_extruder != object_extruders.end(); ++ it_extruder)
|
||||
average_object_extruder_dmr += print_config.nozzle_diameter.get_at(*it_extruder);
|
||||
for (unsigned int extruder_id : object_extruders)
|
||||
average_object_extruder_dmr += print_config.nozzle_diameter.get_at(extruder_id);
|
||||
average_object_extruder_dmr /= coordf_t(object_extruders.size());
|
||||
}
|
||||
params.first_object_layer_height = average_object_extruder_dmr;
|
||||
|
|
|
@ -26,7 +26,7 @@ struct SlicingParameters
|
|||
const PrintConfig &print_config,
|
||||
const PrintObjectConfig &object_config,
|
||||
coordf_t object_height,
|
||||
const std::set<size_t> &object_extruders);
|
||||
const std::vector<unsigned int> &object_extruders);
|
||||
|
||||
// Has any raft layers?
|
||||
bool has_raft() const { return raft_layers() > 0; }
|
||||
|
|
|
@ -145,32 +145,10 @@ PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object
|
|||
m_print_config (&object->print()->config),
|
||||
m_object_config (&object->config),
|
||||
m_slicing_params (slicing_params),
|
||||
|
||||
m_first_layer_flow (Flow::new_from_config_width(
|
||||
frSupportMaterial,
|
||||
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
|
||||
(object->print()->config.first_layer_extrusion_width.value > 0) ? object->print()->config.first_layer_extrusion_width : object->config.support_material_extrusion_width,
|
||||
float(object->print()->config.nozzle_diameter.get_at(object->config.support_material_extruder-1)),
|
||||
float(slicing_params.first_print_layer_height),
|
||||
false)),
|
||||
m_support_material_flow (Flow::new_from_config_width(
|
||||
frSupportMaterial,
|
||||
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
|
||||
(object->config.support_material_extrusion_width.value > 0) ? object->config.support_material_extrusion_width : object->config.extrusion_width,
|
||||
// if object->config.support_material_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
|
||||
float(object->print()->config.nozzle_diameter.get_at(object->config.support_material_extruder-1)),
|
||||
float(slicing_params.layer_height),
|
||||
false)),
|
||||
m_support_material_interface_flow(Flow::new_from_config_width(
|
||||
frSupportMaterialInterface,
|
||||
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
|
||||
(object->config.support_material_extrusion_width > 0) ? object->config.support_material_extrusion_width : object->config.extrusion_width,
|
||||
// if object->config.support_material_interface_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
|
||||
float(object->print()->config.nozzle_diameter.get_at(object->config.support_material_interface_extruder-1)),
|
||||
float(slicing_params.layer_height),
|
||||
false)),
|
||||
|
||||
m_support_layer_height_min (0.01)
|
||||
m_first_layer_flow (support_material_1st_layer_flow(object, float(slicing_params.first_print_layer_height))),
|
||||
m_support_material_flow (support_material_flow(object, float(slicing_params.layer_height))),
|
||||
m_support_material_interface_flow(support_material_interface_flow(object, float(slicing_params.layer_height))),
|
||||
m_support_layer_height_min(0.01)
|
||||
{
|
||||
// Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um.
|
||||
m_support_layer_height_min = 1000000.;
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Slic3r {
|
|||
|
||||
class SurfaceCollection
|
||||
{
|
||||
public:
|
||||
public:
|
||||
Surfaces surfaces;
|
||||
|
||||
SurfaceCollection() {};
|
||||
|
|
|
@ -14,15 +14,10 @@ REGISTER_CLASS(ExtrusionEntityCollection, "ExtrusionPath::Collection");
|
|||
REGISTER_CLASS(ExtrusionSimulator, "ExtrusionSimulator");
|
||||
REGISTER_CLASS(Filler, "Filler");
|
||||
REGISTER_CLASS(Flow, "Flow");
|
||||
REGISTER_CLASS(AvoidCrossingPerimeters, "GCode::AvoidCrossingPerimeters");
|
||||
REGISTER_CLASS(CoolingBuffer, "GCode::CoolingBuffer");
|
||||
REGISTER_CLASS(OozePrevention, "GCode::OozePrevention");
|
||||
REGISTER_CLASS(SpiralVase, "GCode::SpiralVase");
|
||||
REGISTER_CLASS(Wipe, "GCode::Wipe");
|
||||
REGISTER_CLASS(GCode, "GCode");
|
||||
REGISTER_CLASS(GCodeSender, "GCode::Sender");
|
||||
REGISTER_CLASS(GCodeWriter, "GCode::Writer");
|
||||
REGISTER_CLASS(GCodePressureEqualizer, "GCode::PressureEqualizer");
|
||||
REGISTER_CLASS(Layer, "Layer");
|
||||
REGISTER_CLASS(SupportLayer, "Layer::Support");
|
||||
REGISTER_CLASS(LayerRegion, "Layer::Region");
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
#ifndef _xsinit_h_
|
||||
#define _xsinit_h_
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Disable some obnoxious warnings given by Visual Studio with the default warning level 4.
|
||||
#pragma warning(disable: 4100 4127 4189 4244 4267 4700 4702 4800)
|
||||
#endif
|
||||
|
||||
// undef some macros set by Perl which cause compilation errors on Win32
|
||||
#undef read
|
||||
#undef seekdir
|
||||
|
|
|
@ -29,9 +29,6 @@
|
|||
%code{% RETVAL = THIS->has_overhang_point(*point); %};
|
||||
ExtrusionRole role() const;
|
||||
ExtrusionLoopRole loop_role() const;
|
||||
bool is_perimeter();
|
||||
bool is_infill();
|
||||
bool is_solid_infill();
|
||||
Polygons polygons_covered_by_width();
|
||||
Polygons polygons_covered_by_spacing();
|
||||
%{
|
||||
|
|
|
@ -16,9 +16,6 @@
|
|||
void append(ExtrusionPath* path)
|
||||
%code{% THIS->paths.push_back(*path); %};
|
||||
double length();
|
||||
bool is_perimeter();
|
||||
bool is_infill();
|
||||
bool is_solid_infill();
|
||||
Polygons polygons_covered_by_width();
|
||||
Polygons polygons_covered_by_spacing();
|
||||
Clone<Polyline> polyline()
|
||||
|
|
|
@ -23,10 +23,8 @@
|
|||
void simplify(double tolerance);
|
||||
double length();
|
||||
ExtrusionRole role() const;
|
||||
bool is_perimeter();
|
||||
bool is_infill();
|
||||
bool is_solid_infill();
|
||||
bool is_bridge();
|
||||
bool is_bridge()
|
||||
%code{% RETVAL = is_bridge(THIS->role()); %};
|
||||
Polygons polygons_covered_by_width();
|
||||
Polygons polygons_covered_by_spacing();
|
||||
%{
|
||||
|
|
212
xs/xsp/GCode.xsp
212
xs/xsp/GCode.xsp
|
@ -4,176 +4,45 @@
|
|||
#include <xsinit.h>
|
||||
#include "libslic3r/GCode.hpp"
|
||||
#include "libslic3r/GCode/CoolingBuffer.hpp"
|
||||
#include "libslic3r/GCode/SpiralVase.hpp"
|
||||
%}
|
||||
|
||||
%name{Slic3r::GCode::AvoidCrossingPerimeters} class AvoidCrossingPerimeters {
|
||||
AvoidCrossingPerimeters();
|
||||
~AvoidCrossingPerimeters();
|
||||
|
||||
void init_external_mp(ExPolygons islands);
|
||||
void init_layer_mp(ExPolygons islands);
|
||||
Clone<Polyline> travel_to(GCode* gcode, Point* point)
|
||||
%code{% RETVAL = THIS->travel_to(*gcode, *point); %};
|
||||
|
||||
bool use_external_mp()
|
||||
%code{% RETVAL = THIS->use_external_mp; %};
|
||||
void set_use_external_mp(bool value)
|
||||
%code{% THIS->use_external_mp = value; %};
|
||||
|
||||
bool use_external_mp_once()
|
||||
%code{% RETVAL = THIS->use_external_mp_once; %};
|
||||
void set_use_external_mp_once(bool value)
|
||||
%code{% THIS->use_external_mp_once = value; %};
|
||||
|
||||
bool disable_once()
|
||||
%code{% RETVAL = THIS->disable_once; %};
|
||||
void set_disable_once(bool value)
|
||||
%code{% THIS->disable_once = value; %};
|
||||
};
|
||||
|
||||
%name{Slic3r::GCode::OozePrevention} class OozePrevention {
|
||||
OozePrevention();
|
||||
~OozePrevention();
|
||||
|
||||
bool enable()
|
||||
%code{% RETVAL = THIS->enable; %};
|
||||
void set_enable(bool value)
|
||||
%code{% THIS->enable = value; %};
|
||||
|
||||
Points standby_points()
|
||||
%code{% RETVAL = THIS->standby_points; %};
|
||||
void set_standby_points(Points points)
|
||||
%code{% THIS->standby_points = points; %};
|
||||
|
||||
std::string pre_toolchange(GCode* gcodegen)
|
||||
%code{% RETVAL = THIS->pre_toolchange(*gcodegen); %};
|
||||
std::string post_toolchange(GCode* gcodegen)
|
||||
%code{% RETVAL = THIS->post_toolchange(*gcodegen); %};
|
||||
};
|
||||
|
||||
%name{Slic3r::GCode::Wipe} class Wipe {
|
||||
Wipe();
|
||||
~Wipe();
|
||||
|
||||
bool has_path();
|
||||
void reset_path();
|
||||
std::string wipe(GCode* gcodegen, bool toolchange = false)
|
||||
%code{% RETVAL = THIS->wipe(*gcodegen, toolchange); %};
|
||||
|
||||
bool enable()
|
||||
%code{% RETVAL = THIS->enable; %};
|
||||
void set_enable(bool value)
|
||||
%code{% THIS->enable = value; %};
|
||||
|
||||
Ref<Polyline> path()
|
||||
%code{% RETVAL = &(THIS->path); %};
|
||||
void set_path(Polyline* value)
|
||||
%code{% THIS->path = *value; %};
|
||||
};
|
||||
|
||||
%name{Slic3r::GCode::CoolingBuffer} class CoolingBuffer {
|
||||
CoolingBuffer(GCode* gcode)
|
||||
%code{% RETVAL = new CoolingBuffer(*gcode); %};
|
||||
~CoolingBuffer();
|
||||
Ref<GCode> gcodegen();
|
||||
|
||||
std::string append(std::string gcode, std::string obj_id, size_t layer_id, float print_z);
|
||||
std::string append(std::string gcode, size_t object_id, size_t layer_id, bool support_layer);
|
||||
std::string flush();
|
||||
};
|
||||
|
||||
%name{Slic3r::GCode::SpiralVase} class SpiralVase {
|
||||
SpiralVase(StaticPrintConfig* config)
|
||||
%code{% RETVAL = new SpiralVase(*dynamic_cast<PrintConfig*>(config)); %};
|
||||
~SpiralVase();
|
||||
|
||||
bool enable()
|
||||
%code{% RETVAL = THIS->enable; %};
|
||||
void set_enable(bool enable)
|
||||
%code{% THIS->enable = enable; %};
|
||||
std::string process_layer(std::string gcode);
|
||||
};
|
||||
|
||||
%name{Slic3r::GCode} class GCode {
|
||||
GCode();
|
||||
~GCode();
|
||||
|
||||
Ref<Pointf> origin()
|
||||
%code{% RETVAL = &(THIS->origin); %};
|
||||
|
||||
Ref<StaticPrintConfig> config()
|
||||
%code{% RETVAL = &(THIS->config); %};
|
||||
|
||||
Ref<GCodeWriter> writer()
|
||||
%code{% RETVAL = &(THIS->writer); %};
|
||||
|
||||
Ref<PlaceholderParser> placeholder_parser()
|
||||
%code{% RETVAL = THIS->placeholder_parser; %};
|
||||
void set_placeholder_parser(PlaceholderParser* ptr)
|
||||
%code{% THIS->placeholder_parser = ptr; %};
|
||||
|
||||
Ref<OozePrevention> ooze_prevention()
|
||||
%code{% RETVAL = &(THIS->ooze_prevention); %};
|
||||
|
||||
Ref<Wipe> wipe()
|
||||
%code{% RETVAL = &(THIS->wipe); %};
|
||||
|
||||
Ref<AvoidCrossingPerimeters> avoid_crossing_perimeters()
|
||||
%code{% RETVAL = &(THIS->avoid_crossing_perimeters); %};
|
||||
|
||||
bool enable_loop_clipping()
|
||||
%code{% RETVAL = THIS->enable_loop_clipping; %};
|
||||
void set_enable_loop_clipping(bool value)
|
||||
%code{% THIS->enable_loop_clipping = value; %};
|
||||
|
||||
bool enable_cooling_markers()
|
||||
%code{% RETVAL = THIS->enable_cooling_markers; %};
|
||||
void set_enable_cooling_markers(bool value)
|
||||
%code{% THIS->enable_cooling_markers = value; %};
|
||||
|
||||
bool enable_extrusion_role_markers()
|
||||
%code{% RETVAL = THIS->enable_extrusion_role_markers; %};
|
||||
void set_enable_extrusion_role_markers(bool value)
|
||||
%code{% THIS->enable_extrusion_role_markers = value; %};
|
||||
std::string do_export(Print *print, const char *path)
|
||||
%code{%
|
||||
FILE *file = fopen(path, "wb");
|
||||
if (file == nullptr) {
|
||||
RETVAL = std::string("Failed to open ") + path + " for writing.";
|
||||
} else {
|
||||
THIS->do_export(file, *print);
|
||||
fclose(file);
|
||||
RETVAL = std::string();
|
||||
}
|
||||
%};
|
||||
|
||||
int layer_count()
|
||||
%code{% RETVAL = THIS->layer_count; %};
|
||||
void set_layer_count(int value)
|
||||
%code{% THIS->layer_count = value; %};
|
||||
|
||||
int layer_index()
|
||||
%code{% RETVAL = THIS->layer_index; %};
|
||||
void set_layer_index(int value)
|
||||
%code{% THIS->layer_index = value; %};
|
||||
|
||||
bool has_layer()
|
||||
%code{% RETVAL = THIS->layer != NULL; %};
|
||||
Ref<Layer> layer()
|
||||
%code{% RETVAL = THIS->layer; %};
|
||||
void set_layer(Layer* ptr)
|
||||
%code{% THIS->layer = ptr; %};
|
||||
|
||||
bool first_layer()
|
||||
%code{% RETVAL = THIS->first_layer; %};
|
||||
void set_first_layer(bool value)
|
||||
%code{% THIS->first_layer = value; %};
|
||||
|
||||
float elapsed_time()
|
||||
%code{% RETVAL = THIS->elapsed_time; %};
|
||||
void set_elapsed_time(float value)
|
||||
%code{% THIS->elapsed_time = value; %};
|
||||
|
||||
bool last_pos_defined();
|
||||
Ref<Pointf> origin()
|
||||
%code{% RETVAL = &(THIS->origin()); %};
|
||||
void set_origin(Pointf* pointf)
|
||||
%code{% THIS->set_origin(*pointf); %};
|
||||
Ref<Point> last_pos()
|
||||
%code{% RETVAL = &(THIS->last_pos()); %};
|
||||
void set_last_pos(Point* pos)
|
||||
%code{% THIS->set_last_pos(*pos); %};
|
||||
|
||||
double volumetric_speed()
|
||||
%code{% RETVAL = THIS->volumetric_speed; %};
|
||||
void set_volumetric_speed(double value)
|
||||
%code{% THIS->volumetric_speed = value; %};
|
||||
|
||||
|
||||
unsigned int layer_count() const;
|
||||
void set_layer_count(unsigned int value);
|
||||
float elapsed_time() const;
|
||||
void set_elapsed_time(float value);
|
||||
|
||||
void apply_print_config(StaticPrintConfig* print_config)
|
||||
%code{%
|
||||
if (const PrintConfig* config = dynamic_cast<PrintConfig*>(print_config)) {
|
||||
|
@ -182,40 +51,7 @@
|
|||
CONFESS("A PrintConfig object was not supplied to apply_print_config()");
|
||||
}
|
||||
%};
|
||||
void set_extruders(std::vector<unsigned int> extruder_ids);
|
||||
void set_origin(Pointf* pointf)
|
||||
%code{% THIS->set_origin(*pointf); %};
|
||||
std::string preamble();
|
||||
std::string change_layer(Layer* layer)
|
||||
%code{% RETVAL = THIS->change_layer(*layer); %};
|
||||
%name{extrude_loop} std::string extrude(ExtrusionLoop* loop, std::string description = "", double speed = -1)
|
||||
%code{% RETVAL = THIS->extrude(*loop, description, speed); %};
|
||||
%name{extrude_multipath} std::string extrude(ExtrusionMultiPath* multipath, std::string description = "", double speed = -1)
|
||||
%code{% RETVAL = THIS->extrude(*multipath, description, speed); %};
|
||||
%name{extrude_path} std::string extrude(ExtrusionPath* path, std::string description = "", double speed = -1)
|
||||
%code{% RETVAL = THIS->extrude(*path, description, speed); %};
|
||||
std::string extrude_support(ExtrusionEntityCollection *support_fills, unsigned int extruder_id);
|
||||
std::string travel_to(Point* point, ExtrusionRole role, std::string comment)
|
||||
%code{% RETVAL = THIS->travel_to(*point, role, comment); %};
|
||||
bool needs_retraction(Polyline* travel, ExtrusionRole role = erNone)
|
||||
%code{% RETVAL = THIS->needs_retraction(*travel, role); %};
|
||||
std::string retract(bool toolchange = false);
|
||||
std::string unretract();
|
||||
std::string set_extruder(unsigned int extruder_id);
|
||||
Clone<Pointf> point_to_gcode(Point* point)
|
||||
%code{% RETVAL = THIS->point_to_gcode(*point); %};
|
||||
|
||||
%{
|
||||
std::string
|
||||
GCode::extrude(entity, description, speed)
|
||||
SV* entity
|
||||
std::string description;
|
||||
double speed;
|
||||
CODE:
|
||||
ExtrusionEntity* e = (ExtrusionEntity *)SvIV((SV*)SvRV( entity ));
|
||||
RETVAL = THIS->extrude(*e, description, speed);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
%}
|
||||
|
||||
Ref<StaticPrintConfig> config()
|
||||
%code{% RETVAL = const_cast<StaticPrintConfig*>(dynamic_cast<const StaticPrintConfig*>(&THIS->config())); %};
|
||||
};
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
%module{Slic3r::XS};
|
||||
|
||||
%{
|
||||
#include <xsinit.h>
|
||||
#include "libslic3r/GCode/PressureEqualizer.hpp"
|
||||
%}
|
||||
|
||||
%name{Slic3r::GCode::PressureEqualizer} class GCodePressureEqualizer {
|
||||
GCodePressureEqualizer(StaticPrintConfig* config)
|
||||
%code%{ RETVAL = new GCodePressureEqualizer(dynamic_cast<GCodeConfig*>(config)); %};
|
||||
~GCodePressureEqualizer();
|
||||
|
||||
void reset();
|
||||
|
||||
// Process a next batch of G-code lines. Flush the internal buffers if asked for.
|
||||
// const char* process(const char *szGCode, bool flush);
|
||||
// std::string process(const char *szGCode, bool flush)
|
||||
// %code{% const char *out = THIS->process(szGCode, flush); RETVAL = (out == NULL) ? "" : std::string(out); %};
|
||||
|
||||
%{
|
||||
|
||||
SV*
|
||||
GCodePressureEqualizer::process(const char *szGCode, bool flush)
|
||||
CODE:
|
||||
const char *out = THIS->process(szGCode, flush);
|
||||
RETVAL = newSVpv(out, THIS->get_output_buffer_length());
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
%}
|
||||
|
||||
};
|
|
@ -54,9 +54,8 @@ GCodeWriter::extruders()
|
|||
AV* av = newAV();
|
||||
av_fill(av, THIS->extruders.size()-1);
|
||||
int i = 0;
|
||||
for (std::map<unsigned int,Extruder>::iterator it = THIS->extruders.begin(); it != THIS->extruders.end(); ++it) {
|
||||
av_store(av, i++, perl_to_SV_ref(it->second));
|
||||
}
|
||||
for (const Extruder &extruder : THIS->extruders)
|
||||
av_store(av, i++, perl_to_SV_ref(const_cast<Extruder&>(extruder)));
|
||||
RETVAL = newRV_noinc((SV*)av);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
|
|
@ -195,30 +195,6 @@ _constant()
|
|||
void set_step_started(PrintStep step)
|
||||
%code%{ THIS->state.set_started(step); %};
|
||||
|
||||
std::vector<int> object_extruders()
|
||||
%code%{
|
||||
std::set<size_t> extruders = THIS->object_extruders();
|
||||
RETVAL.reserve(extruders.size());
|
||||
for (std::set<size_t>::const_iterator e = extruders.begin(); e != extruders.end(); ++e) {
|
||||
RETVAL.push_back(*e);
|
||||
}
|
||||
%};
|
||||
std::vector<int> support_material_extruders()
|
||||
%code%{
|
||||
std::set<size_t> extruders = THIS->support_material_extruders();
|
||||
RETVAL.reserve(extruders.size());
|
||||
for (std::set<size_t>::const_iterator e = extruders.begin(); e != extruders.end(); ++e) {
|
||||
RETVAL.push_back(*e);
|
||||
}
|
||||
%};
|
||||
std::vector<int> extruders()
|
||||
%code%{
|
||||
std::set<size_t> extruders = THIS->extruders();
|
||||
RETVAL.reserve(extruders.size());
|
||||
for (std::set<size_t>::const_iterator e = extruders.begin(); e != extruders.end(); ++e) {
|
||||
RETVAL.push_back(*e);
|
||||
}
|
||||
%};
|
||||
void clear_filament_stats()
|
||||
%code%{
|
||||
THIS->filament_stats.clear();
|
||||
|
|
|
@ -185,26 +185,10 @@ PlaceholderParser* O_OBJECT_SLIC3R
|
|||
Ref<PlaceholderParser> O_OBJECT_SLIC3R_T
|
||||
Clone<PlaceholderParser> O_OBJECT_SLIC3R_T
|
||||
|
||||
AvoidCrossingPerimeters* O_OBJECT_SLIC3R
|
||||
Ref<AvoidCrossingPerimeters> O_OBJECT_SLIC3R_T
|
||||
Clone<AvoidCrossingPerimeters> O_OBJECT_SLIC3R_T
|
||||
|
||||
Wipe* O_OBJECT_SLIC3R
|
||||
Ref<Wipe> O_OBJECT_SLIC3R_T
|
||||
Clone<Wipe> O_OBJECT_SLIC3R_T
|
||||
|
||||
OozePrevention* O_OBJECT_SLIC3R
|
||||
Ref<OozePrevention> O_OBJECT_SLIC3R_T
|
||||
Clone<OozePrevention> O_OBJECT_SLIC3R_T
|
||||
|
||||
CoolingBuffer* O_OBJECT_SLIC3R
|
||||
Ref<CoolingBuffer> O_OBJECT_SLIC3R_T
|
||||
Clone<CoolingBuffer> O_OBJECT_SLIC3R_T
|
||||
|
||||
SpiralVase* O_OBJECT_SLIC3R
|
||||
Ref<SpiralVase> O_OBJECT_SLIC3R_T
|
||||
Clone<SpiralVase> O_OBJECT_SLIC3R_T
|
||||
|
||||
GCode* O_OBJECT_SLIC3R
|
||||
Ref<GCode> O_OBJECT_SLIC3R_T
|
||||
Clone<GCode> O_OBJECT_SLIC3R_T
|
||||
|
@ -221,10 +205,6 @@ GCodeWriter* O_OBJECT_SLIC3R
|
|||
Ref<GCodeWriter> O_OBJECT_SLIC3R_T
|
||||
Clone<GCodeWriter> O_OBJECT_SLIC3R_T
|
||||
|
||||
GCodePressureEqualizer* O_OBJECT_SLIC3R
|
||||
Ref<GCodePressureEqualizer> O_OBJECT_SLIC3R_T
|
||||
Clone<GCodePressureEqualizer> O_OBJECT_SLIC3R_T
|
||||
|
||||
BridgeDetector* O_OBJECT_SLIC3R
|
||||
Ref<BridgeDetector> O_OBJECT_SLIC3R_T
|
||||
Clone<BridgeDetector> O_OBJECT_SLIC3R_T
|
||||
|
|
|
@ -105,9 +105,6 @@
|
|||
%typemap{GCodeSender*};
|
||||
%typemap{Ref<GCodeSender>}{simple};
|
||||
%typemap{Clone<GCodeSender>}{simple};
|
||||
%typemap{GCodePressureEqualizer*};
|
||||
%typemap{Ref<GCodePressureEqualizer>}{simple};
|
||||
%typemap{Clone<GCodePressureEqualizer>}{simple};
|
||||
%typemap{BridgeDetector*};
|
||||
%typemap{Ref<BridgeDetector>}{simple};
|
||||
%typemap{Clone<BridgeDetector>}{simple};
|
||||
|
@ -152,18 +149,6 @@
|
|||
%typemap{Ref<PlaceholderParser>}{simple};
|
||||
%typemap{Clone<PlaceholderParser>}{simple};
|
||||
|
||||
%typemap{AvoidCrossingPerimeters*};
|
||||
%typemap{Ref<AvoidCrossingPerimeters>}{simple};
|
||||
%typemap{Clone<AvoidCrossingPerimeters>}{simple};
|
||||
|
||||
%typemap{Wipe*};
|
||||
%typemap{Ref<Wipe>}{simple};
|
||||
%typemap{Clone<Wipe>}{simple};
|
||||
|
||||
%typemap{OozePrevention*};
|
||||
%typemap{Ref<OozePrevention>}{simple};
|
||||
%typemap{Clone<OozePrevention>}{simple};
|
||||
|
||||
%typemap{CoolingBuffer*};
|
||||
%typemap{Ref<CoolingBuffer>}{simple};
|
||||
%typemap{Clone<CoolingBuffer>}{simple};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue