mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-14 04:05:57 +08:00
commit
802b1e1aa7
@ -269,7 +269,7 @@ sub contact_area {
|
|||||||
# remove the entire bridges and only support the unsupported edges
|
# remove the entire bridges and only support the unsupported edges
|
||||||
my @bridges = map $_->expolygon,
|
my @bridges = map $_->expolygon,
|
||||||
grep $_->bridge_angle != -1,
|
grep $_->bridge_angle != -1,
|
||||||
@{$layerm->fill_surfaces->filter_by_type(S_TYPE_BOTTOMBRIDGE)};
|
@{$layerm->fill_surfaces->filter_by_type(S_TYPE_BOTTOM + S_TYPE_BRIDGE)};
|
||||||
|
|
||||||
$diff = diff(
|
$diff = diff(
|
||||||
$diff,
|
$diff,
|
||||||
|
@ -4,7 +4,7 @@ use warnings;
|
|||||||
|
|
||||||
require Exporter;
|
require Exporter;
|
||||||
our @ISA = qw(Exporter);
|
our @ISA = qw(Exporter);
|
||||||
our @EXPORT_OK = qw(S_TYPE_TOP S_TYPE_BOTTOM S_TYPE_BOTTOMBRIDGE S_TYPE_INTERNAL S_TYPE_INTERNALSOLID S_TYPE_INTERNALBRIDGE S_TYPE_INTERNALVOID);
|
our @EXPORT_OK = qw(S_TYPE_TOP S_TYPE_BOTTOM S_TYPE_INTERNAL S_TYPE_SOLID S_TYPE_BRIDGE S_TYPE_VOID);
|
||||||
our %EXPORT_TAGS = (types => \@EXPORT_OK);
|
our %EXPORT_TAGS = (types => \@EXPORT_OK);
|
||||||
|
|
||||||
sub p {
|
sub p {
|
||||||
|
@ -82,7 +82,7 @@ plan tests => 8;
|
|||||||
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
|
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
|
||||||
$print->process;
|
$print->process;
|
||||||
|
|
||||||
ok defined(first { @{$_->get_region(0)->fill_surfaces->filter_by_type(S_TYPE_INTERNALVOID)} > 0 }
|
ok defined(first { @{$_->get_region(0)->fill_surfaces->filter_by_type(S_TYPE_INTERNAL + S_TYPE_VOID)} > 0 }
|
||||||
@{$print->print->get_object(0)->layers}),
|
@{$print->print->get_object(0)->layers}),
|
||||||
'infill combination produces internal void surfaces';
|
'infill combination produces internal void surfaces';
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ Layer::make_fills()
|
|||||||
/// Initially all slices are of type S_TYPE_INTERNAL.
|
/// Initially all slices are of type S_TYPE_INTERNAL.
|
||||||
/// Slices are compared against the top / bottom slices and regions and classified to the following groups:
|
/// Slices are compared against the top / bottom slices and regions and classified to the following groups:
|
||||||
/// S_TYPE_TOP - Part of a region, which is not covered by any upper layer. This surface will be filled with a top solid infill.
|
/// S_TYPE_TOP - Part of a region, which is not covered by any upper layer. This surface will be filled with a top solid infill.
|
||||||
/// S_TYPE_BOTTOMBRIDGE - Part of a region, which is not fully supported, but it hangs in the air, or it hangs losely on a support or a raft.
|
/// S_TYPE_BOTTOM | S_TYPE_BRIDGE - Part of a region, which is not fully supported, but it hangs in the air, or it hangs losely on a support or a raft.
|
||||||
/// S_TYPE_BOTTOM - Part of a region, which is not supported by the same region, but it is supported either by another region, or by a soluble interface layer.
|
/// S_TYPE_BOTTOM - Part of a region, which is not supported by the same region, but it is supported either by another region, or by a soluble interface layer.
|
||||||
/// S_TYPE_INTERNAL - Part of a region, which is supported by the same region type.
|
/// S_TYPE_INTERNAL - Part of a region, which is supported by the same region type.
|
||||||
/// If a part of a region is of S_TYPE_BOTTOM and S_TYPE_TOP, the S_TYPE_BOTTOM wins.
|
/// If a part of a region is of S_TYPE_BOTTOM and S_TYPE_TOP, the S_TYPE_BOTTOM wins.
|
||||||
@ -331,7 +331,7 @@ Layer::detect_surfaces_type()
|
|||||||
const SurfaceType surface_type_bottom =
|
const SurfaceType surface_type_bottom =
|
||||||
(object.config.support_material.value && object.config.support_material_contact_distance.value == 0)
|
(object.config.support_material.value && object.config.support_material_contact_distance.value == 0)
|
||||||
? stBottom
|
? stBottom
|
||||||
: stBottomBridge;
|
: (stBottom | stBridge);
|
||||||
|
|
||||||
// Any surface lying on the void is a true bottom bridge (an overhang)
|
// Any surface lying on the void is a true bottom bridge (an overhang)
|
||||||
bottom.append(
|
bottom.append(
|
||||||
@ -370,7 +370,7 @@ Layer::detect_surfaces_type()
|
|||||||
// just like any other bottom surface lying on the void
|
// just like any other bottom surface lying on the void
|
||||||
const SurfaceType surface_type_bottom =
|
const SurfaceType surface_type_bottom =
|
||||||
(object.config.raft_layers.value > 0 && object.config.support_material_contact_distance.value > 0)
|
(object.config.raft_layers.value > 0 && object.config.support_material_contact_distance.value > 0)
|
||||||
? stBottomBridge
|
? (stBottom | stBridge)
|
||||||
: stBottom;
|
: stBottom;
|
||||||
for (Surface &s : bottom.surfaces) s.surface_type = surface_type_bottom;
|
for (Surface &s : bottom.surfaces) s.surface_type = surface_type_bottom;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ LayerRegion::process_external_surfaces()
|
|||||||
|
|
||||||
SurfaceCollection top;
|
SurfaceCollection top;
|
||||||
for (const Surface &surface : surfaces) {
|
for (const Surface &surface : surfaces) {
|
||||||
if (surface.surface_type != stTop) continue;
|
if (!surface.is_top()) continue;
|
||||||
|
|
||||||
// give priority to bottom surfaces
|
// give priority to bottom surfaces
|
||||||
ExPolygons grown = diff_ex(
|
ExPolygons grown = diff_ex(
|
||||||
@ -203,7 +203,7 @@ LayerRegion::process_external_surfaces()
|
|||||||
{
|
{
|
||||||
SurfaceCollection other;
|
SurfaceCollection other;
|
||||||
for (const Surface &s : surfaces)
|
for (const Surface &s : surfaces)
|
||||||
if (s.surface_type != stTop && !s.is_bottom())
|
if (!s.is_top() && !s.is_bottom())
|
||||||
other.surfaces.push_back(s);
|
other.surfaces.push_back(s);
|
||||||
|
|
||||||
// group surfaces
|
// group surfaces
|
||||||
@ -238,21 +238,21 @@ LayerRegion::prepare_fill_surfaces()
|
|||||||
|
|
||||||
// if no solid layers are requested, turn top/bottom surfaces to internal
|
// if no solid layers are requested, turn top/bottom surfaces to internal
|
||||||
if (this->region()->config.top_solid_layers == 0 && this->region()->config.min_top_bottom_shell_thickness <= 0) {
|
if (this->region()->config.top_solid_layers == 0 && this->region()->config.min_top_bottom_shell_thickness <= 0) {
|
||||||
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
|
for (Surface &surface : this->fill_surfaces.surfaces) {
|
||||||
if (surface->surface_type == stTop) {
|
if (surface.surface_type == stTop) {
|
||||||
if (this->layer()->object()->config.infill_only_where_needed) {
|
if (this->layer()->object()->config.infill_only_where_needed) {
|
||||||
surface->surface_type = stInternalVoid;
|
surface.surface_type = (stInternal | stVoid);
|
||||||
} else {
|
} else {
|
||||||
surface->surface_type = stInternal;
|
surface.surface_type = stInternal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->region()->config.bottom_solid_layers == 0 && this->region()->config.min_top_bottom_shell_thickness <= 0) {
|
if (this->region()->config.bottom_solid_layers == 0 && this->region()->config.min_top_bottom_shell_thickness <= 0) {
|
||||||
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
|
for (Surface &surface : this->fill_surfaces.surfaces) {
|
||||||
if (surface->surface_type == stBottom || surface->surface_type == stBottomBridge)
|
if (surface.is_bottom())
|
||||||
surface->surface_type = stInternal;
|
surface.surface_type = stInternal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ LayerRegion::prepare_fill_surfaces()
|
|||||||
const double min_area = this->region()->config.solid_infill_below_area.value / SCALING_FACTOR / SCALING_FACTOR;
|
const double min_area = this->region()->config.solid_infill_below_area.value / SCALING_FACTOR / SCALING_FACTOR;
|
||||||
for (Surface &surface : this->fill_surfaces.surfaces) {
|
for (Surface &surface : this->fill_surfaces.surfaces) {
|
||||||
if (surface.surface_type == stInternal && surface.area() <= min_area)
|
if (surface.surface_type == stInternal && surface.area() <= min_area)
|
||||||
surface.surface_type = stInternalSolid;
|
surface.surface_type = (stInternal | stSolid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,8 @@ LayerRegion::make_fill()
|
|||||||
if (!surface.is_solid() || surface.is_bridge()) continue;
|
if (!surface.is_solid() || surface.is_bridge()) continue;
|
||||||
|
|
||||||
group_attrib[i].is_solid = true;
|
group_attrib[i].is_solid = true;
|
||||||
group_attrib[i].fw = (surface.surface_type == stTop) ? top_solid_infill_flow.width : solid_infill_flow.width;
|
group_attrib[i].fw = (surface.is_top()) ? top_solid_infill_flow.width : solid_infill_flow.width;
|
||||||
group_attrib[i].pattern = surface.surface_type == stTop ? this->region()->config.top_infill_pattern.value
|
group_attrib[i].pattern = surface.is_top() ? this->region()->config.top_infill_pattern.value
|
||||||
: surface.is_bottom() ? this->region()->config.bottom_infill_pattern.value
|
: surface.is_bottom() ? this->region()->config.bottom_infill_pattern.value
|
||||||
: ipRectilinear;
|
: ipRectilinear;
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ LayerRegion::make_fill()
|
|||||||
);
|
);
|
||||||
|
|
||||||
Polygons to_subtract;
|
Polygons to_subtract;
|
||||||
surfaces.filter_by_type(stInternalVoid, &to_subtract);
|
surfaces.filter_by_type((stInternal | stVoid), &to_subtract);
|
||||||
|
|
||||||
append_to(to_subtract, collapsed);
|
append_to(to_subtract, collapsed);
|
||||||
surfaces.append(
|
surfaces.append(
|
||||||
@ -146,7 +146,7 @@ LayerRegion::make_fill()
|
|||||||
to_subtract,
|
to_subtract,
|
||||||
true
|
true
|
||||||
),
|
),
|
||||||
stInternalSolid
|
(stInternal | stSolid)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,19 +162,19 @@ LayerRegion::make_fill()
|
|||||||
surface_it != surfaces.surfaces.end(); ++surface_it) {
|
surface_it != surfaces.surfaces.end(); ++surface_it) {
|
||||||
|
|
||||||
const Surface &surface = *surface_it;
|
const Surface &surface = *surface_it;
|
||||||
if (surface.surface_type == stInternalVoid)
|
if (surface.surface_type == (stInternal | stVoid))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
InfillPattern fill_pattern = this->region()->config.fill_pattern.value;
|
InfillPattern fill_pattern = this->region()->config.fill_pattern.value;
|
||||||
double density = fill_density;
|
double density = fill_density;
|
||||||
FlowRole role = (surface.surface_type == stTop) ? frTopSolidInfill
|
FlowRole role = (surface.is_top()) ? frTopSolidInfill
|
||||||
: surface.is_solid() ? frSolidInfill
|
: surface.is_solid() ? frSolidInfill
|
||||||
: frInfill;
|
: frInfill;
|
||||||
const bool is_bridge = this->layer()->id() > 0 && surface.is_bridge();
|
const bool is_bridge = this->layer()->id() > 0 && surface.is_bridge();
|
||||||
|
|
||||||
if (surface.is_solid()) {
|
if (surface.is_solid()) {
|
||||||
density = 100.;
|
density = 100.;
|
||||||
fill_pattern = (surface.surface_type == stTop) ? this->region()->config.top_infill_pattern.value
|
fill_pattern = (surface.is_top()) ? this->region()->config.top_infill_pattern.value
|
||||||
: (surface.is_bottom() && !is_bridge) ? this->region()->config.bottom_infill_pattern.value
|
: (surface.is_bottom() && !is_bridge) ? this->region()->config.bottom_infill_pattern.value
|
||||||
: ipRectilinear;
|
: ipRectilinear;
|
||||||
} else if (density <= 0)
|
} else if (density <= 0)
|
||||||
@ -277,7 +277,7 @@ LayerRegion::make_fill()
|
|||||||
if (is_bridge) {
|
if (is_bridge) {
|
||||||
role = erBridgeInfill;
|
role = erBridgeInfill;
|
||||||
} else if (surface.is_solid()) {
|
} else if (surface.is_solid()) {
|
||||||
role = (surface.surface_type == stTop) ? erTopSolidInfill : erSolidInfill;
|
role = (surface.is_top()) ? erTopSolidInfill : erSolidInfill;
|
||||||
} else {
|
} else {
|
||||||
role = erInternalInfill;
|
role = erInternalInfill;
|
||||||
}
|
}
|
||||||
|
@ -395,7 +395,7 @@ PrintObject::bridge_over_infill()
|
|||||||
|
|
||||||
// extract the stInternalSolid surfaces that might be transformed into bridges
|
// extract the stInternalSolid surfaces that might be transformed into bridges
|
||||||
Polygons internal_solid;
|
Polygons internal_solid;
|
||||||
layerm->fill_surfaces.filter_by_type(stInternalSolid, &internal_solid);
|
layerm->fill_surfaces.filter_by_type((stInternal | stSolid), &internal_solid);
|
||||||
if (internal_solid.empty()) continue;
|
if (internal_solid.empty()) continue;
|
||||||
|
|
||||||
// check whether we should bridge or not according to density
|
// check whether we should bridge or not according to density
|
||||||
@ -492,15 +492,15 @@ PrintObject::bridge_over_infill()
|
|||||||
{
|
{
|
||||||
Surfaces new_surfaces;
|
Surfaces new_surfaces;
|
||||||
for (Surfaces::const_iterator surface = layerm->fill_surfaces.surfaces.begin(); surface != layerm->fill_surfaces.surfaces.end(); ++surface) {
|
for (Surfaces::const_iterator surface = layerm->fill_surfaces.surfaces.begin(); surface != layerm->fill_surfaces.surfaces.end(); ++surface) {
|
||||||
if (surface->surface_type != stInternalSolid)
|
if (surface->surface_type != (stInternal | stSolid))
|
||||||
new_surfaces.push_back(*surface);
|
new_surfaces.push_back(*surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ExPolygons::const_iterator ex = to_bridge.begin(); ex != to_bridge.end(); ++ex)
|
for (ExPolygons::const_iterator ex = to_bridge.begin(); ex != to_bridge.end(); ++ex)
|
||||||
new_surfaces.push_back(Surface(stInternalBridge, *ex));
|
new_surfaces.push_back(Surface( (stInternal | stBridge), *ex));
|
||||||
|
|
||||||
for (ExPolygons::const_iterator ex = not_to_bridge.begin(); ex != not_to_bridge.end(); ++ex)
|
for (ExPolygons::const_iterator ex = not_to_bridge.begin(); ex != not_to_bridge.end(); ++ex)
|
||||||
new_surfaces.push_back(Surface(stInternalSolid, *ex));
|
new_surfaces.push_back(Surface( (stInternal | stSolid), *ex));
|
||||||
|
|
||||||
layerm->fill_surfaces.surfaces = new_surfaces;
|
layerm->fill_surfaces.surfaces = new_surfaces;
|
||||||
}
|
}
|
||||||
@ -524,7 +524,7 @@ PrintObject::bridge_over_infill()
|
|||||||
)};
|
)};
|
||||||
push @new_surfaces, map Slic3r::Surface->new(
|
push @new_surfaces, map Slic3r::Surface->new(
|
||||||
expolygon => $_,
|
expolygon => $_,
|
||||||
surface_type => S_TYPE_INTERNALVOID,
|
surface_type => S_TYPE_INTERNAL + S_TYPE_VOID,
|
||||||
), @{intersection_ex(
|
), @{intersection_ex(
|
||||||
[ map $_->p, @$group ],
|
[ map $_->p, @$group ],
|
||||||
[ map @$_, @$to_bridge ],
|
[ map @$_, @$to_bridge ],
|
||||||
@ -1376,8 +1376,7 @@ PrintObject::combine_infill()
|
|||||||
// Save void surfaces.
|
// Save void surfaces.
|
||||||
layerm->fill_surfaces.append(
|
layerm->fill_surfaces.append(
|
||||||
intersection_ex(internal, intersection_with_clearance),
|
intersection_ex(internal, intersection_with_clearance),
|
||||||
stInternalVoid
|
(stInternal | stVoid));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1481,7 +1480,7 @@ PrintObject::discover_horizontal_shells()
|
|||||||
|
|
||||||
if (region_config.solid_infill_every_layers() > 0 && region_config.fill_density() > 0
|
if (region_config.solid_infill_every_layers() > 0 && region_config.fill_density() > 0
|
||||||
&& (i % region_config.solid_infill_every_layers()) == 0) {
|
&& (i % region_config.solid_infill_every_layers()) == 0) {
|
||||||
const auto type = region_config.fill_density() == 100 ? stInternalSolid : stInternalBridge;
|
const auto type = region_config.fill_density() == 100 ? (stInternal | stSolid) : (stInternal | stBridge);
|
||||||
for (auto* s : layerm->fill_surfaces.filter_by_type(stInternal))
|
for (auto* s : layerm->fill_surfaces.filter_by_type(stInternal))
|
||||||
s->surface_type = type;
|
s->surface_type = type;
|
||||||
}
|
}
|
||||||
@ -1494,7 +1493,7 @@ void
|
|||||||
PrintObject::_discover_external_horizontal_shells(LayerRegion* layerm, const size_t& i, const size_t& region_id)
|
PrintObject::_discover_external_horizontal_shells(LayerRegion* layerm, const size_t& i, const size_t& region_id)
|
||||||
{
|
{
|
||||||
const auto& region_config = layerm->region()->config;
|
const auto& region_config = layerm->region()->config;
|
||||||
for (auto& type : { stTop, stBottom, stBottomBridge }) {
|
for (auto& type : { stTop, stBottom, (stBottom | stBridge) }) {
|
||||||
// find slices of current type for current layer
|
// find slices of current type for current layer
|
||||||
// use slices instead of fill_surfaces because they also include the perimeter area
|
// use slices instead of fill_surfaces because they also include the perimeter area
|
||||||
// which needs to be propagated in shells; we need to grow slices like we did for
|
// which needs to be propagated in shells; we need to grow slices like we did for
|
||||||
@ -1535,7 +1534,7 @@ PrintObject::_discover_neighbor_horizontal_shells(LayerRegion* layerm, const siz
|
|||||||
{
|
{
|
||||||
const auto& region_config = layerm->region()->config;
|
const auto& region_config = layerm->region()->config;
|
||||||
|
|
||||||
for (int n = (type == stTop ? i-1 : i+1); std::abs(n-int(i)) < solid_layers; (type == stTop ? n-- : n++)) {
|
for (int n = ((type & stTop) != 0 ? i-1 : i+1); std::abs(n-int(i)) < solid_layers; ((type & stTop) != 0 ? n-- : n++)) {
|
||||||
if (n < 0 || static_cast<size_t>(n) >= this->layer_count()) continue;
|
if (n < 0 || static_cast<size_t>(n) >= this->layer_count()) continue;
|
||||||
|
|
||||||
LayerRegion* neighbor_layerm { this->get_layer(n)->get_region(region_id) };
|
LayerRegion* neighbor_layerm { this->get_layer(n)->get_region(region_id) };
|
||||||
@ -1546,7 +1545,7 @@ PrintObject::_discover_neighbor_horizontal_shells(LayerRegion* layerm, const siz
|
|||||||
// intersections have contours and holes
|
// intersections have contours and holes
|
||||||
Polygons new_internal_solid = intersection(
|
Polygons new_internal_solid = intersection(
|
||||||
solid,
|
solid,
|
||||||
to_polygons(neighbor_fill_surfaces.filter_by_type({stInternal, stInternalSolid})),
|
to_polygons(neighbor_fill_surfaces.filter_by_type({stInternal, (stInternal | stSolid)})),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
if (new_internal_solid.empty()) {
|
if (new_internal_solid.empty()) {
|
||||||
@ -1624,25 +1623,25 @@ PrintObject::_discover_neighbor_horizontal_shells(LayerRegion* layerm, const siz
|
|||||||
|
|
||||||
// internal-solid are the union of the existing internal-solid surfaces
|
// internal-solid are the union of the existing internal-solid surfaces
|
||||||
// and new ones
|
// and new ones
|
||||||
Polygons tmp { to_polygons(neighbor_fill_surfaces.filter_by_type(stInternalSolid)) };
|
Polygons tmp { to_polygons(neighbor_fill_surfaces.filter_by_type(stInternal | stSolid)) };
|
||||||
polygons_append(tmp, new_internal_solid);
|
polygons_append(tmp, new_internal_solid);
|
||||||
const auto internal_solid = union_ex(tmp);
|
const ExPolygons internal_solid = union_ex(tmp);
|
||||||
|
|
||||||
// subtract intersections from layer surfaces to get resulting internal surfaces
|
// subtract intersections from layer surfaces to get resulting internal surfaces
|
||||||
tmp = to_polygons(neighbor_fill_surfaces.filter_by_type(stInternal));
|
tmp = to_polygons(neighbor_fill_surfaces.filter_by_type(stInternal));
|
||||||
const auto internal = diff_ex(tmp, to_polygons(internal_solid), 1);
|
const ExPolygons internal = diff_ex(tmp, to_polygons(internal_solid), 1);
|
||||||
|
|
||||||
// assign resulting internal surfaces to layer
|
// assign resulting internal surfaces to layer
|
||||||
neighbor_layerm->fill_surfaces.clear();
|
neighbor_layerm->fill_surfaces.clear();
|
||||||
neighbor_layerm->fill_surfaces.append(internal, stInternal);
|
neighbor_layerm->fill_surfaces.append(internal, stInternal);
|
||||||
|
|
||||||
// assign new internal-solid surfaces to layer
|
// assign new internal-solid surfaces to layer
|
||||||
neighbor_layerm->fill_surfaces.append(internal_solid, stInternalSolid);
|
neighbor_layerm->fill_surfaces.append(internal_solid, (stInternal | stSolid));
|
||||||
|
|
||||||
// assign top and bottom surfaces to layer
|
// assign top and bottom surfaces to layer
|
||||||
SurfaceCollection tmp_coll;
|
SurfaceCollection tmp_coll;
|
||||||
for (const auto& s : neighbor_fill_surfaces.surfaces)
|
for (const Surface& s : neighbor_fill_surfaces.surfaces)
|
||||||
if (s.surface_type == stTop || s.is_bottom())
|
if (s.is_top() || s.is_bottom())
|
||||||
tmp_coll.append(s);
|
tmp_coll.append(s);
|
||||||
|
|
||||||
for (auto s : tmp_coll.group()) {
|
for (auto s : tmp_coll.group()) {
|
||||||
@ -1720,7 +1719,7 @@ PrintObject::clip_fill_surfaces()
|
|||||||
Polygons lower_layer_internal_surfaces;
|
Polygons lower_layer_internal_surfaces;
|
||||||
for (const auto* layerm : lower_layer->regions)
|
for (const auto* layerm : lower_layer->regions)
|
||||||
polygons_append(lower_layer_internal_surfaces, to_polygons(
|
polygons_append(lower_layer_internal_surfaces, to_polygons(
|
||||||
layerm->fill_surfaces.filter_by_type({ stInternal, stInternalVoid })
|
layerm->fill_surfaces.filter_by_type({ stInternal, (stInternal | stVoid) })
|
||||||
));
|
));
|
||||||
upper_internal = intersection(overhangs, lower_layer_internal_surfaces);
|
upper_internal = intersection(overhangs, lower_layer_internal_surfaces);
|
||||||
}
|
}
|
||||||
@ -1730,10 +1729,10 @@ PrintObject::clip_fill_surfaces()
|
|||||||
if (layerm->region()->config.fill_density.value == 0)
|
if (layerm->region()->config.fill_density.value == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Polygons internal{ to_polygons(layerm->fill_surfaces.filter_by_type({ stInternal, stInternalVoid })) };
|
Polygons internal{ to_polygons(layerm->fill_surfaces.filter_by_type({ stInternal, (stInternal | stVoid) })) };
|
||||||
layerm->fill_surfaces.remove_types({ stInternal, stInternalVoid });
|
layerm->fill_surfaces.remove_types({ stInternal, (stInternal | stVoid) });
|
||||||
layerm->fill_surfaces.append(intersection_ex(internal, upper_internal, true), stInternal);
|
layerm->fill_surfaces.append(intersection_ex(internal, upper_internal, true), stInternal);
|
||||||
layerm->fill_surfaces.append(diff_ex (internal, upper_internal, true), stInternalVoid);
|
layerm->fill_surfaces.append(diff_ex (internal, upper_internal, true), (stInternal | stVoid));
|
||||||
|
|
||||||
// If there are voids it means that our internal infill is not adjacent to
|
// If there are voids it means that our internal infill is not adjacent to
|
||||||
// perimeters. In this case it would be nice to add a loop around infill to
|
// perimeters. In this case it would be nice to add a loop around infill to
|
||||||
|
@ -409,7 +409,7 @@ SupportMaterial::contact_area(PrintObject *object)
|
|||||||
if (1) {
|
if (1) {
|
||||||
// Remove the entire bridges and only support the unsupported edges.
|
// Remove the entire bridges and only support the unsupported edges.
|
||||||
ExPolygons bridges;
|
ExPolygons bridges;
|
||||||
for (auto surface : layer_m->fill_surfaces.filter_by_type(stBottomBridge)) {
|
for (auto surface : layer_m->fill_surfaces.filter_by_type(stBottom | stBridge)) {
|
||||||
if (surface->bridge_angle != -1) {
|
if (surface->bridge_angle != -1) {
|
||||||
bridges.push_back(surface->expolygon);
|
bridges.push_back(surface->expolygon);
|
||||||
}
|
}
|
||||||
|
@ -16,42 +16,37 @@ Surface::area() const
|
|||||||
bool
|
bool
|
||||||
Surface::is_solid() const
|
Surface::is_solid() const
|
||||||
{
|
{
|
||||||
return this->surface_type == stTop
|
return (this->surface_type & (stTop | stBottom | stSolid | stBridge)) != 0;
|
||||||
|| this->surface_type == stBottom
|
|
||||||
|| this->surface_type == stBottomBridge
|
|
||||||
|| this->surface_type == stInternalSolid
|
|
||||||
|| this->surface_type == stInternalBridge;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Surface::is_external() const
|
Surface::is_external() const
|
||||||
{
|
{
|
||||||
return this->surface_type == stTop
|
return is_top() || is_bottom();
|
||||||
|| this->surface_type == stBottom
|
|
||||||
|| this->surface_type == stBottomBridge;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Surface::is_internal() const
|
Surface::is_internal() const
|
||||||
{
|
{
|
||||||
return this->surface_type == stInternal
|
return (this->surface_type & stInternal) != 0;
|
||||||
|| this->surface_type == stInternalBridge
|
|
||||||
|| this->surface_type == stInternalSolid
|
|
||||||
|| this->surface_type == stInternalVoid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Surface::is_bottom() const
|
Surface::is_bottom() const
|
||||||
{
|
{
|
||||||
return this->surface_type == stBottom
|
return (this->surface_type & stBottom) != 0;
|
||||||
|| this->surface_type == stBottomBridge;
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Surface::is_top() const
|
||||||
|
{
|
||||||
|
return (this->surface_type & stTop) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Surface::is_bridge() const
|
Surface::is_bridge() const
|
||||||
{
|
{
|
||||||
return this->surface_type == stBottomBridge
|
return (this->surface_type & stBridge) != 0;
|
||||||
|| this->surface_type == stInternalBridge;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,15 +8,22 @@ namespace Slic3r {
|
|||||||
|
|
||||||
/// Surface type enumerations.
|
/// Surface type enumerations.
|
||||||
/// As it is very unlikely that there will be more than 32 or 64 of these surface types, pack into a flag
|
/// As it is very unlikely that there will be more than 32 or 64 of these surface types, pack into a flag
|
||||||
enum SurfaceType {
|
enum SurfaceType : uint16_t {
|
||||||
stTop = 0b1,
|
stTop = 0b1, /// stTop: it has nothing just on top of it
|
||||||
stBottom = 0b10,
|
stBottom = 0b10, /// stBottom: it's a surface with nothing just under it (or the base plate, or a support)
|
||||||
stBottomBridge = 0b100,
|
stInternal = 0b100, /// stInternal: not top nor bottom
|
||||||
stInternal = 0b1000,
|
stSolid = 0b1000, /// stSolid: modify the stInternal to say it should be at 100% infill
|
||||||
stInternalSolid = 0b10000,
|
stBridge = 0b10000, /// stBridge: modify stBottom or stInternal to say it should be extruded as a bridge
|
||||||
stInternalBridge = 0b100000,
|
stVoid = 0b100000 /// stVoid: modify stInternal to say it should be at 0% infill
|
||||||
stInternalVoid = 0b1000000
|
|
||||||
};
|
};
|
||||||
|
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));}
|
||||||
|
inline SurfaceType operator|=(SurfaceType& a, SurfaceType b)
|
||||||
|
{ a = a | b; return a;}
|
||||||
|
inline SurfaceType operator&=(SurfaceType& a, SurfaceType b)
|
||||||
|
{ a = a & b; return a;}
|
||||||
|
|
||||||
class Surface
|
class Surface
|
||||||
{
|
{
|
||||||
@ -37,6 +44,7 @@ class Surface
|
|||||||
bool is_solid() const;
|
bool is_solid() const;
|
||||||
bool is_external() const;
|
bool is_external() const;
|
||||||
bool is_internal() const;
|
bool is_internal() const;
|
||||||
|
bool is_top() const;
|
||||||
bool is_bottom() const;
|
bool is_bottom() const;
|
||||||
bool is_bridge() const;
|
bool is_bridge() const;
|
||||||
};
|
};
|
||||||
|
@ -93,24 +93,26 @@ template bool SurfaceCollection::any_bottom_contains<Polyline>(const Polyline &i
|
|||||||
SurfacesPtr
|
SurfacesPtr
|
||||||
SurfaceCollection::filter_by_type(std::initializer_list<SurfaceType> types)
|
SurfaceCollection::filter_by_type(std::initializer_list<SurfaceType> types)
|
||||||
{
|
{
|
||||||
size_t n {0};
|
|
||||||
for (const auto& t : types)
|
|
||||||
n |= t;
|
|
||||||
SurfacesPtr ss;
|
SurfacesPtr ss;
|
||||||
for (auto& s : this->surfaces)
|
for (Surface& s : this->surfaces)
|
||||||
if ((s.surface_type & n) == s.surface_type) ss.push_back(&s);
|
for (const SurfaceType& t : types)
|
||||||
|
if (s.surface_type == t) {
|
||||||
|
ss.push_back(&s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfacesConstPtr
|
SurfacesConstPtr
|
||||||
SurfaceCollection::filter_by_type(std::initializer_list<SurfaceType> types) const
|
SurfaceCollection::filter_by_type(std::initializer_list<SurfaceType> types) const
|
||||||
{
|
{
|
||||||
size_t n {0};
|
|
||||||
for (const auto& t : types)
|
|
||||||
n |= t;
|
|
||||||
SurfacesConstPtr ss;
|
SurfacesConstPtr ss;
|
||||||
for (auto& s : this->surfaces)
|
for (const Surface& s : this->surfaces)
|
||||||
if ((s.surface_type & n) == s.surface_type) ss.push_back(&s);
|
for (const SurfaceType& t : types)
|
||||||
|
if (s.surface_type == t) {
|
||||||
|
ss.push_back(&s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,12 +202,23 @@ SurfaceCollection::keep_type(const SurfaceType type)
|
|||||||
void
|
void
|
||||||
SurfaceCollection::keep_types(const SurfaceType *types, size_t ntypes)
|
SurfaceCollection::keep_types(const SurfaceType *types, size_t ntypes)
|
||||||
{
|
{
|
||||||
size_t n {0};
|
size_t j = 0;
|
||||||
for (size_t i = 0; i < ntypes; ++i)
|
for (size_t i = 0; i < surfaces.size(); ++ i) {
|
||||||
n |= types[i]; // form bitmask.
|
bool keep = false;
|
||||||
// Use stl remove_if to remove
|
for (int k = 0; k < ntypes; ++ k) {
|
||||||
auto ptr = std::remove_if(surfaces.begin(), surfaces.end(),[n] (const Surface& s) { return (s.surface_type & n) != s.surface_type; });
|
if (surfaces[i].surface_type == types[k]) {
|
||||||
surfaces.erase(ptr, surfaces.cend());
|
keep = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (keep) {
|
||||||
|
if (j < i)
|
||||||
|
std::swap(surfaces[i], surfaces[j]);
|
||||||
|
++ j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j < surfaces.size())
|
||||||
|
surfaces.erase(surfaces.begin() + j, surfaces.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
bool is_external() const;
|
bool is_external() const;
|
||||||
bool is_internal() const;
|
bool is_internal() const;
|
||||||
bool is_bottom() const;
|
bool is_bottom() const;
|
||||||
|
bool is_top() const;
|
||||||
bool is_bridge() const;
|
bool is_bridge() const;
|
||||||
%{
|
%{
|
||||||
|
|
||||||
@ -104,11 +105,10 @@ _constant()
|
|||||||
ALIAS:
|
ALIAS:
|
||||||
S_TYPE_TOP = stTop
|
S_TYPE_TOP = stTop
|
||||||
S_TYPE_BOTTOM = stBottom
|
S_TYPE_BOTTOM = stBottom
|
||||||
S_TYPE_BOTTOMBRIDGE = stBottomBridge
|
|
||||||
S_TYPE_INTERNAL = stInternal
|
S_TYPE_INTERNAL = stInternal
|
||||||
S_TYPE_INTERNALSOLID = stInternalSolid
|
S_TYPE_SOLID = stSolid
|
||||||
S_TYPE_INTERNALBRIDGE = stInternalBridge
|
S_TYPE_BRIDGE = stBridge
|
||||||
S_TYPE_INTERNALVOID = stInternalVoid
|
S_TYPE_VOID = stVoid
|
||||||
PROTOTYPE:
|
PROTOTYPE:
|
||||||
CODE:
|
CODE:
|
||||||
RETVAL = ix;
|
RETVAL = ix;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user