-
-
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?
Brick Layers / Staggered Perimeter implementation #8181
Conversation
Fantastic and what a legend! Excellent to see this being implemented natively, thank you! |
This is an exciting stuff. |
Added extra note to issue of layer preview
…ulrajan/OrcaSlicer into staggered-perimeters-rebased
@philyeahz |
@vipulrajan I created an pull request on your fork for adding the wall sequencing independent of the staggered perimeters and also implemented the staggering for classic wall generator. Next I would like to look at angled walls... Maybe this is an overkill optimization, but I think this could improve extrusion quality. |
That would be necessary in order to avoid over extrusion on the top slanted surfaces. I think you could look at how the one wall top surface detects polygon edges based on the layer underneath and insert a half height (ie half flow) line to support the slant, basically the same as the first layer. Just an idea, haven’t opened the code up in any detail but it may give a pointer :) |
@philyeahz |
sorry for my ignorance but when will this be implemented in orca slicer? |
@Anthony-Bec |
@vipulrajan Thanks for the fast reply! I am new to github. |
One thing I'd recommend adding would be a way to adjust offset layer flow extrusion. The script by TengerTechnologies allows users to adjust the extrusion multiplier of the offset layers to help fill gaps. It will be hard to fix under/over extrusion with staggered perimeters with the traditional flow ratio. |
walls for internal holes are not staggered
Got a comment from @koenvanduffel2084 on my video with some testresults. The extrusion multiplier seams to increase strenght a bit if not overdone.
|
In case you haven’t seen it already Igor dropped an excellent video testing this technique with some very interesting observations from his strength tests |
This proves that an offset flow multiplier will be necessary to get the gains in layer adhesion we're after. |
Only if the original flow is not optimised, which Igor never optimises, since he uses standard profiles. In fact that's a big downside of his tests, he relies on (basically) generic settings. If you do flow calibration and you pick the setting resulting in the smoothest surface, the flow multiplier needed will be close to zero, because you can clearly understand that the gaps between perimeters are not 10% large. |
Even if flow isn't optimized, the tests he did with brick layers at 1.0x flow show that the process inherently causes some under extrusion resulting in less layer adhesion. The addition of an offset flow multiplier is going to be needed if we want to achieve maximum layer adhesion. Until more testing is done I doubt that the issue of under extrusion will be fixable with the standard flow ratio setting. |
I'm only casually following this topic so I may have missed other data along the way... but this opinion seems to discount two major things:
Sure that 50% might be 'padded' due to what you're saying, but it seems to me that the difference is too great to put down to uncalibrated flow rate? |
Indeed any print with a flow increased by just 10% would look terrible, while his prints looked incredibly fine. The meaning of "multiplier" is then clearly different from what we think of it. Probably the script he used has some issues or redefines stuff in a way we don't expect. In other words: besides his strength testing, which is good to know, absolutely NO conclusion can be drawn about the requirements of flow multiplier. |
The multiplier in the script increases directly the amount of filament extruded by multiplying the gcode e value with a number (the multiplier). It does not change line spacing to account for the wider/fatter lines so there does appear to be some “filling in the gaps” property here.
the code is available here: https://github.com/TengerTechnologies/Bricklayers/blob/27cd61b19bbc92c093d45598c853b113f08a6dcd/bricklayers.py#L114 In my view it’s a legitimate thing to explore. Even if Igor used suboptimal flow I’d expect the strength gain to cap out where the extrusion multiplier hit the ideal spot, but it didn’t. Seems like higher extrusion multiplier can force more material in the gap increasing layer adhesion just by virtue of putting higher pressure on the filament to flow around the gap created by the layer below. Kind of like a “mini injection moulding” process where plastic is pressurised to fill a mould. With this technique we are not just laying filament on top of each other any more, rather we are forcing it down to fill a gap between two perimeters. Also something to explore is whether this extra flow only makes sense to apply when the sunken brick layer is between two neighbouring perimeters as this would contain the flow between them. Extra flow without perimeters left and right would merely cause the filament to flow outwards, or inwards towards the sparse infill. Ie with 4 perimeters, 0 is standard, 1 is brick-extra flow, 2 is standard, 3 is brick no extra flow. |
Also something to consider is whether it would be ideal to constrain the allowable number of perimeters to an even number so you never end up with a brick perimeter facing the infill. The hypothesis is that a offset in Z inner most perimeter doesn’t contribute to part strength as the staggering effect would overflow into the sparse infill instead of between a perimeter sandwich. Also consider that topologically, islands can have any number of perimeters up to the max allowable by the users. So when there are less than even perimeters in an island, whether brick sequencing needs to be constrained to the first set of even perimeters, with at least 3 needed to run this. Fortunately we already have algorithms in place to identify this - they are used to run the IOI wall ordering. We can identify how many neighbouring perimeters an island has by running the depth first, contour priority, proximity search used in the IOI wall ordering :) |
I believe the results you quote on (2) come from CNCKitchen's initial test. He tested Brick Layers by using a modifiable slicer. He had a lot of variance in his tests which I suspect were likely caused due to under extrusion. He is supposedly testing the TenTech script so we should get another data set when that drops. |
Limiting wall amount, beyond 1 wall, for the option is probably not a great idea. A better idea, that I propose, would be to have a warning UI element pop up upon activating the brick layer option. (This setting works best with wall amounts of 3 or higher. We recommend sticking to odd numbers to prevent an offset occuring towards the infill.) For Floating sections of perimeter, I am unsure as to whether having those be brick layers also would help improve overall part strength. Although I don't think it would hurt it. |
Sorry what I mean is that each island can have up to N perimeters. Not always guaranteed N. The generated number of perimeters is always variable. The slicer will attempt to generate N but it may not have space to, in which case it generates less. if during this less than 3 perimeters are generated, set a constraint for min 3 and always even number of perimeters to generate a brick layer. 2 perimeters with a brick layer would yield no benefit (or might even hurt performance) as the brick layer has nothing to anchor to if that makes sense? |
@mubeenkhan94 forked @TengerTechnologies pthyon post script and added a lot of useful stuff. New things in his fork include -
May be useful to reference what he has to benefit the in-slicer implementation @vipulrajan. |
@theboee, it looks like @mubeenkhan94's fork has been merged back into @TengerTechnologies's version (at least, it's not showing any changes in the GitHub UI). |
This is the repository I was referring to - https://github.com/mubeenkhan94/Bricklayers/tree/more_sophisticated_geometry_processing |
Used a CI build to try Staggered layers, and it worked beautifully! No issues or errors, and part strength feels stronger across layer lines for the PETG I printed with (totally subjective; I just snapped a piece by hand) 👌 Thank you all for this fantastic feature! |
Hi, I made my tests too, for a part that needed additional strength in layer lines direction. However, I observed a degradation in overhangs quality. The part is a small dome for a ball joint mechanism. I printed it with supports but the dome didn't print well. I did a simple test : print the same part with the same filament (PETG), same settings (3 walls) and at the same time :
Here is the result (left is bricklayers enabled, right is default parameters) : I didn't make more reseaches at the moment, but do you have some ideas ? |
What wall order were you using? Inner/outer? |
I've been testing just upping overall flow rate to fix underextrsuion caused by the new setting and while it is possible to do, it also causes the rest of the part to be out of spec. The part is most affected in the XY plane but does see some issues with Z the higher flow you go. In order to achieve tight tolerances while also getting the most adhesion, a separate flow multiplier that only applies to offset perimeters is a must. Plus I would say IOI wall order should be the default. I am using a K1 Max, and perfect flow rate for my machine is usually in the range of 1.015-1.03 depending on material, but at this setting the parts under extrude allowing you to view gaps between layers when separated. Around 1.06 is was where I saw great layer stacking but parts were swollen and ugly. Especially on top layers. |
@@ -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) { | |||
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 comment
The 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.
if(perimeter_generator.number_of_layers < 4)
return false;
@@ -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 comment
The 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?
@@ -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 comment
The reason will be displayed to describe this comment to others. Learn more.
Would be better to do perimeter_generator.config->staggered_perimeters
check first, the it won't waste computation on odd check when the option is off.
@@ -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 comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
Change to if (perimeter_generator.config->staggered_perimeters && extrusion->inset_idx % 2 == 1)
for better performance
@@ -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 comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason why this was changed to reserve()?
The original resize() call is correct, as per my understanding, since we use the expression inner_outer_extrusions[max_internal - arr_j] = xxx
below.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
This new member variable is not necessary.
We can directly adjust mm3_per_mm
in check_and_stagger_path function.
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 |
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?
I have suggestion regarding the name, shall we call it |
@SoftFever I will make those changes. I have few a other things to look at. In the coming week I will make all these changes. |
From what I can tell, the setting reverts back to normal for layers with large or steep overhangs. We should also have a correction layer to make those change areas flat. |
Brick layers have been a hot topic lately. I prefer calling it staggered perimeter. Printing alternate perimeters at an offset can create significantly stronger prints.

Screenshots/Recordings/Graphs
VID_20250125_123307.mp4
Tests
Currently testing with prints. Issues have been found. It's in alpha stage