diff --git a/xs/src/libslic3r/GCode/ToolOrdering.cpp b/xs/src/libslic3r/GCode/ToolOrdering.cpp index 0ffdbcc434..a8954eca51 100644 --- a/xs/src/libslic3r/GCode/ToolOrdering.cpp +++ b/xs/src/libslic3r/GCode/ToolOrdering.cpp @@ -1,7 +1,16 @@ #include "Print.hpp" #include "ToolOrdering.hpp" -#include +// #define SLIC3R_DEBUG + +// Make assert active if SLIC3R_DEBUG +#ifdef SLIC3R_DEBUG + #define DEBUG + #define _DEBUG + #undef NDEBUG +#endif + +#include #include namespace Slic3r { @@ -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 <_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 <_extra = *m_layer_tools.insert(m_layer_tools.begin() + j, lt_new); + LayerTools <_prev = m_layer_tools[j - 1]; + LayerTools <_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; diff --git a/xs/src/libslic3r/GCode/ToolOrdering.hpp b/xs/src/libslic3r/GCode/ToolOrdering.hpp index abf1aa6b20..c92806b19b 100644 --- a/xs/src/libslic3r/GCode/ToolOrdering.hpp +++ b/xs/src/libslic3r/GCode/ToolOrdering.hpp @@ -69,6 +69,8 @@ public: const LayerTools& front() const { return m_layer_tools.front(); } const LayerTools& back() const { return m_layer_tools.back(); } + std::vector::const_iterator begin() const { return m_layer_tools.begin(); } + std::vector::const_iterator end() const { return m_layer_tools.end(); } bool empty() const { return m_layer_tools.empty(); } const std::vector& 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; } diff --git a/xs/src/libslic3r/Layer.hpp b/xs/src/libslic3r/Layer.hpp index f8fdcdd4d2..f3b4604430 100644 --- a/xs/src/libslic3r/Layer.hpp +++ b/xs/src/libslic3r/Layer.hpp @@ -161,7 +161,9 @@ public: // 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() {} diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index 190fbfe6ed..7739983944 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -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 < = 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 < = const_cast(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), diff --git a/xs/src/libslic3r/SupportMaterial.cpp b/xs/src/libslic3r/SupportMaterial.cpp index 07943fb15a..b8df67ba6b 100644 --- a/xs/src/libslic3r/SupportMaterial.cpp +++ b/xs/src/libslic3r/SupportMaterial.cpp @@ -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; } diff --git a/xs/xsp/Layer.xsp b/xs/xsp/Layer.xsp index 71fc540dc2..4f09fb5214 100644 --- a/xs/xsp/Layer.xsp +++ b/xs/xsp/Layer.xsp @@ -50,10 +50,6 @@ int id(); void set_id(int id); Ref object(); - Ref upper_layer() - %code%{ RETVAL = THIS->upper_layer; %}; - Ref lower_layer() - %code%{ RETVAL = THIS->lower_layer; %}; bool slicing_errors() %code%{ RETVAL = THIS->slicing_errors; %}; coordf_t slice_z() @@ -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 get_region(int idx); Ref add_region(PrintRegion* print_region); @@ -112,10 +99,6 @@ int id(); void set_id(int id); Ref object(); - Ref upper_layer() - %code%{ RETVAL = (SupportLayer*)THIS->upper_layer; %}; - Ref lower_layer() - %code%{ RETVAL = (SupportLayer*)THIS->lower_layer; %}; bool slicing_errors() %code%{ RETVAL = THIS->slicing_errors; %}; coordf_t slice_z() @@ -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 get_region(int idx); Ref add_region(PrintRegion* print_region); diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index 1148fd4aa6..2e418253b0 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -91,7 +91,6 @@ _constant() size_t support_layer_count(); void clear_support_layers(); Ref get_support_layer(int idx); - Ref add_support_layer(int id, coordf_t height, coordf_t print_z); bool step_done(PrintObjectStep step) %code%{ RETVAL = THIS->state.is_done(step); %};