mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-30 22:32:02 +08:00
Fix phantom solid surfaces.
move solid_over_perimeters (as it only works with ensure_vertical_shell_thickness activated) TODO: maybe try to not create too thin solid surfaces in the first place? and really merge same surfaces?
This commit is contained in:
parent
994997ab90
commit
878ea577c7
@ -14,7 +14,6 @@ group:Horizontal shells
|
||||
setting:bottom_solid_min_thickness
|
||||
end_line
|
||||
top_bottom_shell_thickness_explanation
|
||||
setting:solid_over_perimeters
|
||||
setting:enforce_full_fill_volume
|
||||
group:Quality
|
||||
line:Only one perimeter
|
||||
@ -26,7 +25,10 @@ group:Quality
|
||||
setting:label_width$8:extra_perimeters_overhangs
|
||||
setting:label_width$10:extra_perimeters_odd_layers
|
||||
end_line
|
||||
setting:ensure_vertical_shell_thickness
|
||||
line:Ensure vertical shell thickness
|
||||
setting:label$_:ensure_vertical_shell_thickness
|
||||
setting:solid_over_perimeters
|
||||
end_line
|
||||
line:Avoid crossing perimeters
|
||||
setting:label$_:avoid_crossing_perimeters
|
||||
setting:label_width$12:label$Not on first layer:avoid_crossing_not_first_layer
|
||||
|
@ -252,6 +252,7 @@ private:
|
||||
void clip_fill_surfaces();
|
||||
void tag_under_bridge();
|
||||
void discover_horizontal_shells();
|
||||
void clean_surfaces();
|
||||
void combine_infill();
|
||||
void _generate_support_material();
|
||||
std::pair<FillAdaptive::OctreePtr, FillAdaptive::OctreePtr> prepare_adaptive_infill_data();
|
||||
|
@ -763,7 +763,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->category = OptionCategory::perimeter;
|
||||
def->tooltip = L("Add solid infill near sloping surfaces to guarantee the vertical shell thickness "
|
||||
"(top+bottom solid layers)."
|
||||
"\n!! solid_over_perimeters may erase these surfaces !! So you should deactivate it if you want to use this.");
|
||||
"\n!! solid_over_perimeters may erase these surfaces !!");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
@ -4022,7 +4022,7 @@ void PrintConfigDef::init_fff_params()
|
||||
" the top/bottom solid layer count, it won't do anything. If this setting is set to 1, it will evict "
|
||||
" all solid fill above/below perimeters. "
|
||||
"\nSet zero to disable."
|
||||
"\n!! ensure_vertical_shell_thickness may be erased by this setting !!.");
|
||||
"\n!! ensure_vertical_shell_thickness needs to be activated so this algorithm can work !!.");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInt(2));
|
||||
|
@ -490,10 +490,12 @@ namespace Slic3r {
|
||||
// to close these surfaces reliably.
|
||||
//FIXME Vojtech: Is this a good place to add supporting infills below sloping perimeters?
|
||||
//note: only if not "ensure vertical shell"
|
||||
//TODO merill: as "ensure_vertical_shell_thickness" is innefective, this should be simplified / streamlined / deleted?
|
||||
this->discover_horizontal_shells();
|
||||
m_print->throw_if_canceled();
|
||||
|
||||
//as there is some too thin solid surface, please deleted them and merge all of the surfacesthat are contigous.
|
||||
this->clean_surfaces();
|
||||
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++region_id) {
|
||||
for (const Layer* layer : m_layers) {
|
||||
@ -3748,6 +3750,65 @@ static void fix_mesh_connectivity(TriangleMesh &mesh)
|
||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||
}
|
||||
|
||||
void merge_surfaces(LayerRegion* lregion) {
|
||||
//merge regions with same type (other things are all the same anyway)
|
||||
std::map< SurfaceType, std::vector< Surface*>> type2srfs;
|
||||
for (Surface& surface : lregion->fill_surfaces.surfaces) {
|
||||
type2srfs[surface.surface_type].push_back(&surface);
|
||||
}
|
||||
bool changed = false;
|
||||
std::map< SurfaceType, ExPolygons> type2newpolys;
|
||||
for (auto& entry : type2srfs) {
|
||||
if (entry.second.size() > 2) {
|
||||
ExPolygons merged = union_ex(to_expolygons(entry.second), true);
|
||||
if (merged.size() < entry.second.size()) {
|
||||
changed = true;
|
||||
type2newpolys[entry.first] = std::move(merged);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
Surfaces newSrfs;
|
||||
for (auto& entry : type2srfs) {
|
||||
if (type2newpolys.find(entry.first) == type2newpolys.end()) {
|
||||
for (Surface* srfPtr : entry.second) {
|
||||
newSrfs.emplace_back(*srfPtr);
|
||||
}
|
||||
} else {
|
||||
for (ExPolygon& expoly : type2newpolys[entry.first]) {
|
||||
newSrfs.emplace_back(*entry.second.front(), expoly);
|
||||
}
|
||||
}
|
||||
}
|
||||
lregion->fill_surfaces.surfaces = std::move(newSrfs);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintObject::clean_surfaces() {
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, this->layers().size() - 1),
|
||||
[this](const tbb::blocked_range<size_t>& range) {
|
||||
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++idx_layer) {
|
||||
for (LayerRegion* lregion : this->layers()[idx_layer]->regions()) {
|
||||
coord_t extrusion_width = lregion->flow(frInfill).scaled_width();
|
||||
merge_surfaces(lregion);
|
||||
// collapse too thin solid surfaces.
|
||||
bool changed_type = false;
|
||||
for (Surface& surface : lregion->fill_surfaces.surfaces) {
|
||||
if (surface.has_fill_solid() && surface.has_pos_internal()) {
|
||||
if (offset2_ex(surface.expolygon, -extrusion_width / 2, extrusion_width / 2).empty()) {
|
||||
//convert to sparse
|
||||
surface.surface_type = (surface.surface_type ^ SurfaceType::stDensSolid) | SurfaceType::stDensSparse;
|
||||
changed_type = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
merge_surfaces(lregion);
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
// combine fill surfaces across layers to honor the "infill every N layers" option
|
||||
// Idempotence of this method is guaranteed by the fact that we don't remove things from
|
||||
// fill_surfaces but we only turn them into VOID surfaces, thus preserving the boundaries.
|
||||
|
@ -35,7 +35,10 @@ inline SurfaceType operator|(SurfaceType a, SurfaceType b) {
|
||||
return static_cast<SurfaceType>(static_cast<uint16_t>(a) | static_cast<uint16_t>(b));
|
||||
}
|
||||
inline SurfaceType operator&(SurfaceType a, SurfaceType b) {
|
||||
return static_cast<SurfaceType>(static_cast<uint16_t>(a)& static_cast<uint16_t>(b));
|
||||
return static_cast<SurfaceType>(static_cast<uint16_t>(a) & static_cast<uint16_t>(b));
|
||||
}
|
||||
inline SurfaceType operator^(SurfaceType a, SurfaceType b) {
|
||||
return static_cast<SurfaceType>(static_cast<uint16_t>(a) ^ static_cast<uint16_t>(b));
|
||||
}
|
||||
inline SurfaceType operator|=(SurfaceType& a, SurfaceType b) {
|
||||
a = a | b; return a;
|
||||
|
Loading…
x
Reference in New Issue
Block a user