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

Brim overhaul: New features and Bug fixes #1613

Merged
merged 69 commits into from
Oct 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
4aede4d
aux: find middle between polygons
BagelOrb Feb 22, 2021
fe5a29d
initial brim_per_material functionality
BagelOrb Feb 22, 2021
de4e274
lil hack to speed up brim
BagelOrb Feb 24, 2021
a48d10b
allow for skirt_brim_extruder_nr to be -1
BagelOrb Aug 12, 2022
c211367
lil fix for new Simplify class
BagelOrb Aug 12, 2022
35adf07
reimplement brim_per_material
BagelOrb Feb 11, 2022
621146e
allow for polylines longer than 2 in brim
BagelOrb Feb 11, 2022
f47882e
Revert "aux: find middle between polygons"
BagelOrb Feb 11, 2022
7c41db3
aux Polygons function
BagelOrb Feb 14, 2022
b68a316
fix Brim only on outside for parts inside other parts
BagelOrb Feb 14, 2022
948ca4c
dissolve primeTower.outer_poly_first_layer
BagelOrb Feb 14, 2022
770a963
fix prime tower brim
BagelOrb Feb 14, 2022
240e6a7
fix initial layer line width percentage in brim
BagelOrb Feb 14, 2022
36c728b
lil speedup
BagelOrb Feb 14, 2022
da03144
feat: settings.get<Polygons>
BagelOrb Aug 12, 2022
a3d2095
fix raft doesn't take prime tower brim into account anymore
BagelOrb Aug 12, 2022
fb97bc7
take disallowed areas into account when printing tree support
BagelOrb Feb 14, 2022
cf8d919
use extruder offset on disallowed areas
BagelOrb Feb 15, 2022
bf30994
limit brim to allowed_areas
BagelOrb Feb 15, 2022
337305d
speed up brim computation
BagelOrb Feb 15, 2022
60a9707
fix border offsets separately from disallowed areas
BagelOrb Feb 15, 2022
0f19c4a
fix: only process brim for used extruders
BagelOrb Feb 15, 2022
a56a71c
Don't print a prime tower if a single extruder is used
BagelOrb Feb 15, 2022
015a883
Fix prime tower brim extruder to be the one of the outer ring
BagelOrb Feb 15, 2022
ad502f2
Remove getMachineBorder(.):adhesion_offset functionality
BagelOrb Aug 12, 2022
6f5248b
Allow brim of left extruder to be paced more to the left
BagelOrb Feb 15, 2022
3fa5eb7
simplify brim code
BagelOrb Feb 15, 2022
07902c5
fix brim for support
BagelOrb Feb 15, 2022
30386a5
skirt fix
BagelOrb Feb 15, 2022
d0c9797
lil todo
BagelOrb Feb 16, 2022
8272f36
generate brim for ooze- and draft shield
BagelOrb Feb 17, 2022
871e631
ensure primary brims minimal length
BagelOrb Feb 17, 2022
e8f8465
refactor: store common info in class instead of static and move gener…
BagelOrb Feb 17, 2022
8a84f88
lil refactor to allow generateOffset to store in different location
BagelOrb Feb 17, 2022
8ae1bf7
simplify Offset struct
BagelOrb Feb 17, 2022
84b5be1
simplify brim algorithm
BagelOrb Feb 17, 2022
0e0fca9
fix skirt for secondary extruders
BagelOrb Feb 17, 2022
8966256
fix skirt
BagelOrb Feb 18, 2022
5cec2e5
remove old brim code
BagelOrb Feb 18, 2022
54178ae
fix offsetting of external-only brim
BagelOrb Feb 18, 2022
8982933
put secondary skirt on very outside only
BagelOrb Feb 18, 2022
ded025c
prevent brim from overlapping with prime blob
BagelOrb Feb 18, 2022
7cddd50
initial brim printing order requirements
BagelOrb Feb 18, 2022
86e06c3
simplify brim lines
BagelOrb Feb 24, 2022
55be4cf
Fix brim overlapping with internal holes
BagelOrb Mar 16, 2022
9739ab5
remove brim lines which are very short
BagelOrb Mar 16, 2022
6f7c9f3
prevent overlap between shields and prime tower
BagelOrb Aug 12, 2022
95f8ce6
Print support brim.
BagelOrb Mar 16, 2022
1e7ab04
Prevent shield brim from ending up inside the brim_inside_margin
BagelOrb Mar 17, 2022
bc880d0
make brim_inside_margin a user setting
BagelOrb Mar 17, 2022
ad44082
Never print shield brim inside other parts
BagelOrb Mar 17, 2022
fe5ed2a
Print brim outer to inner if there's enough distance
BagelOrb Mar 17, 2022
0297afc
clean up old brim code
BagelOrb Mar 17, 2022
00994d0
header cleanup and documentation
BagelOrb Mar 17, 2022
2d7b8c3
indent only
BagelOrb Mar 17, 2022
886add8
remove TODO comments
BagelOrb Mar 17, 2022
3339732
split up large function into chunks
BagelOrb Mar 17, 2022
5ad5151
Fix prime tower brim
BagelOrb Mar 17, 2022
9a35852
fix for high hole_brim_distance
BagelOrb Mar 17, 2022
fe9f19b
Merge branch 'main' into brim_per_material_optimized_order
rburema Oct 25, 2022
4b454ff
'Mutable' makes no sense here.
rburema Oct 26, 2022
39569fc
Use closure instead of function-struct (+ code style).
rburema Oct 26, 2022
54a70cc
Modern-style typing.
rburema Oct 26, 2022
2c9bb5e
Add default parameter.
rburema Oct 26, 2022
24781a5
Code-style.
rburema Oct 26, 2022
96462e1
Code-style, remove outdated (TODO's), and apply D.R.Y.
rburema Oct 30, 2022
f6d19fe
Correctly apply simplification to skirt/brim.
rburema Oct 30, 2022
b6fba68
Can now access wether to offset disallowed areas for nozzles from fro…
rburema Oct 30, 2022
4f053c7
Code style.
rburema Oct 30, 2022
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
4 changes: 3 additions & 1 deletion include/LayerPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -618,8 +618,10 @@ class LayerPlan : public NoCopy
* \param flow_ratio The ratio with which to multiply the extrusion amount
* \param near_start_location Optional: Location near where to add the first line. If not provided the last position is used.
* \param fan_speed optional fan speed override for this path
* \param reverse_print_direction Whether to reverse the optimized order and their printing direction.
* \param order_requirements Pairs where first needs to be printed before second. Pointers are pointing to elements of \p polygons
*/
void addLinesByOptimizer(const Polygons& polygons, const GCodePathConfig& config, const SpaceFillType space_fill_type, const bool enable_travel_optimization = false, const coord_t wipe_dist = 0, const Ratio flow_ratio = 1.0, const std::optional<Point> near_start_location = std::optional<Point>(), const double fan_speed = GCodePathConfig::FAN_SPEED_DEFAULT, const bool reverse_print_direction = false);
void addLinesByOptimizer(const Polygons& polygons, const GCodePathConfig& config, const SpaceFillType space_fill_type, const bool enable_travel_optimization = false, const coord_t wipe_dist = 0, const Ratio flow_ratio = 1.0, const std::optional<Point> near_start_location = std::optional<Point>(), const double fan_speed = GCodePathConfig::FAN_SPEED_DEFAULT, const bool reverse_print_direction = false, const std::unordered_set<std::pair<ConstPolygonPointer, ConstPolygonPointer>>& order_requirements = PathOrderOptimizer<ConstPolygonPointer>::no_order_requirements);

/*!
* Add polygons to the g-code with monotonic order.
Expand Down
2 changes: 2 additions & 0 deletions include/PathOrderOptimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,10 @@ class PathOrderOptimizer
*/
bool reverse_direction;

public:
static const std::unordered_set<std::pair<PathType, PathType>> no_order_requirements;

protected:
/*!
* Order requirements on the paths.
* For each pair the first needs to be printe before the second.
Expand Down
6 changes: 5 additions & 1 deletion include/PrimeTower.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ class PrimeTower
bool would_have_actual_tower; //!< Whether there is an actual tower.
bool multiple_extruders_on_first_layer; //!< Whether multiple extruders are allowed on the first layer of the prime tower (e.g. when a raft is there)
Polygons outer_poly; //!< The outline of the outermost prime tower.
Polygons outer_poly_first_layer; //!< The outermost outline, plus optional brim on 'brim for prime tower' is enabled.

/*
* In which order, from outside to inside, will we be printing the prime
Expand All @@ -66,6 +65,11 @@ class PrimeTower
*/
PrimeTower();

/*!
* Check whether we actually use the prime tower.
*/
void checkUsed(const SliceDataStorage& storage);

/*!
* Generate the prime tower area to be used on each layer
*
Expand Down
166 changes: 157 additions & 9 deletions include/SkirtBrim.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,91 @@
#define SKIRT_BRIM_H

#include "utils/Coord_t.h"
#include "ExtruderTrain.h"
#include "settings/EnumSettings.h"
#include "sliceDataStorage.h"

#include <variant>

namespace cura
{

class Polygons;
class SliceDataStorage;

constexpr coord_t min_brim_line_length = 3000u; //!< open polyline brim lines smaller than this will be removed

class SkirtBrim
{
private:
/*!
* A helper class to store an offset yet to be performed on either an outline polygon, or based on an earlier generated brim line.
*/
struct Offset
{
Offset
(
const std::variant<Polygons*, int>& reference_outline_or_index,
const bool external_only,
const coord_t offset_value,
const coord_t total_offset,
const size_t inset_idx,
const int extruder_nr,
const bool is_last
) :
reference_outline_or_index(reference_outline_or_index),
external_only(external_only),
offset_value(offset_value),
total_offset(total_offset),
inset_idx(inset_idx),
extruder_nr(extruder_nr),
is_last(is_last)
{}

std::variant<Polygons*, int> reference_outline_or_index;
bool external_only; //!< Wether to only offset outward from the reference polygons
coord_t offset_value; //!< Distance by which to offset from the reference
coord_t total_offset; //!< Total distance from the model
int inset_idx; //!< The outset index of this brimline
int extruder_nr; //!< The extruder by which to print this brim line
bool is_last; //!< Whether this is the last planned offset for this extruder.
};

/*!
* Defines an order on offsets (potentially from different extruders) based on how far the offset is from the original outline.
*/
static inline const auto OffsetSorter
{
[](const Offset& a, const Offset& b)
{
// Use extruder_nr in case both extruders have the same offset settings.
return a.total_offset != b.total_offset ? a.total_offset < b.total_offset : a.extruder_nr < b.extruder_nr;
}
};

SliceDataStorage& storage; //!< Where to retrieve settings and store brim lines.
const EPlatformAdhesion adhesion_type; //!< Whether we are generating brim, skirt, or raft
const bool has_ooze_shield; //!< Whether the meshgroup has an ooze shield
const bool has_draft_shield; //!< Whether the meshgroup has a draft shield
const std::vector<ExtruderTrain>& extruders; //!< The extruders of the current slice
const int extruder_count; //!< The total number of extruders
const std::vector<bool> extruder_is_used; //!< For each extruder whether it is actually used in this print
int first_used_extruder_nr; //!< The first extruder which is used
int skirt_brim_extruder_nr; //!< The extruder with which the skirt/brim is printed or -1 if printed with both
std::vector<bool> external_polys_only; //!< For each extruder whether to only generate brim on the outside
std::vector<coord_t> line_widths; //!< For each extruder the skirt/brim line width
std::vector<coord_t> skirt_brim_minimal_length; //!< For each extruder the minimal brim length
std::vector<int> line_count; //!< For each extruder the (minimal) number of brim lines to generate
std::vector<coord_t> gap; //!< For each extruder the gap between the part and the first brim/skirt line

public:
/*!
* Precomputes some values used in several functions when calling \ref generate
*
* \param storage Storage containing the parts at the first layer.
*/
SkirtBrim(SliceDataStorage& storage);

/*!
* Generate skirt or brim (depending on parameters).
*
Expand All @@ -28,7 +103,41 @@ class SkirtBrim
* \param primary_line_count Number of offsets / brim lines of the primary extruder.
* \param set to false to force not doing brim generation for helper-structures (support and ooze/draft shields)
*/
static void generate(SliceDataStorage& storage, Polygons first_layer_outline, const coord_t distance, size_t primary_line_count, const bool allow_helpers = true);
void generate();

private:
/*!
* Plan the offsets which we will be going to perform and put them in the right order.
*
* In order for brims of different materials to grow toward the middle,
* we need to perform the offsets alternatingly.
* We therefore first create all planned Offset objects,
* and then order them according to distance from the boundary.
* \param[out] starting_outlines The first layer outlines from which to compute the offsets. Returned as output parameter because pointers need to stay valid.
* \return An ordered list of offsets to perform in the order in which they are to be performed.
*/
std::vector<Offset> generateBrimOffsetPlan(std::vector<Polygons>& starting_outlines);

/*!
* Generate the primary skirt/brim of the one skirt_brim_extruder or of all extruders simultaneously.
*
* \param[in,out] all_brim_offsets The offsets to perform. Adjusted when the minimal length constraint isn't met yet.
* \param[in,out] covered_area The area of the first layer covered by model or generated brim lines.
* \param[in,out] allowed_areas_per_extruder The difference between the machine bed area (offsetted by the nozzle offset) and the covered_area.
* \return The total length of the brim lines added by this method per extruder.
*/
std::vector<coord_t> generatePrimaryBrim(std::vector<Offset>& all_brim_offsets, Polygons& covered_area, std::vector<Polygons>& allowed_areas_per_extruder);

/*!
* Generate the brim inside the ooze shield and draft shield
*
* \warning Adjusts brim_covered_area
*
* \param storage Storage containing the parts at the first layer.
* \param[in,out] brim_covered_area The area that was covered with brim before (in) and after (out) adding the shield brims
* \param[in,out] allowed_areas_per_extruder The difference between the machine areas and the \p covered_area
*/
void generateShieldBrim(Polygons& brim_covered_area, std::vector<Polygons>& allowed_areas_per_extruder);

/*!
* \brief Get the reference outline of the first layer around which to
Expand All @@ -38,17 +147,56 @@ class SkirtBrim
* in order to meet criteria for putting brim around the model as well as
* around the support.
*
* \param storage Storage containing the parts at the first layer.
* \param primary_line_count Number of offsets / brim lines of the primary
* extruder.
* \param is_skirt Whether a skirt is being generated vs a brim
* \param[out] first_layer_outline The resulting reference polygons
* \param extruder_nr The extruder for which to get the outlines. -1 to include outliens for all extruders
* \return The resulting reference polygons
*/
static void getFirstLayerOutline(SliceDataStorage& storage, const size_t primary_line_count, const bool is_skirt, Polygons& first_layer_outline);
Polygons getFirstLayerOutline(const int extruder_nr = -1);

private:
static void generateSupportBrim(SliceDataStorage& storage, const bool merge_with_model_skirtbrim);
/*!
* The disallowed area around the internal holes of parts with other parts inside which would get an external brim.
*
* In order to prevent the external_only brim of a part inside another part to overlap with the internal holes of the outer part,
* we generate a disallowed area around those internal hole polygons.
*
* \param outline The full layer outlines
* \param extruder_nr The extruder for which to compute disallowed areas
* \return The disallowed areas
*/
Polygons getInternalHoleExclusionArea(const Polygons& outline, const int extruder_nr);

/*!
* Generate a brim line with offset parameters given by \p offset from the \p starting_outlines and store it in the \ref storage.
*
* \warning Has side effects on \p covered_area, \p allowed_areas_per_extruder and \p total_length
*
* \param offset The parameters with which to perform the offset
* \param[in,out] covered_area The total area covered by the brims (and models) on the first layer.
* \param[in,out] allowed_areas_per_extruder The difference between the machine areas and the \p covered_area
* \param[out] result Where to store the resulting brim line
* \return The length of the added lines
*/
coord_t generateOffset(const Offset& offset, Polygons& covered_area, std::vector<Polygons>& allowed_areas_per_extruder, SkirtBrimLine& result);

/*!
* Generate a skirt of extruders which don't yet comply with the minimum length requirement.
*
* This skirt goes directly adjacent to all primary brims.
*
* The skirt is stored in storage.skirt_brim.
*
* \param[in,out] covered_area The total area covered by the brims (and models) on the first layer.
* \param[in,out] allowed_areas_per_extruder The difference between the machine areas and the \p covered_area
* \param[in,out] total_length The total length of the brim lines for each extruder.
*/
void generateSecondarySkirtBrim(Polygons& covered_area, std::vector<Polygons>& allowed_areas_per_extruder, std::vector<coord_t>& total_length);

public:
/*!
* Generate the brim which is printed from the outlines of the support inward.
*/
void generateSupportBrim();

private:
/*!
* \brief Generate the skirt/brim lines around the model.
*
Expand Down
4 changes: 2 additions & 2 deletions include/TreeModelVolumes.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class TreeModelVolumes
*
* \param a Polygons object representing the non-printable areas on and around the build platform
*/
static Polygons calculateMachineBorderCollision(Polygon machine_border);
static Polygons calculateMachineBorderCollision(const Polygons&& machine_border);

/*!
* \brief Polygons representing the limits of the printable area of the
Expand Down Expand Up @@ -199,4 +199,4 @@ class TreeModelVolumes

}

#endif //TREEMODELVOLUMES_H
#endif //TREEMODELVOLUMES_H
1 change: 0 additions & 1 deletion include/settings/PathConfigStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ class PathConfigStorage
const size_t support_infill_extruder_nr;
const size_t support_roof_extruder_nr;
const size_t support_bottom_extruder_nr;
ExtruderTrain& skirt_brim_train;
ExtruderTrain& raft_base_train;
ExtruderTrain& raft_interface_train;
ExtruderTrain& raft_surface_train;
Expand Down
26 changes: 17 additions & 9 deletions include/sliceDataStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,15 @@ class SliceMeshStorage
Point getZSeamHint() const;
};

/*!
* Class to store all open polylines or closed polygons related to one outset index of brim/skirt.
*/
struct SkirtBrimLine
{
Polygons open_polylines;
Polygons closed_polygons;
};

class SliceDataStorage : public NoCopy
{
public:
Expand All @@ -315,9 +324,9 @@ class SliceDataStorage : public NoCopy
std::vector<RetractionConfig> extruder_switch_retraction_config_per_extruder; //!< Retraction config per extruder for when performing an extruder switch

SupportStorage support;

Polygons skirt_brim[MAX_EXTRUDERS]; //!< Skirt and brim polygons per extruder, ordered from inner to outer polygons.
size_t skirt_brim_max_locked_part_order[MAX_EXTRUDERS]; //!< Some parts (like skirt) always need to be printed before parts like support-brim, so lock 0..n for each extruder, where n is the value saved in this array.
std::vector<SkirtBrimLine> skirt_brim[MAX_EXTRUDERS]; //!< Skirt/brim polygons per extruder, ordered from inner to outer polygons.
Polygons support_brim; //!< brim lines for support, going from the edge of the support inward. \note Not ordered by inset.
Polygons raftOutline; //Storage for the outline of the raft. Will be filled with lines when the GCode is generated.
Polygons primeRaftOutline; // ... the raft underneath the prime-tower will have to be printed first, if there is one. (When the raft has top layers with a different extruder for example.)

Expand Down Expand Up @@ -352,9 +361,9 @@ class SliceDataStorage : public NoCopy
* \param include_prime_tower Whether to include the prime tower in the
* outline.
* \param external_polys_only Whether to disregard all hole polygons.
* \param for_brim Whether the outline is to be used to construct the brim.
* \param extruder_nr (optional) only give back outlines for this extruder (where the walls are printed with this extruder)
*/
Polygons getLayerOutlines(const LayerIndex layer_nr, const bool include_support, const bool include_prime_tower, const bool external_polys_only = false, const bool for_brim = false) const;
Polygons getLayerOutlines(const LayerIndex layer_nr, const bool include_support, const bool include_prime_tower, const bool external_polys_only = false, const int extruder_nr = -1) const;

/*!
* Get the extruders used.
Expand Down Expand Up @@ -383,11 +392,10 @@ class SliceDataStorage : public NoCopy
/*!
* Gets the border of the usable print area for this machine.
*
* \param adhesion_offset whether to offset the border by the adhesion width to account for brims, skirts and
* rafts, if present.
* \return a Polygon representing the usable area of the print bed.
* \param extruder_nr The extruder for which to return the allowed areas. -1 if the areas allowed for all extruders should be returned.
* \return the Polygons representing the usable area of the print bed.
*/
Polygon getMachineBorder(bool adhesion_offset = false) const;
Polygons getMachineBorder(int extruder_nr = -1) const;

private:
/*!
Expand Down
22 changes: 22 additions & 0 deletions include/utils/polygon.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ class PolygonRef : public ConstPolygonRef
{
}

/*!
* Reserve a number of polygons to prevent reallocation and breakage of pointers.
* \param min_size The minimum size the new underlying array should have.
*/
void reserve(size_t min_size)
{
path->reserve(min_size);
Expand Down Expand Up @@ -754,6 +758,11 @@ class Polygons
return paths.size();
}

void reserve(size_t new_cap)
{
paths.reserve(new_cap);
}

/*!
* Convenience function to check if the polygon has no points.
*
Expand Down Expand Up @@ -970,6 +979,11 @@ class Polygons
*/
Polygons intersectionPolyLines(const Polygons& polylines, bool restitch = true, const coord_t max_stitch_distance = 10_mu) const;

/*!
* Add the front to each polygon so that the polygon is represented as a polyline
*/
void toPolylines();

/*!
* Split this poly line object into several line segment objects
* and store them in the \p result
Expand Down Expand Up @@ -1179,6 +1193,13 @@ class Polygons
*/
std::vector<PolygonsPart> splitIntoParts(bool unionAll = false) const;

/*!
* Sort the polygons into bins where each bin has polygons which are contained within one of the polygons in the previous bin.
*
* \warning When polygons are crossing each other the result is undefined.
*/
std::vector<Polygons> sortByNesting() const;

/*!
* Utility method for creating the tube (or 'donut') of a shape.
* \param inner_offset Offset relative to the original shape-outline towards the inside of the shape. Sort-of like a negative normal offset, except it's the offset part that's kept, not the shape.
Expand All @@ -1196,6 +1217,7 @@ class Polygons
*/
void removeEmptyHoles_processPolyTreeNode(const ClipperLib::PolyNode& node, const bool remove_holes, Polygons& ret) const;
void splitIntoParts_processPolyTreeNode(ClipperLib::PolyNode* node, std::vector<PolygonsPart>& ret) const;
void sortByNesting_processPolyTreeNode(ClipperLib::PolyNode* node, const size_t nesting_idx, std::vector<Polygons>& ret) const;

public:
/*!
Expand Down
Loading