-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Brick Layers / Staggered Perimeter implementation #8181
base: main
Are you sure you want to change the base?
Changes from all commits
5a239de
044a260
3bd38ea
5da2804
2885aca
228e958
3e19234
4ef5fc0
a1f623d
ea18878
8849e1d
07623dc
e4b992b
0f49af9
568cf97
5d78b1c
1b08552
f45565d
9726cff
ef91303
533d80b
89fa2d6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Staggered layers is currently in *Alpha*. | ||
|
||
 | ||
|
||
--- | ||
|
||
## If you find an issue or encounter a bug that is not on this list, please let us know by either: | ||
#### - Opening an issue on this GitHub repo | ||
#### - Sending an Email to `[email protected]` | ||
#### - Sending a Direct Message on Discord to `Divide#4615` or `Xero#1678` | ||
|
||
----- | ||
|
||
# Known Issues: | ||
- Staggared layers does not take in to account the slope of a wall, leading to `Inner-wall`s getting staggared even when visible from above ( [img1](https://cdn.discordapp.com/attachments/1314975632236609651/1332410916154773504/image.png?ex=679527dd&is=6793d65d&hm=683e08e6b6629974bc8bc11e14b9d0acd0e23335eafebeb43ede828c2acea57e&) | [img2](https://cdn.discordapp.com/attachments/1314975632236609651/1332410869975486484/image.png?ex=679527d2&is=6793d652&hm=8196be2e6b31e7202fb11f628ae4aa1d9deed9f4daa41bb414cecefff1a6448f&) ) | ||
- When `only_one_wall_first_layer` is **enabled**, the flowrate adjustment to correct for the lifted `Inner-wall`s is not correctly applied ( [img1](https://cdn.discordapp.com/attachments/1314975632236609651/1332410869975486484/image.png?ex=679527d2&is=6793d652&hm=8196be2e6b31e7202fb11f628ae4aa1d9deed9f4daa41bb414cecefff1a6448f&) | [img2](https://cdn.discordapp.com/attachments/1314975632236609651/1332422246735548478/image.png?ex=6795326a&is=6793e0ea&hm=02358016b0ae7c4d39cca76d1d926fe2cb2e3ee659517d519542c3c06a07471f&) ) | ||
- Having multiple models of different heights causes the check for the top layer to only work on the talest model (even if only 1 of the models has the setting enabled | ||
- Orca slicer layer preview sees 1 layer as multiple different layers (usually 3, (lower walls, raised walls, infill). Sometimes 2, (lower walls and infill, raised walls)) (this is worsened if an object has 2 seperate sections of `outer-walls` as they get treated as seperate 'towers') | ||
- Perimiters on internal holes are not staggered, only the outer most walls ( [img1](https://cdn.discordapp.com/attachments/1314975632236609651/1333403537425829898/image.png?ex=6798c450&is=679772d0&hm=dc87d94afa168c7ce6bdf75775669932daab1a034929302b3ff5c55c989beb83&) | [img2](https://cdn.discordapp.com/attachments/1314975632236609651/1333403854011629588/image.png?ex=6798c49c&is=6797731c&hm=2aa02f8e42fe59a4e954000a8d0f1912177b92234b947952dbda476a6ce67ca7&) ) | ||
|
||
# Incompatible settings: | ||
- `Adaptive Layer Height` is not currently supported | ||
- `Initial_layer_print_height` & `Layer_height` must currently be the same |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -160,10 +160,14 @@ class ExtrusionPath : public ExtrusionEntity | |
// Height of the extrusion, used for visualization purposes. | ||
float height; | ||
|
||
ExtrusionPath() : mm3_per_mm(-1), width(-1), height(-1), m_role(erNone), m_no_extrusion(false) {} | ||
ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), m_role(role), m_no_extrusion(false) {} | ||
ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height, bool no_extrusion = false) : mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role), m_no_extrusion(no_extrusion) {} | ||
ExtrusionPath(double overhang_degree, int curve_degree, ExtrusionRole role, double mm3_per_mm, float width, float height) : overhang_degree(overhang_degree), curve_degree(curve_degree), mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role) {} | ||
//These properties are just for staggered perimeter production. | ||
float z_offset; //z_offset to be multiplied to the layer height, default is 0 | ||
float extrusion_multiplier; //increase in extrusion, default is 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This new member variable is not necessary. |
||
|
||
ExtrusionPath() : mm3_per_mm(-1), width(-1), height(-1), m_role(erNone), m_no_extrusion(false), z_offset(0.0), extrusion_multiplier(1.0){} | ||
ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), m_role(role), m_no_extrusion(false), z_offset(0.0), extrusion_multiplier(1.0) {} | ||
ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height, bool no_extrusion = false) : mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role), m_no_extrusion(no_extrusion) , z_offset(0.0), extrusion_multiplier(1.0) {} | ||
ExtrusionPath(double overhang_degree, int curve_degree, ExtrusionRole role, double mm3_per_mm, float width, float height) : overhang_degree(overhang_degree), curve_degree(curve_degree), mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role) , z_offset(0.0), extrusion_multiplier(1.0){} | ||
|
||
ExtrusionPath(const ExtrusionPath &rhs) | ||
: polyline(rhs.polyline) | ||
|
@@ -175,6 +179,8 @@ class ExtrusionPath : public ExtrusionEntity | |
, m_can_reverse(rhs.m_can_reverse) | ||
, m_role(rhs.m_role) | ||
, m_no_extrusion(rhs.m_no_extrusion) | ||
, z_offset(rhs.z_offset) | ||
, extrusion_multiplier(rhs.extrusion_multiplier) | ||
{} | ||
ExtrusionPath(ExtrusionPath &&rhs) | ||
: polyline(std::move(rhs.polyline)) | ||
|
@@ -186,6 +192,8 @@ class ExtrusionPath : public ExtrusionEntity | |
, m_can_reverse(rhs.m_can_reverse) | ||
, m_role(rhs.m_role) | ||
, m_no_extrusion(rhs.m_no_extrusion) | ||
, z_offset(rhs.z_offset) | ||
, extrusion_multiplier(rhs.extrusion_multiplier) | ||
{} | ||
ExtrusionPath(const Polyline &polyline, const ExtrusionPath &rhs) | ||
: polyline(polyline) | ||
|
@@ -197,6 +205,8 @@ class ExtrusionPath : public ExtrusionEntity | |
, m_can_reverse(rhs.m_can_reverse) | ||
, m_role(rhs.m_role) | ||
, m_no_extrusion(rhs.m_no_extrusion) | ||
, z_offset(rhs.z_offset) | ||
, extrusion_multiplier(rhs.extrusion_multiplier) | ||
{} | ||
ExtrusionPath(Polyline &&polyline, const ExtrusionPath &rhs) | ||
: polyline(std::move(polyline)) | ||
|
@@ -208,6 +218,8 @@ class ExtrusionPath : public ExtrusionEntity | |
, m_can_reverse(rhs.m_can_reverse) | ||
, m_role(rhs.m_role) | ||
, m_no_extrusion(rhs.m_no_extrusion) | ||
, z_offset(rhs.z_offset) | ||
, extrusion_multiplier(rhs.extrusion_multiplier) | ||
{} | ||
|
||
ExtrusionPath& operator=(const ExtrusionPath& rhs) { | ||
|
@@ -220,6 +232,8 @@ class ExtrusionPath : public ExtrusionEntity | |
this->overhang_degree = rhs.overhang_degree; | ||
this->curve_degree = rhs.curve_degree; | ||
this->polyline = rhs.polyline; | ||
this->z_offset = rhs.z_offset; | ||
this->extrusion_multiplier = rhs.extrusion_multiplier; | ||
return *this; | ||
} | ||
ExtrusionPath& operator=(ExtrusionPath&& rhs) { | ||
|
@@ -232,6 +246,8 @@ class ExtrusionPath : public ExtrusionEntity | |
this->overhang_degree = rhs.overhang_degree; | ||
this->curve_degree = rhs.curve_degree; | ||
this->polyline = std::move(rhs.polyline); | ||
this->z_offset = rhs.z_offset; | ||
this->extrusion_multiplier = rhs.extrusion_multiplier; | ||
return *this; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1291,6 +1291,29 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p | |
extrusion_paths_append(paths, *extrusion, role, is_external ? perimeter_generator.ext_perimeter_flow : perimeter_generator.perimeter_flow); | ||
} | ||
|
||
auto check_and_stagger_path = [perimeter_generator](ExtrusionPath& cur_path) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Based on the codes below, would it be better call it "update_stagger_path" for clarity? |
||
bool was_staggered = false; | ||
if (perimeter_generator.layer_id == 1 && perimeter_generator.number_of_layers >= 4) // i.e. layer after the first one | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems to make more sense to just check the number_of_layers at the beginning.
|
||
{ | ||
cur_path.extrusion_multiplier = 1.5; | ||
was_staggered = true; | ||
} else if (perimeter_generator.layer_id == perimeter_generator.number_of_layers - 2 && | ||
perimeter_generator.number_of_layers >= 4) // i.e. last layer before the last one | ||
{ | ||
cur_path.extrusion_multiplier = 0.5; | ||
was_staggered = true; | ||
} | ||
|
||
if (perimeter_generator.layer_id != perimeter_generator.number_of_layers - 2 && | ||
perimeter_generator.number_of_layers >= 4) // i.e. last layer | ||
{ | ||
cur_path.z_offset = 0.5; | ||
was_staggered = true; | ||
} | ||
|
||
return was_staggered; | ||
}; | ||
|
||
// Append paths to collection. | ||
if (!paths.empty()) { | ||
if (extrusion->is_closed) { | ||
|
@@ -1304,6 +1327,14 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p | |
} | ||
assert(extrusion_loop.paths.front().first_point() == extrusion_loop.paths.back().last_point()); | ||
|
||
//This is for staggered layers. | ||
//All odd perimeters are staggerd up by half the layer height | ||
if (extrusion->inset_idx % 2 == 1 && perimeter_generator.config->staggered_perimeters) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be better to do |
||
for (size_t path_idx = 0; path_idx < extrusion_loop.paths.size(); path_idx++) { | ||
ExtrusionPath& cur_path = extrusion_loop.paths[path_idx]; | ||
check_and_stagger_path(cur_path); | ||
} | ||
} | ||
extrusion_coll.append(std::move(extrusion_loop)); | ||
} | ||
else { | ||
|
@@ -1325,6 +1356,15 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p | |
multi_path.paths.emplace_back(std::move(*it_path)); | ||
} | ||
|
||
//This is for staggered layers. | ||
//All odd perimeters are staggerd up by half the layer height | ||
if (extrusion->inset_idx % 2 == 1 && perimeter_generator.config->staggered_perimeters) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
for (size_t path_idx = 0; path_idx < multi_path.paths.size(); path_idx++) { | ||
ExtrusionPath& cur_path = multi_path.paths[path_idx]; | ||
check_and_stagger_path(cur_path); | ||
} | ||
} | ||
|
||
extrusion_coll.append(ExtrusionMultiPath(std::move(multi_path))); | ||
} | ||
} | ||
|
@@ -3162,8 +3202,15 @@ void PerimeterGenerator::process_arachne() | |
} | ||
} | ||
|
||
if (this->config->staggered_perimeters) { // If staggered layers are on, all odd perimeters will be staggered and should be printed after the non staggered perimeters | ||
std::sort(ordered_extrusions.begin(), ordered_extrusions.end(), | ||
[](PerimeterGeneratorArachneExtrusion extrusion_1, PerimeterGeneratorArachneExtrusion extrusion_2) -> bool { | ||
return extrusion_1.extrusion->inset_idx % 2 <= extrusion_2.extrusion->inset_idx % 2; | ||
}); | ||
} | ||
|
||
// printf("New Layer: Layer ID %d\n",layer_id); //debug - new layer | ||
if (this->config->wall_sequence == WallSequence::InnerOuterInner && layer_id > 0) { // only enable inner outer inner algorithm after first layer | ||
if (this->config->wall_sequence == WallSequence::InnerOuterInner && layer_id > 0 && !this->config->staggered_perimeters ) { // only enable inner outer inner algorithm after first layer | ||
if (ordered_extrusions.size() > 2) { // 3 walls minimum needed to do inner outer inner ordering | ||
int position = 0; // index to run the re-ordering for multiple external perimeters in a single island. | ||
int arr_i, arr_j = 0; // indexes to run through the walls in the for loops | ||
|
@@ -3239,7 +3286,7 @@ void PerimeterGenerator::process_arachne() | |
// printf("Layer ID %d, Outer index %d, inner index %d, second inner index %d, maximum internal perimeter %d \n",layer_id,outer,first_internal,second_internal, max_internal); | ||
if (outer > -1 && first_internal > -1 && second_internal > -1) { // found all three perimeters to re-order? If not the perimeters will be processed outside in. | ||
std::vector<PerimeterGeneratorArachneExtrusion> inner_outer_extrusions; // temporary array to hold extrusions for reordering | ||
inner_outer_extrusions.resize(max_internal - position + 1); // reserve array containing the number of perimeters before a new island. Variables are array indexes hence need to add +1 to convert to position allocations | ||
inner_outer_extrusions.reserve(max_internal - position + 1); // reserve array containing the number of perimeters before a new island. Variables are array indexes hence need to add +1 to convert to position allocations | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any reason why this was changed to reserve()? |
||
// printf("Allocated array size %d, max_internal index %d, start position index %d \n",max_internal-position+1,max_internal,position); | ||
|
||
for (arr_j = max_internal; arr_j >=position; --arr_j){ // go inside out towards the external perimeter (perimeters in reverse order) and store all internal perimeters until the first one identified with inset index 2 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mind to rename it to something like
staggered_perimeter_z_offset
to avoid poteintial confusion?