Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions include/FffGcodeWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,16 @@ class FffGcodeWriter : public NoCopy
*/
unsigned int findSpiralizedLayerSeamVertexIndex(const SliceDataStorage& storage, const SliceMeshStorage& mesh, const int layer_nr, const int last_layer_nr);

/*!
* Retrieve all skin relevant to skin support from the indicated layer w.r.t. the indicated part (on an adjacent layer).
*
* \param skin_combined [out] Return parameter.
* \param mesh [in] Relevant mesh.
* \param part [in] The part that we're currently checking.
* \param skin_layer_nr [in] A layer that is adjacent to the part (so either above or below the layer of the part).
*/
static void getCombinedSkinForSkinSupport(Shape& skin_combined, const SliceMeshStorage& mesh, const SliceLayerPart& part, int skin_layer_nr);

/*!
* Partition the Infill regions by the skin at N layers above.
*
Expand All @@ -753,6 +763,7 @@ class FffGcodeWriter : public NoCopy
*
* \param infill_below_skin [out] Polygons with infill below the skin
* \param infill_not_below_skin [out] Polygons with infill outside of skin regions above
* \param infill_sandwiched [out] Polygons with infill that both has regions of skin both above _and_ below
* \param gcode_layer The initial planning of the gcode of the layer
* \param mesh the mesh containing the layer of interest
* \param part \param part The part for which to create gcode
Expand All @@ -761,6 +772,7 @@ class FffGcodeWriter : public NoCopy
static void partitionInfillBySkinAbove(
Shape& infill_below_skin,
Shape& infill_not_below_skin,
Shape& infill_sandwiched,
const LayerPlan& gcode_layer,
const SliceMeshStorage& mesh,
const SliceLayerPart& part,
Expand Down
117 changes: 66 additions & 51 deletions src/FffGcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2173,10 +2173,11 @@ bool FffGcodeWriter::processSingleLayerInfill(
// boundary edge
Shape infill_below_skin;
Shape infill_not_below_skin;
Shape infill_sandwiched;
AngleDegrees skin_support_angle;
if (gcode_layer.getLayerNr() > 0)
{
partitionInfillBySkinAbove(infill_below_skin, infill_not_below_skin, gcode_layer, mesh, part, infill_line_width);
partitionInfillBySkinAbove(infill_below_skin, infill_not_below_skin, infill_sandwiched, gcode_layer, mesh, part, infill_line_width);
}

if (! infill_below_skin.empty())
Expand All @@ -2185,7 +2186,8 @@ bool FffGcodeWriter::processSingleLayerInfill(
const coord_t infill_wall_offset = -infill_wall_line_count * infill_line_width;
const Shape infill_contour = part.infill_area.offset(-(infill_line_width / 2) + infill_overlap + infill_wall_offset);
const LayerPlan* completed_layer_below = layer_plan_buffer.getCompletedLayerPlan(gcode_layer.getLayerNr() - 1);
std::tie(infill_below_skin, skin_support_angle) = makeBridgeOverInfillPrintable(infill_contour, infill_below_skin, mesh, completed_layer_below, gcode_layer.getLayerNr());
std::tie(infill_below_skin, skin_support_angle)
= makeBridgeOverInfillPrintable(infill_contour.difference(infill_sandwiched), infill_below_skin, mesh, completed_layer_below, gcode_layer.getLayerNr());
infill_not_below_skin = infill_not_below_skin.difference(infill_below_skin);
}

Expand Down Expand Up @@ -2417,75 +2419,88 @@ bool FffGcodeWriter::processSingleLayerInfill(
return added_something;
}

void FffGcodeWriter::partitionInfillBySkinAbove(
Shape& infill_below_skin,
Shape& infill_not_below_skin,
const LayerPlan& gcode_layer,
const SliceMeshStorage& mesh,
const SliceLayerPart& part,
coord_t infill_line_width)
void FffGcodeWriter::getCombinedSkinForSkinSupport(Shape& skin_combined, const SliceMeshStorage& mesh, const SliceLayerPart& part, int skin_layer_nr)
{
constexpr coord_t tiny_infill_offset = 20;
const bool skin_support = mesh.settings.get<bool>("skin_support");

if (! skin_support)
if (skin_layer_nr >= mesh.layers.size() || skin_layer_nr < 1)
{
return;
}

Shape skin_above_combined; // skin regions on the layers above combined with small gaps between

const size_t skin_layer_nr = gcode_layer.getLayerNr() + 1;
if (skin_layer_nr < mesh.layers.size())
for (const SliceLayerPart& part_i : mesh.layers[skin_layer_nr].parts)
{
for (const SliceLayerPart& part_i : mesh.layers[skin_layer_nr].parts)
for (const SkinPart& skin_part : part_i.skin_parts)
{
for (const SkinPart& skin_part : part_i.skin_parts)
{
// Limit considered areas to the ones that should have infill underneath at the current layer.
const Shape relevant_outline = skin_part.outline.intersection(part.getOwnInfillArea());
// Limit considered areas to the ones that should have infill underneath at the current layer.
const Shape relevant_outline = skin_part.outline.intersection(part.getOwnInfillArea());

if (! skin_above_combined.empty())
if (! skin_combined.empty())
{
// does this skin part overlap with any of the skin parts on the layers above?
const Shape overlap = skin_combined.intersection(relevant_outline);
if (! overlap.empty())
{
// does this skin part overlap with any of the skin parts on the layers above?
const Shape overlap = skin_above_combined.intersection(relevant_outline);
if (! overlap.empty())
{
// yes, it overlaps, need to leave a gap between this skin part and the others
// add this layer's skin region without subtracting the overlap but still make a gap between this skin region and what has been accumulated so
// far we do this so that these skin region edges will definitely have infill walls below them

// looking from the side, if the combined regions so far look like this...
//
// ----------------------------------
//
// and the new skin part looks like this...
//
// -------------------------------------
//
// the result should be like this...
//
// ------- -------------------------------------

skin_above_combined = skin_above_combined.difference(relevant_outline.offset(tiny_infill_offset));
skin_above_combined.push_back(relevant_outline);
}
else // no overlap
{
skin_above_combined.push_back(relevant_outline);
}
// yes, it overlaps, need to leave a gap between this skin part and the others
// add this layer's skin region without subtracting the overlap but still make a gap between this skin region and what has been accumulated so
// far we do this so that these skin region edges will definitely have infill walls below them

// looking from the side, if the combined regions so far look like this...
//
// ----------------------------------
//
// and the new skin part looks like this...
//
// -------------------------------------
//
// the result should be like this...
//
// ------- -------------------------------------

skin_combined = skin_combined.difference(relevant_outline.offset(tiny_infill_offset));
skin_combined.push_back(relevant_outline);
}
else // this is the first skin region we have looked at
else // no overlap
{
skin_above_combined.push_back(relevant_outline);
skin_combined.push_back(relevant_outline);
}
}
else // this is the first skin region we have looked at
{
skin_combined.push_back(relevant_outline);
}
}
}
}

void FffGcodeWriter::partitionInfillBySkinAbove(
Shape& infill_below_skin,
Shape& infill_not_below_skin,
Shape& infill_sandwiched,
const LayerPlan& gcode_layer,
const SliceMeshStorage& mesh,
const SliceLayerPart& part,
coord_t infill_line_width)
{
const bool skin_support = mesh.settings.get<bool>("skin_support");

if (! skin_support)
{
return;
}

Shape skin_above_combined; // skin regions on the layers above combined with small gaps between
Shape skin_below_combined; // same for the skin below (to check if we're sandwiching only 1 layer of infill, in which case we shouldn't do the support)
getCombinedSkinForSkinSupport(skin_above_combined, mesh, part, gcode_layer.getLayerNr() + 1);
getCombinedSkinForSkinSupport(skin_below_combined, mesh, part, std::max(LayerIndex{ 1 }, gcode_layer.getLayerNr()) - 1);
infill_sandwiched = skin_above_combined.intersection(skin_below_combined);

// the shrink/expand here is to remove regions of infill below skin that are narrower than the width of the infill walls otherwise the infill walls could merge and form
// a bump
infill_below_skin = skin_above_combined.intersection(part.infill_area_per_combine_per_density.back().front()).offset(-infill_line_width).offset(infill_line_width);
infill_below_skin = skin_above_combined.difference(skin_below_combined)
.intersection(part.infill_area_per_combine_per_density.back().front())
.offset(-infill_line_width)
.offset(infill_line_width);

constexpr bool remove_small_holes_from_infill_below_skin = true;
constexpr double min_area_multiplier = 25;
Expand Down
Loading