mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-15 00:45:57 +08:00
Organic supports: Adding bridge detection using the same algorithms
as the regular supports. Partial fix to #9493
This commit is contained in:
parent
957572fb8a
commit
f1977b07be
@ -361,6 +361,8 @@ inline Slic3r::Polygons expand(const Slic3r::Polygon &polygon, const float del
|
|||||||
{ assert(delta > 0); return offset(polygon, delta, joinType, miterLimit); }
|
{ assert(delta > 0); return offset(polygon, delta, joinType, miterLimit); }
|
||||||
inline Slic3r::Polygons expand(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit)
|
inline Slic3r::Polygons expand(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit)
|
||||||
{ assert(delta > 0); return offset(polygons, delta, joinType, miterLimit); }
|
{ assert(delta > 0); return offset(polygons, delta, joinType, miterLimit); }
|
||||||
|
inline Slic3r::Polygons expand(const Slic3r::ExPolygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit)
|
||||||
|
{ assert(delta > 0); return offset(polygons, delta, joinType, miterLimit); }
|
||||||
inline Slic3r::ExPolygons expand_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit)
|
inline Slic3r::ExPolygons expand_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit)
|
||||||
{ assert(delta > 0); return offset_ex(polygons, delta, joinType, miterLimit); }
|
{ assert(delta > 0); return offset_ex(polygons, delta, joinType, miterLimit); }
|
||||||
// Input polygons for shrinking shall be "normalized": There must be no overlap / intersections between the input polygons.
|
// Input polygons for shrinking shall be "normalized": There must be no overlap / intersections between the input polygons.
|
||||||
|
@ -1260,20 +1260,20 @@ namespace SupportMaterialInternal {
|
|||||||
collect_bridging_perimeter_areas(*static_cast<const ExtrusionLoop*>(ee), expansion_scaled, out);
|
collect_bridging_perimeter_areas(*static_cast<const ExtrusionLoop*>(ee), expansion_scaled, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void remove_bridges_from_contacts(
|
void remove_bridges_from_contacts(
|
||||||
const PrintConfig &print_config,
|
const PrintConfig &print_config,
|
||||||
const Layer &lower_layer,
|
const Layer &lower_layer,
|
||||||
const Polygons &lower_layer_polygons,
|
|
||||||
const LayerRegion &layerm,
|
const LayerRegion &layerm,
|
||||||
float fw,
|
float fw,
|
||||||
Polygons &contact_polygons)
|
Polygons &contact_polygons)
|
||||||
{
|
{
|
||||||
// compute the area of bridging perimeters
|
// compute the area of bridging perimeters
|
||||||
Polygons bridges;
|
Polygons bridges;
|
||||||
{
|
{
|
||||||
// Surface supporting this layer, expanded by 0.5 * nozzle_diameter, as we consider this kind of overhang to be sufficiently supported.
|
// Surface supporting this layer, expanded by 0.5 * nozzle_diameter, as we consider this kind of overhang to be sufficiently supported.
|
||||||
Polygons lower_grown_slices = expand(lower_layer_polygons,
|
Polygons lower_grown_slices = expand(lower_layer.lslices,
|
||||||
//FIXME to mimic the decision in the perimeter generator, we should use half the external perimeter width.
|
//FIXME to mimic the decision in the perimeter generator, we should use half the external perimeter width.
|
||||||
0.5f * float(scale_(print_config.nozzle_diameter.get_at(layerm.region().config().perimeter_extruder-1))),
|
0.5f * float(scale_(print_config.nozzle_diameter.get_at(layerm.region().config().perimeter_extruder-1))),
|
||||||
SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
||||||
@ -1340,7 +1340,6 @@ namespace SupportMaterialInternal {
|
|||||||
{ { union_ex(contact_polygons) }, { "contact_polygons", "blue", 0.5f } },
|
{ { union_ex(contact_polygons) }, { "contact_polygons", "blue", 0.5f } },
|
||||||
{ { union_ex(bridges) }, { "bridges", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
|
{ { union_ex(bridges) }, { "bridges", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
|
||||||
#endif /* SLIC3R_DEBUG */
|
#endif /* SLIC3R_DEBUG */
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Polygons> PrintObjectSupportMaterial::buildplate_covered(const PrintObject &object) const
|
std::vector<Polygons> PrintObjectSupportMaterial::buildplate_covered(const PrintObject &object) const
|
||||||
@ -1558,8 +1557,7 @@ static inline std::tuple<Polygons, Polygons, Polygons, float> detect_overhangs(
|
|||||||
|
|
||||||
if (object_config.dont_support_bridges)
|
if (object_config.dont_support_bridges)
|
||||||
//FIXME Expensive, potentially not precise enough. Misses gap fill extrusions, which bridge.
|
//FIXME Expensive, potentially not precise enough. Misses gap fill extrusions, which bridge.
|
||||||
SupportMaterialInternal::remove_bridges_from_contacts(
|
remove_bridges_from_contacts(print_config, lower_layer, *layerm, fw, diff_polygons);
|
||||||
print_config, lower_layer, lower_layer_polygons, *layerm, fw, diff_polygons);
|
|
||||||
|
|
||||||
if (diff_polygons.empty())
|
if (diff_polygons.empty())
|
||||||
continue;
|
continue;
|
||||||
|
@ -147,6 +147,15 @@ struct SupportParameters {
|
|||||||
bool with_sheath;
|
bool with_sheath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Remove bridges from support contact areas.
|
||||||
|
// To be called if PrintObjectConfig::dont_support_bridges.
|
||||||
|
void remove_bridges_from_contacts(
|
||||||
|
const PrintConfig &print_config,
|
||||||
|
const Layer &lower_layer,
|
||||||
|
const LayerRegion &layerm,
|
||||||
|
float fw,
|
||||||
|
Polygons &contact_polygons);
|
||||||
|
|
||||||
// Generate raft layers, also expand the 1st support layer
|
// Generate raft layers, also expand the 1st support layer
|
||||||
// in case there is no raft layer to improve support adhesion.
|
// in case there is no raft layer to improve support adhesion.
|
||||||
SupportGeneratorLayersPtr generate_raft_base(
|
SupportGeneratorLayersPtr generate_raft_base(
|
||||||
|
@ -226,6 +226,7 @@ void tree_supports_show_error(std::string_view message, bool critical)
|
|||||||
{
|
{
|
||||||
std::vector<Polygons> out(print_object.layer_count(), Polygons{});
|
std::vector<Polygons> out(print_object.layer_count(), Polygons{});
|
||||||
|
|
||||||
|
const PrintConfig &print_config = print_object.print()->config();
|
||||||
const PrintObjectConfig &config = print_object.config();
|
const PrintObjectConfig &config = print_object.config();
|
||||||
const bool support_auto = config.support_material.value && config.support_material_auto.value;
|
const bool support_auto = config.support_material.value && config.support_material_auto.value;
|
||||||
const int support_enforce_layers = config.support_material_enforce_layers.value;
|
const int support_enforce_layers = config.support_material_enforce_layers.value;
|
||||||
@ -242,7 +243,8 @@ void tree_supports_show_error(std::string_view message, bool critical)
|
|||||||
|
|
||||||
size_t num_overhang_layers = support_auto ? out.size() : std::max(size_t(support_enforce_layers), enforcers_layers.size());
|
size_t num_overhang_layers = support_auto ? out.size() : std::max(size_t(support_enforce_layers), enforcers_layers.size());
|
||||||
tbb::parallel_for(tbb::blocked_range<LayerIndex>(1, num_overhang_layers),
|
tbb::parallel_for(tbb::blocked_range<LayerIndex>(1, num_overhang_layers),
|
||||||
[&print_object, &enforcers_layers, &blockers_layers, support_auto, support_enforce_layers, support_threshold_auto, tan_threshold, enforcer_overhang_offset, &throw_on_cancel, &out]
|
[&print_object, &config, &print_config, &enforcers_layers, &blockers_layers,
|
||||||
|
support_auto, support_enforce_layers, support_threshold_auto, tan_threshold, enforcer_overhang_offset, &throw_on_cancel, &out]
|
||||||
(const tbb::blocked_range<LayerIndex> &range) {
|
(const tbb::blocked_range<LayerIndex> &range) {
|
||||||
for (LayerIndex layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
|
for (LayerIndex layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
|
||||||
const Layer ¤t_layer = *print_object.get_layer(layer_id);
|
const Layer ¤t_layer = *print_object.get_layer(layer_id);
|
||||||
@ -275,6 +277,11 @@ void tree_supports_show_error(std::string_view message, bool critical)
|
|||||||
}
|
}
|
||||||
if (! (enforced_layer || blockers_layers.empty() || blockers_layers[layer_id].empty()))
|
if (! (enforced_layer || blockers_layers.empty() || blockers_layers[layer_id].empty()))
|
||||||
overhangs = diff(overhangs, blockers_layers[layer_id], ApplySafetyOffset::Yes);
|
overhangs = diff(overhangs, blockers_layers[layer_id], ApplySafetyOffset::Yes);
|
||||||
|
if (config.dont_support_bridges) {
|
||||||
|
for (const LayerRegion *layerm : current_layer.regions())
|
||||||
|
remove_bridges_from_contacts(print_config, lower_layer, *layerm,
|
||||||
|
float(layerm->flow(frExternalPerimeter).scaled_width()), overhangs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//check_self_intersections(overhangs, "generate_overhangs1");
|
//check_self_intersections(overhangs, "generate_overhangs1");
|
||||||
if (! enforcers_layers.empty() && ! enforcers_layers[layer_id].empty()) {
|
if (! enforcers_layers.empty() && ! enforcers_layers[layer_id].empty()) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user