mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-12 21:29:00 +08:00
commit
802b1e1aa7
@ -269,7 +269,7 @@ sub contact_area {
|
||||
# remove the entire bridges and only support the unsupported edges
|
||||
my @bridges = map $_->expolygon,
|
||||
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,
|
||||
|
@ -4,7 +4,7 @@ use warnings;
|
||||
|
||||
require 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);
|
||||
|
||||
sub p {
|
||||
|
@ -82,7 +82,7 @@ plan tests => 8;
|
||||
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
|
||||
$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}),
|
||||
'infill combination produces internal void surfaces';
|
||||
|
||||
|
@ -267,7 +267,7 @@ Layer::make_fills()
|
||||
/// 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:
|
||||
/// 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_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.
|
||||
@ -331,7 +331,7 @@ Layer::detect_surfaces_type()
|
||||
const SurfaceType surface_type_bottom =
|
||||
(object.config.support_material.value && object.config.support_material_contact_distance.value == 0)
|
||||
? stBottom
|
||||
: stBottomBridge;
|
||||
: (stBottom | stBridge);
|
||||
|
||||
// Any surface lying on the void is a true bottom bridge (an overhang)
|
||||
bottom.append(
|
||||
@ -370,7 +370,7 @@ Layer::detect_surfaces_type()
|
||||
// just like any other bottom surface lying on the void
|
||||
const SurfaceType surface_type_bottom =
|
||||
(object.config.raft_layers.value > 0 && object.config.support_material_contact_distance.value > 0)
|
||||
? stBottomBridge
|
||||
? (stBottom | stBridge)
|
||||
: stBottom;
|
||||
for (Surface &s : bottom.surfaces) s.surface_type = surface_type_bottom;
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ LayerRegion::process_external_surfaces()
|
||||
|
||||
SurfaceCollection top;
|
||||
for (const Surface &surface : surfaces) {
|
||||
if (surface.surface_type != stTop) continue;
|
||||
if (!surface.is_top()) continue;
|
||||
|
||||
// give priority to bottom surfaces
|
||||
ExPolygons grown = diff_ex(
|
||||
@ -203,7 +203,7 @@ LayerRegion::process_external_surfaces()
|
||||
{
|
||||
SurfaceCollection other;
|
||||
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);
|
||||
|
||||
// group surfaces
|
||||
@ -238,21 +238,21 @@ LayerRegion::prepare_fill_surfaces()
|
||||
|
||||
// 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) {
|
||||
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
|
||||
if (surface->surface_type == stTop) {
|
||||
for (Surface &surface : this->fill_surfaces.surfaces) {
|
||||
if (surface.surface_type == stTop) {
|
||||
if (this->layer()->object()->config.infill_only_where_needed) {
|
||||
surface->surface_type = stInternalVoid;
|
||||
surface.surface_type = (stInternal | stVoid);
|
||||
} 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) {
|
||||
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
|
||||
if (surface->surface_type == stBottom || surface->surface_type == stBottomBridge)
|
||||
surface->surface_type = stInternal;
|
||||
for (Surface &surface : this->fill_surfaces.surfaces) {
|
||||
if (surface.is_bottom())
|
||||
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;
|
||||
for (Surface &surface : this->fill_surfaces.surfaces) {
|
||||
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;
|
||||
|
||||
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].pattern = surface.surface_type == stTop ? this->region()->config.top_infill_pattern.value
|
||||
group_attrib[i].fw = (surface.is_top()) ? top_solid_infill_flow.width : solid_infill_flow.width;
|
||||
group_attrib[i].pattern = surface.is_top() ? this->region()->config.top_infill_pattern.value
|
||||
: surface.is_bottom() ? this->region()->config.bottom_infill_pattern.value
|
||||
: ipRectilinear;
|
||||
}
|
||||
@ -137,7 +137,7 @@ LayerRegion::make_fill()
|
||||
);
|
||||
|
||||
Polygons to_subtract;
|
||||
surfaces.filter_by_type(stInternalVoid, &to_subtract);
|
||||
surfaces.filter_by_type((stInternal | stVoid), &to_subtract);
|
||||
|
||||
append_to(to_subtract, collapsed);
|
||||
surfaces.append(
|
||||
@ -146,7 +146,7 @@ LayerRegion::make_fill()
|
||||
to_subtract,
|
||||
true
|
||||
),
|
||||
stInternalSolid
|
||||
(stInternal | stSolid)
|
||||
);
|
||||
}
|
||||
|
||||
@ -162,20 +162,20 @@ LayerRegion::make_fill()
|
||||
surface_it != surfaces.surfaces.end(); ++surface_it) {
|
||||
|
||||
const Surface &surface = *surface_it;
|
||||
if (surface.surface_type == stInternalVoid)
|
||||
if (surface.surface_type == (stInternal | stVoid))
|
||||
continue;
|
||||
|
||||
InfillPattern fill_pattern = this->region()->config.fill_pattern.value;
|
||||
double density = fill_density;
|
||||
FlowRole role = (surface.surface_type == stTop) ? frTopSolidInfill
|
||||
FlowRole role = (surface.is_top()) ? frTopSolidInfill
|
||||
: surface.is_solid() ? frSolidInfill
|
||||
: frInfill;
|
||||
const bool is_bridge = this->layer()->id() > 0 && surface.is_bridge();
|
||||
|
||||
if (surface.is_solid()) {
|
||||
density = 100.;
|
||||
fill_pattern = (surface.surface_type == stTop) ? this->region()->config.top_infill_pattern.value
|
||||
: (surface.is_bottom() && !is_bridge) ? this->region()->config.bottom_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
|
||||
: ipRectilinear;
|
||||
} else if (density <= 0)
|
||||
continue;
|
||||
@ -277,7 +277,7 @@ LayerRegion::make_fill()
|
||||
if (is_bridge) {
|
||||
role = erBridgeInfill;
|
||||
} else if (surface.is_solid()) {
|
||||
role = (surface.surface_type == stTop) ? erTopSolidInfill : erSolidInfill;
|
||||
role = (surface.is_top()) ? erTopSolidInfill : erSolidInfill;
|
||||
} else {
|
||||
role = erInternalInfill;
|
||||
}
|
||||
|
@ -395,7 +395,7 @@ PrintObject::bridge_over_infill()
|
||||
|
||||
// extract the stInternalSolid surfaces that might be transformed into bridges
|
||||
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;
|
||||
|
||||
// check whether we should bridge or not according to density
|
||||
@ -492,15 +492,15 @@ PrintObject::bridge_over_infill()
|
||||
{
|
||||
Surfaces new_surfaces;
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
new_surfaces.push_back(Surface(stInternalSolid, *ex));
|
||||
new_surfaces.push_back(Surface( (stInternal | stSolid), *ex));
|
||||
|
||||
layerm->fill_surfaces.surfaces = new_surfaces;
|
||||
}
|
||||
@ -524,7 +524,7 @@ PrintObject::bridge_over_infill()
|
||||
)};
|
||||
push @new_surfaces, map Slic3r::Surface->new(
|
||||
expolygon => $_,
|
||||
surface_type => S_TYPE_INTERNALVOID,
|
||||
surface_type => S_TYPE_INTERNAL + S_TYPE_VOID,
|
||||
), @{intersection_ex(
|
||||
[ map $_->p, @$group ],
|
||||
[ map @$_, @$to_bridge ],
|
||||
@ -1375,9 +1375,8 @@ PrintObject::combine_infill()
|
||||
} else {
|
||||
// Save void surfaces.
|
||||
layerm->fill_surfaces.append(
|
||||
intersection_ex(internal, intersection_with_clearance),
|
||||
stInternalVoid
|
||||
);
|
||||
intersection_ex(internal, intersection_with_clearance),
|
||||
(stInternal | stVoid));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1481,7 +1480,7 @@ PrintObject::discover_horizontal_shells()
|
||||
|
||||
if (region_config.solid_infill_every_layers() > 0 && region_config.fill_density() > 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))
|
||||
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)
|
||||
{
|
||||
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
|
||||
// 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
|
||||
@ -1535,7 +1534,7 @@ PrintObject::_discover_neighbor_horizontal_shells(LayerRegion* layerm, const siz
|
||||
{
|
||||
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;
|
||||
|
||||
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
|
||||
Polygons new_internal_solid = intersection(
|
||||
solid,
|
||||
to_polygons(neighbor_fill_surfaces.filter_by_type({stInternal, stInternalSolid})),
|
||||
to_polygons(neighbor_fill_surfaces.filter_by_type({stInternal, (stInternal | stSolid)})),
|
||||
true
|
||||
);
|
||||
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
|
||||
// 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);
|
||||
const auto internal_solid = union_ex(tmp);
|
||||
const ExPolygons internal_solid = union_ex(tmp);
|
||||
|
||||
// subtract intersections from layer surfaces to get resulting internal surfaces
|
||||
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
|
||||
neighbor_layerm->fill_surfaces.clear();
|
||||
neighbor_layerm->fill_surfaces.append(internal, stInternal);
|
||||
|
||||
// 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
|
||||
SurfaceCollection tmp_coll;
|
||||
for (const auto& s : neighbor_fill_surfaces.surfaces)
|
||||
if (s.surface_type == stTop || s.is_bottom())
|
||||
for (const Surface& s : neighbor_fill_surfaces.surfaces)
|
||||
if (s.is_top() || s.is_bottom())
|
||||
tmp_coll.append(s);
|
||||
|
||||
for (auto s : tmp_coll.group()) {
|
||||
@ -1720,7 +1719,7 @@ PrintObject::clip_fill_surfaces()
|
||||
Polygons lower_layer_internal_surfaces;
|
||||
for (const auto* layerm : lower_layer->regions)
|
||||
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);
|
||||
}
|
||||
@ -1730,10 +1729,10 @@ PrintObject::clip_fill_surfaces()
|
||||
if (layerm->region()->config.fill_density.value == 0)
|
||||
continue;
|
||||
|
||||
Polygons internal{ to_polygons(layerm->fill_surfaces.filter_by_type({ stInternal, stInternalVoid })) };
|
||||
layerm->fill_surfaces.remove_types({ stInternal, stInternalVoid });
|
||||
Polygons internal{ to_polygons(layerm->fill_surfaces.filter_by_type({ stInternal, (stInternal | stVoid) })) };
|
||||
layerm->fill_surfaces.remove_types({ stInternal, (stInternal | stVoid) });
|
||||
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
|
||||
// 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) {
|
||||
// Remove the entire bridges and only support the unsupported edges.
|
||||
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) {
|
||||
bridges.push_back(surface->expolygon);
|
||||
}
|
||||
|
@ -16,42 +16,37 @@ Surface::area() const
|
||||
bool
|
||||
Surface::is_solid() const
|
||||
{
|
||||
return this->surface_type == stTop
|
||||
|| this->surface_type == stBottom
|
||||
|| this->surface_type == stBottomBridge
|
||||
|| this->surface_type == stInternalSolid
|
||||
|| this->surface_type == stInternalBridge;
|
||||
return (this->surface_type & (stTop | stBottom | stSolid | stBridge)) != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Surface::is_external() const
|
||||
{
|
||||
return this->surface_type == stTop
|
||||
|| this->surface_type == stBottom
|
||||
|| this->surface_type == stBottomBridge;
|
||||
return is_top() || is_bottom();
|
||||
}
|
||||
|
||||
bool
|
||||
Surface::is_internal() const
|
||||
{
|
||||
return this->surface_type == stInternal
|
||||
|| this->surface_type == stInternalBridge
|
||||
|| this->surface_type == stInternalSolid
|
||||
|| this->surface_type == stInternalVoid;
|
||||
return (this->surface_type & stInternal) != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Surface::is_bottom() const
|
||||
{
|
||||
return this->surface_type == stBottom
|
||||
|| this->surface_type == stBottomBridge;
|
||||
return (this->surface_type & stBottom) != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Surface::is_top() const
|
||||
{
|
||||
return (this->surface_type & stTop) != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Surface::is_bridge() const
|
||||
{
|
||||
return this->surface_type == stBottomBridge
|
||||
|| this->surface_type == stInternalBridge;
|
||||
return (this->surface_type & stBridge) != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,15 +8,22 @@ namespace Slic3r {
|
||||
|
||||
/// 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
|
||||
enum SurfaceType {
|
||||
stTop = 0b1,
|
||||
stBottom = 0b10,
|
||||
stBottomBridge = 0b100,
|
||||
stInternal = 0b1000,
|
||||
stInternalSolid = 0b10000,
|
||||
stInternalBridge = 0b100000,
|
||||
stInternalVoid = 0b1000000
|
||||
enum SurfaceType : uint16_t {
|
||||
stTop = 0b1, /// stTop: it has nothing just on top of it
|
||||
stBottom = 0b10, /// stBottom: it's a surface with nothing just under it (or the base plate, or a support)
|
||||
stInternal = 0b100, /// stInternal: not top nor bottom
|
||||
stSolid = 0b1000, /// stSolid: modify the stInternal to say it should be at 100% infill
|
||||
stBridge = 0b10000, /// stBridge: modify stBottom or stInternal to say it should be extruded as a bridge
|
||||
stVoid = 0b100000 /// stVoid: modify stInternal to say it should be at 0% infill
|
||||
};
|
||||
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
|
||||
{
|
||||
@ -37,6 +44,7 @@ class Surface
|
||||
bool is_solid() const;
|
||||
bool is_external() const;
|
||||
bool is_internal() const;
|
||||
bool is_top() const;
|
||||
bool is_bottom() const;
|
||||
bool is_bridge() const;
|
||||
};
|
||||
|
@ -93,24 +93,26 @@ template bool SurfaceCollection::any_bottom_contains<Polyline>(const Polyline &i
|
||||
SurfacesPtr
|
||||
SurfaceCollection::filter_by_type(std::initializer_list<SurfaceType> types)
|
||||
{
|
||||
size_t n {0};
|
||||
for (const auto& t : types)
|
||||
n |= t;
|
||||
SurfacesPtr ss;
|
||||
for (auto& s : this->surfaces)
|
||||
if ((s.surface_type & n) == s.surface_type) ss.push_back(&s);
|
||||
for (Surface& s : this->surfaces)
|
||||
for (const SurfaceType& t : types)
|
||||
if (s.surface_type == t) {
|
||||
ss.push_back(&s);
|
||||
break;
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
|
||||
SurfacesConstPtr
|
||||
SurfaceCollection::filter_by_type(std::initializer_list<SurfaceType> types) const
|
||||
{
|
||||
size_t n {0};
|
||||
for (const auto& t : types)
|
||||
n |= t;
|
||||
SurfacesConstPtr ss;
|
||||
for (auto& s : this->surfaces)
|
||||
if ((s.surface_type & n) == s.surface_type) ss.push_back(&s);
|
||||
for (const Surface& s : this->surfaces)
|
||||
for (const SurfaceType& t : types)
|
||||
if (s.surface_type == t) {
|
||||
ss.push_back(&s);
|
||||
break;
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
|
||||
@ -200,12 +202,23 @@ SurfaceCollection::keep_type(const SurfaceType type)
|
||||
void
|
||||
SurfaceCollection::keep_types(const SurfaceType *types, size_t ntypes)
|
||||
{
|
||||
size_t n {0};
|
||||
for (size_t i = 0; i < ntypes; ++i)
|
||||
n |= types[i]; // form bitmask.
|
||||
// Use stl remove_if to remove
|
||||
auto ptr = std::remove_if(surfaces.begin(), surfaces.end(),[n] (const Surface& s) { return (s.surface_type & n) != s.surface_type; });
|
||||
surfaces.erase(ptr, surfaces.cend());
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < surfaces.size(); ++ i) {
|
||||
bool keep = false;
|
||||
for (int k = 0; k < ntypes; ++ k) {
|
||||
if (surfaces[i].surface_type == types[k]) {
|
||||
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
|
||||
|
@ -19,6 +19,7 @@
|
||||
bool is_external() const;
|
||||
bool is_internal() const;
|
||||
bool is_bottom() const;
|
||||
bool is_top() const;
|
||||
bool is_bridge() const;
|
||||
%{
|
||||
|
||||
@ -104,11 +105,10 @@ _constant()
|
||||
ALIAS:
|
||||
S_TYPE_TOP = stTop
|
||||
S_TYPE_BOTTOM = stBottom
|
||||
S_TYPE_BOTTOMBRIDGE = stBottomBridge
|
||||
S_TYPE_INTERNAL = stInternal
|
||||
S_TYPE_INTERNALSOLID = stInternalSolid
|
||||
S_TYPE_INTERNALBRIDGE = stInternalBridge
|
||||
S_TYPE_INTERNALVOID = stInternalVoid
|
||||
S_TYPE_SOLID = stSolid
|
||||
S_TYPE_BRIDGE = stBridge
|
||||
S_TYPE_VOID = stVoid
|
||||
PROTOTYPE:
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
|
Loading…
x
Reference in New Issue
Block a user