Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new z-dither branch which implements feature described in issue #9388 #10391

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/libslic3r/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,8 @@ set(SLIC3R_SOURCES
TriangleSelectorWrapper.cpp
TriangleSelectorWrapper.hpp
MTUtils.hpp
ZDither.hpp
ZDither.cpp
Zipper.hpp
Zipper.cpp
MinAreaBoundingBox.hpp
Expand Down
14 changes: 9 additions & 5 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,7 @@ std::vector<std::pair<coordf_t, GCode::ObjectsLayerToPrint>> GCode::collect_laye
coordf_t print_z;
size_t object_idx;
size_t layer_idx;
coordf_t layer_height;
};

std::vector<ObjectsLayerToPrint> per_object(print.objects().size(), ObjectsLayerToPrint());
Expand All @@ -664,11 +665,14 @@ std::vector<std::pair<coordf_t, GCode::ObjectsLayerToPrint>> GCode::collect_laye
for (const ObjectLayerToPrint &ltp : per_object[i]) {
ordering_item.print_z = ltp.print_z();
ordering_item.layer_idx = &ltp - &front;
ordering_item.layer_height = ltp.layer()->height;
ordering.emplace_back(ordering_item);
}
}

std::sort(ordering.begin(), ordering.end(), [](const OrderingItem& oi1, const OrderingItem& oi2) { return oi1.print_z < oi2.print_z; });
std::sort(ordering.begin(), ordering.end(), [](const OrderingItem &oi1, const OrderingItem &oi2) {
return fabs(oi1.print_z - oi2.print_z) > EPSILON ? oi1.print_z < oi2.print_z : oi1.layer_height < oi2.layer_height;
});

std::vector<std::pair<coordf_t, ObjectsLayerToPrint>> layers_to_print;

Expand All @@ -677,16 +681,16 @@ std::vector<std::pair<coordf_t, GCode::ObjectsLayerToPrint>> GCode::collect_laye
// Find the last layer with roughly the same print_z.
size_t j = i + 1;
coordf_t zmax = ordering[i].print_z + EPSILON;
for (; j < ordering.size() && ordering[j].print_z <= zmax; ++j);
coordf_t hmax = ordering[i].layer_height + EPSILON; // z-dithering may make layers of different height but same print_z
for (; j < ordering.size() && ordering[j].print_z <= zmax && ordering[j].layer_height < hmax; ++j);
// Merge into layers_to_print.
std::pair<coordf_t, ObjectsLayerToPrint> merged;
// Assign an average print_z to the set of layers with nearly equal print_z.
merged.first = 0.5 * (ordering[i].print_z + ordering[j - 1].print_z);
merged.second.assign(print.objects().size(), ObjectLayerToPrint());
// z-dithering may result in 2 layers from the same object in merged
for (; i < j; ++i) {
const OrderingItem& oi = ordering[i];
assert(merged.second[oi.object_idx].layer() == nullptr);
merged.second[oi.object_idx] = std::move(per_object[oi.object_idx][oi.layer_idx]);
merged.second.emplace_back(std::move(per_object[oi.object_idx][oi.layer_idx]));
}
layers_to_print.emplace_back(std::move(merged));
}
Expand Down
8 changes: 6 additions & 2 deletions src/libslic3r/Layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ class Layer
coordf_t print_z; // Z used for printing in unscaled coordinates
coordf_t height; // layer height in unscaled coordinates
coordf_t bottom_z() const { return this->print_z - this->height; }
bool dithered = false; // is this is a layer produced by z-dithering.

//Extrusions estimated to be seriously malformed, estimated during "Estimating curled extrusions" step. These lines should be avoided during fast travels.
CurledLines curled_lines;
Expand Down Expand Up @@ -391,6 +392,8 @@ class Layer
friend class PrintObject;
friend std::vector<Layer*> new_layers(PrintObject*, const std::vector<coordf_t>&);
friend std::string fix_slicing_errors(LayerPtrs&, const std::function<void()>&);
// Create dithering layer. bottom & top >= 0 and <= 1
friend Layer *make_dithered_layer(Layer *refLayer, double bottom, double top);

Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z) :
upper_layer(nullptr), lower_layer(nullptr),
Expand Down Expand Up @@ -455,12 +458,13 @@ class SupportLayer : public Layer
};

template<typename LayerContainer>
inline std::vector<float> zs_from_layers(const LayerContainer &layers)
inline std::vector<float> zs_from_layers(const LayerContainer &layers, bool exclude_dithered = true)
{
std::vector<float> zs;
zs.reserve(layers.size());
for (const Layer *l : layers)
zs.emplace_back((float)l->slice_z);
if (!(l->dithered && exclude_dithered))
zs.emplace_back((float) l->slice_z);
return zs;
}

Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Preset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ static std::vector<std::string> s_Preset_print_options {
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "gcode_resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
"wipe_tower_width", "wipe_tower_cone_angle", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
"wipe_tower_no_sparse_layers", "wipe_tower_extra_spacing", "compatible_printers", "compatible_printers_condition", "inherits",
"perimeter_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
"perimeter_generator", "z_dither", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
"wall_distribution_count", "min_feature_size", "min_bead_width"
};

Expand Down
7 changes: 7 additions & 0 deletions src/libslic3r/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,13 @@ std::string Print::validate(std::string* warning) const
return _u8L("Variable layer height is not supported with Organic supports.");
}

if (m_default_object_config.z_dither) {
if (m_default_region_config.infill_every_layers > 1)
return _u8L("Z-dither slicing option is not compatible with option to combine infills of multiple layers.");
if (extruders.size() > 1) // Is there a better way to check for a possibility of multimaterial printing?
return _u8L("Z-dither slicing option is currently not supported for printers with multiple extruders.");
}

if (this->has_wipe_tower() && ! m_objects.empty()) {
// Make sure all extruders use same diameter filament and have the same nozzle diameter
// EPSILON comparison is used for nozzles and 10 % tolerance is used for filaments
Expand Down
2 changes: 2 additions & 0 deletions src/libslic3r/Print.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ class PrintObject : public PrintObjectBaseWithState<Print, PrintObjectStep, posC

void slice_volumes();
// Has any support (not counting the raft).
// find the next layer below or above idx; In case of z-dithering it may be different from incrementing/decrementing idx
int next_layer_index(size_t idx, bool lower) const; // returns int to allow -1
void detect_surfaces_type();
void process_external_surfaces();
void discover_vertical_shells();
Expand Down
10 changes: 8 additions & 2 deletions src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2377,6 +2377,14 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionInt(1));

def = this->add("z_dither", coBool);
def->label = L("Z-dither");
def->category = L("Layers and Perimeters");
def->tooltip = L("This experimental setting is used to halve stairstep effect on low slope surfaces. "
"Near slice periphery it introduces additional layers that are 25% and 50% of nominal layer height.");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));

def = this->add("slowdown_below_layer_time", coInts);
def->label = L("Slow down if layer print time is below");
def->tooltip = L("If layer print time is estimated below this number of seconds, print moves "
Expand Down Expand Up @@ -3881,8 +3889,6 @@ void PrintConfigDef::init_sla_params()
def->multiline = true;
def->full_width = true;
def->height = 13;
// TODO currently notes are the only way to pass data
// for non-PrusaResearch printers. We therefore need to always show them
def->mode = comSimple;
def->set_default_value(new ConfigOptionString(""));

Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/PrintConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ PRINT_CONFIG_CLASS_DEFINE(
// The rest
((ConfigOptionBool, thick_bridges))
((ConfigOptionFloat, xy_size_compensation))
((ConfigOptionBool, z_dither))
((ConfigOptionBool, wipe_into_objects))
)

Expand Down