Skip to content

Commit

Permalink
Merge remote-tracking branch 'trahm/tree_support_2' into CURA-10415_m…
Browse files Browse the repository at this point in the history
…ain_based_update_tree
  • Loading branch information
rburema committed Apr 21, 2023
2 parents ec8dffc + bb5380a commit a11681d
Show file tree
Hide file tree
Showing 14 changed files with 508 additions and 87 deletions.
4 changes: 3 additions & 1 deletion include/SupportInfillPart.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ class SupportInfillPart
// for infill_areas[x][n], x means the density level and n means the thickness
std::vector<VariableWidthLines> wall_toolpaths; //!< Any walls go here, not in the areas, where they could be combined vertically (don't combine walls). Binned by inset_idx.

SupportInfillPart(const PolygonsPart& outline, coord_t support_line_width, int inset_count_to_generate = 0);
coord_t custom_line_distance;

SupportInfillPart(const PolygonsPart& outline, coord_t support_line_width, int inset_count_to_generate = 0, coord_t custom_line_distance = 0 );

const Polygons& getInfillArea() const;
};
Expand Down
15 changes: 13 additions & 2 deletions include/TreeSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ constexpr auto TREE_PROGRESS_GENERATE_BRANCH_AREAS = TREE_PROGRESS_DRAW_AREAS /
constexpr auto TREE_PROGRESS_SMOOTH_BRANCH_AREAS = TREE_PROGRESS_DRAW_AREAS / 3;
constexpr auto TREE_PROGRESS_FINALIZE_BRANCH_AREAS = TREE_PROGRESS_DRAW_AREAS / 3;

constexpr auto SUPPORT_TREE_MINIMUM_FAKE_ROOF_AREA = 100;
constexpr auto SUPPORT_TREE_MINIMUM_FAKE_ROOF_LAYERS = 1;
constexpr auto SUPPORT_TREE_MINIMUM_ROOF_AREA_HARD_LIMIT = false;
constexpr auto SUPPORT_TREE_ONLY_GRACIOUS_TO_MODEL = false;
constexpr auto SUPPORT_TREE_AVOID_SUPPORT_BLOCKER = true;
Expand Down Expand Up @@ -276,6 +278,9 @@ class TreeSupport
const std::map<TreeSupportElement*, TreeSupportElement*>& inverse_tree_order
);


void filterFloatingLines(std::vector<Polygons>& support_layer_storage);

/*!
* \brief Generates Support Floor, ensures Support Roof can not cut of branches, and saves the branches as support to storage
*
Expand All @@ -295,12 +300,18 @@ class TreeSupport

/*!
* \brief Settings with the indexes of meshes that use these settings.
*
*/
std::vector<std::pair<TreeSupportSettings, std::vector<size_t>>> grouped_meshes;

std::vector<Polygons> additional_required_support_area; //todo doku
/*!
* \brief Areas that should have been support roof, but where the roof settings would not allow any lines to be generated.
*/
std::vector<Polygons> additional_required_support_area;

/*!
* \brief A representation of already placed lines. Required for subtracting from new support areas.
*/
std::vector<Polygons> placed_support_lines_support_areas;

/*!
* \brief Generator for model collision, avoidance and internal guide volumes.
Expand Down
5 changes: 5 additions & 0 deletions include/TreeSupportElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,11 @@ struct TreeSupportElement
*/
Polygons influence_area_limit_area;

/*!
* \brief Additional locations that the tip should reach
*/
std::vector<Point> additional_ovalization_targets;


bool operator==(const TreeSupportElement& other) const
{
Expand Down
20 changes: 19 additions & 1 deletion include/TreeSupportSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ struct TreeSupportSettings
connect_zigzags(mesh_group_settings.get<bool>("support_connect_zigzags")),
settings(mesh_group_settings),
min_feature_size(mesh_group_settings.get<coord_t>("min_feature_size")),
min_wall_line_width(settings.get<coord_t>("min_wall_line_width")),
fill_outline_gaps(settings.get<bool>("fill_outline_gaps")),
simplifier(Simplify(mesh_group_settings))
{
layer_start_bp_radius = (bp_radius - branch_radius) / (branch_radius * diameter_scale_bp_radius);
Expand Down Expand Up @@ -110,7 +112,11 @@ struct TreeSupportSettings
}
};

getInterfaceAngles(support_infill_angles, support_pattern);
if(support_infill_angles.empty())
{
support_infill_angles.push_back(0);
}

getInterfaceAngles(support_roof_angles, roof_pattern);
const std::unordered_map<std::string, InterfacePreference> interface_map =
{
Expand Down Expand Up @@ -354,6 +360,16 @@ struct TreeSupportSettings
*/
coord_t min_feature_size;

/*!
* \brief Minimum thickness a wall can have.
*/
coord_t min_wall_line_width;

/*!
* \brief If areas of min_feature_size are enlarged to min_wall_line_width
*/
bool fill_outline_gaps;

/*!
* \brief Simplifier to simplify polygons.
*/
Expand Down Expand Up @@ -403,6 +419,8 @@ struct TreeSupportSettings
min_feature_size == other.min_feature_size && // interface_preference should be identical to ensure the tree will correctly interact with the roof.
support_rest_preference == other.support_rest_preference &&
max_radius == other.max_radius &&
min_wall_line_width == other.min_wall_line_width &&
fill_outline_gaps == other.fill_outline_gaps &&
// The infill class now wants the settings object and reads a lot of settings, and as the infill class is used to calculate support roof lines for interface-preference. Not all of these may be required to be identical, but as I am not sure, better safe than sorry
(
interface_preference == InterfacePreference::INTERFACE_AREA_OVERWRITES_SUPPORT ||
Expand Down
32 changes: 23 additions & 9 deletions include/TreeSupportTipGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class TreeSupportTipGenerator
* \return All lines of the \p polylines object, with information for each point regarding in which avoidance it is currently valid in.
*/
void generateTips(SliceDataStorage& storage,const SliceMeshStorage& mesh ,std::vector<std::set<TreeSupportElement*>>& move_bounds, std::vector<Polygons>& additional_support_areas);
void generateTips(SliceDataStorage& storage,const SliceMeshStorage& mesh ,std::vector<std::set<TreeSupportElement*>>& move_bounds, std::vector<Polygons>& additional_support_areas, std::vector<Polygons>& placed_support_lines_support_areas);

private:

Expand Down Expand Up @@ -103,9 +103,10 @@ class TreeSupportTipGenerator
* \param input[in] The lines on which evenly spaced points should be placed.
* \param distance[in] The distance the points should be from each other.
* \param min_points[in] The amount of points that have to be placed. If not enough can be placed the distance will be reduced to place this many points.
* \param enforce_distance[in] If points should not be added if they are closer than distance to other points.
* \return A Polygons object containing the evenly spaced points. Does not represent an area, more a collection of points on lines.
*/
Polygons ensureMaximumDistancePolyline(const Polygons& input, coord_t distance, size_t min_points) const;
Polygons ensureMaximumDistancePolyline(const Polygons& input, coord_t distance, size_t min_points, bool enforce_distance) const;

/*!
* \brief Creates a valid CrossInfillProvider
Expand Down Expand Up @@ -142,7 +143,7 @@ class TreeSupportTipGenerator
* \param roof[in] Whether the tip supports a roof.
* \param skip_ovalisation[in] Whether the tip may be ovalized when drawn later.
*/
void addPointAsInfluenceArea(std::vector<std::set<TreeSupportElement *>>& move_bounds, std::pair<Point, LineStatus> p, size_t dtt, LayerIndex insert_layer, size_t dont_move_until, bool roof, bool skip_ovalisation);
void addPointAsInfluenceArea(std::vector<std::set<TreeSupportElement *>>& move_bounds, std::pair<Point, LineStatus> p, size_t dtt, LayerIndex insert_layer, size_t dont_move_until, bool roof, bool skip_ovalisation, std::vector<Point> additional_ovalization_targets = std::vector<Point>());


/*!
Expand All @@ -154,7 +155,7 @@ class TreeSupportTipGenerator
* \param supports_roof[in] Whether the tip supports a roof.
* \param dont_move_until[in] Until which dtt the branch should not move if possible.
*/
void addLinesAsInfluenceAreas(std::vector<std::set<TreeSupportElement *>>& move_bounds, std::vector<TreeSupportTipGenerator::LineInformation> lines, size_t roof_tip_layers, LayerIndex insert_layer_idx, bool supports_roof, size_t dont_move_until);
void addLinesAsInfluenceAreas(std::vector<std::set<TreeSupportElement *>>& move_bounds, std::vector<TreeSupportTipGenerator::LineInformation> lines, size_t roof_tip_layers, LayerIndex insert_layer_idx, bool supports_roof, size_t dont_move_until, bool connect_points);

/*!
* \brief Remove tips that should not have been added in the first place.
Expand All @@ -164,9 +165,14 @@ class TreeSupportTipGenerator
*/
void removeUselessAddedPoints(std::vector<std::set<TreeSupportElement *>>& move_bounds,SliceDataStorage& storage, std::vector<Polygons>& additional_support_areas);


/*!
* \brief If large areas should be supported by a roof out of regular support lines.
*/
bool use_fake_roof;

/*!
* \brief Generator for model collision, avoidance and internal guide volumes.
*
*/
TreeModelVolumes& volumes_;

Expand All @@ -175,10 +181,6 @@ class TreeSupportTipGenerator
*/
TreeSupportSettings config;

/*!
* \brief Distance between support roof lines. Is required for generating roof patterns.
*/
const coord_t support_roof_line_distance;

/*!
* \brief Minimum area an overhang has to have to become a roof.
Expand All @@ -205,6 +207,12 @@ class TreeSupportTipGenerator
*/
const coord_t support_tree_branch_distance;

/*!
* \brief Distance between support roof lines. Is required for generating roof patterns.
*/
const coord_t support_roof_line_distance;


/*!
* \brief Amount of offset to each overhang for support with regular branches (as opposed to roof).
*/
Expand Down Expand Up @@ -260,6 +268,10 @@ class TreeSupportTipGenerator
*/
const bool force_minimum_roof_area = SUPPORT_TREE_MINIMUM_ROOF_AREA_HARD_LIMIT;

/*!
* \brief Distance between branches when the branches support a support pattern
*/
coord_t support_supporting_branch_distance;

/*!
* \brief Required to generate cross infill patterns
Expand All @@ -282,6 +294,8 @@ class TreeSupportTipGenerator
std::vector<Polygons> roof_tips_drawn;




std::mutex critical_move_bounds;
std::mutex critical_roof_tips;

Expand Down
25 changes: 22 additions & 3 deletions include/TreeSupportUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,16 @@ class TreeSupportUtils
* \param layer_idx[in] The current layer index.
* \param support_infill_distance[in] The distance that should be between the infill lines.
* \param cross_fill_provider[in] A SierpinskiFillProvider required for cross infill.
*
* \param include_walls[in] If the result should also contain walls, or only the infill.
* todo doku
* \return A Polygons object that represents the resulting infill lines.
*/
[[nodiscard]] static Polygons generateSupportInfillLines(const Polygons& area,const TreeSupportSettings& config, bool roof, LayerIndex layer_idx, coord_t support_infill_distance, SierpinskiFillProvider* cross_fill_provider, bool include_walls)
[[nodiscard]] static Polygons generateSupportInfillLines(const Polygons& area,const TreeSupportSettings& config, bool roof, LayerIndex layer_idx, coord_t support_infill_distance, SierpinskiFillProvider* cross_fill_provider, bool include_walls, bool generate_support_supporting = false)
{
Polygons gaps;
// As we effectivly use lines to place our supportPoints we may use the Infill class for it, while not made for it, it works perfectly.

const EFillMethod pattern = roof ? config.roof_pattern : config.support_pattern;
const EFillMethod pattern = generate_support_supporting ? EFillMethod::GRID : roof ? config.roof_pattern : config.support_pattern;

const bool zig_zaggify_infill = roof ? pattern == EFillMethod::ZIG_ZAG : config.zig_zaggify_support;
const bool connect_polygons = false;
Expand Down Expand Up @@ -324,6 +325,24 @@ class TreeSupportUtils

return result;
}

[[nodiscard]]static VariableWidthLines polyLineToVWL(const Polygons& polylines, coord_t line_width)
{
VariableWidthLines result;
for (auto path: polylines)
{
ExtrusionLine vwl_line(1,true);

for(Point p: path)
{
vwl_line.emplace_back(p,line_width,1);
}
result.emplace_back(vwl_line);
}
return result;
}


};

} //namespace cura
Expand Down
1 change: 1 addition & 0 deletions include/utils/polygon.h
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,7 @@ class Polygons
return ret;
}


/*!
* Intersect polylines with this area Polygons object.
*
Expand Down
9 changes: 9 additions & 0 deletions include/utils/polygonUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,15 @@ class PolygonUtils

static Polygons unionManySmall(const Polygons& p);


/*!
* Intersects a polygon with an AABB.
* \param src The polygon that has to be intersected with an AABB
* \param aabb The AABB with which the polygon that has to be intersected with
* \return A new Polygon that is said intersection
*/
static Polygons clipPolygonWithAABB(const Polygons& src, const AABB& aabb);

private:
/*!
* Helper function for PolygonUtils::moveInside2: moves a point \p from which was moved onto \p closest_polygon_point towards inside/outside when it's not already inside/outside by enough distance.
Expand Down
5 changes: 2 additions & 3 deletions src/FffGcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2805,13 +2805,12 @@ bool FffGcodeWriter::processSupportInfill(const SliceDataStorage& storage, Layer
}

const unsigned int density_factor = 2 << density_idx; // == pow(2, density_idx + 1)
int support_line_distance_here = default_support_line_distance * density_factor; // the highest density infill combines with the next to create a grid with density_factor 1
int support_line_distance_here = (part.custom_line_distance > 0 ? part.custom_line_distance : default_support_line_distance * density_factor); // the highest density infill combines with the next to create a grid with density_factor 1
const int support_shift = support_line_distance_here / 2;
if (density_idx == max_density_idx || support_pattern == EFillMethod::CROSS || support_pattern == EFillMethod::CROSS_3D)
if (part.custom_line_distance == 0 && (density_idx == max_density_idx || support_pattern == EFillMethod::CROSS || support_pattern == EFillMethod::CROSS_3D))
{
support_line_distance_here /= 2;
}

const Polygons& area = part.infill_area_per_combine_per_density[density_idx][combine_idx];

constexpr size_t wall_count = 0; // Walls are generated somewhere else, so their layers aren't vertically combined.
Expand Down
3 changes: 2 additions & 1 deletion src/SupportInfillPart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
using namespace cura;


SupportInfillPart::SupportInfillPart(const PolygonsPart& outline, coord_t support_line_width, int inset_count_to_generate)
SupportInfillPart::SupportInfillPart(const PolygonsPart& outline, coord_t support_line_width, int inset_count_to_generate, coord_t custom_line_distance)
: outline(outline)
, outline_boundary_box(outline)
, support_line_width(support_line_width)
, inset_count_to_generate(inset_count_to_generate)
, custom_line_distance(custom_line_distance)
{
infill_area_per_combine_per_density.clear();
}
Loading

0 comments on commit a11681d

Please sign in to comment.