mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-13 01:37:53 -06:00
Visualization of fill surfaces.
This commit is contained in:
parent
e0d1aa8a1a
commit
790b640521
6 changed files with 314 additions and 26 deletions
|
@ -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 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue