Visualization of fill surfaces.

This commit is contained in:
bubnikv 2016-09-26 13:56:24 +02:00
parent e0d1aa8a1a
commit 790b640521
6 changed files with 314 additions and 26 deletions

View file

@ -2,6 +2,7 @@
#include "BoundingBox.hpp"
#include "ClipperUtils.hpp"
#include "Geometry.hpp"
#include "SVG.hpp"
namespace Slic3r {
@ -358,6 +359,167 @@ PrintObject::process_external_surfaces()
}
}
void
PrintObject::discover_vertical_shells()
{
for (size_t idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) {
for (size_t idx_layer = 0; idx_layer < this->layers.size(); ++ idx_layer) {
Layer* layer = this->layers[idx_layer];
LayerRegion* layerm = layer->get_region(idx_region);
// Find a union of perimeters below / above this surface to guarantee a minimum shell thickness.
Polygons shell;
ExPolygons shell_ex;
if (1)
{
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
static size_t idx = 0;
char path_cummulative[2048];
sprintf(path_cummulative, "out\\discover_vertical_shells-perimeters-before-union-run%d.svg", idx);
SVG svg_cummulative(path_cummulative, this->bounding_box());
for (int n = (int)idx_layer - layerm->region()->config.bottom_solid_layers + 1; n < (int)idx_layer + layerm->region()->config.top_solid_layers; ++ n) {
if (n < 0 || n >= (int)this->layers.size())
continue;
ExPolygons &expolys = this->layers[n]->perimeter_expolygons;
for (size_t i = 0; i < expolys.size(); ++ i) {
char path[2048];
sprintf(path, "out\\discover_vertical_shells-perimeters-before-union-run%d-layer%d-expoly%d.svg", idx, n, i);
SVG svg(path, get_extents(expolys[i]));
svg.draw(expolys[i]);
svg.draw_outline(expolys[i].contour, "black", scale_(0.05));
svg.draw_outline(expolys[i].holes, "blue", scale_(0.05));
svg.Close();
svg_cummulative.draw(expolys[i]);
svg_cummulative.draw_outline(expolys[i].contour, "black", scale_(0.05));
svg_cummulative.draw_outline(expolys[i].holes, "blue", scale_(0.05));
}
}
++ idx;
}
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
for (int n = (int)idx_layer - layerm->region()->config.bottom_solid_layers + 1; n < (int)idx_layer + layerm->region()->config.top_solid_layers; ++ n) {
if (n < 0 || n >= (int)this->layers.size())
continue;
ExPolygons &expolys = this->layers[n]->perimeter_expolygons;
for (size_t i = 0; i < expolys.size(); ++ i) {
shell.push_back(expolys[i].contour);
shell.insert(shell.end(), expolys[i].holes.begin(), expolys[i].holes.end());
}
}
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
static size_t idx = 0;
char path[2048];
sprintf(path, "out\\discover_vertical_shells-perimeters-before-union-%d.svg", idx ++);
SVG svg(path, get_extents(shell));
svg.draw(shell);
svg.draw_outline(shell, "black", scale_(0.05));
svg.Close();
}
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
shell = union_(shell, true);
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
shell_ex = union_ex(shell, true);
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
}
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
static size_t idx = 0;
char path[2048];
sprintf(path, "out\\discover_vertical_shells-perimeters-after-union-%d.svg", idx ++);
SVG svg(path, get_extents(shell));
svg.draw(shell_ex);
svg.draw_outline(shell_ex, "black", "blue", scale_(0.05));
svg.Close();
}
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
static size_t idx = 0;
char path[2048];
sprintf(path, "out\\discover_vertical_shells-internal-wshell-%d.svg", idx ++);
SVG svg(path, get_extents(shell));
svg.draw(layerm->fill_surfaces.filter_by_type(stInternal), "yellow", 0.5);
svg.draw_outline(layerm->fill_surfaces.filter_by_type(stInternal), "black", "blue", scale_(0.05));
svg.draw(shell_ex, "blue", 0.5);
svg.draw_outline(shell_ex, "black", "blue", scale_(0.05));
svg.Close();
}
{
static size_t idx = 0;
char path[2048];
sprintf(path, "out\\discover_vertical_shells-internalvoid-wshell-%d.svg", idx ++);
SVG svg(path, get_extents(shell));
svg.draw(layerm->fill_surfaces.filter_by_type(stInternalVoid), "yellow", 0.5);
svg.draw_outline(layerm->fill_surfaces.filter_by_type(stInternalVoid), "black", "blue", scale_(0.05));
svg.draw(shell_ex, "blue", 0.5);
svg.draw_outline(shell_ex, "black", "blue", scale_(0.05));
svg.Close();
}
{
static size_t idx = 0;
char path[2048];
sprintf(path, "out\\discover_vertical_shells-internalvoid-wshell-%d.svg", idx ++);
SVG svg(path, get_extents(shell));
svg.draw(layerm->fill_surfaces.filter_by_type(stInternalVoid), "yellow", 0.5);
svg.draw_outline(layerm->fill_surfaces.filter_by_type(stInternalVoid), "black", "blue", scale_(0.05));
svg.draw(shell_ex, "blue", 0.5);
svg.draw_outline(shell_ex, "black", "blue", scale_(0.05));
svg.Close();
}
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
// Trim the internal & internalvoid by the $shell.
Slic3r::ExPolygons new_internal = diff_ex(
to_polygons(layerm->fill_surfaces.filter_by_type(stInternal)),
shell,
false
);
Slic3r::ExPolygons new_internal_void = diff_ex(
to_polygons(layerm->fill_surfaces.filter_by_type(stInternalVoid)),
shell,
false
);
// Add shells tstInternalVoido internal & internalvoid.
const SurfaceType surfaceTypesInternal[] = { stInternal, stInternalVoid };
Slic3r::ExPolygons new_internal_solid = intersection_ex(
to_polygons(layerm->fill_surfaces.filter_by_types(surfaceTypesInternal, 2)),
shell,
true
);
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
static size_t idx = 0;
char path[2048];
sprintf(path, "out\\discover_vertical_shells-new_internal-%d.svg", idx);
SVG::export_expolygons(path, get_extents(shell), new_internal, "black", "blue", scale_(0.05));
sprintf(path, "out\\discover_vertical_shells-new_internal_void-%d.svg", idx);
SVG::export_expolygons(path, get_extents(shell), new_internal_void, "black", "blue", scale_(0.05));
sprintf(path, "out\\discover_vertical_shells-new_internal_solid-%d.svg", idx);
SVG::export_expolygons(path, get_extents(shell), new_internal_solid, "black", "blue", scale_(0.05));
++ idx;
}
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
// Assign resulting internal surfaces to layer.
const SurfaceType surfaceTypesKeep[] = { stTop, stBottom, stBottomBridge, stInternalSolid };
layerm->fill_surfaces.keep_types(surfaceTypesKeep, sizeof(surfaceTypesKeep)/sizeof(SurfaceType));
layerm->fill_surfaces.append(stInternal , new_internal);
layerm->fill_surfaces.append(stInternalVoid , new_internal_void);
layerm->fill_surfaces.append(stInternalSolid, new_internal_solid);
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
layerm->export_region_slices_to_svg_debug("4_discover_vertical_shells");
layerm->export_region_fill_surfaces_to_svg_debug("4_discover_vertical_shells");
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
} // for each layer
} // for each region
}
/* This method applies bridge flow to the first internal solid layer above
sparse infill */
void
@ -415,6 +577,9 @@ PrintObject::bridge_over_infill()
}
// there's no point in bridging too thin/short regions
//FIXME Vojtech: The offset2 function is not a geometric offset,
// therefore it may create 1) gaps, and 2) sharp corners, which are outside the original contour.
// The gaps will be filled by a separate region, which makes the infill less stable and it takes longer.
{
double min_width = bridge_flow.scaled_width() * 3;
to_bridge_pp = offset2(to_bridge_pp, -min_width, +min_width);
@ -432,22 +597,17 @@ PrintObject::bridge_over_infill()
// compute the remaning internal solid surfaces as difference
ExPolygons not_to_bridge = diff_ex(internal_solid, to_bridge, true);
to_bridge = intersection_ex(to_polygons(to_bridge), internal_solid, true);
// build the new collection of fill_surfaces
{
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)
new_surfaces.push_back(*surface);
}
layerm->fill_surfaces.remove_type(stInternalSolid);
for (ExPolygons::const_iterator ex = to_bridge.begin(); ex != to_bridge.end(); ++ex)
new_surfaces.push_back(Surface(stInternalBridge, *ex));
layerm->fill_surfaces.surfaces.push_back(Surface(stInternalBridge, *ex));
for (ExPolygons::const_iterator ex = not_to_bridge.begin(); ex != not_to_bridge.end(); ++ex)
new_surfaces.push_back(Surface(stInternalSolid, *ex));
layerm->fill_surfaces.surfaces = new_surfaces;
layerm->fill_surfaces.surfaces.push_back(Surface(stInternalSolid, *ex));
}
/*
@ -483,6 +643,11 @@ PrintObject::bridge_over_infill()
}
}
*/
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
layerm->export_region_slices_to_svg_debug("7_bridge_over_infill");
layerm->export_region_fill_surfaces_to_svg_debug("7_bridge_over_infill");
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
}
}
}