Merge remote-tracking branch 'origin/lm_wipe_tower_block_improvements_merged'
This commit is contained in:
commit
6a9bd540c1
@ -144,6 +144,11 @@ sub new {
|
|||||||
my ($angle_z) = @_;
|
my ($angle_z) = @_;
|
||||||
$self->rotate(rad2deg($angle_z), Z, 'absolute');
|
$self->rotate(rad2deg($angle_z), Z, 'absolute');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# callback to call schedule_background_process
|
||||||
|
my $on_request_update = sub {
|
||||||
|
$self->schedule_background_process;
|
||||||
|
};
|
||||||
|
|
||||||
# callback to update object's geometry info while using gizmos
|
# callback to update object's geometry info while using gizmos
|
||||||
my $on_update_geometry_info = sub {
|
my $on_update_geometry_info = sub {
|
||||||
@ -202,6 +207,8 @@ sub new {
|
|||||||
|
|
||||||
Slic3r::GUI::_3DScene::register_on_viewport_changed_callback($self->{canvas3D}, sub { Slic3r::GUI::_3DScene::set_viewport_from_scene($self->{preview3D}->canvas, $self->{canvas3D}); });
|
Slic3r::GUI::_3DScene::register_on_viewport_changed_callback($self->{canvas3D}, sub { Slic3r::GUI::_3DScene::set_viewport_from_scene($self->{preview3D}->canvas, $self->{canvas3D}); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Slic3r::_GUI::register_on_request_update_callback($on_request_update);
|
||||||
|
|
||||||
# # Initialize 2D preview canvas
|
# # Initialize 2D preview canvas
|
||||||
# $self->{canvas} = Slic3r::GUI::Plater::2D->new($self->{preview_notebook}, wxDefaultSize, $self->{objects}, $self->{model}, $self->{config});
|
# $self->{canvas} = Slic3r::GUI::Plater::2D->new($self->{preview_notebook}, wxDefaultSize, $self->{objects}, $self->{model}, $self->{config});
|
||||||
@ -1286,6 +1293,11 @@ sub async_apply_config {
|
|||||||
$self->{gcode_preview_data}->reset;
|
$self->{gcode_preview_data}->reset;
|
||||||
$self->{toolpaths2D}->reload_print if $self->{toolpaths2D};
|
$self->{toolpaths2D}->reload_print if $self->{toolpaths2D};
|
||||||
$self->{preview3D}->reload_print if $self->{preview3D};
|
$self->{preview3D}->reload_print if $self->{preview3D};
|
||||||
|
|
||||||
|
# We also need to reload 3D scene because of the wipe tower preview box
|
||||||
|
if ($self->{config}->wipe_tower) {
|
||||||
|
Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 1) if $self->{canvas3D}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1498,6 +1510,9 @@ sub on_process_completed {
|
|||||||
return if $error;
|
return if $error;
|
||||||
$self->{toolpaths2D}->reload_print if $self->{toolpaths2D};
|
$self->{toolpaths2D}->reload_print if $self->{toolpaths2D};
|
||||||
$self->{preview3D}->reload_print if $self->{preview3D};
|
$self->{preview3D}->reload_print if $self->{preview3D};
|
||||||
|
|
||||||
|
# in case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth:
|
||||||
|
Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 1);
|
||||||
|
|
||||||
# if we have an export filename, start a new thread for exporting G-code
|
# if we have an export filename, start a new thread for exporting G-code
|
||||||
if ($self->{export_gcode_output_file}) {
|
if ($self->{export_gcode_output_file}) {
|
||||||
|
@ -167,6 +167,18 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
|
|||||||
{
|
{
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
|
|
||||||
|
// Toolchangeresult.gcode assumes the wipe tower corner is at the origin
|
||||||
|
// We want to rotate and shift all extrusions (gcode postprocessing) and starting and ending position
|
||||||
|
float alpha = m_wipe_tower_rotation/180.f * M_PI;
|
||||||
|
WipeTower::xy start_pos = tcr.start_pos;
|
||||||
|
WipeTower::xy end_pos = tcr.end_pos;
|
||||||
|
start_pos.rotate(alpha);
|
||||||
|
start_pos.translate(m_wipe_tower_pos);
|
||||||
|
end_pos.rotate(alpha);
|
||||||
|
end_pos.translate(m_wipe_tower_pos);
|
||||||
|
std::string tcr_rotated_gcode = rotate_wipe_tower_moves(tcr.gcode, tcr.start_pos, m_wipe_tower_pos, alpha);
|
||||||
|
|
||||||
|
|
||||||
// Disable linear advance for the wipe tower operations.
|
// Disable linear advance for the wipe tower operations.
|
||||||
gcode += "M900 K0\n";
|
gcode += "M900 K0\n";
|
||||||
// Move over the wipe tower.
|
// Move over the wipe tower.
|
||||||
@ -174,14 +186,14 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
|
|||||||
gcode += gcodegen.retract(true);
|
gcode += gcodegen.retract(true);
|
||||||
gcodegen.m_avoid_crossing_perimeters.use_external_mp_once = true;
|
gcodegen.m_avoid_crossing_perimeters.use_external_mp_once = true;
|
||||||
gcode += gcodegen.travel_to(
|
gcode += gcodegen.travel_to(
|
||||||
wipe_tower_point_to_object_point(gcodegen, tcr.start_pos),
|
wipe_tower_point_to_object_point(gcodegen, start_pos),
|
||||||
erMixed,
|
erMixed,
|
||||||
"Travel to a Wipe Tower");
|
"Travel to a Wipe Tower");
|
||||||
gcode += gcodegen.unretract();
|
gcode += gcodegen.unretract();
|
||||||
|
|
||||||
// Let the tool change be executed by the wipe tower class.
|
// Let the tool change be executed by the wipe tower class.
|
||||||
// Inform the G-code writer about the changes done behind its back.
|
// Inform the G-code writer about the changes done behind its back.
|
||||||
gcode += tcr.gcode;
|
gcode += tcr_rotated_gcode;
|
||||||
// Let the m_writer know the current extruder_id, but ignore the generated G-code.
|
// Let the m_writer know the current extruder_id, but ignore the generated G-code.
|
||||||
if (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id))
|
if (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id))
|
||||||
gcodegen.writer().toolchange(new_extruder_id);
|
gcodegen.writer().toolchange(new_extruder_id);
|
||||||
@ -195,18 +207,18 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
|
|||||||
check_add_eol(gcode);
|
check_add_eol(gcode);
|
||||||
}
|
}
|
||||||
// A phony move to the end position at the wipe tower.
|
// A phony move to the end position at the wipe tower.
|
||||||
gcodegen.writer().travel_to_xy(Pointf(tcr.end_pos.x, tcr.end_pos.y));
|
gcodegen.writer().travel_to_xy(Pointf(end_pos.x, end_pos.y));
|
||||||
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, tcr.end_pos));
|
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, end_pos));
|
||||||
|
|
||||||
// Prepare a future wipe.
|
// Prepare a future wipe.
|
||||||
gcodegen.m_wipe.path.points.clear();
|
gcodegen.m_wipe.path.points.clear();
|
||||||
if (new_extruder_id >= 0) {
|
if (new_extruder_id >= 0) {
|
||||||
// Start the wipe at the current position.
|
// Start the wipe at the current position.
|
||||||
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, tcr.end_pos));
|
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, end_pos));
|
||||||
// Wipe end point: Wipe direction away from the closer tower edge to the further tower edge.
|
// Wipe end point: Wipe direction away from the closer tower edge to the further tower edge.
|
||||||
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen,
|
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen,
|
||||||
WipeTower::xy((std::abs(m_left - tcr.end_pos.x) < std::abs(m_right - tcr.end_pos.x)) ? m_right : m_left,
|
WipeTower::xy((std::abs(m_left - end_pos.x) < std::abs(m_right - end_pos.x)) ? m_right : m_left,
|
||||||
tcr.end_pos.y)));
|
end_pos.y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let the planner know we are traveling between objects.
|
// Let the planner know we are traveling between objects.
|
||||||
@ -214,6 +226,57 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
|
|||||||
return gcode;
|
return gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function postprocesses gcode_original, rotates and moves all G1 extrusions and returns resulting gcode
|
||||||
|
// Starting position has to be supplied explicitely (otherwise it would fail in case first G1 command only contained one coordinate)
|
||||||
|
std::string WipeTowerIntegration::rotate_wipe_tower_moves(const std::string& gcode_original, const WipeTower::xy& start_pos, const WipeTower::xy& translation, float angle) const
|
||||||
|
{
|
||||||
|
std::istringstream gcode_str(gcode_original);
|
||||||
|
std::string gcode_out;
|
||||||
|
std::string line;
|
||||||
|
WipeTower::xy pos = start_pos;
|
||||||
|
WipeTower::xy transformed_pos;
|
||||||
|
WipeTower::xy old_pos(-1000.1f, -1000.1f);
|
||||||
|
|
||||||
|
while (gcode_str) {
|
||||||
|
std::getline(gcode_str, line); // we read the gcode line by line
|
||||||
|
if (line.find("G1 ") == 0) {
|
||||||
|
std::ostringstream line_out;
|
||||||
|
std::istringstream line_str(line);
|
||||||
|
line_str >> std::noskipws; // don't skip whitespace
|
||||||
|
char ch = 0;
|
||||||
|
while (line_str >> ch) {
|
||||||
|
if (ch == 'X')
|
||||||
|
line_str >> pos.x;
|
||||||
|
else
|
||||||
|
if (ch == 'Y')
|
||||||
|
line_str >> pos.y;
|
||||||
|
else
|
||||||
|
line_out << ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
transformed_pos = pos;
|
||||||
|
transformed_pos.rotate(angle);
|
||||||
|
transformed_pos.translate(translation);
|
||||||
|
|
||||||
|
if (transformed_pos != old_pos) {
|
||||||
|
line = line_out.str();
|
||||||
|
char buf[2048] = "G1";
|
||||||
|
if (transformed_pos.x != old_pos.x)
|
||||||
|
sprintf(buf + strlen(buf), " X%.3f", transformed_pos.x);
|
||||||
|
if (transformed_pos.y != old_pos.y)
|
||||||
|
sprintf(buf + strlen(buf), " Y%.3f", transformed_pos.y);
|
||||||
|
|
||||||
|
line.replace(line.find("G1 "), 3, buf);
|
||||||
|
old_pos = transformed_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gcode_out += line + "\n";
|
||||||
|
}
|
||||||
|
return gcode_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string WipeTowerIntegration::prime(GCode &gcodegen)
|
std::string WipeTowerIntegration::prime(GCode &gcodegen)
|
||||||
{
|
{
|
||||||
assert(m_layer_idx == 0);
|
assert(m_layer_idx == 0);
|
||||||
|
@ -83,8 +83,10 @@ public:
|
|||||||
const WipeTower::ToolChangeResult &priming,
|
const WipeTower::ToolChangeResult &priming,
|
||||||
const std::vector<std::vector<WipeTower::ToolChangeResult>> &tool_changes,
|
const std::vector<std::vector<WipeTower::ToolChangeResult>> &tool_changes,
|
||||||
const WipeTower::ToolChangeResult &final_purge) :
|
const WipeTower::ToolChangeResult &final_purge) :
|
||||||
m_left(float(print_config.wipe_tower_x.value)),
|
m_left(/*float(print_config.wipe_tower_x.value)*/ 0.f),
|
||||||
m_right(float(print_config.wipe_tower_x.value + print_config.wipe_tower_width.value)),
|
m_right(float(/*print_config.wipe_tower_x.value +*/ print_config.wipe_tower_width.value)),
|
||||||
|
m_wipe_tower_pos(float(print_config.wipe_tower_x.value), float(print_config.wipe_tower_y.value)),
|
||||||
|
m_wipe_tower_rotation(float(print_config.wipe_tower_rotation_angle)),
|
||||||
m_priming(priming),
|
m_priming(priming),
|
||||||
m_tool_changes(tool_changes),
|
m_tool_changes(tool_changes),
|
||||||
m_final_purge(final_purge),
|
m_final_purge(final_purge),
|
||||||
@ -101,9 +103,14 @@ private:
|
|||||||
WipeTowerIntegration& operator=(const WipeTowerIntegration&);
|
WipeTowerIntegration& operator=(const WipeTowerIntegration&);
|
||||||
std::string append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const;
|
std::string append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const;
|
||||||
|
|
||||||
|
// Postprocesses gcode: rotates and moves all G1 extrusions and returns result
|
||||||
|
std::string rotate_wipe_tower_moves(const std::string& gcode_original, const WipeTower::xy& start_pos, const WipeTower::xy& translation, float angle) const;
|
||||||
|
|
||||||
// Left / right edges of the wipe tower, for the planning of wipe moves.
|
// Left / right edges of the wipe tower, for the planning of wipe moves.
|
||||||
const float m_left;
|
const float m_left;
|
||||||
const float m_right;
|
const float m_right;
|
||||||
|
const WipeTower::xy m_wipe_tower_pos;
|
||||||
|
const float m_wipe_tower_rotation;
|
||||||
// Reference to cached values at the Printer class.
|
// Reference to cached values at the Printer class.
|
||||||
const WipeTower::ToolChangeResult &m_priming;
|
const WipeTower::ToolChangeResult &m_priming;
|
||||||
const std::vector<std::vector<WipeTower::ToolChangeResult>> &m_tool_changes;
|
const std::vector<std::vector<WipeTower::ToolChangeResult>> &m_tool_changes;
|
||||||
@ -112,6 +119,7 @@ private:
|
|||||||
int m_layer_idx;
|
int m_layer_idx;
|
||||||
int m_tool_change_idx;
|
int m_tool_change_idx;
|
||||||
bool m_brim_done;
|
bool m_brim_done;
|
||||||
|
bool i_have_brim = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GCode {
|
class GCode {
|
||||||
|
@ -134,6 +134,11 @@ BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object
|
|||||||
// The projection does not contain the priming regions.
|
// The projection does not contain the priming regions.
|
||||||
BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_t max_print_z)
|
BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_t max_print_z)
|
||||||
{
|
{
|
||||||
|
// Wipe tower extrusions are saved as if the tower was at the origin with no rotation
|
||||||
|
// We need to get position and angle of the wipe tower to transform them to actual position.
|
||||||
|
Pointf wipe_tower_pos(print.config.wipe_tower_x.value, print.config.wipe_tower_y.value);
|
||||||
|
float wipe_tower_angle = print.config.wipe_tower_rotation_angle.value;
|
||||||
|
|
||||||
BoundingBoxf bbox;
|
BoundingBoxf bbox;
|
||||||
for (const std::vector<WipeTower::ToolChangeResult> &tool_changes : print.m_wipe_tower_tool_changes) {
|
for (const std::vector<WipeTower::ToolChangeResult> &tool_changes : print.m_wipe_tower_tool_changes) {
|
||||||
if (! tool_changes.empty() && tool_changes.front().print_z > max_print_z)
|
if (! tool_changes.empty() && tool_changes.front().print_z > max_print_z)
|
||||||
@ -144,6 +149,11 @@ BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_
|
|||||||
if (e.width > 0) {
|
if (e.width > 0) {
|
||||||
Pointf p1((&e - 1)->pos.x, (&e - 1)->pos.y);
|
Pointf p1((&e - 1)->pos.x, (&e - 1)->pos.y);
|
||||||
Pointf p2(e.pos.x, e.pos.y);
|
Pointf p2(e.pos.x, e.pos.y);
|
||||||
|
p1.rotate(wipe_tower_angle);
|
||||||
|
p1.translate(wipe_tower_pos);
|
||||||
|
p2.rotate(wipe_tower_angle);
|
||||||
|
p2.translate(wipe_tower_pos);
|
||||||
|
|
||||||
bbox.merge(p1);
|
bbox.merge(p1);
|
||||||
coordf_t radius = 0.5 * e.width;
|
coordf_t radius = 0.5 * e.width;
|
||||||
bbox.min.x = std::min(bbox.min.x, std::min(p1.x, p2.x) - radius);
|
bbox.min.x = std::min(bbox.min.x, std::min(p1.x, p2.x) - radius);
|
||||||
|
@ -25,18 +25,30 @@ public:
|
|||||||
bool operator==(const xy &rhs) const { return x == rhs.x && y == rhs.y; }
|
bool operator==(const xy &rhs) const { return x == rhs.x && y == rhs.y; }
|
||||||
bool operator!=(const xy &rhs) const { return x != rhs.x || y != rhs.y; }
|
bool operator!=(const xy &rhs) const { return x != rhs.x || y != rhs.y; }
|
||||||
|
|
||||||
// Rotate the point around given point about given angle (in degrees)
|
// Rotate the point around center of the wipe tower about given angle (in degrees)
|
||||||
// shifts the result so that point of rotation is in the middle of the tower
|
xy rotate(float width, float depth, float angle) const {
|
||||||
xy rotate(const xy& origin, float width, float depth, float angle) const {
|
|
||||||
xy out(0,0);
|
xy out(0,0);
|
||||||
float temp_x = x - width / 2.f;
|
float temp_x = x - width / 2.f;
|
||||||
float temp_y = y - depth / 2.f;
|
float temp_y = y - depth / 2.f;
|
||||||
angle *= M_PI/180.;
|
angle *= M_PI/180.;
|
||||||
out.x += (temp_x - origin.x) * cos(angle) - (temp_y - origin.y) * sin(angle);
|
out.x += temp_x * cos(angle) - temp_y * sin(angle) + width / 2.f;
|
||||||
out.y += (temp_x - origin.x) * sin(angle) + (temp_y - origin.y) * cos(angle);
|
out.y += temp_x * sin(angle) + temp_y * cos(angle) + depth / 2.f;
|
||||||
return out + origin;
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rotate the point around origin about given angle in degrees
|
||||||
|
void rotate(float angle) {
|
||||||
|
float temp_x = x * cos(angle) - y * sin(angle);
|
||||||
|
y = x * sin(angle) + y * cos(angle);
|
||||||
|
x = temp_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void translate(const xy& vect) {
|
||||||
|
x += vect.x;
|
||||||
|
y += vect.y;
|
||||||
|
}
|
||||||
|
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
};
|
};
|
||||||
@ -104,6 +116,9 @@ public:
|
|||||||
// This is useful not only for the print time estimation, but also for the control of layer cooling.
|
// This is useful not only for the print time estimation, but also for the control of layer cooling.
|
||||||
float elapsed_time;
|
float elapsed_time;
|
||||||
|
|
||||||
|
// Is this a priming extrusion? (If so, the wipe tower rotation & translation will not be applied later)
|
||||||
|
bool priming;
|
||||||
|
|
||||||
// Sum the total length of the extrusion.
|
// Sum the total length of the extrusion.
|
||||||
float total_extrusion_length_in_plane() {
|
float total_extrusion_length_in_plane() {
|
||||||
float e_length = 0.f;
|
float e_length = 0.f;
|
||||||
|
@ -5,7 +5,7 @@ TODO LIST
|
|||||||
|
|
||||||
1. cooling moves - DONE
|
1. cooling moves - DONE
|
||||||
2. account for perimeter and finish_layer extrusions and subtract it from last wipe - DONE
|
2. account for perimeter and finish_layer extrusions and subtract it from last wipe - DONE
|
||||||
3. priming extrusions (last wipe must clear the color)
|
3. priming extrusions (last wipe must clear the color) - DONE
|
||||||
4. Peter's wipe tower - layer's are not exactly square
|
4. Peter's wipe tower - layer's are not exactly square
|
||||||
5. Peter's wipe tower - variable width for higher levels
|
5. Peter's wipe tower - variable width for higher levels
|
||||||
6. Peter's wipe tower - make sure it is not too sparse (apply max_bridge_distance and make last wipe longer)
|
6. Peter's wipe tower - make sure it is not too sparse (apply max_bridge_distance and make last wipe longer)
|
||||||
@ -17,7 +17,6 @@ TODO LIST
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
@ -68,8 +67,11 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Writer& set_initial_position(const WipeTower::xy &pos) {
|
Writer& set_initial_position(const WipeTower::xy &pos, float width = 0.f, float depth = 0.f, float internal_angle = 0.f) {
|
||||||
m_start_pos = WipeTower::xy(pos,0.f,m_y_shift).rotate(m_wipe_tower_pos, m_wipe_tower_width, m_wipe_tower_depth, m_angle_deg);
|
m_wipe_tower_width = width;
|
||||||
|
m_wipe_tower_depth = depth;
|
||||||
|
m_internal_angle = internal_angle;
|
||||||
|
m_start_pos = WipeTower::xy(pos,0.f,m_y_shift).rotate(m_wipe_tower_width, m_wipe_tower_depth, m_internal_angle);
|
||||||
m_current_pos = pos;
|
m_current_pos = pos;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -81,9 +83,6 @@ public:
|
|||||||
|
|
||||||
Writer& set_extrusion_flow(float flow)
|
Writer& set_extrusion_flow(float flow)
|
||||||
{ m_extrusion_flow = flow; return *this; }
|
{ m_extrusion_flow = flow; return *this; }
|
||||||
|
|
||||||
Writer& set_rotation(WipeTower::xy& pos, float width, float depth, float angle)
|
|
||||||
{ m_wipe_tower_pos = pos; m_wipe_tower_width = width; m_wipe_tower_depth=depth; m_angle_deg = angle; return (*this); }
|
|
||||||
|
|
||||||
Writer& set_y_shift(float shift) {
|
Writer& set_y_shift(float shift) {
|
||||||
m_current_pos.y -= shift-m_y_shift;
|
m_current_pos.y -= shift-m_y_shift;
|
||||||
@ -110,7 +109,7 @@ public:
|
|||||||
float y() const { return m_current_pos.y; }
|
float y() const { return m_current_pos.y; }
|
||||||
const WipeTower::xy& pos() const { return m_current_pos; }
|
const WipeTower::xy& pos() const { return m_current_pos; }
|
||||||
const WipeTower::xy start_pos_rotated() const { return m_start_pos; }
|
const WipeTower::xy start_pos_rotated() const { return m_start_pos; }
|
||||||
const WipeTower::xy pos_rotated() const { return WipeTower::xy(m_current_pos,0.f,m_y_shift).rotate(m_wipe_tower_pos, m_wipe_tower_width, m_wipe_tower_depth, m_angle_deg); }
|
const WipeTower::xy pos_rotated() const { return WipeTower::xy(m_current_pos, 0.f, m_y_shift).rotate(m_wipe_tower_width, m_wipe_tower_depth, m_internal_angle); }
|
||||||
float elapsed_time() const { return m_elapsed_time; }
|
float elapsed_time() const { return m_elapsed_time; }
|
||||||
|
|
||||||
// Extrude with an explicitely provided amount of extrusion.
|
// Extrude with an explicitely provided amount of extrusion.
|
||||||
@ -125,9 +124,9 @@ public:
|
|||||||
double len = sqrt(dx*dx+dy*dy);
|
double len = sqrt(dx*dx+dy*dy);
|
||||||
|
|
||||||
|
|
||||||
// For rotated wipe tower, transform position to printer coordinates
|
// Now do the "internal rotation" with respect to the wipe tower center
|
||||||
WipeTower::xy rotated_current_pos(WipeTower::xy(m_current_pos,0.f,m_y_shift).rotate(m_wipe_tower_pos, m_wipe_tower_width, m_wipe_tower_depth, m_angle_deg)); // this is where we are
|
WipeTower::xy rotated_current_pos(WipeTower::xy(m_current_pos,0.f,m_y_shift).rotate(m_wipe_tower_width, m_wipe_tower_depth, m_internal_angle)); // this is where we are
|
||||||
WipeTower::xy rot(WipeTower::xy(x,y+m_y_shift).rotate(m_wipe_tower_pos, m_wipe_tower_width, m_wipe_tower_depth, m_angle_deg)); // this is where we want to go
|
WipeTower::xy rot(WipeTower::xy(x,y+m_y_shift).rotate(m_wipe_tower_width, m_wipe_tower_depth, m_internal_angle)); // this is where we want to go
|
||||||
|
|
||||||
if (! m_preview_suppressed && e > 0.f && len > 0.) {
|
if (! m_preview_suppressed && e > 0.f && len > 0.) {
|
||||||
// Width of a squished extrusion, corrected for the roundings of the squished extrusions.
|
// Width of a squished extrusion, corrected for the roundings of the squished extrusions.
|
||||||
@ -147,6 +146,7 @@ public:
|
|||||||
if (std::abs(rot.y - rotated_current_pos.y) > EPSILON)
|
if (std::abs(rot.y - rotated_current_pos.y) > EPSILON)
|
||||||
m_gcode += set_format_Y(rot.y);
|
m_gcode += set_format_Y(rot.y);
|
||||||
|
|
||||||
|
|
||||||
if (e != 0.f)
|
if (e != 0.f)
|
||||||
m_gcode += set_format_E(e);
|
m_gcode += set_format_E(e);
|
||||||
|
|
||||||
@ -397,9 +397,8 @@ private:
|
|||||||
std::string m_gcode;
|
std::string m_gcode;
|
||||||
std::vector<WipeTower::Extrusion> m_extrusions;
|
std::vector<WipeTower::Extrusion> m_extrusions;
|
||||||
float m_elapsed_time;
|
float m_elapsed_time;
|
||||||
float m_angle_deg = 0.f;
|
float m_internal_angle = 0.f;
|
||||||
float m_y_shift = 0.f;
|
float m_y_shift = 0.f;
|
||||||
WipeTower::xy m_wipe_tower_pos;
|
|
||||||
float m_wipe_tower_width = 0.f;
|
float m_wipe_tower_width = 0.f;
|
||||||
float m_wipe_tower_depth = 0.f;
|
float m_wipe_tower_depth = 0.f;
|
||||||
float m_last_fan_speed = 0.f;
|
float m_last_fan_speed = 0.f;
|
||||||
@ -539,6 +538,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
|
|||||||
m_print_brim = true;
|
m_print_brim = true;
|
||||||
|
|
||||||
ToolChangeResult result;
|
ToolChangeResult result;
|
||||||
|
result.priming = true;
|
||||||
result.print_z = this->m_z_pos;
|
result.print_z = this->m_z_pos;
|
||||||
result.layer_height = this->m_layer_height;
|
result.layer_height = this->m_layer_height;
|
||||||
result.gcode = writer.gcode();
|
result.gcode = writer.gcode();
|
||||||
@ -575,7 +575,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
box_coordinates cleaning_box(
|
box_coordinates cleaning_box(
|
||||||
m_wipe_tower_pos + xy(m_perimeter_width / 2.f, m_perimeter_width / 2.f),
|
xy(m_perimeter_width / 2.f, m_perimeter_width / 2.f),
|
||||||
m_wipe_tower_width - m_perimeter_width,
|
m_wipe_tower_width - m_perimeter_width,
|
||||||
(tool != (unsigned int)(-1) ? /*m_layer_info->depth*/wipe_area+m_depth_traversed-0.5*m_perimeter_width
|
(tool != (unsigned int)(-1) ? /*m_layer_info->depth*/wipe_area+m_depth_traversed-0.5*m_perimeter_width
|
||||||
: m_wipe_tower_depth-m_perimeter_width));
|
: m_wipe_tower_depth-m_perimeter_width));
|
||||||
@ -584,7 +584,6 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
|
|||||||
writer.set_extrusion_flow(m_extrusion_flow)
|
writer.set_extrusion_flow(m_extrusion_flow)
|
||||||
.set_z(m_z_pos)
|
.set_z(m_z_pos)
|
||||||
.set_initial_tool(m_current_tool)
|
.set_initial_tool(m_current_tool)
|
||||||
.set_rotation(m_wipe_tower_pos, m_wipe_tower_width, m_wipe_tower_depth, m_wipe_tower_rotation_angle)
|
|
||||||
.set_y_shift(m_y_shift + (tool!=(unsigned int)(-1) && (m_current_shape == SHAPE_REVERSED && !m_peters_wipe_tower) ? m_layer_info->depth - m_layer_info->toolchanges_depth(): 0.f))
|
.set_y_shift(m_y_shift + (tool!=(unsigned int)(-1) && (m_current_shape == SHAPE_REVERSED && !m_peters_wipe_tower) ? m_layer_info->depth - m_layer_info->toolchanges_depth(): 0.f))
|
||||||
.append(";--------------------\n"
|
.append(";--------------------\n"
|
||||||
"; CP TOOLCHANGE START\n")
|
"; CP TOOLCHANGE START\n")
|
||||||
@ -594,7 +593,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
|
|||||||
.speed_override(100);
|
.speed_override(100);
|
||||||
|
|
||||||
xy initial_position = cleaning_box.ld + WipeTower::xy(0.f,m_depth_traversed);
|
xy initial_position = cleaning_box.ld + WipeTower::xy(0.f,m_depth_traversed);
|
||||||
writer.set_initial_position(initial_position);
|
writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
|
||||||
|
|
||||||
// Increase the extruder driver current to allow fast ramming.
|
// Increase the extruder driver current to allow fast ramming.
|
||||||
writer.set_extruder_trimpot(750);
|
writer.set_extruder_trimpot(750);
|
||||||
@ -616,11 +615,11 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
|
|||||||
if (last_change_in_layer) {// draw perimeter line
|
if (last_change_in_layer) {// draw perimeter line
|
||||||
writer.set_y_shift(m_y_shift);
|
writer.set_y_shift(m_y_shift);
|
||||||
if (m_peters_wipe_tower)
|
if (m_peters_wipe_tower)
|
||||||
writer.rectangle(m_wipe_tower_pos,m_layer_info->depth + 3*m_perimeter_width,m_wipe_tower_depth);
|
writer.rectangle(WipeTower::xy(0.f, 0.f),m_layer_info->depth + 3*m_perimeter_width,m_wipe_tower_depth);
|
||||||
else {
|
else {
|
||||||
writer.rectangle(m_wipe_tower_pos,m_wipe_tower_width, m_layer_info->depth + m_perimeter_width);
|
writer.rectangle(WipeTower::xy(0.f, 0.f),m_wipe_tower_width, m_layer_info->depth + m_perimeter_width);
|
||||||
if (layer_finished()) { // no finish_layer will be called, we must wipe the nozzle
|
if (layer_finished()) { // no finish_layer will be called, we must wipe the nozzle
|
||||||
writer.travel(m_wipe_tower_pos.x + (writer.x()> (m_wipe_tower_pos.x + m_wipe_tower_width) / 2.f ? 0.f : m_wipe_tower_width), writer.y());
|
writer.travel(writer.x()> m_wipe_tower_width / 2.f ? 0.f : m_wipe_tower_width, writer.y());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -634,6 +633,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
|
|||||||
"\n\n");
|
"\n\n");
|
||||||
|
|
||||||
ToolChangeResult result;
|
ToolChangeResult result;
|
||||||
|
result.priming = false;
|
||||||
result.print_z = this->m_z_pos;
|
result.print_z = this->m_z_pos;
|
||||||
result.layer_height = this->m_layer_height;
|
result.layer_height = this->m_layer_height;
|
||||||
result.gcode = writer.gcode();
|
result.gcode = writer.gcode();
|
||||||
@ -647,7 +647,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
|
|||||||
WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(bool sideOnly, float y_offset)
|
WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(bool sideOnly, float y_offset)
|
||||||
{
|
{
|
||||||
const box_coordinates wipeTower_box(
|
const box_coordinates wipeTower_box(
|
||||||
m_wipe_tower_pos,
|
WipeTower::xy(0.f, 0.f),
|
||||||
m_wipe_tower_width,
|
m_wipe_tower_width,
|
||||||
m_wipe_tower_depth);
|
m_wipe_tower_depth);
|
||||||
|
|
||||||
@ -655,12 +655,11 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(bool sideOnly, flo
|
|||||||
writer.set_extrusion_flow(m_extrusion_flow * 1.1f)
|
writer.set_extrusion_flow(m_extrusion_flow * 1.1f)
|
||||||
.set_z(m_z_pos) // Let the writer know the current Z position as a base for Z-hop.
|
.set_z(m_z_pos) // Let the writer know the current Z position as a base for Z-hop.
|
||||||
.set_initial_tool(m_current_tool)
|
.set_initial_tool(m_current_tool)
|
||||||
.set_rotation(m_wipe_tower_pos, m_wipe_tower_width, m_wipe_tower_depth, m_wipe_tower_rotation_angle)
|
|
||||||
.append(";-------------------------------------\n"
|
.append(";-------------------------------------\n"
|
||||||
"; CP WIPE TOWER FIRST LAYER BRIM START\n");
|
"; CP WIPE TOWER FIRST LAYER BRIM START\n");
|
||||||
|
|
||||||
xy initial_position = wipeTower_box.lu - xy(m_perimeter_width * 6.f, 0);
|
xy initial_position = wipeTower_box.lu - xy(m_perimeter_width * 6.f, 0);
|
||||||
writer.set_initial_position(initial_position);
|
writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
|
||||||
|
|
||||||
writer.extrude_explicit(wipeTower_box.ld - xy(m_perimeter_width * 6.f, 0), // Prime the extruder left of the wipe tower.
|
writer.extrude_explicit(wipeTower_box.ld - xy(m_perimeter_width * 6.f, 0), // Prime the extruder left of the wipe tower.
|
||||||
1.5f * m_extrusion_flow * (wipeTower_box.lu.y - wipeTower_box.ld.y), 2400);
|
1.5f * m_extrusion_flow * (wipeTower_box.lu.y - wipeTower_box.ld.y), 2400);
|
||||||
@ -685,6 +684,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(bool sideOnly, flo
|
|||||||
m_print_brim = false; // Mark the brim as extruded
|
m_print_brim = false; // Mark the brim as extruded
|
||||||
|
|
||||||
ToolChangeResult result;
|
ToolChangeResult result;
|
||||||
|
result.priming = false;
|
||||||
result.print_z = this->m_z_pos;
|
result.print_z = this->m_z_pos;
|
||||||
result.layer_height = this->m_layer_height;
|
result.layer_height = this->m_layer_height;
|
||||||
result.gcode = writer.gcode();
|
result.gcode = writer.gcode();
|
||||||
@ -724,7 +724,7 @@ void WipeTowerPrusaMM::toolchange_Unload(
|
|||||||
if (m_layer_info > m_plan.begin() && m_layer_info < m_plan.end() && (m_layer_info-1!=m_plan.begin() || !m_adhesion )) {
|
if (m_layer_info > m_plan.begin() && m_layer_info < m_plan.end() && (m_layer_info-1!=m_plan.begin() || !m_adhesion )) {
|
||||||
|
|
||||||
// this is y of the center of previous sparse infill border
|
// this is y of the center of previous sparse infill border
|
||||||
float sparse_beginning_y = m_wipe_tower_pos.y;
|
float sparse_beginning_y = 0.f;
|
||||||
if (m_current_shape == SHAPE_REVERSED)
|
if (m_current_shape == SHAPE_REVERSED)
|
||||||
sparse_beginning_y += ((m_layer_info-1)->depth - (m_layer_info-1)->toolchanges_depth())
|
sparse_beginning_y += ((m_layer_info-1)->depth - (m_layer_info-1)->toolchanges_depth())
|
||||||
- ((m_layer_info)->depth-(m_layer_info)->toolchanges_depth()) ;
|
- ((m_layer_info)->depth-(m_layer_info)->toolchanges_depth()) ;
|
||||||
@ -742,7 +742,7 @@ void WipeTowerPrusaMM::toolchange_Unload(
|
|||||||
for (const auto& tch : m_layer_info->tool_changes) { // let's find this toolchange
|
for (const auto& tch : m_layer_info->tool_changes) { // let's find this toolchange
|
||||||
if (tch.old_tool == m_current_tool) {
|
if (tch.old_tool == m_current_tool) {
|
||||||
sum_of_depths += tch.ramming_depth;
|
sum_of_depths += tch.ramming_depth;
|
||||||
float ramming_end_y = m_wipe_tower_pos.y + sum_of_depths;
|
float ramming_end_y = sum_of_depths;
|
||||||
ramming_end_y -= (y_step/m_extra_spacing-m_perimeter_width) / 2.f; // center of final ramming line
|
ramming_end_y -= (y_step/m_extra_spacing-m_perimeter_width) / 2.f; // center of final ramming line
|
||||||
|
|
||||||
// debugging:
|
// debugging:
|
||||||
@ -950,7 +950,7 @@ void WipeTowerPrusaMM::toolchange_Wipe(
|
|||||||
if (m_layer_info != m_plan.end() && m_current_tool != m_layer_info->tool_changes.back().new_tool) {
|
if (m_layer_info != m_plan.end() && m_current_tool != m_layer_info->tool_changes.back().new_tool) {
|
||||||
m_left_to_right = !m_left_to_right;
|
m_left_to_right = !m_left_to_right;
|
||||||
writer.travel(writer.x(), writer.y() - dy)
|
writer.travel(writer.x(), writer.y() - dy)
|
||||||
.travel(m_wipe_tower_pos.x + (m_left_to_right ? m_wipe_tower_width : 0.f), writer.y());
|
.travel(m_left_to_right ? m_wipe_tower_width : 0.f, writer.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.set_extrusion_flow(m_extrusion_flow); // Reset the extrusion flow.
|
writer.set_extrusion_flow(m_extrusion_flow); // Reset the extrusion flow.
|
||||||
@ -969,7 +969,6 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::finish_layer()
|
|||||||
writer.set_extrusion_flow(m_extrusion_flow)
|
writer.set_extrusion_flow(m_extrusion_flow)
|
||||||
.set_z(m_z_pos)
|
.set_z(m_z_pos)
|
||||||
.set_initial_tool(m_current_tool)
|
.set_initial_tool(m_current_tool)
|
||||||
.set_rotation(m_wipe_tower_pos, m_wipe_tower_width, m_wipe_tower_depth, m_wipe_tower_rotation_angle)
|
|
||||||
.set_y_shift(m_y_shift - (m_current_shape == SHAPE_REVERSED && !m_peters_wipe_tower ? m_layer_info->toolchanges_depth() : 0.f))
|
.set_y_shift(m_y_shift - (m_current_shape == SHAPE_REVERSED && !m_peters_wipe_tower ? m_layer_info->toolchanges_depth() : 0.f))
|
||||||
.append(";--------------------\n"
|
.append(";--------------------\n"
|
||||||
"; CP EMPTY GRID START\n")
|
"; CP EMPTY GRID START\n")
|
||||||
@ -978,14 +977,12 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::finish_layer()
|
|||||||
// Slow down on the 1st layer.
|
// Slow down on the 1st layer.
|
||||||
float speed_factor = m_is_first_layer ? 0.5f : 1.f;
|
float speed_factor = m_is_first_layer ? 0.5f : 1.f;
|
||||||
float current_depth = m_layer_info->depth - m_layer_info->toolchanges_depth();
|
float current_depth = m_layer_info->depth - m_layer_info->toolchanges_depth();
|
||||||
box_coordinates fill_box(m_wipe_tower_pos + xy(m_perimeter_width, m_depth_traversed + m_perimeter_width),
|
box_coordinates fill_box(xy(m_perimeter_width, m_depth_traversed + m_perimeter_width),
|
||||||
m_wipe_tower_width - 2 * m_perimeter_width, current_depth-m_perimeter_width);
|
m_wipe_tower_width - 2 * m_perimeter_width, current_depth-m_perimeter_width);
|
||||||
|
|
||||||
if (m_left_to_right) // so there is never a diagonal travel
|
|
||||||
writer.set_initial_position(fill_box.ru);
|
|
||||||
else
|
|
||||||
writer.set_initial_position(fill_box.lu);
|
|
||||||
|
|
||||||
|
writer.set_initial_position((m_left_to_right ? fill_box.ru : fill_box.lu), // so there is never a diagonal travel
|
||||||
|
m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
|
||||||
|
|
||||||
box_coordinates box = fill_box;
|
box_coordinates box = fill_box;
|
||||||
for (int i=0;i<2;++i) {
|
for (int i=0;i<2;++i) {
|
||||||
@ -1044,6 +1041,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::finish_layer()
|
|||||||
m_depth_traversed = m_wipe_tower_depth-m_perimeter_width;
|
m_depth_traversed = m_wipe_tower_depth-m_perimeter_width;
|
||||||
|
|
||||||
ToolChangeResult result;
|
ToolChangeResult result;
|
||||||
|
result.priming = false;
|
||||||
result.print_z = this->m_z_pos;
|
result.print_z = this->m_z_pos;
|
||||||
result.layer_height = this->m_layer_height;
|
result.layer_height = this->m_layer_height;
|
||||||
result.gcode = writer.gcode();
|
result.gcode = writer.gcode();
|
||||||
@ -1165,9 +1163,9 @@ void WipeTowerPrusaMM::generate(std::vector<std::vector<WipeTower::ToolChangeRes
|
|||||||
{
|
{
|
||||||
set_layer(layer.z,layer.height,0,layer.z == m_plan.front().z,layer.z == m_plan.back().z);
|
set_layer(layer.z,layer.height,0,layer.z == m_plan.front().z,layer.z == m_plan.back().z);
|
||||||
if (m_peters_wipe_tower)
|
if (m_peters_wipe_tower)
|
||||||
m_wipe_tower_rotation_angle += 90.f;
|
m_internal_rotation += 90.f;
|
||||||
else
|
else
|
||||||
m_wipe_tower_rotation_angle += 180.f;
|
m_internal_rotation += 180.f;
|
||||||
|
|
||||||
if (!m_peters_wipe_tower && m_layer_info->depth < m_wipe_tower_depth - m_perimeter_width)
|
if (!m_peters_wipe_tower && m_layer_info->depth < m_wipe_tower_depth - m_perimeter_width)
|
||||||
m_y_shift = (m_wipe_tower_depth-m_layer_info->depth-m_perimeter_width)/2.f;
|
m_y_shift = (m_wipe_tower_depth-m_layer_info->depth-m_perimeter_width)/2.f;
|
||||||
@ -1188,7 +1186,7 @@ void WipeTowerPrusaMM::generate(std::vector<std::vector<WipeTower::ToolChangeRes
|
|||||||
last_toolchange.gcode += buf;
|
last_toolchange.gcode += buf;
|
||||||
}
|
}
|
||||||
last_toolchange.gcode += finish_layer_toolchange.gcode;
|
last_toolchange.gcode += finish_layer_toolchange.gcode;
|
||||||
last_toolchange.extrusions.insert(last_toolchange.extrusions.end(),finish_layer_toolchange.extrusions.begin(),finish_layer_toolchange.extrusions.end());
|
last_toolchange.extrusions.insert(last_toolchange.extrusions.end(), finish_layer_toolchange.extrusions.begin(), finish_layer_toolchange.extrusions.end());
|
||||||
last_toolchange.end_pos = finish_layer_toolchange.end_pos;
|
last_toolchange.end_pos = finish_layer_toolchange.end_pos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -102,6 +102,8 @@ public:
|
|||||||
// Iterates through prepared m_plan, generates ToolChangeResults and appends them to "result"
|
// Iterates through prepared m_plan, generates ToolChangeResults and appends them to "result"
|
||||||
void generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &result);
|
void generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &result);
|
||||||
|
|
||||||
|
float get_depth() const { return m_wipe_tower_depth; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Switch to a next layer.
|
// Switch to a next layer.
|
||||||
@ -189,6 +191,7 @@ private:
|
|||||||
float m_wipe_tower_width; // Width of the wipe tower.
|
float m_wipe_tower_width; // Width of the wipe tower.
|
||||||
float m_wipe_tower_depth = 0.f; // Depth of the wipe tower
|
float m_wipe_tower_depth = 0.f; // Depth of the wipe tower
|
||||||
float m_wipe_tower_rotation_angle = 0.f; // Wipe tower rotation angle in degrees (with respect to x axis)
|
float m_wipe_tower_rotation_angle = 0.f; // Wipe tower rotation angle in degrees (with respect to x axis)
|
||||||
|
float m_internal_rotation = 0.f;
|
||||||
float m_y_shift = 0.f; // y shift passed to writer
|
float m_y_shift = 0.f; // y shift passed to writer
|
||||||
float m_z_pos = 0.f; // Current Z position.
|
float m_z_pos = 0.f; // Current Z position.
|
||||||
float m_layer_height = 0.f; // Current layer height.
|
float m_layer_height = 0.f; // Current layer height.
|
||||||
|
@ -167,7 +167,10 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
|
|||||||
"use_relative_e_distances",
|
"use_relative_e_distances",
|
||||||
"use_volumetric_e",
|
"use_volumetric_e",
|
||||||
"variable_layer_height",
|
"variable_layer_height",
|
||||||
"wipe"
|
"wipe",
|
||||||
|
"wipe_tower_x",
|
||||||
|
"wipe_tower_y",
|
||||||
|
"wipe_tower_rotation_angle"
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<PrintStep> steps;
|
std::vector<PrintStep> steps;
|
||||||
@ -176,7 +179,12 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
|
|||||||
|
|
||||||
// Always invalidate the wipe tower. This is probably necessary because of the wipe_into_infill / wipe_into_objects
|
// Always invalidate the wipe tower. This is probably necessary because of the wipe_into_infill / wipe_into_objects
|
||||||
// features - nearly anything can influence what should (and could) be wiped into.
|
// features - nearly anything can influence what should (and could) be wiped into.
|
||||||
steps.emplace_back(psWipeTower);
|
// Only these three parameters don't invalidate the wipe tower (they only affect the gcode export):
|
||||||
|
for (const t_config_option_key &opt_key : opt_keys)
|
||||||
|
if (opt_key != "wipe_tower_x" && opt_key != "wipe_tower_y" && opt_key != "wipe_tower_rotation_angle") {
|
||||||
|
steps.emplace_back(psWipeTower);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for (const t_config_option_key &opt_key : opt_keys) {
|
for (const t_config_option_key &opt_key : opt_keys) {
|
||||||
if (steps_ignore.find(opt_key) != steps_ignore.end()) {
|
if (steps_ignore.find(opt_key) != steps_ignore.end()) {
|
||||||
@ -213,10 +221,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
|
|||||||
|| opt_key == "spiral_vase"
|
|| opt_key == "spiral_vase"
|
||||||
|| opt_key == "temperature"
|
|| opt_key == "temperature"
|
||||||
|| opt_key == "wipe_tower"
|
|| opt_key == "wipe_tower"
|
||||||
|| opt_key == "wipe_tower_x"
|
|
||||||
|| opt_key == "wipe_tower_y"
|
|
||||||
|| opt_key == "wipe_tower_width"
|
|| opt_key == "wipe_tower_width"
|
||||||
|| opt_key == "wipe_tower_rotation_angle"
|
|
||||||
|| opt_key == "wipe_tower_bridging"
|
|| opt_key == "wipe_tower_bridging"
|
||||||
|| opt_key == "wiping_volumes_matrix"
|
|| opt_key == "wiping_volumes_matrix"
|
||||||
|| opt_key == "parking_pos_retraction"
|
|| opt_key == "parking_pos_retraction"
|
||||||
@ -1052,6 +1057,8 @@ void Print::_make_wipe_tower()
|
|||||||
if (! this->has_wipe_tower())
|
if (! this->has_wipe_tower())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
m_wipe_tower_depth = 0.f;
|
||||||
|
|
||||||
// Get wiping matrix to get number of extruders and convert vector<double> to vector<float>:
|
// Get wiping matrix to get number of extruders and convert vector<double> to vector<float>:
|
||||||
std::vector<float> wiping_matrix((this->config.wiping_volumes_matrix.values).begin(),(this->config.wiping_volumes_matrix.values).end());
|
std::vector<float> wiping_matrix((this->config.wiping_volumes_matrix.values).begin(),(this->config.wiping_volumes_matrix.values).end());
|
||||||
// Extract purging volumes for each extruder pair:
|
// Extract purging volumes for each extruder pair:
|
||||||
@ -1163,7 +1170,8 @@ void Print::_make_wipe_tower()
|
|||||||
// Generate the wipe tower layers.
|
// Generate the wipe tower layers.
|
||||||
m_wipe_tower_tool_changes.reserve(m_tool_ordering.layer_tools().size());
|
m_wipe_tower_tool_changes.reserve(m_tool_ordering.layer_tools().size());
|
||||||
wipe_tower.generate(m_wipe_tower_tool_changes);
|
wipe_tower.generate(m_wipe_tower_tool_changes);
|
||||||
|
m_wipe_tower_depth = wipe_tower.get_depth();
|
||||||
|
|
||||||
// Unload the current filament over the purge tower.
|
// Unload the current filament over the purge tower.
|
||||||
coordf_t layer_height = this->objects.front()->config.layer_height.value;
|
coordf_t layer_height = this->objects.front()->config.layer_height.value;
|
||||||
if (m_tool_ordering.back().wipe_tower_partitions > 0) {
|
if (m_tool_ordering.back().wipe_tower_partitions > 0) {
|
||||||
|
@ -273,6 +273,7 @@ public:
|
|||||||
|
|
||||||
void add_model_object(ModelObject* model_object, int idx = -1);
|
void add_model_object(ModelObject* model_object, int idx = -1);
|
||||||
bool apply_config(DynamicPrintConfig config);
|
bool apply_config(DynamicPrintConfig config);
|
||||||
|
float get_wipe_tower_depth() const { return m_wipe_tower_depth; }
|
||||||
bool has_infinite_skirt() const;
|
bool has_infinite_skirt() const;
|
||||||
bool has_skirt() const;
|
bool has_skirt() const;
|
||||||
// Returns an empty string if valid, otherwise returns an error message.
|
// Returns an empty string if valid, otherwise returns an error message.
|
||||||
@ -326,6 +327,9 @@ private:
|
|||||||
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
|
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
|
||||||
PrintRegionConfig _region_config_from_model_volume(const ModelVolume &volume);
|
PrintRegionConfig _region_config_from_model_volume(const ModelVolume &volume);
|
||||||
|
|
||||||
|
// Depth of the wipe tower to pass to GLCanvas3D for exact bounding box:
|
||||||
|
float m_wipe_tower_depth = 0.f;
|
||||||
|
|
||||||
// Has the calculation been canceled?
|
// Has the calculation been canceled?
|
||||||
tbb::atomic<bool> m_canceled;
|
tbb::atomic<bool> m_canceled;
|
||||||
};
|
};
|
||||||
|
@ -75,6 +75,7 @@ bool PrintObject::delete_last_copy()
|
|||||||
|
|
||||||
bool PrintObject::set_copies(const Points &points)
|
bool PrintObject::set_copies(const Points &points)
|
||||||
{
|
{
|
||||||
|
bool copies_num_changed = this->_copies.size() != points.size();
|
||||||
this->_copies = points;
|
this->_copies = points;
|
||||||
|
|
||||||
// order copies with a nearest neighbor search and translate them by _copies_shift
|
// order copies with a nearest neighbor search and translate them by _copies_shift
|
||||||
@ -93,7 +94,8 @@ bool PrintObject::set_copies(const Points &points)
|
|||||||
|
|
||||||
bool invalidated = this->_print->invalidate_step(psSkirt);
|
bool invalidated = this->_print->invalidate_step(psSkirt);
|
||||||
invalidated |= this->_print->invalidate_step(psBrim);
|
invalidated |= this->_print->invalidate_step(psBrim);
|
||||||
invalidated |= this->_print->invalidate_step(psWipeTower);
|
if (copies_num_changed)
|
||||||
|
invalidated |= this->_print->invalidate_step(psWipeTower);
|
||||||
return invalidated;
|
return invalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,20 +644,62 @@ std::vector<int> GLVolumeCollection::load_object(
|
|||||||
return volumes_idx;
|
return volumes_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GLVolumeCollection::load_wipe_tower_preview(
|
|
||||||
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs)
|
|
||||||
{
|
|
||||||
float color[4] = { 0.5f, 0.5f, 0.0f, 0.5f };
|
|
||||||
this->volumes.emplace_back(new GLVolume(color));
|
|
||||||
GLVolume &v = *this->volumes.back();
|
|
||||||
|
|
||||||
|
int GLVolumeCollection::load_wipe_tower_preview(
|
||||||
|
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width)
|
||||||
|
{
|
||||||
|
if (depth < 0.01f)
|
||||||
|
return int(this->volumes.size() - 1);
|
||||||
if (height == 0.0f)
|
if (height == 0.0f)
|
||||||
height = 0.1f;
|
height = 0.1f;
|
||||||
|
|
||||||
auto mesh = make_cube(width, depth, height);
|
|
||||||
mesh.translate(-width / 2.f, -depth / 2.f, 0.f);
|
|
||||||
Point origin_of_rotation(0.f, 0.f);
|
Point origin_of_rotation(0.f, 0.f);
|
||||||
mesh.rotate(rotation_angle,&origin_of_rotation);
|
TriangleMesh mesh;
|
||||||
|
float color[4] = { 0.5f, 0.5f, 0.0f, 1.f };
|
||||||
|
|
||||||
|
// In case we don't know precise dimensions of the wipe tower yet, we'll draw the box with different color with one side jagged:
|
||||||
|
if (size_unknown) {
|
||||||
|
color[0] = 0.9f;
|
||||||
|
color[1] = 0.6f;
|
||||||
|
|
||||||
|
depth = std::max(depth, 10.f); // Too narrow tower would interfere with the teeth. The estimate is not precise anyway.
|
||||||
|
float min_width = 30.f;
|
||||||
|
// We'll now create the box with jagged edge. y-coordinates of the pre-generated model are shifted so that the front
|
||||||
|
// edge has y=0 and centerline of the back edge has y=depth:
|
||||||
|
Pointf3s points;
|
||||||
|
std::vector<Point3> facets;
|
||||||
|
float out_points_idx[][3] = {{0, -depth, 0}, {0, 0, 0}, {38.453, 0, 0}, {61.547, 0, 0}, {100, 0, 0}, {100, -depth, 0}, {55.7735, -10, 0}, {44.2265, 10, 0},
|
||||||
|
{38.453, 0, 1}, {0, 0, 1}, {0, -depth, 1}, {100, -depth, 1}, {100, 0, 1}, {61.547, 0, 1}, {55.7735, -10, 1}, {44.2265, 10, 1}};
|
||||||
|
int out_facets_idx[][3] = {{0, 1, 2}, {3, 4, 5}, {6, 5, 0}, {3, 5, 6}, {6, 2, 7}, {6, 0, 2}, {8, 9, 10}, {11, 12, 13}, {10, 11, 14}, {14, 11, 13}, {15, 8, 14},
|
||||||
|
{8, 10, 14}, {3, 12, 4}, {3, 13, 12}, {6, 13, 3}, {6, 14, 13}, {7, 14, 6}, {7, 15, 14}, {2, 15, 7}, {2, 8, 15}, {1, 8, 2}, {1, 9, 8},
|
||||||
|
{0, 9, 1}, {0, 10, 9}, {5, 10, 0}, {5, 11, 10}, {4, 11, 5}, {4, 12, 11}};
|
||||||
|
for (int i=0;i<16;++i)
|
||||||
|
points.push_back(Pointf3(out_points_idx[i][0] / (100.f/min_width), out_points_idx[i][1] + depth, out_points_idx[i][2]));
|
||||||
|
for (int i=0;i<28;++i)
|
||||||
|
facets.push_back(Point3(out_facets_idx[i][0], out_facets_idx[i][1], out_facets_idx[i][2]));
|
||||||
|
TriangleMesh tooth_mesh(points, facets);
|
||||||
|
|
||||||
|
// We have the mesh ready. It has one tooth and width of min_width. We will now append several of these together until we are close to
|
||||||
|
// the required width of the block. Than we can scale it precisely.
|
||||||
|
size_t n = std::max(1, int(width/min_width)); // How many shall be merged?
|
||||||
|
for (size_t i=0;i<n;++i) {
|
||||||
|
mesh.merge(tooth_mesh);
|
||||||
|
tooth_mesh.translate(min_width, 0.f, 0.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.scale(Pointf3(width/(n*min_width), 1.f, height)); // Scaling to proper width
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mesh = make_cube(width, depth, height);
|
||||||
|
|
||||||
|
// We'll make another mesh to show the brim (fixed layer height):
|
||||||
|
TriangleMesh brim_mesh = make_cube(width+2.f*brim_width, depth+2.f*brim_width, 0.2f);
|
||||||
|
brim_mesh.translate(-brim_width, -brim_width, 0.f);
|
||||||
|
mesh.merge(brim_mesh);
|
||||||
|
|
||||||
|
mesh.rotate(rotation_angle, &origin_of_rotation); // rotates the box according to the config rotation setting
|
||||||
|
|
||||||
|
this->volumes.emplace_back(new GLVolume(color));
|
||||||
|
GLVolume &v = *this->volumes.back();
|
||||||
|
|
||||||
if (use_VBOs)
|
if (use_VBOs)
|
||||||
v.indexed_vertex_array.load_mesh_full_shading(mesh);
|
v.indexed_vertex_array.load_mesh_full_shading(mesh);
|
||||||
|
@ -401,7 +401,7 @@ public:
|
|||||||
bool use_VBOs);
|
bool use_VBOs);
|
||||||
|
|
||||||
int load_wipe_tower_preview(
|
int load_wipe_tower_preview(
|
||||||
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs);
|
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width);
|
||||||
|
|
||||||
// Render the volumes by OpenGL.
|
// Render the volumes by OpenGL.
|
||||||
void render_VBOs() const;
|
void render_VBOs() const;
|
||||||
|
@ -2314,7 +2314,12 @@ void GLCanvas3D::reload_scene(bool force)
|
|||||||
float w = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_width"))->value;
|
float w = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_width"))->value;
|
||||||
float a = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_rotation_angle"))->value;
|
float a = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_rotation_angle"))->value;
|
||||||
|
|
||||||
m_volumes.load_wipe_tower_preview(1000, x, y, w, 15.0f * (float)(extruders_count - 1), (float)height, a, m_use_VBOs && m_initialized);
|
float depth = m_print->get_wipe_tower_depth();
|
||||||
|
if (!m_print->state.is_done(psWipeTower))
|
||||||
|
depth = (900.f/w) * (float)(extruders_count - 1) ;
|
||||||
|
|
||||||
|
m_volumes.load_wipe_tower_preview(1000, x, y, w, depth, (float)height, a, m_use_VBOs && m_initialized, !m_print->state.is_done(psWipeTower),
|
||||||
|
m_print->config.nozzle_diameter.values[0] * 1.25f * 4.5f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4063,6 +4068,8 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_
|
|||||||
{
|
{
|
||||||
const Print *print;
|
const Print *print;
|
||||||
const std::vector<float> *tool_colors;
|
const std::vector<float> *tool_colors;
|
||||||
|
WipeTower::xy wipe_tower_pos;
|
||||||
|
float wipe_tower_angle;
|
||||||
|
|
||||||
// Number of vertices (each vertex is 6x4=24 bytes long)
|
// Number of vertices (each vertex is 6x4=24 bytes long)
|
||||||
static const size_t alloc_size_max() { return 131072; } // 3.15MB
|
static const size_t alloc_size_max() { return 131072; } // 3.15MB
|
||||||
@ -4095,6 +4102,9 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_
|
|||||||
if (m_print->m_wipe_tower_final_purge)
|
if (m_print->m_wipe_tower_final_purge)
|
||||||
ctxt.final.emplace_back(*m_print->m_wipe_tower_final_purge.get());
|
ctxt.final.emplace_back(*m_print->m_wipe_tower_final_purge.get());
|
||||||
|
|
||||||
|
ctxt.wipe_tower_angle = ctxt.print->config.wipe_tower_rotation_angle.value/180.f * M_PI;
|
||||||
|
ctxt.wipe_tower_pos = WipeTower::xy(ctxt.print->config.wipe_tower_x.value, ctxt.print->config.wipe_tower_y.value);
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start";
|
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start";
|
||||||
|
|
||||||
//FIXME Improve the heuristics for a grain size.
|
//FIXME Improve the heuristics for a grain size.
|
||||||
@ -4152,12 +4162,25 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_
|
|||||||
lines.reserve(n_lines);
|
lines.reserve(n_lines);
|
||||||
widths.reserve(n_lines);
|
widths.reserve(n_lines);
|
||||||
heights.assign(n_lines, extrusions.layer_height);
|
heights.assign(n_lines, extrusions.layer_height);
|
||||||
|
WipeTower::Extrusion e_prev = extrusions.extrusions[i-1];
|
||||||
|
|
||||||
|
if (!extrusions.priming) { // wipe tower extrusions describe the wipe tower at the origin with no rotation
|
||||||
|
e_prev.pos.rotate(ctxt.wipe_tower_angle);
|
||||||
|
e_prev.pos.translate(ctxt.wipe_tower_pos);
|
||||||
|
}
|
||||||
|
|
||||||
for (; i < j; ++i) {
|
for (; i < j; ++i) {
|
||||||
const WipeTower::Extrusion &e = extrusions.extrusions[i];
|
WipeTower::Extrusion e = extrusions.extrusions[i];
|
||||||
assert(e.width > 0.f);
|
assert(e.width > 0.f);
|
||||||
const WipeTower::Extrusion &e_prev = *(&e - 1);
|
if (!extrusions.priming) {
|
||||||
|
e.pos.rotate(ctxt.wipe_tower_angle);
|
||||||
|
e.pos.translate(ctxt.wipe_tower_pos);
|
||||||
|
}
|
||||||
|
|
||||||
lines.emplace_back(Point::new_scale(e_prev.pos.x, e_prev.pos.y), Point::new_scale(e.pos.x, e.pos.y));
|
lines.emplace_back(Point::new_scale(e_prev.pos.x, e_prev.pos.y), Point::new_scale(e.pos.x, e.pos.y));
|
||||||
widths.emplace_back(e.width);
|
widths.emplace_back(e.width);
|
||||||
|
|
||||||
|
e_prev = e;
|
||||||
}
|
}
|
||||||
_3DScene::thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z,
|
_3DScene::thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z,
|
||||||
*vols[ctxt.volume_idx(e.tool, 0)]);
|
*vols[ctxt.volume_idx(e.tool, 0)]);
|
||||||
@ -4716,8 +4739,11 @@ void GLCanvas3D::_load_shells()
|
|||||||
const PrintConfig& config = m_print->config;
|
const PrintConfig& config = m_print->config;
|
||||||
unsigned int extruders_count = config.nozzle_diameter.size();
|
unsigned int extruders_count = config.nozzle_diameter.size();
|
||||||
if ((extruders_count > 1) && config.single_extruder_multi_material && config.wipe_tower && !config.complete_objects) {
|
if ((extruders_count > 1) && config.single_extruder_multi_material && config.wipe_tower && !config.complete_objects) {
|
||||||
const float width_per_extruder = 15.0f; // a simple workaround after wipe_tower_per_color_wipe got obsolete
|
float depth = m_print->get_wipe_tower_depth();
|
||||||
m_volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, width_per_extruder * (extruders_count - 1), max_z, config.wipe_tower_rotation_angle, m_use_VBOs && m_initialized);
|
if (!m_print->state.is_done(psWipeTower))
|
||||||
|
depth = (900.f/config.wipe_tower_width) * (float)(extruders_count - 1) ;
|
||||||
|
m_volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
|
||||||
|
m_use_VBOs && m_initialized, !m_print->state.is_done(psWipeTower), m_print->config.nozzle_diameter.values[0] * 1.25f * 4.5f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,6 +903,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl
|
|||||||
std::vector<float> extruders = dlg.get_extruders();
|
std::vector<float> extruders = dlg.get_extruders();
|
||||||
(config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values = std::vector<double>(matrix.begin(),matrix.end());
|
(config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values = std::vector<double>(matrix.begin(),matrix.end());
|
||||||
(config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values = std::vector<double>(extruders.begin(),extruders.end());
|
(config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values = std::vector<double>(extruders.begin(),extruders.end());
|
||||||
|
g_on_request_update_callback.call();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
return sizer;
|
return sizer;
|
||||||
@ -919,6 +920,10 @@ ConfigOptionsGroup* get_optgroup()
|
|||||||
return m_optgroup.get();
|
return m_optgroup.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void register_on_request_update_callback(void* callback) {
|
||||||
|
if (callback != nullptr)
|
||||||
|
g_on_request_update_callback.register_callback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
wxButton* get_wiping_dialog_button()
|
wxButton* get_wiping_dialog_button()
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Config.hpp"
|
#include "Config.hpp"
|
||||||
|
#include "../../libslic3r/Utils.hpp"
|
||||||
|
|
||||||
#include <wx/intl.h>
|
#include <wx/intl.h>
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
@ -171,6 +172,9 @@ wxString from_u8(const std::string &str);
|
|||||||
|
|
||||||
void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer);
|
void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer);
|
||||||
|
|
||||||
|
static PerlCallback g_on_request_update_callback;
|
||||||
|
void register_on_request_update_callback(void* callback);
|
||||||
|
|
||||||
ConfigOptionsGroup* get_optgroup();
|
ConfigOptionsGroup* get_optgroup();
|
||||||
wxButton* get_wiping_dialog_button();
|
wxButton* get_wiping_dialog_button();
|
||||||
|
|
||||||
|
@ -104,3 +104,12 @@ void fix_model_by_win10_sdk_gui(ModelObject *model_object_src, Print *print, Mod
|
|||||||
|
|
||||||
void set_3DScene(SV *scene)
|
void set_3DScene(SV *scene)
|
||||||
%code%{ Slic3r::GUI::set_3DScene((_3DScene *)wxPli_sv_2_object(aTHX_ scene, "Slic3r::Model::3DScene") ); %};
|
%code%{ Slic3r::GUI::set_3DScene((_3DScene *)wxPli_sv_2_object(aTHX_ scene, "Slic3r::Model::3DScene") ); %};
|
||||||
|
|
||||||
|
%package{Slic3r::_GUI};
|
||||||
|
%{
|
||||||
|
void
|
||||||
|
register_on_request_update_callback(callback)
|
||||||
|
SV *callback;
|
||||||
|
CODE:
|
||||||
|
Slic3r::GUI::register_on_request_update_callback((void*)callback);
|
||||||
|
%}
|
||||||
|
@ -89,7 +89,7 @@
|
|||||||
|
|
||||||
std::vector<int> load_object(ModelObject *object, int obj_idx, std::vector<int> instance_idxs, std::string color_by, std::string select_by, std::string drag_by, bool use_VBOs);
|
std::vector<int> load_object(ModelObject *object, int obj_idx, std::vector<int> instance_idxs, std::string color_by, std::string select_by, std::string drag_by, bool use_VBOs);
|
||||||
|
|
||||||
int load_wipe_tower_preview(int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs);
|
int load_wipe_tower_preview(int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width);
|
||||||
|
|
||||||
void erase()
|
void erase()
|
||||||
%code{% THIS->clear(); %};
|
%code{% THIS->clear(); %};
|
||||||
|
Loading…
Reference in New Issue
Block a user