mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-23 22:54:26 +08:00
hole size compensation
slic3r/Slic3r#3323 prusa3d/Slic3r#1065 prusa3d/Slic3r#794 prusa3d/Slic3r#515
This commit is contained in:
parent
21f56f62a8
commit
dd20123d0f
@ -194,6 +194,7 @@ public:
|
||||
SlicingParameters slicing_parameters() const;
|
||||
|
||||
void _slice();
|
||||
void _offsetHoles(float hole_delta, LayerRegion *layerm);
|
||||
std::string _fix_slicing_errors();
|
||||
void _simplify_slices(double distance);
|
||||
void _prepare_infill();
|
||||
|
@ -2210,11 +2210,21 @@ PrintConfigDef::PrintConfigDef()
|
||||
def->category = L("Advanced");
|
||||
def->tooltip = L("The object will be grown/shrunk in the XY plane by the configured value "
|
||||
"(negative = inwards, positive = outwards). This might be useful "
|
||||
"for fine-tuning hole sizes.");
|
||||
"for fine-tuning sizes.");
|
||||
def->sidetext = L("mm");
|
||||
def->cli = "xy-size-compensation=f";
|
||||
def->default_value = new ConfigOptionFloat(0);
|
||||
|
||||
def = this->add("hole_size_compensation", coFloat);
|
||||
def->label = L("Holes");
|
||||
def->category = L("Advanced");
|
||||
def->tooltip = L("The convex holes will be grown in the XY plane by the configured value"
|
||||
" (negative = inwards, positive = outwards, should be positive as the holes are always a bit smaller)."
|
||||
" This might be useful for fine-tuning hole sizes.");
|
||||
def->sidetext = L("mm");
|
||||
def->cli = "hole-size-compensation=f";
|
||||
def->default_value = new ConfigOptionFloat(0);
|
||||
|
||||
def = this->add("z_offset", coFloat);
|
||||
def->label = L("Z offset");
|
||||
def->tooltip = L("This value will be added (or subtracted) from all the Z coordinates "
|
||||
|
@ -339,6 +339,7 @@ public:
|
||||
ConfigOptionBool support_material_with_sheath;
|
||||
ConfigOptionFloatOrPercent support_material_xy_spacing;
|
||||
ConfigOptionFloat xy_size_compensation;
|
||||
ConfigOptionFloat hole_size_compensation;
|
||||
ConfigOptionBool wipe_into_objects;
|
||||
|
||||
protected:
|
||||
@ -376,6 +377,7 @@ protected:
|
||||
OPT_PTR(support_material_threshold);
|
||||
OPT_PTR(support_material_with_sheath);
|
||||
OPT_PTR(xy_size_compensation);
|
||||
OPT_PTR(hole_size_compensation);
|
||||
OPT_PTR(wipe_into_objects);
|
||||
}
|
||||
};
|
||||
|
@ -169,7 +169,8 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|
||||
opt_key == "clip_multipart_objects"
|
||||
|| opt_key == "elefant_foot_compensation"
|
||||
|| opt_key == "support_material_contact_distance"
|
||||
|| opt_key == "xy_size_compensation") {
|
||||
|| opt_key == "xy_size_compensation"
|
||||
|| opt_key == "hole_size_compensation") {
|
||||
steps.emplace_back(posSlice);
|
||||
} else if (
|
||||
opt_key == "support_material"
|
||||
@ -1575,6 +1576,7 @@ end:
|
||||
Layer *layer = this->layers[layer_id];
|
||||
// Apply size compensation and perform clipping of multi-part objects.
|
||||
float delta = float(scale_(this->config.xy_size_compensation.value));
|
||||
float hole_delta = float(scale_(this->config.hole_size_compensation.value));
|
||||
if (layer_id == 0)
|
||||
delta -= float(scale_(this->config.elefant_foot_compensation.value));
|
||||
bool scale = delta != 0.f;
|
||||
@ -1585,7 +1587,8 @@ end:
|
||||
LayerRegion *layerm = layer->regions.front();
|
||||
layerm->slices.set(offset_ex(to_expolygons(std::move(layerm->slices.surfaces)), delta), stInternal);
|
||||
}
|
||||
} else if (scale || clip) {
|
||||
_offsetHoles(hole_delta, layer->regions.front());
|
||||
} else if (scale || clip || hole_delta != 0.f) {
|
||||
// Multiple regions, growing, shrinking or just clipping one region by the other.
|
||||
// When clipping the regions, priority is given to the first regions.
|
||||
Polygons processed;
|
||||
@ -1601,6 +1604,7 @@ end:
|
||||
// Collect the already processed regions to trim the to be processed regions.
|
||||
polygons_append(processed, slices);
|
||||
layerm->slices.set(std::move(slices), stInternal);
|
||||
_offsetHoles(hole_delta, layerm);
|
||||
}
|
||||
}
|
||||
// Merge all regions' slices to get islands, chain them by a shortest path.
|
||||
@ -1610,6 +1614,45 @@ end:
|
||||
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - end";
|
||||
}
|
||||
|
||||
void PrintObject::_offsetHoles(float hole_delta, LayerRegion *layerm) {
|
||||
if (hole_delta != 0.f) {
|
||||
ExPolygons& polys = to_expolygons(std::move(layerm->slices.surfaces));
|
||||
ExPolygons new_polys;
|
||||
for (ExPolygon ex_poly : polys) {
|
||||
ExPolygon new_ex_poly(ex_poly);
|
||||
new_ex_poly.holes.clear();
|
||||
for (Polygon hole : ex_poly.holes) {
|
||||
//check if convex to reduce it
|
||||
// check whether first point forms a convex angle
|
||||
bool ok = true;
|
||||
ok = (hole.points.front().ccw_angle(hole.points.back(), *(hole.points.begin() + 1)) <= PI + 0.001);
|
||||
|
||||
|
||||
// check whether points 1..(n-1) form convex angles
|
||||
if (ok)
|
||||
for (Points::const_iterator p = hole.points.begin() + 1; p != hole.points.end() - 1; ++p) {
|
||||
ok = (p->ccw_angle(*(p - 1), *(p + 1)) <= PI + 0.001);
|
||||
if (!ok) break;
|
||||
}
|
||||
|
||||
// check whether last point forms a convex angle
|
||||
ok &= (hole.points.back().ccw_angle(*(hole.points.end() - 2), hole.points.front()) <= PI + 0.001);
|
||||
|
||||
if (ok) {
|
||||
for (Polygon newHole : offset(hole, hole_delta)) {
|
||||
//reverse because it's a hole, not an object
|
||||
newHole.make_clockwise();
|
||||
new_ex_poly.holes.push_back(newHole);
|
||||
}
|
||||
} else
|
||||
new_ex_poly.holes.push_back(hole);
|
||||
}
|
||||
new_polys.push_back(new_ex_poly);
|
||||
}
|
||||
layerm->slices.set(std::move(new_polys), stInternal);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ExPolygons> PrintObject::_slice_region(size_t region_id, const std::vector<float> &z, bool modifier)
|
||||
{
|
||||
std::vector<ExPolygons> layers;
|
||||
|
@ -298,10 +298,11 @@ const std::vector<std::string>& Preset::print_options()
|
||||
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
|
||||
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio",
|
||||
"over_bridge_flow_ratio", "clip_multipart_objects", "enforce_full_fill_volume", "external_infill_margin", "bridged_infill_margin",
|
||||
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
|
||||
"wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", "only_one_perimeter_top", "compatible_printers",
|
||||
"compatible_printers_condition", "inherits", "infill_dense_layers", "infill_dense_density", "infill_dense_pattern",
|
||||
"infill_dense_angle", "no_perimeter_unsupported", "min_perimeter_unsupported", "noperi_bridge_only"
|
||||
"elefant_foot_compensation", "xy_size_compensation", "hole_size_compensation", "threads", "resolution",
|
||||
"wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging",
|
||||
"only_one_perimeter_top", "compatible_printers", "compatible_printers_condition", "inherits",
|
||||
"infill_dense_layers", "infill_dense_density", "infill_dense_pattern", "infill_dense_angle",
|
||||
"no_perimeter_unsupported", "min_perimeter_unsupported", "noperi_bridge_only"
|
||||
};
|
||||
return s_opts;
|
||||
}
|
||||
|
@ -963,6 +963,7 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("clip_multipart_objects");
|
||||
optgroup->append_single_option_line("elefant_foot_compensation");
|
||||
optgroup->append_single_option_line("xy_size_compensation");
|
||||
optgroup->append_single_option_line("hole_size_compensation");
|
||||
// # optgroup->append_single_option_line("threads");
|
||||
optgroup->append_single_option_line("resolution");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user