Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CURA-12234 combing over top surface #2168

Merged
merged 8 commits into from
Nov 11, 2024
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
9 changes: 2 additions & 7 deletions include/skin.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,9 @@ class SkinInfillAreaComputation
void generateRoofingFillAndSkinFill(SliceLayerPart& part);

/*!
* Remove the areas which are directly under air in the top-most surface and directly above air in bottom-most
* surfaces from the \ref SkinPart::inner_infill and save them in the \ref SkinPart::bottom_most_surface_fill and
* \ref SkinPart::top_most_surface_fill (respectively) of the \p part.
*
* \param[in,out] part Where to get the SkinParts to get the outline info from and to store the top and bottom-most
* infill areas
* Generate the top and bottom-most surfaces of the given \p part, i.e. the surfaces that have nothing above or below
*/
void generateTopAndBottomMostSkinFill(SliceLayerPart& part);
void generateTopAndBottomMostSurfaces(SliceLayerPart& part);

/*!
* Helper function to calculate and return the areas which are 'directly' under air.
Expand Down
4 changes: 2 additions & 2 deletions include/sliceDataStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ class SkinPart
//!< roofing and non-roofing.
Shape skin_fill; //!< The part of the skin which is not roofing.
Shape roofing_fill; //!< The inner infill which has air directly above
Shape top_most_surface_fill; //!< The inner infill of the uppermost top layer which has air directly above.
Shape bottom_most_surface_fill; //!< The inner infill of the bottommost bottom layer which has air directly below.
};

/*!
Expand All @@ -69,6 +67,8 @@ class SliceLayerPart
std::vector<SkinPart> skin_parts; //!< The skin parts which are filled for 100% with lines and/or insets.
std::vector<VariableWidthLines> wall_toolpaths; //!< toolpaths for walls, will replace(?) the insets. Binned by inset_idx.
std::vector<VariableWidthLines> infill_wall_toolpaths; //!< toolpaths for the walls of the infill areas. Binned by inset_idx.
Shape top_most_surface; //!< Sub-part of the outline containing the area that is not covered by something above
Shape bottom_most_surface; //!< Sub-part of the outline containing the area that has nothing below

/*!
* The areas inside of the mesh.
Expand Down
41 changes: 22 additions & 19 deletions src/LayerPlan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,16 @@ Shape LayerPlan::computeCombBoundary(const CombBoundary boundary_type)
{
continue;
}

constexpr coord_t extra_offset = 10; // Additional offset to avoid zero-width polygons remains
coord_t offset;
switch (boundary_type)
{
case CombBoundary::MINIMUM:
offset = -mesh.settings.get<coord_t>("machine_nozzle_size") / 2 - mesh.settings.get<coord_t>("wall_line_width_0") / 2;
offset = -mesh.settings.get<coord_t>("machine_nozzle_size") / 2 - mesh.settings.get<coord_t>("wall_line_width_0") / 2 - extra_offset;
break;
case CombBoundary::PREFERRED:
offset = -mesh.settings.get<coord_t>("machine_nozzle_size") * 3 / 2 - mesh.settings.get<coord_t>("wall_line_width_0") / 2;
offset = -mesh.settings.get<coord_t>("machine_nozzle_size") * 3 / 2 - mesh.settings.get<coord_t>("wall_line_width_0") / 2 - extra_offset;
break;
default:
offset = 0;
Expand All @@ -208,36 +210,37 @@ Shape LayerPlan::computeCombBoundary(const CombBoundary boundary_type)
const CombingMode combing_mode = mesh.settings.get<CombingMode>("retraction_combing");
for (const SliceLayerPart& part : layer.parts)
{
if (combing_mode == CombingMode::ALL) // Add the increased outline offset (skin, infill and part of the inner walls)
{
comb_boundary.push_back(part.outline.offset(offset));
}
else if (combing_mode == CombingMode::NO_SKIN) // Add the increased outline offset, subtract skin (infill and part of the inner walls)
Shape part_combing_boundary;

if (combing_mode == CombingMode::INFILL)
{
comb_boundary.push_back(part.outline.offset(offset).difference(part.inner_area.difference(part.infill_area)));
part_combing_boundary = part.infill_area;
}
else if (combing_mode == CombingMode::NO_OUTER_SURFACES)
else
{
Shape top_and_bottom_most_fill;
for (const SliceLayerPart& outer_surface_part : layer.parts)
part_combing_boundary = part.outline.offset(offset);

if (combing_mode == CombingMode::NO_SKIN) // Add the increased outline offset, subtract skin (infill and part of the inner walls)
{
for (const SkinPart& skin_part : outer_surface_part.skin_parts)
part_combing_boundary = part_combing_boundary.difference(part.inner_area.difference(part.infill_area));
}
else if (combing_mode == CombingMode::NO_OUTER_SURFACES)
{
for (const SliceLayerPart& outer_surface_part : layer.parts)
{
top_and_bottom_most_fill.push_back(skin_part.top_most_surface_fill);
top_and_bottom_most_fill.push_back(skin_part.bottom_most_surface_fill);
part_combing_boundary = part_combing_boundary.difference(outer_surface_part.top_most_surface);
part_combing_boundary = part_combing_boundary.difference(outer_surface_part.bottom_most_surface);
}
}
comb_boundary.push_back(part.outline.offset(offset).difference(top_and_bottom_most_fill));
}
else if (combing_mode == CombingMode::INFILL) // Add the infill (infill only)
{
comb_boundary.push_back(part.infill_area);
}

comb_boundary.push_back(part_combing_boundary);
}
}
break;
}
}

return comb_boundary;
}

Expand Down
38 changes: 17 additions & 21 deletions src/skin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void SkinInfillAreaComputation::generateSkinsAndInfill()
{
generateRoofingFillAndSkinFill(part);

generateTopAndBottomMostSkinFill(part);
generateTopAndBottomMostSurfaces(part);
}
}

Expand Down Expand Up @@ -343,6 +343,22 @@ void SkinInfillAreaComputation::generateRoofingFillAndSkinFill(SliceLayerPart& p
}
}

void SkinInfillAreaComputation::generateTopAndBottomMostSurfaces(SliceLayerPart& part)
{
const Shape outline_above = getOutlineOnLayer(part, layer_nr_ + 1);
part.top_most_surface = part.outline.difference(outline_above);

if (layer_nr_ > 0)
{
const Shape outline_below = getOutlineOnLayer(part, layer_nr_ + 1);
part.bottom_most_surface = part.outline.difference(outline_below);
}
else
{
part.bottom_most_surface = part.outline;
}
}

/*
* This function is executed in a parallel region based on layer_nr.
* When modifying make sure any changes does not introduce data races.
Expand Down Expand Up @@ -633,24 +649,4 @@ void SkinInfillAreaComputation::combineInfillLayers(SliceMeshStorage& mesh)
}
}

/*
* This function is executed in a parallel region based on layer_nr.
* When modifying make sure any changes does not introduce data races.
*
* this function may only read/write the skin and infill from the *current* layer.
*/

void SkinInfillAreaComputation::generateTopAndBottomMostSkinFill(SliceLayerPart& part)
{
for (SkinPart& skin_part : part.skin_parts)
{
Shape filled_area_above = generateFilledAreaAbove(part, 1);
skin_part.top_most_surface_fill = skin_part.outline.difference(filled_area_above);

Shape filled_area_below = generateFilledAreaBelow(part, 1);
skin_part.bottom_most_surface_fill = skin_part.skin_fill.difference(filled_area_below);
}
}


} // namespace cura
Loading