mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-14 19:26:03 +08:00
bugfix #93
clean a bit some methods with newer c++ add more const to surfacecollection & create surfaceconstptr & a slice() method in layerregion that return const surfacecollection.
This commit is contained in:
parent
6cc8f63f84
commit
81dc1e19d3
@ -21,7 +21,7 @@ Layer::~Layer()
|
||||
bool Layer::empty() const
|
||||
{
|
||||
for (const LayerRegion *layerm : m_regions)
|
||||
if (layerm != nullptr && ! layerm->slices.empty())
|
||||
if (layerm != nullptr && ! layerm->slices().empty())
|
||||
// Non empty layer.
|
||||
return false;
|
||||
return true;
|
||||
@ -39,11 +39,11 @@ void Layer::make_slices()
|
||||
ExPolygons slices;
|
||||
if (m_regions.size() == 1) {
|
||||
// optimization: if we only have one region, take its slices
|
||||
slices = m_regions.front()->slices;
|
||||
slices = m_regions.front()->slices();
|
||||
} else {
|
||||
Polygons slices_p;
|
||||
for (LayerRegion *layerm : m_regions)
|
||||
polygons_append(slices_p, to_polygons(layerm->slices));
|
||||
polygons_append(slices_p, to_polygons(layerm->slices()));
|
||||
slices = union_ex(slices_p);
|
||||
}
|
||||
|
||||
@ -71,11 +71,11 @@ void Layer::merge_slices()
|
||||
if (m_regions.size() == 1) {
|
||||
// Optimization, also more robust. Don't merge classified pieces of layerm->slices,
|
||||
// but use the non-split islands of a layer. For a single region print, these shall be equal.
|
||||
m_regions.front()->slices.set(this->slices.expolygons, stPosInternal | stDensSparse);
|
||||
m_regions.front()->m_slices.set(this->slices.expolygons, stPosInternal | stDensSparse);
|
||||
} else {
|
||||
for (LayerRegion *layerm : m_regions)
|
||||
// without safety offset, artifacts are generated (GH #2494)
|
||||
layerm->slices.set(union_ex(to_polygons(std::move(layerm->slices.surfaces)), true), stPosInternal | stDensSparse);
|
||||
layerm->m_slices.set(union_ex(to_polygons(std::move(layerm->m_slices.surfaces)), true), stPosInternal | stDensSparse);
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ ExPolygons Layer::merged(float offset_scaled) const
|
||||
}
|
||||
Polygons polygons;
|
||||
for (LayerRegion *layerm : m_regions)
|
||||
append(polygons, offset(to_expolygons(layerm->slices.surfaces), offset_scaled));
|
||||
append(polygons, offset(to_expolygons(layerm->slices().surfaces), offset_scaled));
|
||||
ExPolygons out = union_ex(polygons);
|
||||
if (offset_scaled2 != 0.f)
|
||||
out = offset_ex(out, offset_scaled2);
|
||||
@ -145,7 +145,7 @@ void Layer::make_perimeters()
|
||||
|
||||
if (layerms.size() == 1) { // optimization
|
||||
(*layerm)->fill_surfaces.surfaces.clear();
|
||||
(*layerm)->make_perimeters((*layerm)->slices, &(*layerm)->fill_surfaces);
|
||||
(*layerm)->make_perimeters((*layerm)->slices(), &(*layerm)->fill_surfaces);
|
||||
(*layerm)->fill_expolygons = to_expolygons((*layerm)->fill_surfaces.surfaces);
|
||||
} else {
|
||||
SurfaceCollection new_slices;
|
||||
@ -155,7 +155,7 @@ void Layer::make_perimeters()
|
||||
// group slices (surfaces) according to number of extra perimeters
|
||||
std::map<unsigned short, Surfaces> slices; // extra_perimeters => [ surface, surface... ]
|
||||
for (LayerRegion *layerm : layerms) {
|
||||
for (Surface &surface : layerm->slices.surfaces)
|
||||
for (const Surface &surface : layerm->slices().surfaces)
|
||||
slices[surface.extra_perimeters].emplace_back(surface);
|
||||
if (layerm->region()->config().fill_density > layerm_config->region()->config().fill_density)
|
||||
layerm_config = layerm;
|
||||
@ -173,7 +173,7 @@ void Layer::make_perimeters()
|
||||
if (!fill_surfaces.surfaces.empty()) {
|
||||
for (LayerRegionPtrs::iterator l = layerms.begin(); l != layerms.end(); ++l) {
|
||||
// Separate the fill surfaces.
|
||||
ExPolygons expp = intersection_ex(to_polygons(fill_surfaces), (*l)->slices);
|
||||
ExPolygons expp = intersection_ex(to_polygons(fill_surfaces), (*l)->slices());
|
||||
(*l)->fill_expolygons = expp;
|
||||
(*l)->fill_no_overlap_expolygons = (*layerm)->fill_no_overlap_expolygons;
|
||||
(*l)->fill_surfaces.set(std::move(expp), fill_surfaces.surfaces.front());
|
||||
@ -202,8 +202,8 @@ void Layer::make_fills()
|
||||
void Layer::export_region_slices_to_svg(const char *path) const
|
||||
{
|
||||
BoundingBox bbox;
|
||||
for (const auto *region : m_regions)
|
||||
for (const auto &surface : region->slices.surfaces)
|
||||
for (const LayerRegion *region : m_regions)
|
||||
for (const Surface &surface : region->slices().surfaces)
|
||||
bbox.merge(get_extents(surface.expolygon));
|
||||
Point legend_size = export_surface_type_legend_to_svg_box_size();
|
||||
Point legend_pos(bbox.min(0), bbox.max(1));
|
||||
@ -211,8 +211,8 @@ void Layer::export_region_slices_to_svg(const char *path) const
|
||||
|
||||
SVG svg(path, bbox);
|
||||
const float transparency = 0.5f;
|
||||
for (const auto *region : m_regions)
|
||||
for (const auto &surface : region->slices.surfaces)
|
||||
for (const LayerRegion *region : m_regions)
|
||||
for (const Surface &surface : region->slices().surfaces)
|
||||
svg.draw(surface.expolygon, surface_type_to_color_name(surface.surface_type), transparency);
|
||||
export_surface_type_legend_to_svg(svg, legend_pos);
|
||||
svg.Close();
|
||||
@ -228,8 +228,8 @@ void Layer::export_region_slices_to_svg_debug(const char *name) const
|
||||
void Layer::export_region_fill_surfaces_to_svg(const char *path) const
|
||||
{
|
||||
BoundingBox bbox;
|
||||
for (const auto *region : m_regions)
|
||||
for (const auto &surface : region->slices.surfaces)
|
||||
for (const LayerRegion *region : m_regions)
|
||||
for (const Surface &surface : region->slices().surfaces)
|
||||
bbox.merge(get_extents(surface.expolygon));
|
||||
Point legend_size = export_surface_type_legend_to_svg_box_size();
|
||||
Point legend_pos(bbox.min(0), bbox.max(1));
|
||||
@ -237,8 +237,8 @@ void Layer::export_region_fill_surfaces_to_svg(const char *path) const
|
||||
|
||||
SVG svg(path, bbox);
|
||||
const float transparency = 0.5f;
|
||||
for (const auto *region : m_regions)
|
||||
for (const auto &surface : region->slices.surfaces)
|
||||
for (const LayerRegion *region : m_regions)
|
||||
for (const Surface &surface : region->slices().surfaces)
|
||||
svg.draw(surface.expolygon, surface_type_to_color_name(surface.surface_type), transparency);
|
||||
export_surface_type_legend_to_svg(svg, legend_pos);
|
||||
svg.Close();
|
||||
|
@ -25,7 +25,8 @@ public:
|
||||
|
||||
// collection of surfaces generated by slicing the original geometry
|
||||
// divided by type top/bottom/internal
|
||||
SurfaceCollection slices;
|
||||
SurfaceCollection m_slices;
|
||||
const SurfaceCollection& slices() const { return m_slices; }
|
||||
|
||||
// collection of extrusion paths/loops filling gaps
|
||||
// These fills are generated by the perimeter generator.
|
||||
@ -63,7 +64,7 @@ public:
|
||||
Flow flow(FlowRole role, bool bridge = false, double width = -1) const;
|
||||
void slices_to_fill_surfaces_clipped();
|
||||
void prepare_fill_surfaces();
|
||||
void make_perimeters(SurfaceCollection &slices, SurfaceCollection* fill_surfaces);
|
||||
void make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces);
|
||||
void process_external_surfaces(const Layer *lower_layer, const Polygons *lower_layer_covered);
|
||||
double infill_area_threshold() const;
|
||||
// Trim surfaces by trimming polygons. Used by the elephant foot compensation at the 1st layer.
|
||||
@ -129,7 +130,7 @@ public:
|
||||
// Slices merged into islands, to be used by the elephant foot compensation to trim the individual surfaces with the shrunk merged slices.
|
||||
ExPolygons merged(float offset) const;
|
||||
template <class T> bool any_internal_region_slice_contains(const T &item) const {
|
||||
for (const LayerRegion *layerm : m_regions) if (layerm->slices.any_internal_contains(item)) return true;
|
||||
for (const LayerRegion *layerm : m_regions) if (layerm->slices().any_internal_contains(item)) return true;
|
||||
return false;
|
||||
}
|
||||
template <class T> bool any_bottom_region_slice_contains(const T &item) const {
|
||||
|
@ -39,7 +39,7 @@ void LayerRegion::slices_to_fill_surfaces_clipped()
|
||||
Polygons fill_boundaries = to_polygons(this->fill_expolygons);
|
||||
// Collect polygons per surface type.
|
||||
std::map<SurfaceType, Polygons> polygons_by_surface;
|
||||
for (Surface &surface : this->slices.surfaces) {
|
||||
for (const Surface &surface : this->slices().surfaces) {
|
||||
polygons_append(polygons_by_surface[surface.surface_type], surface.expolygon);
|
||||
}
|
||||
// Trim surfaces by the fill_boundaries.
|
||||
@ -53,7 +53,7 @@ void LayerRegion::slices_to_fill_surfaces_clipped()
|
||||
}
|
||||
}
|
||||
|
||||
void LayerRegion::make_perimeters(SurfaceCollection &slices, SurfaceCollection* fill_surfaces)
|
||||
void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces)
|
||||
{
|
||||
this->perimeters.clear();
|
||||
this->thin_fills.clear();
|
||||
@ -438,7 +438,7 @@ void LayerRegion::trim_surfaces(const Polygons &trimming_polygons)
|
||||
for (const Surface &surface : this->slices.surfaces)
|
||||
assert(surface.surface_type == (stPosInternal | stDensSparse));
|
||||
#endif /* NDEBUG */
|
||||
this->slices.set(intersection_ex(to_polygons(std::move(this->slices.surfaces)), trimming_polygons, false), stPosInternal | stDensSparse);
|
||||
this->m_slices.set(intersection_ex(to_polygons(std::move(this->slices().surfaces)), trimming_polygons, false), stPosInternal | stDensSparse);
|
||||
}
|
||||
|
||||
void LayerRegion::elephant_foot_compensation_step(const float elephant_foot_compensation_perimeter_step, const Polygons &trimming_polygons)
|
||||
@ -447,25 +447,25 @@ void LayerRegion::elephant_foot_compensation_step(const float elephant_foot_comp
|
||||
for (const Surface &surface : this->slices.surfaces)
|
||||
assert(surface.surface_type == (stPosInternal | stDensSparse));
|
||||
#endif /* NDEBUG */
|
||||
ExPolygons slices_expolygons = to_expolygons(std::move(this->slices.surfaces));
|
||||
ExPolygons slices_expolygons = to_expolygons(std::move(this->slices().surfaces));
|
||||
Polygons slices_polygons = to_polygons(slices_expolygons);
|
||||
Polygons tmp = intersection(slices_polygons, trimming_polygons, false);
|
||||
append(tmp, diff(slices_polygons, offset(offset_ex(slices_expolygons, -elephant_foot_compensation_perimeter_step), elephant_foot_compensation_perimeter_step)));
|
||||
this->slices.set(std::move(union_ex(tmp)), stPosInternal | stDensSparse);
|
||||
this->m_slices.set(std::move(union_ex(tmp)), stPosInternal | stDensSparse);
|
||||
}
|
||||
|
||||
void LayerRegion::export_region_slices_to_svg(const char *path) const
|
||||
{
|
||||
BoundingBox bbox;
|
||||
for (Surfaces::const_iterator surface = this->slices.surfaces.begin(); surface != this->slices.surfaces.end(); ++surface)
|
||||
bbox.merge(get_extents(surface->expolygon));
|
||||
for (const Surface& surface : this->slices().surfaces)
|
||||
bbox.merge(get_extents(surface.expolygon));
|
||||
Point legend_size = export_surface_type_legend_to_svg_box_size();
|
||||
Point legend_pos(bbox.min(0), bbox.max(1));
|
||||
bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
|
||||
|
||||
SVG svg(path, bbox);
|
||||
const float transparency = 0.5f;
|
||||
for (Surfaces::const_iterator surface = this->slices.surfaces.begin(); surface != this->slices.surfaces.end(); ++surface)
|
||||
for (Surfaces::const_iterator surface = this->slices().surfaces.begin(); surface != this->slices().surfaces.end(); ++surface)
|
||||
svg.draw(surface->expolygon, surface_type_to_color_name(surface->surface_type), transparency);
|
||||
for (Surfaces::const_iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface)
|
||||
svg.draw(surface->expolygon.lines(), surface_type_to_color_name(surface->surface_type));
|
||||
|
@ -353,7 +353,7 @@ void Print::_simplify_slices(double distance)
|
||||
for (Layer *layer : object->m_layers) {
|
||||
layer->slices.simplify(distance);
|
||||
for (LayerRegion *layerm : layer->regions())
|
||||
layerm->slices.simplify(distance);
|
||||
layerm->m_slices.simplify(distance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +185,6 @@ private:
|
||||
void _smooth_curves(LayerRegion *layerm);
|
||||
std::string _fix_slicing_errors();
|
||||
void _simplify_slices(double distance);
|
||||
void _make_perimeters();
|
||||
bool has_support_material() const;
|
||||
void detect_surfaces_type();
|
||||
void process_external_surfaces();
|
||||
|
@ -170,7 +170,7 @@ void PrintObject::make_perimeters()
|
||||
m_print->throw_if_canceled();
|
||||
LayerRegion &layerm = *m_layers[layer_idx]->m_regions[region_id];
|
||||
const LayerRegion &upper_layerm = *m_layers[layer_idx+1]->m_regions[region_id];
|
||||
const Polygons upper_layerm_polygons = upper_layerm.slices;
|
||||
const Polygons upper_layerm_polygons = upper_layerm.slices();
|
||||
// Filter upper layer polygons in intersection_ppl by their bounding boxes?
|
||||
// my $upper_layerm_poly_bboxes= [ map $_->bounding_box, @{$upper_layerm_polygons} ];
|
||||
const double total_loop_length = total_length(upper_layerm_polygons);
|
||||
@ -179,7 +179,7 @@ void PrintObject::make_perimeters()
|
||||
const coord_t ext_perimeter_width = ext_perimeter_flow.scaled_width();
|
||||
const coord_t ext_perimeter_spacing = ext_perimeter_flow.scaled_spacing();
|
||||
|
||||
for (Surface &slice : layerm.slices.surfaces) {
|
||||
for (Surface &slice : layerm.m_slices.surfaces) {
|
||||
for (;;) {
|
||||
// compute the total thickness of perimeters
|
||||
const coord_t perimeters_thickness = ext_perimeter_width/2 + ext_perimeter_spacing/2
|
||||
@ -924,20 +924,21 @@ void PrintObject::detect_surfaces_type()
|
||||
// unless internal shells are requested
|
||||
Layer *upper_layer = (idx_layer + 1 < this->layer_count()) ? m_layers[idx_layer + 1] : nullptr;
|
||||
Layer *lower_layer = (idx_layer > 0) ? m_layers[idx_layer - 1] : nullptr;
|
||||
Layer *under_lower_layer = (idx_layer > 1) ? this->layers()[idx_layer - 2] : nullptr;
|
||||
// collapse very narrow parts (using the safety offset in the diff is not enough)
|
||||
float offset = layerm->flow(frExternalPerimeter).scaled_width() / 10.f;
|
||||
|
||||
Polygons layerm_slices_surfaces = to_polygons(layerm->slices().surfaces);
|
||||
// no_perimeter_full_bridge allow to put bridges where there are nothing, hence adding area to silce, that's why we need to start from the result of PerimeterGenerator.
|
||||
// i don't see the need tostart from layerm->slices.surfaces, but i'll keep that "in case of".
|
||||
Polygons layerm_slices_surfaces = layerm->region()->config().no_perimeter_unsupported_algo == npuaFilled ? to_polygons(layerm->fill_surfaces) : to_polygons(layerm->slices.surfaces);
|
||||
if (layerm->region()->config().no_perimeter_unsupported_algo == npuaFilled) {
|
||||
layerm_slices_surfaces = union_(layerm_slices_surfaces, to_polygons(layerm->fill_surfaces));
|
||||
}
|
||||
|
||||
// find top surfaces (difference between current surfaces
|
||||
// of current layer and upper one)
|
||||
Surfaces top;
|
||||
if (upper_layer) {
|
||||
Polygons upper_slices = interface_shells ?
|
||||
to_polygons(upper_layer->get_region(idx_region)->slices.surfaces) :
|
||||
to_polygons(upper_layer->get_region(idx_region)->slices().surfaces) :
|
||||
to_polygons(upper_layer->slices);
|
||||
surfaces_append(top,
|
||||
//FIXME implement offset2_ex working over ExPolygons, that should be a bit more efficient than calling offset_ex twice.
|
||||
@ -946,7 +947,7 @@ void PrintObject::detect_surfaces_type()
|
||||
} else {
|
||||
// if no upper layer, all surfaces of this one are solid
|
||||
// we clone surfaces because we're going to clear the slices collection
|
||||
top = layerm->slices.surfaces;
|
||||
top = layerm->m_slices.surfaces;
|
||||
for (Surface &surface : top)
|
||||
surface.surface_type = stPosTop | stDensSolid;
|
||||
}
|
||||
@ -985,7 +986,7 @@ void PrintObject::detect_surfaces_type()
|
||||
offset2_ex(
|
||||
diff(
|
||||
intersection(layerm_slices_surfaces, to_polygons(lower_slices)), // supported
|
||||
to_polygons(lower_layer->get_region(idx_region)->slices.surfaces),
|
||||
to_polygons(lower_layer->get_region(idx_region)->slices().surfaces),
|
||||
true),
|
||||
-offset, offset),
|
||||
stPosBottom | stDensSolid);
|
||||
@ -994,7 +995,7 @@ void PrintObject::detect_surfaces_type()
|
||||
} else {
|
||||
// if no lower layer, all surfaces of this one are solid
|
||||
// we clone surfaces because we're going to clear the slices collection
|
||||
bottom = layerm->slices.surfaces;
|
||||
bottom = layerm->slices().surfaces;
|
||||
for (Surface &surface : bottom)
|
||||
surface.surface_type = surface_type_bottom_1st;
|
||||
}
|
||||
@ -1019,14 +1020,13 @@ void PrintObject::detect_surfaces_type()
|
||||
std::vector<std::pair<Slic3r::ExPolygons, SVG::ExPolygonAttributes>> expolygons_with_attributes;
|
||||
expolygons_with_attributes.emplace_back(std::make_pair(union_ex(top), SVG::ExPolygonAttributes("green")));
|
||||
expolygons_with_attributes.emplace_back(std::make_pair(union_ex(bottom), SVG::ExPolygonAttributes("brown")));
|
||||
expolygons_with_attributes.emplace_back(std::make_pair(union_ex(bottomOverBridge), SVG::ExPolygonAttributes("grey")));
|
||||
expolygons_with_attributes.emplace_back(std::make_pair(to_expolygons(layerm->slices.surfaces), SVG::ExPolygonAttributes("black")));
|
||||
expolygons_with_attributes.emplace_back(std::make_pair(to_expolygons(layerm->slices().surfaces), SVG::ExPolygonAttributes("black")));
|
||||
SVG::export_expolygons(debug_out_path("1_detect_surfaces_type_%d_region%d-layer_%f.svg", iRun ++, idx_region, layer->print_z).c_str(), expolygons_with_attributes);
|
||||
}
|
||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||
|
||||
// save surfaces to layer
|
||||
Surfaces &surfaces_out = interface_shells ? surfaces_new[idx_layer] : layerm->slices.surfaces;
|
||||
Surfaces &surfaces_out = interface_shells ? surfaces_new[idx_layer] : layerm->m_slices.surfaces;
|
||||
surfaces_out.clear();
|
||||
|
||||
// find internal surfaces (difference between top/bottom surfaces and others)
|
||||
@ -1054,8 +1054,8 @@ void PrintObject::detect_surfaces_type()
|
||||
|
||||
if (interface_shells) {
|
||||
// Move surfaces_new to layerm->slices.surfaces
|
||||
for (size_t idx_layer = 0; idx_layer < m_layers.size(); ++ idx_layer)
|
||||
m_layers[idx_layer]->get_region(idx_region)->slices.surfaces = std::move(surfaces_new[idx_layer]);
|
||||
for (size_t idx_layer = 0; idx_layer < m_layers.size(); ++idx_layer)
|
||||
m_layers[idx_layer]->get_region(idx_region)->m_slices.surfaces = std::move(surfaces_new[idx_layer]);
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " - clipping in parallel - start";
|
||||
@ -1211,16 +1211,16 @@ void PrintObject::discover_vertical_shells()
|
||||
LayerRegion &layerm = *layer.m_regions[idx_region];
|
||||
float min_perimeter_infill_spacing = float(layerm.flow(frSolidInfill).scaled_spacing()) * 1.05f;
|
||||
// Top surfaces.
|
||||
append(cache.top_surfaces, offset(to_expolygons(layerm.slices.filter_by_type(stPosTop | stDensSolid)), min_perimeter_infill_spacing));
|
||||
append(cache.top_surfaces, offset(to_expolygons(layerm.slices().filter_by_type(stPosTop | stDensSolid)), min_perimeter_infill_spacing));
|
||||
append(cache.top_surfaces, offset(to_expolygons(layerm.fill_surfaces.filter_by_type(stPosTop | stDensSolid)), min_perimeter_infill_spacing));
|
||||
// Bottom surfaces.
|
||||
const SurfaceType surfaces_bottom[2] = { stPosBottom | stDensSolid, stPosBottom | stDensSolid | stModBridge };
|
||||
append(cache.bottom_surfaces, offset(to_expolygons(layerm.slices.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing));
|
||||
append(cache.bottom_surfaces, offset(to_expolygons(layerm.slices().filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing));
|
||||
append(cache.bottom_surfaces, offset(to_expolygons(layerm.fill_surfaces.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing));
|
||||
// Calculate the maximum perimeter offset as if the slice was extruded with a single extruder only.
|
||||
// First find the maxium number of perimeters per region slice.
|
||||
unsigned int perimeters = 0;
|
||||
for (Surface &s : layerm.slices.surfaces)
|
||||
for (const Surface &s : layerm.slices().surfaces)
|
||||
perimeters = std::max<unsigned int>(perimeters, s.extra_perimeters);
|
||||
perimeters += layerm.region()->config().perimeters.value;
|
||||
// Then calculate the infill offset.
|
||||
@ -1287,11 +1287,11 @@ void PrintObject::discover_vertical_shells()
|
||||
float min_perimeter_infill_spacing = float(layerm.flow(frSolidInfill).scaled_spacing()) * 1.05f;
|
||||
// Top surfaces.
|
||||
auto &cache = cache_top_botom_regions[idx_layer];
|
||||
cache.top_surfaces = offset(to_expolygons(layerm.slices.filter_by_type(stPosTop | stDensSolid)), min_perimeter_infill_spacing);
|
||||
cache.top_surfaces = offset(to_expolygons(layerm.slices().filter_by_type(stPosTop | stDensSolid)), min_perimeter_infill_spacing);
|
||||
append(cache.top_surfaces, offset(to_expolygons(layerm.fill_surfaces.filter_by_type(stPosTop | stDensSolid)), min_perimeter_infill_spacing));
|
||||
// Bottom surfaces.
|
||||
const SurfaceType surfaces_bottom[2] = { stPosBottom | stDensSolid, stPosBottom | stDensSolid | stModBridge };
|
||||
cache.bottom_surfaces = offset(to_expolygons(layerm.slices.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing);
|
||||
cache.bottom_surfaces = offset(to_expolygons(layerm.slices().filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing);
|
||||
append(cache.bottom_surfaces, offset(to_expolygons(layerm.fill_surfaces.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing));
|
||||
// Holes over all regions. Only collect them once, they are valid for all idx_region iterations.
|
||||
if (cache.holes.empty()) {
|
||||
@ -1939,7 +1939,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
||||
m_print->throw_if_canceled();
|
||||
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - append slices " << region_id << " start";
|
||||
for (size_t layer_id = 0; layer_id < expolygons_by_layer.size(); ++ layer_id)
|
||||
m_layers[layer_id]->regions()[region_id]->slices.append(std::move(expolygons_by_layer[layer_id]), stPosInternal | stDensSparse);
|
||||
m_layers[layer_id]->regions()[region_id]->m_slices.append(std::move(expolygons_by_layer[layer_id]), stPosInternal | stDensSparse);
|
||||
m_print->throw_if_canceled();
|
||||
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - append slices " << region_id << " end";
|
||||
}
|
||||
@ -2018,7 +2018,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
||||
if (num_volumes > 1)
|
||||
// Merge the islands using a positive / negative offset.
|
||||
expolygons = offset_ex(offset_ex(expolygons, double(scale_(EPSILON))), double( - scale_(EPSILON)));
|
||||
m_layers[layer_id]->regions()[region_id]->slices.append(std::move(expolygons), stPosInternal | stDensSparse);
|
||||
m_layers[layer_id]->regions()[region_id]->m_slices.append(std::move(expolygons), stPosInternal | stDensSparse);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -2048,16 +2048,16 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
||||
Layer *layer = m_layers[layer_id];
|
||||
LayerRegion *layerm = layer->m_regions[region_id];
|
||||
LayerRegion *other_layerm = layer->m_regions[other_region_id];
|
||||
if (layerm == nullptr || other_layerm == nullptr || other_layerm->slices.empty() || expolygons_by_layer[layer_id].empty())
|
||||
if (layerm == nullptr || other_layerm == nullptr || other_layerm->slices().empty() || expolygons_by_layer[layer_id].empty())
|
||||
continue;
|
||||
Polygons other_slices = to_polygons(other_layerm->slices);
|
||||
Polygons other_slices = to_polygons(other_layerm->slices());
|
||||
ExPolygons my_parts = intersection_ex(other_slices, to_polygons(expolygons_by_layer[layer_id]));
|
||||
if (my_parts.empty())
|
||||
continue;
|
||||
// Remove such parts from original region.
|
||||
other_layerm->slices.set(diff_ex(other_slices, to_polygons(my_parts)), stPosInternal | stDensSparse);
|
||||
other_layerm->m_slices.set(diff_ex(other_slices, to_polygons(my_parts)), stPosInternal | stDensSparse);
|
||||
// Append new parts to our region.
|
||||
layerm->slices.append(std::move(my_parts), stPosInternal | stDensSparse);
|
||||
layerm->m_slices.append(std::move(my_parts), stPosInternal | stDensSparse);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -2114,8 +2114,8 @@ end:
|
||||
LayerRegion *layerm = layer->m_regions.front();
|
||||
// Apply the XY compensation.
|
||||
ExPolygons expolygons = (delta == 0.f) ?
|
||||
to_expolygons(std::move(layerm->slices.surfaces)) :
|
||||
offset_ex(to_expolygons(std::move(layerm->slices.surfaces)), delta);
|
||||
to_expolygons(std::move(layerm->slices().surfaces)) :
|
||||
offset_ex(to_expolygons(std::move(layerm->slices().surfaces)), delta);
|
||||
// Apply the elephant foot compensation.
|
||||
if (elephant_foot_compensation != 0) {
|
||||
float elephant_foot_spacing = float(layerm->flow(frExternalPerimeter).scaled_elephant_foot_spacing());
|
||||
@ -2130,7 +2130,7 @@ end:
|
||||
expolygons = union_ex(tmp);
|
||||
}
|
||||
}
|
||||
layerm->slices.set(std::move(expolygons), stPosInternal | stDensSparse);
|
||||
layerm->m_slices.set(std::move(expolygons), stPosInternal | stDensSparse);
|
||||
}
|
||||
_offset_holes(hole_delta, layer->regions().front());
|
||||
_smooth_curves(layer->regions().front());
|
||||
@ -2143,7 +2143,7 @@ end:
|
||||
Polygons processed;
|
||||
for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) {
|
||||
LayerRegion *layerm = layer->m_regions[region_id];
|
||||
ExPolygons slices = to_expolygons(std::move(layerm->slices.surfaces));
|
||||
ExPolygons slices = to_expolygons(std::move(layerm->slices().surfaces));
|
||||
if (upscale)
|
||||
slices = offset_ex(std::move(slices), delta);
|
||||
if (region_id > 0 && clip)
|
||||
@ -2152,7 +2152,7 @@ end:
|
||||
if (clip && (region_id + 1 < layer->m_regions.size()))
|
||||
// Collect the already processed regions to trim the to be processed regions.
|
||||
polygons_append(processed, slices);
|
||||
layerm->slices.set(std::move(slices), stPosInternal | stDensSparse);
|
||||
layerm->m_slices.set(std::move(slices), stPosInternal | stDensSparse);
|
||||
}
|
||||
}
|
||||
if (delta < 0.f) {
|
||||
@ -2193,7 +2193,7 @@ end:
|
||||
|
||||
void PrintObject::_offset_holes(double hole_delta, LayerRegion *layerm) {
|
||||
if (hole_delta != 0.f) {
|
||||
ExPolygons polys = to_expolygons(std::move(layerm->slices.surfaces));
|
||||
ExPolygons polys = to_expolygons(std::move(layerm->slices().surfaces));
|
||||
ExPolygons new_polys;
|
||||
for (const ExPolygon &ex_poly : polys) {
|
||||
ExPolygon new_ex_poly(ex_poly);
|
||||
@ -2226,7 +2226,7 @@ void PrintObject::_offset_holes(double hole_delta, LayerRegion *layerm) {
|
||||
}
|
||||
new_polys.push_back(new_ex_poly);
|
||||
}
|
||||
layerm->slices.set(std::move(new_polys), stPosInternal | stDensSparse);
|
||||
layerm->m_slices.set(std::move(new_polys), stPosInternal | stDensSparse);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2317,7 +2317,7 @@ void PrintObject::_smooth_curves(LayerRegion *layerm) {
|
||||
|
||||
if (layerm->region()->config().curve_smoothing_precision.value > 0.f) {
|
||||
ExPolygons new_polys;
|
||||
for (const Surface &srf : layerm->slices.surfaces) {
|
||||
for (const Surface &srf : layerm->slices().surfaces) {
|
||||
const ExPolygon &ex_poly = srf.expolygon;
|
||||
ExPolygon new_ex_poly(ex_poly);
|
||||
new_ex_poly.contour = _smooth_curve(new_ex_poly.contour, PI,
|
||||
@ -2336,7 +2336,7 @@ void PrintObject::_smooth_curves(LayerRegion *layerm) {
|
||||
}
|
||||
new_polys.push_back(new_ex_poly);
|
||||
}
|
||||
layerm->slices.set(std::move(new_polys), stPosInternal | stDensSparse);
|
||||
layerm->m_slices.set(std::move(new_polys), stPosInternal | stDensSparse);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2591,12 +2591,12 @@ std::string PrintObject::_fix_slicing_errors()
|
||||
const Surfaces *lower_surfaces = nullptr;
|
||||
for (size_t j = idx_layer + 1; j < m_layers.size(); ++ j)
|
||||
if (! m_layers[j]->slicing_errors) {
|
||||
upper_surfaces = &m_layers[j]->regions()[region_id]->slices.surfaces;
|
||||
upper_surfaces = &m_layers[j]->regions()[region_id]->slices().surfaces;
|
||||
break;
|
||||
}
|
||||
for (int j = int(idx_layer) - 1; j >= 0; -- j)
|
||||
if (! m_layers[j]->slicing_errors) {
|
||||
lower_surfaces = &m_layers[j]->regions()[region_id]->slices.surfaces;
|
||||
lower_surfaces = &m_layers[j]->regions()[region_id]->slices().surfaces;
|
||||
break;
|
||||
}
|
||||
// Collect outer contours and holes from the valid layers above & below.
|
||||
@ -2623,7 +2623,7 @@ std::string PrintObject::_fix_slicing_errors()
|
||||
if (lower_surfaces)
|
||||
for (const auto &surface : *lower_surfaces)
|
||||
polygons_append(holes, surface.expolygon.holes);
|
||||
layerm->slices.set(diff_ex(union_(outer), holes, false), stPosInternal | stDensSparse);
|
||||
layerm->m_slices.set(diff_ex(union_(outer), holes, false), stPosInternal | stDensSparse);
|
||||
}
|
||||
// Update layer slices after repairing the single regions.
|
||||
layer->make_slices();
|
||||
@ -2659,115 +2659,13 @@ void PrintObject::_simplify_slices(double distance)
|
||||
m_print->throw_if_canceled();
|
||||
Layer *layer = m_layers[layer_idx];
|
||||
for (size_t region_idx = 0; region_idx < layer->m_regions.size(); ++ region_idx)
|
||||
layer->m_regions[region_idx]->slices.simplify(distance);
|
||||
layer->m_regions[region_idx]->m_slices.simplify(distance);
|
||||
layer->slices.simplify(distance);
|
||||
}
|
||||
});
|
||||
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - siplifying slices in parallel - end";
|
||||
}
|
||||
|
||||
void PrintObject::_make_perimeters()
|
||||
{
|
||||
if (! this->set_started(posPerimeters))
|
||||
return;
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Generating perimeters..." << log_memory_info();
|
||||
|
||||
// merge slices if they were split into types
|
||||
if (this->typed_slices) {
|
||||
for (Layer *layer : m_layers)
|
||||
layer->merge_slices();
|
||||
this->typed_slices = false;
|
||||
this->invalidate_step(posPrepareInfill);
|
||||
}
|
||||
|
||||
// compare each layer to the one below, and mark those slices needing
|
||||
// one additional inner perimeter, like the top of domed objects-
|
||||
|
||||
// this algorithm makes sure that at least one perimeter is overlapping
|
||||
// but we don't generate any extra perimeter if fill density is zero, as they would be floating
|
||||
// inside the object - infill_only_where_needed should be the method of choice for printing
|
||||
// hollow objects
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
const PrintRegion ®ion = *m_print->regions()[region_id];
|
||||
if (! region.config().extra_perimeters || region.config().perimeters == 0 || region.config().fill_density == 0 || this->layer_count() < 2)
|
||||
continue;
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Generating extra perimeters for region " << region_id << " in parallel - start";
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<size_t>(0, m_layers.size() - 1),
|
||||
[this, ®ion, region_id](const tbb::blocked_range<size_t>& range) {
|
||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
|
||||
LayerRegion &layerm = *m_layers[layer_idx]->regions()[region_id];
|
||||
const LayerRegion &upper_layerm = *m_layers[layer_idx+1]->regions()[region_id];
|
||||
const Polygons upper_layerm_polygons = upper_layerm.slices;
|
||||
// Filter upper layer polygons in intersection_ppl by their bounding boxes?
|
||||
// my $upper_layerm_poly_bboxes= [ map $_->bounding_box, @{$upper_layerm_polygons} ];
|
||||
const double total_loop_length = total_length(upper_layerm_polygons);
|
||||
const coord_t perimeter_spacing = layerm.flow(frPerimeter).scaled_spacing();
|
||||
const Flow ext_perimeter_flow = layerm.flow(frExternalPerimeter);
|
||||
const coord_t ext_perimeter_width = ext_perimeter_flow.scaled_width();
|
||||
const coord_t ext_perimeter_spacing = ext_perimeter_flow.scaled_spacing();
|
||||
|
||||
for (Surface &slice : layerm.slices.surfaces) {
|
||||
for (;;) {
|
||||
// compute the total thickness of perimeters
|
||||
const coord_t perimeters_thickness = ext_perimeter_width/2 + ext_perimeter_spacing/2
|
||||
+ (region.config().perimeters-1 + slice.extra_perimeters) * perimeter_spacing;
|
||||
// define a critical area where we don't want the upper slice to fall into
|
||||
// (it should either lay over our perimeters or outside this area)
|
||||
const coord_t critical_area_depth = coord_t(perimeter_spacing * 1.5);
|
||||
const Polygons critical_area = diff(
|
||||
offset(slice.expolygon, double(- perimeters_thickness)),
|
||||
offset(slice.expolygon, double(- perimeters_thickness - critical_area_depth))
|
||||
);
|
||||
// check whether a portion of the upper slices falls inside the critical area
|
||||
const Polylines intersection = intersection_pl(to_polylines(upper_layerm_polygons), critical_area);
|
||||
// only add an additional loop if at least 30% of the slice loop would benefit from it
|
||||
if (total_length(intersection) <= total_loop_length*0.3)
|
||||
break;
|
||||
/*
|
||||
if (0) {
|
||||
require "Slic3r/SVG.pm";
|
||||
Slic3r::SVG::output(
|
||||
"extra.svg",
|
||||
no_arrows => 1,
|
||||
expolygons => union_ex($critical_area),
|
||||
polylines => [ map $_->split_at_first_point, map $_->p, @{$upper_layerm->slices} ],
|
||||
);
|
||||
}
|
||||
*/
|
||||
++ slice.extra_perimeters;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (slice.extra_perimeters > 0)
|
||||
printf(" adding %d more perimeter(s) at layer %zu\n", slice.extra_perimeters, layer_idx);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
});
|
||||
BOOST_LOG_TRIVIAL(debug) << "Generating extra perimeters for region " << region_id << " in parallel - end";
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Generating perimeters in parallel - start";
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<size_t>(0, m_layers.size()),
|
||||
[this](const tbb::blocked_range<size_t>& range) {
|
||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx)
|
||||
m_layers[layer_idx]->make_perimeters();
|
||||
}
|
||||
);
|
||||
BOOST_LOG_TRIVIAL(debug) << "Generating perimeters in parallel - end";
|
||||
|
||||
/*
|
||||
simplify slices (both layer and region slices),
|
||||
we only need the max resolution for perimeters
|
||||
### This makes this method not-idempotent, so we keep it disabled for now.
|
||||
###$self->_simplify_slices(&Slic3r::SCALED_RESOLUTION);
|
||||
*/
|
||||
|
||||
this->set_done(posPerimeters);
|
||||
}
|
||||
|
||||
// Only active if config->infill_only_where_needed. This step trims the sparse infill,
|
||||
// so it acts as an internal support. It maintains all other infill types intact.
|
||||
@ -2895,7 +2793,7 @@ void PrintObject::discover_horizontal_shells()
|
||||
// (not covered by a layer above / below).
|
||||
// This does not contain the areas covered by perimeters!
|
||||
Polygons solid;
|
||||
for (const Surface &surface : layerm->slices.surfaces)
|
||||
for (const Surface &surface : layerm->slices().surfaces)
|
||||
if (surface.surface_type == type)
|
||||
polygons_append(solid, to_polygons(surface.expolygon));
|
||||
// Infill areas (slices without the perimeters).
|
||||
|
@ -279,7 +279,6 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
|
||||
MyLayersPtr intermediate_layers = this->raft_and_intermediate_support_layers(
|
||||
object, bottom_contacts, top_contacts, layer_storage);
|
||||
|
||||
|
||||
// this->trim_support_layers_by_object(object, top_contacts, m_slicing_params.soluble_interface ? 0. : m_support_layer_height_min, 0., m_gap_xy);
|
||||
this->trim_support_layers_by_object(object, top_contacts,
|
||||
m_slicing_params.soluble_interface ? 0. : this->m_slicing_params.gap_support_object,
|
||||
@ -429,14 +428,14 @@ Polygons collect_region_slices_by_type(const Layer &layer, SurfaceType surface_t
|
||||
// 1) Count the new polygons first.
|
||||
size_t n_polygons_new = 0;
|
||||
for (const LayerRegion *region : layer.regions())
|
||||
for (const Surface &surface : region->slices.surfaces)
|
||||
for (const Surface &surface : region->slices().surfaces)
|
||||
if (surface.surface_type == surface_type)
|
||||
n_polygons_new += surface.expolygon.holes.size() + 1;
|
||||
// 2) Collect the new polygons.
|
||||
Polygons out;
|
||||
out.reserve(n_polygons_new);
|
||||
for (const LayerRegion *region : layer.regions())
|
||||
for (const Surface &surface : region->slices.surfaces)
|
||||
for (const Surface &surface : region->slices().surfaces)
|
||||
if (surface.surface_type == surface_type)
|
||||
polygons_append(out, surface.expolygon);
|
||||
return out;
|
||||
@ -791,7 +790,6 @@ namespace SupportMaterialInternal {
|
||||
{
|
||||
for (const ExtrusionEntity *ee : perimeters.entities) {
|
||||
if (ee->is_collection()) {
|
||||
const ExtrusionEntityCollection * eec = static_cast<const ExtrusionEntityCollection*>(ee);
|
||||
for (const ExtrusionEntity *ee2 : static_cast<const ExtrusionEntityCollection*>(ee)->entities) {
|
||||
//assert(! ee2->is_collection()); // there are loops for perimeters and collections for thin walls !!
|
||||
if (ee2->is_loop())
|
||||
@ -854,15 +852,11 @@ namespace SupportMaterialInternal {
|
||||
}
|
||||
}
|
||||
}
|
||||
static void collect_bridging_perimeter_areas(const ExtrusionEntityCollection &perimeters, const float expansion_scaled, Polygons &out)
|
||||
static void collect_bridging_perimeter_areas(const ExtrusionEntitiesPtr &perimeters, const float expansion_scaled, Polygons &out)
|
||||
{
|
||||
for (const ExtrusionEntity *ee : perimeters.entities) {
|
||||
for (const ExtrusionEntity *ee : perimeters) {
|
||||
if (ee->is_collection()) {
|
||||
for (const ExtrusionEntity *ee2 : static_cast<const ExtrusionEntityCollection*>(ee)->entities) {
|
||||
//assert(! ee2->is_collection()); // there are loops for perimeters and collections for thin walls !!
|
||||
if (ee2->is_loop())
|
||||
collect_bridging_perimeter_areas(*static_cast<const ExtrusionLoop*>(ee2), expansion_scaled, out);
|
||||
}
|
||||
collect_bridging_perimeter_areas(static_cast<const ExtrusionEntityCollection*>(ee)->entities, expansion_scaled, out);
|
||||
} else if (ee->is_loop())
|
||||
collect_bridging_perimeter_areas(*static_cast<const ExtrusionLoop*>(ee), expansion_scaled, out);
|
||||
}
|
||||
@ -1027,7 +1021,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
||||
Polygons contact_polygons;
|
||||
Polygons slices_margin_cached;
|
||||
double slices_margin_cached_offset = -1.;
|
||||
Polygons lower_layer_polygons = (layer_id == 0) ? Polygons() : to_polygons(object.layers()[layer_id-1]->slices.expolygons);
|
||||
Polygons lower_layer_polygons = (layer_id == 0) ? Polygons() : to_polygons(object.layers()[layer_id - 1]->slices.expolygons);
|
||||
// Offset of the lower layer, to trim the support polygons with to calculate dense supports.
|
||||
double no_interface_offset = 0.;
|
||||
if (layer_id == 0) {
|
||||
@ -1056,7 +1050,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
||||
0.5f * fw);
|
||||
// Overhang polygons for this layer and region.
|
||||
Polygons diff_polygons;
|
||||
Polygons layerm_polygons = to_polygons(layerm->slices);
|
||||
Polygons layerm_polygons = to_polygons(layerm->slices());
|
||||
if (lower_layer_offset == 0.f) {
|
||||
// Support everything.
|
||||
diff_polygons = diff(layerm_polygons, lower_layer_polygons);
|
||||
@ -1466,7 +1460,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
|
||||
if (! m_object_config->support_material_buildplate_only)
|
||||
// Find the bottom contact layers above the top surfaces of this layer.
|
||||
task_group.run([this, &object, &top_contacts, contact_idx, &layer, layer_id, &layer_storage, &layer_support_areas, &bottom_contacts, &projection_raw] {
|
||||
Polygons top = collect_region_slices_by_type(layer, stPosTop| stDensSolid);
|
||||
Polygons top = collect_region_slices_by_type(layer, stPosTop | stDensSolid);
|
||||
#ifdef SLIC3R_DEBUG
|
||||
{
|
||||
BoundingBox bbox = get_extents(projection_raw);
|
||||
@ -1538,7 +1532,6 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SLIC3R_DEBUG
|
||||
Slic3r::SVG::export_expolygons(
|
||||
debug_out_path("support-bottom-contacts-%d-%lf.svg", iRun, layer_new.print_z),
|
||||
@ -2135,7 +2128,7 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object(
|
||||
offset(to_expolygons(region->fill_surfaces.filter_by_type(stPosBottom | stDensSolid | stModBridge)),
|
||||
gap_xy_scaled, SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
||||
if (region->region()->config().overhangs.value)
|
||||
SupportMaterialInternal::collect_bridging_perimeter_areas(region->perimeters, gap_xy_scaled, polygons_trimming);
|
||||
SupportMaterialInternal::collect_bridging_perimeter_areas(region->perimeters.entities, gap_xy_scaled, polygons_trimming);
|
||||
}
|
||||
if (! some_region_overlaps)
|
||||
break;
|
||||
|
@ -140,6 +140,7 @@ public:
|
||||
|
||||
typedef std::vector<Surface> Surfaces;
|
||||
typedef std::vector<Surface*> SurfacesPtr;
|
||||
typedef std::vector<const Surface*> SurfacesConstPtr;
|
||||
|
||||
inline Polygons to_polygons(const Surfaces &src)
|
||||
{
|
||||
@ -171,6 +172,21 @@ inline Polygons to_polygons(const SurfacesPtr &src)
|
||||
return polygons;
|
||||
}
|
||||
|
||||
inline Polygons to_polygons(const SurfacesConstPtr &src)
|
||||
{
|
||||
size_t num = 0;
|
||||
for (SurfacesConstPtr::const_iterator it = src.begin(); it != src.end(); ++it)
|
||||
num += (*it)->expolygon.holes.size() + 1;
|
||||
Polygons polygons;
|
||||
polygons.reserve(num);
|
||||
for (SurfacesConstPtr::const_iterator it = src.begin(); it != src.end(); ++it) {
|
||||
polygons.emplace_back((*it)->expolygon.contour);
|
||||
for (Polygons::const_iterator ith = (*it)->expolygon.holes.begin(); ith != (*it)->expolygon.holes.end(); ++ith)
|
||||
polygons.emplace_back(*ith);
|
||||
}
|
||||
return polygons;
|
||||
}
|
||||
|
||||
inline ExPolygons to_expolygons(const Surfaces &src)
|
||||
{
|
||||
ExPolygons expolygons;
|
||||
@ -199,6 +215,15 @@ inline ExPolygons to_expolygons(const SurfacesPtr &src)
|
||||
return expolygons;
|
||||
}
|
||||
|
||||
inline ExPolygons to_expolygons(const SurfacesConstPtr &src)
|
||||
{
|
||||
ExPolygons expolygons;
|
||||
expolygons.reserve(src.size());
|
||||
for (SurfacesConstPtr::const_iterator it = src.begin(); it != src.end(); ++it)
|
||||
expolygons.emplace_back((*it)->expolygon);
|
||||
return expolygons;
|
||||
}
|
||||
|
||||
// Count a nuber of polygons stored inside the vector of expolygons.
|
||||
// Useful for allocating space for polygons when converting expolygons to polygons.
|
||||
inline size_t number_polygons(const Surfaces &surfaces)
|
||||
|
@ -54,34 +54,34 @@ SurfaceCollection::group(std::vector<SurfacesPtr> *retval)
|
||||
}
|
||||
}
|
||||
|
||||
SurfacesPtr
|
||||
SurfaceCollection::filter_by_type(const SurfaceType type)
|
||||
SurfacesConstPtr
|
||||
SurfaceCollection::filter_by_type(const SurfaceType type) const
|
||||
{
|
||||
SurfacesPtr ss;
|
||||
for (Surfaces::iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface) {
|
||||
if (surface->surface_type == type) ss.push_back(&*surface);
|
||||
SurfacesConstPtr ss;
|
||||
for (const Surface & surface : this->surfaces) {
|
||||
if (surface.surface_type == type) ss.push_back(&surface);
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
|
||||
SurfacesPtr
|
||||
SurfaceCollection::filter_by_type_flag(const SurfaceType allowed, const SurfaceType not_allowed)
|
||||
SurfacesConstPtr
|
||||
SurfaceCollection::filter_by_type_flag(const SurfaceType allowed, const SurfaceType not_allowed) const
|
||||
{
|
||||
SurfacesPtr ss;
|
||||
for (Surfaces::iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface) {
|
||||
if ((surface->surface_type & allowed) == allowed && (surface->surface_type & not_allowed) == 0) ss.push_back(&*surface);
|
||||
SurfacesConstPtr ss;
|
||||
for (const Surface & surface : this->surfaces) {
|
||||
if ((surface.surface_type & allowed) == allowed && (surface.surface_type & not_allowed) == 0) ss.push_back(&surface);
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
|
||||
SurfacesPtr
|
||||
SurfaceCollection::filter_by_types(const SurfaceType *types, int ntypes)
|
||||
SurfacesConstPtr
|
||||
SurfaceCollection::filter_by_types(const SurfaceType *types, int ntypes) const
|
||||
{
|
||||
SurfacesPtr ss;
|
||||
for (Surfaces::iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface) {
|
||||
SurfacesConstPtr ss;
|
||||
for (const Surface & surface : this->surfaces) {
|
||||
for (int i = 0; i < ntypes; ++ i) {
|
||||
if (surface->surface_type == types[i]) {
|
||||
ss.push_back(&*surface);
|
||||
if (surface.surface_type == types[i]) {
|
||||
ss.push_back(&surface);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -90,21 +90,21 @@ SurfaceCollection::filter_by_types(const SurfaceType *types, int ntypes)
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceCollection::filter_by_type(const SurfaceType type, Polygons* polygons)
|
||||
SurfaceCollection::filter_by_type(const SurfaceType type, Polygons* polygons) const
|
||||
{
|
||||
for (Surfaces::iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface) {
|
||||
if (surface->surface_type == type) {
|
||||
Polygons pp = surface->expolygon;
|
||||
for (const Surface & surface : this->surfaces) {
|
||||
if (surface.surface_type == type) {
|
||||
Polygons pp = surface.expolygon;
|
||||
polygons->insert(polygons->end(), pp.begin(), pp.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
void
|
||||
SurfaceCollection::filter_by_type_flag(Polygons* polygons, const SurfaceType flags_needed, const SurfaceType flags_not_allowed)
|
||||
SurfaceCollection::filter_by_type_flag(Polygons* polygons, const SurfaceType flags_needed, const SurfaceType flags_not_allowed) const
|
||||
{
|
||||
for (Surfaces::iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface) {
|
||||
if ((surface->surface_type & flags_needed) == flags_needed && (surface->surface_type & flags_not_allowed)==0) {
|
||||
Polygons pp = surface->expolygon;
|
||||
for (const Surface & surface : this->surfaces) {
|
||||
if ((surface.surface_type & flags_needed) == flags_needed && (surface.surface_type & flags_not_allowed)==0) {
|
||||
Polygons pp = surface.expolygon;
|
||||
polygons->insert(polygons->end(), pp.begin(), pp.end());
|
||||
}
|
||||
}
|
||||
|
@ -27,17 +27,17 @@ public:
|
||||
for (const Surface &surface : this->surfaces) if (surface.has_pos_bottom() && surface.expolygon.contains(item)) return true;
|
||||
return false;
|
||||
}
|
||||
SurfacesPtr filter_by_type(const SurfaceType type);
|
||||
SurfacesPtr filter_by_type_flag(const SurfaceType allowed, const SurfaceType not_allowed = stNone);
|
||||
SurfacesPtr filter_by_types(const SurfaceType *types, int ntypes);
|
||||
SurfacesConstPtr filter_by_type(const SurfaceType type) const;
|
||||
SurfacesConstPtr filter_by_type_flag(const SurfaceType allowed, const SurfaceType not_allowed = stNone) const;
|
||||
SurfacesConstPtr filter_by_types(const SurfaceType *types, int ntypes) const;
|
||||
void keep_type(const SurfaceType type);
|
||||
void keep_type_flag(const SurfaceType flags_needed, const SurfaceType flags_to_remove = stNone);
|
||||
void keep_types(const SurfaceType *types, int ntypes);
|
||||
void keep_types_flag(const SurfaceType flags_to_keep, const SurfaceType flags_to_remove = stNone);
|
||||
void remove_type(const SurfaceType type);
|
||||
void remove_types(const SurfaceType *types, int ntypes);
|
||||
void filter_by_type(const SurfaceType type, Polygons* polygons);
|
||||
void filter_by_type_flag(Polygons* polygons, const SurfaceType flags_needed, const SurfaceType flags_not_allowed = stNone);
|
||||
void filter_by_type(const SurfaceType type, Polygons* polygons) const;
|
||||
void filter_by_type_flag(Polygons* polygons, const SurfaceType flags_needed, const SurfaceType flags_not_allowed = stNone) const;
|
||||
|
||||
void clear() { surfaces.clear(); }
|
||||
bool empty() const { return surfaces.empty(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user