Skip to content

Commit

Permalink
Fix of
Browse files Browse the repository at this point in the history
"Multimaterial printer switches filament at the wrong time during a print"
#607

There was a single layer between the raft top and the object first layer
missing on the wipe tower, and after this missing layer all the tool
changes were shifted by one layer, meaning two color print had the colors
switched.
  • Loading branch information
bubnikv committed Dec 11, 2017
1 parent 1938828 commit 61e6f23
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 43 deletions.
28 changes: 22 additions & 6 deletions xs/src/libslic3r/GCode/ToolOrdering.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
#include "Print.hpp"
#include "ToolOrdering.hpp"

#include <assert.h>
// #define SLIC3R_DEBUG

// Make assert active if SLIC3R_DEBUG
#ifdef SLIC3R_DEBUG
#define DEBUG
#define _DEBUG
#undef NDEBUG
#endif

#include <cassert>
#include <limits>

namespace Slic3r {
Expand Down Expand Up @@ -257,11 +266,18 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_
LayerTools lt_new(0.5f * (lt.print_z + lt_object.print_z));
// Find the 1st layer above lt_new.
for (j = i + 1; j < m_layer_tools.size() && m_layer_tools[j].print_z < lt_new.print_z; ++ j);
LayerTools &lt_extra = (m_layer_tools[j].print_z == lt_new.print_z) ?
m_layer_tools[j] :
*m_layer_tools.insert(m_layer_tools.begin() + j, lt_new);
lt_extra.has_wipe_tower = true;
lt_extra.wipe_tower_partitions = lt_object.wipe_tower_partitions;
if (m_layer_tools[j].print_z == lt_new.print_z) {
m_layer_tools[j].has_wipe_tower = true;
} else {
LayerTools &lt_extra = *m_layer_tools.insert(m_layer_tools.begin() + j, lt_new);
LayerTools &lt_prev = m_layer_tools[j - 1];
LayerTools &lt_next = m_layer_tools[j + 1];
assert(! lt_prev.extruders.empty() && ! lt_next.extruders.empty());
assert(lt_prev.extruders.back() == lt_next.extruders.front());
lt_extra.has_wipe_tower = true;
lt_extra.extruders.push_back(lt_next.extruders.front());
lt_extra.wipe_tower_partitions = lt_next.wipe_tower_partitions;
}
}
}
break;
Expand Down
2 changes: 2 additions & 0 deletions xs/src/libslic3r/GCode/ToolOrdering.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class ToolOrdering

const LayerTools& front() const { return m_layer_tools.front(); }
const LayerTools& back() const { return m_layer_tools.back(); }
std::vector<LayerTools>::const_iterator begin() const { return m_layer_tools.begin(); }
std::vector<LayerTools>::const_iterator end() const { return m_layer_tools.end(); }
bool empty() const { return m_layer_tools.empty(); }
const std::vector<LayerTools>& layer_tools() const { return m_layer_tools; }
bool has_wipe_tower() const { return ! m_layer_tools.empty() && m_first_printing_extruder != (unsigned int)-1 && m_layer_tools.front().wipe_tower_partitions > 0; }
Expand Down
4 changes: 3 additions & 1 deletion xs/src/libslic3r/Layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ class SupportLayer : public Layer {
// Is there any valid extrusion assigned to this LayerRegion?
virtual bool has_extrusions() const { return ! support_fills.empty(); }

protected:
//protected:
// The constructor has been made public to be able to insert additional support layers for the skirt or a wipe tower
// between the raft and the object first layer.
SupportLayer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z) :
Layer(id, object, height, print_z, slice_z) {}
virtual ~SupportLayer() {}
Expand Down
37 changes: 37 additions & 0 deletions xs/src/libslic3r/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,43 @@ void Print::_make_wipe_tower()
// Don't generate any wipe tower.
return;

// Check whether there are any layers in m_tool_ordering, which are marked with has_wipe_tower,
// they print neither object, nor support. These layers are above the raft and below the object, and they
// shall be added to the support layers to be printed.
// see https://github.com/prusa3d/Slic3r/issues/607
{
size_t idx_begin = size_t(-1);
size_t idx_end = m_tool_ordering.layer_tools().size();
// Find the first wipe tower layer, which does not have a counterpart in an object or a support layer.
for (size_t i = 0; i < idx_end; ++ i) {
const ToolOrdering::LayerTools &lt = m_tool_ordering.layer_tools()[i];
if (lt.has_wipe_tower && ! lt.has_object && ! lt.has_support) {
idx_begin = i;
break;
}
}
if (idx_begin != size_t(-1)) {
// Find the position in this->objects.first()->support_layers to insert these new support layers.
double wipe_tower_new_layer_print_z_first = m_tool_ordering.layer_tools()[idx_begin].print_z;
SupportLayerPtrs::iterator it_layer = this->objects.front()->support_layers.begin();
for (; (*it_layer)->print_z - EPSILON < wipe_tower_new_layer_print_z_first; ++ it_layer) ;
// Find the stopper of the sequence of wipe tower layers, which do not have a counterpart in an object or a support layer.
for (size_t i = idx_begin; i < idx_end; ++ i) {
ToolOrdering::LayerTools &lt = const_cast<ToolOrdering::LayerTools&>(m_tool_ordering.layer_tools()[i]);
if (! (lt.has_wipe_tower && ! lt.has_object && ! lt.has_support))
break;
lt.has_support = true;
// Insert the new support layer.
//FIXME the support layer ID is duplicated, but Vojtech hopes it is not being used anywhere anyway.
double height = lt.print_z - m_tool_ordering.layer_tools()[i-1].print_z;
auto *new_layer = new SupportLayer((*it_layer)->id(), this->objects.front(),
height, lt.print_z, lt.print_z - 0.5 * height);
it_layer = this->objects.front()->support_layers.insert(it_layer, new_layer);
++ it_layer;
}
}
}

// Initialize the wipe tower.
WipeTowerPrusaMM wipe_tower(
float(this->config.wipe_tower_x.value), float(this->config.wipe_tower_y.value),
Expand Down
12 changes: 3 additions & 9 deletions xs/src/libslic3r/SupportMaterial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,15 +373,9 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
height_min = std::min(height_min, layer.height);
}
if (! empty) {
object.add_support_layer(layer_id, height_min, zavg);
if (layer_id > 0) {
// Inter-link the support layers into a linked list.
SupportLayer *sl1 = object.support_layers[object.support_layer_count() - 2];
SupportLayer *sl2 = object.support_layers.back();
sl1->upper_layer = sl2;
sl2->lower_layer = sl1;
}
++layer_id;
// Here the upper_layer and lower_layer pointers are left to null at the support layers,
// as they are never used. These pointers are candidates for removal.
object.add_support_layer(layer_id ++, height_min, zavg);
}
i = j;
}
Expand Down
26 changes: 0 additions & 26 deletions xs/xsp/Layer.xsp
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@
int id();
void set_id(int id);
Ref<PrintObject> object();
Ref<Layer> upper_layer()
%code%{ RETVAL = THIS->upper_layer; %};
Ref<Layer> lower_layer()
%code%{ RETVAL = THIS->lower_layer; %};
bool slicing_errors()
%code%{ RETVAL = THIS->slicing_errors; %};
coordf_t slice_z()
Expand All @@ -63,15 +59,6 @@
coordf_t height()
%code%{ RETVAL = THIS->height; %};

void set_upper_layer(Layer *layer)
%code%{ THIS->upper_layer = layer; %};
void set_lower_layer(Layer *layer)
%code%{ THIS->lower_layer = layer; %};
bool has_upper_layer()
%code%{ RETVAL = (THIS->upper_layer != NULL); %};
bool has_lower_layer()
%code%{ RETVAL = (THIS->lower_layer != NULL); %};

size_t region_count();
Ref<LayerRegion> get_region(int idx);
Ref<LayerRegion> add_region(PrintRegion* print_region);
Expand Down Expand Up @@ -112,10 +99,6 @@
int id();
void set_id(int id);
Ref<PrintObject> object();
Ref<SupportLayer> upper_layer()
%code%{ RETVAL = (SupportLayer*)THIS->upper_layer; %};
Ref<SupportLayer> lower_layer()
%code%{ RETVAL = (SupportLayer*)THIS->lower_layer; %};
bool slicing_errors()
%code%{ RETVAL = THIS->slicing_errors; %};
coordf_t slice_z()
Expand All @@ -125,15 +108,6 @@
coordf_t height()
%code%{ RETVAL = THIS->height; %};

void set_upper_layer(SupportLayer *layer)
%code%{ THIS->upper_layer = layer; %};
void set_lower_layer(SupportLayer *layer)
%code%{ THIS->lower_layer = layer; %};
bool has_upper_layer()
%code%{ RETVAL = (THIS->upper_layer != NULL); %};
bool has_lower_layer()
%code%{ RETVAL = (THIS->lower_layer != NULL); %};

size_t region_count();
Ref<LayerRegion> get_region(int idx);
Ref<LayerRegion> add_region(PrintRegion* print_region);
Expand Down
1 change: 0 additions & 1 deletion xs/xsp/Print.xsp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ _constant()
size_t support_layer_count();
void clear_support_layers();
Ref<SupportLayer> get_support_layer(int idx);
Ref<SupportLayer> add_support_layer(int id, coordf_t height, coordf_t print_z);

bool step_done(PrintObjectStep step)
%code%{ RETVAL = THIS->state.is_done(step); %};
Expand Down

0 comments on commit 61e6f23

Please sign in to comment.