WIP: Layers split into islands, islands overlapping in Z interconnected
into a graph with links to the layer above / below. In addition: Members of LayerRegion were made private, public interface const only. this->m_xxx replaced with just m_xxx SurfacesPtr was made a vector of const pointers.
This commit is contained in:
parent
f57744ad12
commit
ee626eb65a
39 changed files with 751 additions and 356 deletions
src/libslic3r
|
@ -157,7 +157,7 @@ void PrintObject::make_perimeters()
|
|||
m_print->throw_if_canceled();
|
||||
LayerRegion &layerm = *m_layers[layer_idx]->get_region(region_id);
|
||||
const LayerRegion &upper_layerm = *m_layers[layer_idx+1]->get_region(region_id);
|
||||
const Polygons upper_layerm_polygons = to_polygons(upper_layerm.slices.surfaces);
|
||||
const Polygons upper_layerm_polygons = to_polygons(upper_layerm.slices().surfaces);
|
||||
// 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);
|
||||
|
@ -166,7 +166,8 @@ 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) {
|
||||
// slice is not const because slice.extra_perimeters is being incremented.
|
||||
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
|
||||
|
@ -418,7 +419,7 @@ void PrintObject::generate_support_spots()
|
|||
BOOST_LOG_TRIVIAL(debug)
|
||||
<< "Searching support spots - start";
|
||||
m_print->set_status(75, L("Searching support spots"));
|
||||
if (this->m_config.support_material && !this->m_config.support_material_auto &&
|
||||
if (m_config.support_material && !m_config.support_material_auto &&
|
||||
std::all_of(this->model_object()->volumes.begin(), this->model_object()->volumes.end(),
|
||||
[](const ModelVolume* mv){return mv->supported_facets.empty();})
|
||||
) {
|
||||
|
@ -500,7 +501,7 @@ std::pair<FillAdaptive::OctreePtr, FillAdaptive::OctreePtr> PrintObject::prepare
|
|||
m_print->throw_if_canceled();
|
||||
const Layer *layer = this->layers()[idx_layer];
|
||||
for (const LayerRegion *layerm : layer->regions())
|
||||
for (const Surface &surface : layerm->fill_surfaces.surfaces)
|
||||
for (const Surface &surface : layerm->fill_surfaces())
|
||||
if (surface.surface_type == stInternalBridge)
|
||||
append(out, triangulate_expolygon_3d(surface.expolygon, layer->bottom_z()));
|
||||
}
|
||||
|
@ -883,13 +884,13 @@ void PrintObject::detect_surfaces_type()
|
|||
Surfaces top;
|
||||
if (upper_layer) {
|
||||
ExPolygons upper_slices = interface_shells ?
|
||||
diff_ex(layerm->slices.surfaces, upper_layer->m_regions[region_id]->slices.surfaces, ApplySafetyOffset::Yes) :
|
||||
diff_ex(layerm->slices.surfaces, upper_layer->lslices, ApplySafetyOffset::Yes);
|
||||
diff_ex(layerm->slices().surfaces, upper_layer->m_regions[region_id]->slices().surfaces, ApplySafetyOffset::Yes) :
|
||||
diff_ex(layerm->slices().surfaces, upper_layer->lslices, ApplySafetyOffset::Yes);
|
||||
surfaces_append(top, opening_ex(upper_slices, offset), stTop);
|
||||
} 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->slices().surfaces;
|
||||
for (Surface &surface : top)
|
||||
surface.surface_type = stTop;
|
||||
}
|
||||
|
@ -910,7 +911,7 @@ void PrintObject::detect_surfaces_type()
|
|||
surfaces_append(
|
||||
bottom,
|
||||
opening_ex(
|
||||
diff_ex(layerm->slices.surfaces, lower_layer->lslices, ApplySafetyOffset::Yes),
|
||||
diff_ex(layerm->slices().surfaces, lower_layer->lslices, ApplySafetyOffset::Yes),
|
||||
offset),
|
||||
surface_type_bottom_other);
|
||||
// if user requested internal shells, we need to identify surfaces
|
||||
|
@ -922,8 +923,8 @@ void PrintObject::detect_surfaces_type()
|
|||
bottom,
|
||||
opening_ex(
|
||||
diff_ex(
|
||||
intersection(layerm->slices.surfaces, lower_layer->lslices), // supported
|
||||
lower_layer->m_regions[region_id]->slices.surfaces,
|
||||
intersection(layerm->slices().surfaces, lower_layer->lslices), // supported
|
||||
lower_layer->m_regions[region_id]->slices().surfaces,
|
||||
ApplySafetyOffset::Yes),
|
||||
offset),
|
||||
stBottom);
|
||||
|
@ -932,7 +933,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 = stBottom;
|
||||
}
|
||||
|
@ -961,13 +962,13 @@ void PrintObject::detect_surfaces_type()
|
|||
#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->slices().surfaces;
|
||||
Surfaces surfaces_backup;
|
||||
if (! interface_shells) {
|
||||
surfaces_backup = std::move(surfaces_out);
|
||||
surfaces_out.clear();
|
||||
}
|
||||
const Surfaces &surfaces_prev = interface_shells ? layerm->slices.surfaces : surfaces_backup;
|
||||
const Surfaces &surfaces_prev = interface_shells ? layerm->slices().surfaces : surfaces_backup;
|
||||
|
||||
// find internal surfaces (difference between top/bottom surfaces and others)
|
||||
{
|
||||
|
@ -993,15 +994,15 @@ void PrintObject::detect_surfaces_type()
|
|||
if (interface_shells) {
|
||||
// Move surfaces_new to layerm->slices.surfaces
|
||||
for (size_t idx_layer = 0; idx_layer < num_layers; ++ idx_layer)
|
||||
m_layers[idx_layer]->m_regions[region_id]->slices.surfaces = std::move(surfaces_new[idx_layer]);
|
||||
m_layers[idx_layer]->m_regions[region_id]->m_slices.set(std::move(surfaces_new[idx_layer]));
|
||||
}
|
||||
|
||||
if (spiral_vase) {
|
||||
if (num_layers > 1)
|
||||
// Turn the last bottom layer infill to a top infill, so it will be extruded with a proper pattern.
|
||||
m_layers[num_layers - 1]->m_regions[region_id]->slices.set_type(stTop);
|
||||
m_layers[num_layers - 1]->m_regions[region_id]->m_slices.set_type(stTop);
|
||||
for (size_t i = num_layers; i < m_layers.size(); ++ i)
|
||||
m_layers[i]->m_regions[region_id]->slices.set_type(stInternal);
|
||||
m_layers[i]->m_regions[region_id]->m_slices.set_type(stInternal);
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << region_id << " - clipping in parallel - start";
|
||||
|
@ -1048,7 +1049,7 @@ void PrintObject::process_external_surfaces()
|
|||
bool expansions = false;
|
||||
bool voids = false;
|
||||
for (const LayerRegion *layerm : layer->regions()) {
|
||||
for (const Surface &surface : layerm->fill_surfaces.surfaces) {
|
||||
for (const Surface &surface : layerm->fill_surfaces()) {
|
||||
if (surface.surface_type == stInternal)
|
||||
voids = true;
|
||||
else
|
||||
|
@ -1073,7 +1074,7 @@ void PrintObject::process_external_surfaces()
|
|||
Polygons voids;
|
||||
for (const LayerRegion *layerm : m_layers[layer_idx]->regions()) {
|
||||
if (layerm->region().config().fill_density.value == 0.)
|
||||
for (const Surface &surface : layerm->fill_surfaces.surfaces)
|
||||
for (const Surface &surface : layerm->fill_surfaces())
|
||||
// Shrink the holes, let the layer above expand slightly inside the unsupported areas.
|
||||
polygons_append(voids, offset(surface.expolygon, unsupported_width));
|
||||
}
|
||||
|
@ -1102,7 +1103,7 @@ void PrintObject::process_external_surfaces()
|
|||
m_print->throw_if_canceled();
|
||||
BOOST_LOG_TRIVIAL(debug) << "Processing external surfaces for region " << region_id << " in parallel - end";
|
||||
}
|
||||
}
|
||||
} // void PrintObject::process_external_surfaces()
|
||||
|
||||
void PrintObject::discover_vertical_shells()
|
||||
{
|
||||
|
@ -1170,15 +1171,15 @@ void PrintObject::discover_vertical_shells()
|
|||
LayerRegion &layerm = *layer.m_regions[region_id];
|
||||
float min_perimeter_infill_spacing = float(layerm.flow(frSolidInfill).scaled_spacing()) * 1.05f;
|
||||
// Top surfaces.
|
||||
append(cache.top_surfaces, offset(layerm.slices.filter_by_type(stTop), min_perimeter_infill_spacing));
|
||||
append(cache.top_surfaces, offset(layerm.fill_surfaces.filter_by_type(stTop), min_perimeter_infill_spacing));
|
||||
append(cache.top_surfaces, offset(layerm.slices().filter_by_type(stTop), min_perimeter_infill_spacing));
|
||||
append(cache.top_surfaces, offset(layerm.fill_surfaces().filter_by_type(stTop), min_perimeter_infill_spacing));
|
||||
// Bottom surfaces.
|
||||
append(cache.bottom_surfaces, offset(layerm.slices.filter_by_types(surfaces_bottom, 2), min_perimeter_infill_spacing));
|
||||
append(cache.bottom_surfaces, offset(layerm.fill_surfaces.filter_by_types(surfaces_bottom, 2), min_perimeter_infill_spacing));
|
||||
append(cache.bottom_surfaces, offset(layerm.slices().filter_by_types(surfaces_bottom, 2), min_perimeter_infill_spacing));
|
||||
append(cache.bottom_surfaces, offset(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())
|
||||
perimeters = std::max<unsigned int>(perimeters, s.extra_perimeters);
|
||||
perimeters += layerm.region().config().perimeters.value;
|
||||
// Then calculate the infill offset.
|
||||
|
@ -1189,7 +1190,7 @@ void PrintObject::discover_vertical_shells()
|
|||
0.5f * float(extflow.scaled_width() + extflow.scaled_spacing()) + (float(perimeters) - 1.f) * flow.scaled_spacing());
|
||||
perimeter_min_spacing = std::min(perimeter_min_spacing, float(std::min(extflow.scaled_spacing(), flow.scaled_spacing())));
|
||||
}
|
||||
polygons_append(cache.holes, to_polygons(layerm.fill_expolygons));
|
||||
polygons_append(cache.holes, to_polygons(layerm.fill_expolygons()));
|
||||
}
|
||||
// Save some computing time by reducing the number of polygons.
|
||||
cache.top_surfaces = union_(cache.top_surfaces);
|
||||
|
@ -1242,15 +1243,15 @@ 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(layerm.slices.filter_by_type(stTop), min_perimeter_infill_spacing);
|
||||
append(cache.top_surfaces, offset(layerm.fill_surfaces.filter_by_type(stTop), min_perimeter_infill_spacing));
|
||||
cache.top_surfaces = offset(layerm.slices().filter_by_type(stTop), min_perimeter_infill_spacing);
|
||||
append(cache.top_surfaces, offset(layerm.fill_surfaces().filter_by_type(stTop), min_perimeter_infill_spacing));
|
||||
// Bottom surfaces.
|
||||
cache.bottom_surfaces = offset(layerm.slices.filter_by_types(surfaces_bottom, 2), min_perimeter_infill_spacing);
|
||||
append(cache.bottom_surfaces, offset(layerm.fill_surfaces.filter_by_types(surfaces_bottom, 2), min_perimeter_infill_spacing));
|
||||
cache.bottom_surfaces = offset(layerm.slices().filter_by_types(surfaces_bottom, 2), min_perimeter_infill_spacing);
|
||||
append(cache.bottom_surfaces, offset(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 region_id iterations.
|
||||
if (cache.holes.empty()) {
|
||||
for (size_t region_id = 0; region_id < layer.regions().size(); ++ region_id)
|
||||
polygons_append(cache.holes, to_polygons(layer.regions()[region_id]->fill_expolygons));
|
||||
polygons_append(cache.holes, to_polygons(layer.regions()[region_id]->fill_expolygons()));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1407,14 +1408,14 @@ void PrintObject::discover_vertical_shells()
|
|||
|
||||
// Trim the shells region by the internal & internal void surfaces.
|
||||
const SurfaceType surfaceTypesInternal[] = { stInternal, stInternalVoid, stInternalSolid };
|
||||
const Polygons polygonsInternal = to_polygons(layerm->fill_surfaces.filter_by_types(surfaceTypesInternal, 3));
|
||||
const Polygons polygonsInternal = to_polygons(layerm->fill_surfaces().filter_by_types(surfaceTypesInternal, 3));
|
||||
shell = intersection(shell, polygonsInternal, ApplySafetyOffset::Yes);
|
||||
polygons_append(shell, diff(polygonsInternal, holes));
|
||||
if (shell.empty())
|
||||
continue;
|
||||
|
||||
// Append the internal solids, so they will be merged with the new ones.
|
||||
polygons_append(shell, to_polygons(layerm->fill_surfaces.filter_by_type(stInternalSolid)));
|
||||
polygons_append(shell, to_polygons(layerm->fill_surfaces().filter_by_type(stInternalSolid)));
|
||||
|
||||
// These regions will be filled by a rectilinear full infill. Currently this type of infill
|
||||
// only fills regions, which fit at least a single line. To avoid gaps in the sparse infill,
|
||||
|
@ -1461,8 +1462,8 @@ void PrintObject::discover_vertical_shells()
|
|||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||
|
||||
// Trim the internal & internalvoid by the shell.
|
||||
Slic3r::ExPolygons new_internal = diff_ex(layerm->fill_surfaces.filter_by_type(stInternal), shell);
|
||||
Slic3r::ExPolygons new_internal_void = diff_ex(layerm->fill_surfaces.filter_by_type(stInternalVoid), shell);
|
||||
Slic3r::ExPolygons new_internal = diff_ex(layerm->fill_surfaces().filter_by_type(stInternal), shell);
|
||||
Slic3r::ExPolygons new_internal_void = diff_ex(layerm->fill_surfaces().filter_by_type(stInternalVoid), shell);
|
||||
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
{
|
||||
|
@ -1474,10 +1475,10 @@ void PrintObject::discover_vertical_shells()
|
|||
|
||||
// Assign resulting internal surfaces to layer.
|
||||
const SurfaceType surfaceTypesKeep[] = { stTop, stBottom, stBottomBridge };
|
||||
layerm->fill_surfaces.keep_types(surfaceTypesKeep, sizeof(surfaceTypesKeep)/sizeof(SurfaceType));
|
||||
layerm->fill_surfaces.append(new_internal, stInternal);
|
||||
layerm->fill_surfaces.append(new_internal_void, stInternalVoid);
|
||||
layerm->fill_surfaces.append(new_internal_solid, stInternalSolid);
|
||||
layerm->m_fill_surfaces.keep_types(surfaceTypesKeep, sizeof(surfaceTypesKeep)/sizeof(SurfaceType));
|
||||
layerm->m_fill_surfaces.append(new_internal, stInternal);
|
||||
layerm->m_fill_surfaces.append(new_internal_void, stInternalVoid);
|
||||
layerm->m_fill_surfaces.append(new_internal_solid, stInternalSolid);
|
||||
} // for each layer
|
||||
});
|
||||
m_print->throw_if_canceled();
|
||||
|
@ -1491,7 +1492,7 @@ void PrintObject::discover_vertical_shells()
|
|||
}
|
||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||
} // for each region
|
||||
}
|
||||
} // void PrintObject::discover_vertical_shells()
|
||||
|
||||
// This method applies bridge flow to the first internal solid layer above sparse infill.
|
||||
void PrintObject::bridge_over_infill()
|
||||
|
@ -1514,7 +1515,7 @@ void PrintObject::bridge_over_infill()
|
|||
for (Layer *layer : m_layers) {
|
||||
Polygons sum;
|
||||
for (const LayerRegion *layerm : layer->m_regions)
|
||||
layerm->fill_surfaces.filter_by_type(stInternal, &sum);
|
||||
layerm->fill_surfaces().filter_by_type(stInternal, &sum);
|
||||
internals.emplace_back(std::move(sum));
|
||||
}
|
||||
|
||||
|
@ -1531,7 +1532,7 @@ void PrintObject::bridge_over_infill()
|
|||
|
||||
// Extract the stInternalSolid surfaces that might be transformed into bridges.
|
||||
ExPolygons internal_solid;
|
||||
layerm->fill_surfaces.remove_type(stInternalSolid, &internal_solid);
|
||||
layerm->m_fill_surfaces.remove_type(stInternalSolid, &internal_solid);
|
||||
if (internal_solid.empty())
|
||||
// No internal solid -> no new bridges for this layer region.
|
||||
continue;
|
||||
|
@ -1563,7 +1564,7 @@ void PrintObject::bridge_over_infill()
|
|||
if (to_bridge_pp.empty()) {
|
||||
// Restore internal_solid surfaces.
|
||||
for (ExPolygon &ex : internal_solid)
|
||||
layerm->fill_surfaces.surfaces.push_back(Surface(stInternalSolid, std::move(ex)));
|
||||
layerm->m_fill_surfaces.surfaces.push_back(Surface(stInternalSolid, std::move(ex)));
|
||||
continue;
|
||||
}
|
||||
// convert into ExPolygons
|
||||
|
@ -1579,9 +1580,9 @@ void PrintObject::bridge_over_infill()
|
|||
to_bridge = intersection_ex(to_bridge, internal_solid, ApplySafetyOffset::Yes);
|
||||
// build the new collection of fill_surfaces
|
||||
for (ExPolygon &ex : to_bridge)
|
||||
layerm->fill_surfaces.surfaces.push_back(Surface(stInternalBridge, std::move(ex)));
|
||||
layerm->m_fill_surfaces.surfaces.push_back(Surface(stInternalBridge, std::move(ex)));
|
||||
for (ExPolygon &ex : not_to_bridge)
|
||||
layerm->fill_surfaces.surfaces.push_back(Surface(stInternalSolid, std::move(ex)));
|
||||
layerm->m_fill_surfaces.surfaces.push_back(Surface(stInternalSolid, std::move(ex)));
|
||||
/*
|
||||
# exclude infill from the layers below if needed
|
||||
# see discussion at https://github.com/alexrj/Slic3r/issues/240
|
||||
|
@ -1622,7 +1623,7 @@ void PrintObject::bridge_over_infill()
|
|||
m_print->throw_if_canceled();
|
||||
}
|
||||
});
|
||||
}
|
||||
} // void PrintObject::bridge_over_infill()
|
||||
|
||||
static void clamp_exturder_to_default(ConfigOptionInt &opt, size_t num_extruders)
|
||||
{
|
||||
|
@ -1829,7 +1830,7 @@ void PrintObject::clip_fill_surfaces()
|
|||
// Solid surfaces to be supported.
|
||||
Polygons overhangs;
|
||||
for (const LayerRegion *layerm : layer->m_regions)
|
||||
for (const Surface &surface : layerm->fill_surfaces.surfaces) {
|
||||
for (const Surface &surface : layerm->fill_surfaces()) {
|
||||
Polygons polygons = to_polygons(surface.expolygon);
|
||||
if (surface.is_solid())
|
||||
polygons_append(overhangs, polygons);
|
||||
|
@ -1838,7 +1839,7 @@ void PrintObject::clip_fill_surfaces()
|
|||
Polygons lower_layer_fill_surfaces;
|
||||
Polygons lower_layer_internal_surfaces;
|
||||
for (const LayerRegion *layerm : lower_layer->m_regions)
|
||||
for (const Surface &surface : layerm->fill_surfaces.surfaces) {
|
||||
for (const Surface &surface : layerm->fill_surfaces()) {
|
||||
Polygons polygons = to_polygons(surface.expolygon);
|
||||
if (surface.surface_type == stInternal || surface.surface_type == stInternalVoid)
|
||||
polygons_append(lower_layer_internal_surfaces, polygons);
|
||||
|
@ -1873,12 +1874,12 @@ void PrintObject::clip_fill_surfaces()
|
|||
continue;
|
||||
SurfaceType internal_surface_types[] = { stInternal, stInternalVoid };
|
||||
Polygons internal;
|
||||
for (Surface &surface : layerm->fill_surfaces.surfaces)
|
||||
for (Surface &surface : layerm->m_fill_surfaces.surfaces)
|
||||
if (surface.surface_type == stInternal || surface.surface_type == stInternalVoid)
|
||||
polygons_append(internal, std::move(surface.expolygon));
|
||||
layerm->fill_surfaces.remove_types(internal_surface_types, 2);
|
||||
layerm->fill_surfaces.append(intersection_ex(internal, upper_internal, ApplySafetyOffset::Yes), stInternal);
|
||||
layerm->fill_surfaces.append(diff_ex (internal, upper_internal, ApplySafetyOffset::Yes), stInternalVoid);
|
||||
layerm->m_fill_surfaces.remove_types(internal_surface_types, 2);
|
||||
layerm->m_fill_surfaces.append(intersection_ex(internal, upper_internal, ApplySafetyOffset::Yes), stInternal);
|
||||
layerm->m_fill_surfaces.append(diff_ex (internal, upper_internal, ApplySafetyOffset::Yes), stInternalVoid);
|
||||
// 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
|
||||
// make it more robust and nicer. TODO.
|
||||
|
@ -1888,7 +1889,7 @@ void PrintObject::clip_fill_surfaces()
|
|||
}
|
||||
m_print->throw_if_canceled();
|
||||
}
|
||||
}
|
||||
} // void PrintObject::clip_fill_surfaces()
|
||||
|
||||
void PrintObject::discover_horizontal_shells()
|
||||
{
|
||||
|
@ -1904,7 +1905,7 @@ void PrintObject::discover_horizontal_shells()
|
|||
(i % region_config.solid_infill_every_layers) == 0) {
|
||||
// Insert a solid internal layer. Mark stInternal surfaces as stInternalSolid or stInternalBridge.
|
||||
SurfaceType type = (region_config.fill_density == 100 || region_config.solid_infill_every_layers == 1) ? stInternalSolid : stInternalBridge;
|
||||
for (Surface &surface : layerm->fill_surfaces.surfaces)
|
||||
for (Surface &surface : layerm->m_fill_surfaces.surfaces)
|
||||
if (surface.surface_type == stInternal)
|
||||
surface.surface_type = type;
|
||||
}
|
||||
|
@ -1935,11 +1936,11 @@ 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())
|
||||
if (surface.surface_type == type)
|
||||
polygons_append(solid, to_polygons(surface.expolygon));
|
||||
// Infill areas (slices without the perimeters).
|
||||
for (const Surface &surface : layerm->fill_surfaces.surfaces)
|
||||
for (const Surface &surface : layerm->fill_surfaces())
|
||||
if (surface.surface_type == type)
|
||||
polygons_append(solid, to_polygons(surface.expolygon));
|
||||
if (solid.empty())
|
||||
|
@ -1972,7 +1973,7 @@ void PrintObject::discover_horizontal_shells()
|
|||
Polygons new_internal_solid;
|
||||
{
|
||||
Polygons internal;
|
||||
for (const Surface &surface : neighbor_layerm->fill_surfaces.surfaces)
|
||||
for (const Surface &surface : neighbor_layerm->fill_surfaces())
|
||||
if (surface.surface_type == stInternal || surface.surface_type == stInternalSolid)
|
||||
polygons_append(internal, to_polygons(surface.expolygon));
|
||||
new_internal_solid = intersection(solid, internal, ApplySafetyOffset::Yes);
|
||||
|
@ -2028,7 +2029,7 @@ void PrintObject::discover_horizontal_shells()
|
|||
// additional area in the next shell too
|
||||
// make sure our grown surfaces don't exceed the fill area
|
||||
Polygons internal;
|
||||
for (const Surface &surface : neighbor_layerm->fill_surfaces.surfaces)
|
||||
for (const Surface &surface : neighbor_layerm->fill_surfaces())
|
||||
if (surface.is_internal() && !surface.is_bridge())
|
||||
polygons_append(internal, to_polygons(surface.expolygon));
|
||||
polygons_append(new_internal_solid,
|
||||
|
@ -2047,16 +2048,16 @@ void PrintObject::discover_horizontal_shells()
|
|||
|
||||
// internal-solid are the union of the existing internal-solid surfaces
|
||||
// and new ones
|
||||
SurfaceCollection backup = std::move(neighbor_layerm->fill_surfaces);
|
||||
SurfaceCollection backup = std::move(neighbor_layerm->m_fill_surfaces);
|
||||
polygons_append(new_internal_solid, to_polygons(backup.filter_by_type(stInternalSolid)));
|
||||
ExPolygons internal_solid = union_ex(new_internal_solid);
|
||||
// assign new internal-solid surfaces to layer
|
||||
neighbor_layerm->fill_surfaces.set(internal_solid, stInternalSolid);
|
||||
neighbor_layerm->m_fill_surfaces.set(internal_solid, stInternalSolid);
|
||||
// subtract intersections from layer surfaces to get resulting internal surfaces
|
||||
Polygons polygons_internal = to_polygons(std::move(internal_solid));
|
||||
ExPolygons internal = diff_ex(backup.filter_by_type(stInternal), polygons_internal, ApplySafetyOffset::Yes);
|
||||
// assign resulting internal surfaces to layer
|
||||
neighbor_layerm->fill_surfaces.append(internal, stInternal);
|
||||
neighbor_layerm->m_fill_surfaces.append(internal, stInternal);
|
||||
polygons_append(polygons_internal, to_polygons(std::move(internal)));
|
||||
// assign top and bottom surfaces to layer
|
||||
SurfaceType surface_types_solid[] = { stTop, stBottom, stBottomBridge };
|
||||
|
@ -2064,7 +2065,7 @@ void PrintObject::discover_horizontal_shells()
|
|||
std::vector<SurfacesPtr> top_bottom_groups;
|
||||
backup.group(&top_bottom_groups);
|
||||
for (SurfacesPtr &group : top_bottom_groups)
|
||||
neighbor_layerm->fill_surfaces.append(
|
||||
neighbor_layerm->m_fill_surfaces.append(
|
||||
diff_ex(group, polygons_internal),
|
||||
// Use an existing surface as a template, it carries the bridge angle etc.
|
||||
*group.front());
|
||||
|
@ -2083,7 +2084,7 @@ void PrintObject::discover_horizontal_shells()
|
|||
} // for each layer
|
||||
} // for each region
|
||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||
}
|
||||
} // void PrintObject::discover_horizontal_shells()
|
||||
|
||||
// combine fill surfaces across layers to honor the "infill every N layers" option
|
||||
// Idempotence of this method is guaranteed by the fact that we don't remove things from
|
||||
|
@ -2141,10 +2142,10 @@ void PrintObject::combine_infill()
|
|||
layerms.emplace_back(m_layers[i]->regions()[region_id]);
|
||||
// We need to perform a multi-layer intersection, so let's split it in pairs.
|
||||
// Initialize the intersection with the candidates of the lowest layer.
|
||||
ExPolygons intersection = to_expolygons(layerms.front()->fill_surfaces.filter_by_type(stInternal));
|
||||
ExPolygons intersection = to_expolygons(layerms.front()->fill_surfaces().filter_by_type(stInternal));
|
||||
// Start looping from the second layer and intersect the current intersection with it.
|
||||
for (size_t i = 1; i < layerms.size(); ++ i)
|
||||
intersection = intersection_ex(layerms[i]->fill_surfaces.filter_by_type(stInternal), intersection);
|
||||
intersection = intersection_ex(layerms[i]->fill_surfaces().filter_by_type(stInternal), intersection);
|
||||
double area_threshold = layerms.front()->infill_area_threshold();
|
||||
if (! intersection.empty() && area_threshold > 0.)
|
||||
intersection.erase(std::remove_if(intersection.begin(), intersection.end(),
|
||||
|
@ -2173,9 +2174,9 @@ void PrintObject::combine_infill()
|
|||
for (ExPolygon &expoly : intersection)
|
||||
polygons_append(intersection_with_clearance, offset(expoly, clearance_offset));
|
||||
for (LayerRegion *layerm : layerms) {
|
||||
Polygons internal = to_polygons(std::move(layerm->fill_surfaces.filter_by_type(stInternal)));
|
||||
layerm->fill_surfaces.remove_type(stInternal);
|
||||
layerm->fill_surfaces.append(diff_ex(internal, intersection_with_clearance), stInternal);
|
||||
Polygons internal = to_polygons(std::move(layerm->fill_surfaces().filter_by_type(stInternal)));
|
||||
layerm->m_fill_surfaces.remove_type(stInternal);
|
||||
layerm->m_fill_surfaces.append(diff_ex(internal, intersection_with_clearance), stInternal);
|
||||
if (layerm == layerms.back()) {
|
||||
// Apply surfaces back with adjusted depth to the uppermost layer.
|
||||
Surface templ(stInternal, ExPolygon());
|
||||
|
@ -2183,17 +2184,17 @@ void PrintObject::combine_infill()
|
|||
for (LayerRegion *layerm2 : layerms)
|
||||
templ.thickness += layerm2->layer()->height;
|
||||
templ.thickness_layers = (unsigned short)layerms.size();
|
||||
layerm->fill_surfaces.append(intersection, templ);
|
||||
layerm->m_fill_surfaces.append(intersection, templ);
|
||||
} else {
|
||||
// Save void surfaces.
|
||||
layerm->fill_surfaces.append(
|
||||
layerm->m_fill_surfaces.append(
|
||||
intersection_ex(internal, intersection_with_clearance),
|
||||
stInternalVoid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // void PrintObject::combine_infill()
|
||||
|
||||
void PrintObject::_generate_support_material()
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue