Skip to content

Commit

Permalink
Merge z-dither prusa3d#10391
Browse files Browse the repository at this point in the history
  • Loading branch information
vovodroid committed May 22, 2023
1 parent 0942cee commit b6c81fd
Show file tree
Hide file tree
Showing 16 changed files with 563 additions and 99 deletions.
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
12 changes: 7 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,12 @@ 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 +679,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 @@ -325,6 +325,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 @@ -392,6 +393,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 @@ -456,12 +459,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 @@ -549,6 +549,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 @@ -2464,6 +2464,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 @@ -3999,8 +4007,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))
((ConfigOptionInt, bridge_fan_speed_layers))
)
Expand Down

0 comments on commit b6c81fd

Please sign in to comment.