Skip to content

Allow specifying rotation patterns for Sparse and Solid infill#9924

Merged
SoftFever merged 16 commits into
mainfrom
feature/flex-infill-direction
Jun 22, 2025
Merged

Allow specifying rotation patterns for Sparse and Solid infill#9924
SoftFever merged 16 commits into
mainfrom
feature/flex-infill-direction

Conversation

@SoftFever

@SoftFever SoftFever commented Jun 17, 2025

Copy link
Copy Markdown
Collaborator

Description

This PR allow user to specify rotation pattern for sparse and solid infill.
NOTE: the old "Rotate solid infill direction" option will be automatically upgraded to the new option.

Screenshots/Recordings/Graphs

Sparse infill:

sparse.mp4

Solid infill:

solid.mp4

closes #3970

Tests

@discip

discip commented Jun 17, 2025

Copy link
Copy Markdown
Contributor

@SoftFever
What about combining this PR with #9890? 😊

@pi-squared-studio

Copy link
Copy Markdown
Contributor

Good mod! It so happened that independently of each other, the author of Orca Slicer and I asked the same question.
But upon closer examination, it turned out that the functionality does not overlap, but even complements each other. In my implementation, rotation cannot be programmed, and in some cases, I suspect, it is necessary. In the author's implementation, this can be done much easier, for example, to organize the rotation of only two layers after 5.

I suggest extending this feature by adding a simple metalanguage of this patterns system:

  • if there is at least one "+" character in the line, then the entire line will be interpolated as a relative rotation value, not an absolute one. That is, the cyclic rotation scheme will be simpler. This entry [+10; +15; +20] it will mean a turn to 10, 25, 45, 55, 70, 90, 100... degrees etc.
  • if the number is followed by a value in parentheses, then this is the number of cycles of this value for the next layer. For example, this entry [15(2); 0(3)] will mean that you need to print 2 layers at an angle of 15, and 3 layers at an angle of 0.

@SoftFever

Copy link
Copy Markdown
Collaborator Author

Good mod! It so happened that independently of each other, the author of Orca Slicer and I asked the same question. But upon closer examination, it turned out that the functionality does not overlap, but even complements each other. In my implementation, rotation cannot be programmed, and in some cases, I suspect, it is necessary. In the author's implementation, this can be done much easier, for example, to organize the rotation of only two layers after 5.

I suggest extending this feature by adding a simple metalanguage of this patterns system:

  • if there is at least one "+" character in the line, then the entire line will be interpolated as a relative rotation value, not an absolute one. That is, the cyclic rotation scheme will be simpler. This entry [+10; +15; +20] it will mean a turn to 10, 25, 45, 55, 70, 90, 100... degrees etc.
  • if the number is followed by a value in parentheses, then this is the number of cycles of this value for the next layer. For example, this entry [15(2); 0(3)] will mean that you need to print 2 layers at an angle of 15, and 3 layers at an angle of 0.

Hi @pi-squared-studio
Thanks for your comment. I was thinking along the same lines and agree with your proposed direction!

I agree that the best approach would be to combine the logic in your PR with the options introduced in this PR. While reviewing your PR, I was hesitant to add numerous extra options for niche requirements. A more elegant solution would be to expand the option in this PR to support metalanguage, allowing power users to define flexible rotation patterns.

I'd like to make some changes to your proposed parsing rule to ensure consistency:

Use , as delimiters here instead of ;, which is used for line separator in Orca.

  • Case 1: Fixed Angle Pattern (already in this PR)
    Example: [90] or [0,30,90]
  • Case 2: Incremental Angle Pattern
    Example: [+10] or [+10, +15, +20]
  • Case 3: Advanced Angle Pattern (using / for simplicity). By default, it's per-layer. [90] is same as [90/1]
    Example: [15/2, 0/3]
  • Case 4: Complex Incremental Pattern (for completeness)
    Example: [+1/2, +2/2]. Similar to the previous one but support incremental angle with layers. This may be over-engineering, list it here just for the sake of documenting.
    NOTE: to avoid potential users errors, fixing angles can't be mixed with incremental angles, [+10, 10] or [+10/3, 5/3] are invalid.
    NOTE 2: if not specified,
    Let me know what you think.

@pi-squared-studio

Copy link
Copy Markdown
Contributor

Hi,
I have read your comments, to be honest, I do not insist on my version and will support the author's version of the final code implementation. The main thing is to make it convenient for the end user to use.
I used approximately the same metalanguage scheme in another personal closed project, and it proved very well. Namely, I interpreted the ip ranges with a free spelling input. It allowed the input of "," instead of ".", for example, the string "192,1,0.*" or "192,1,0.0-255" translated into the required "192.168.0.0/24"... Regarding the comma or period as separator: I'm just from a country where the decimal separator is "," and it's much more convenient to use a different sign than this one. When you type in the wrong keyboard layout, it just becomes difficult to enter such values. (By the way, such layout errors are immediately corrected by the ConfigOptionFloat element.) But I repeat, it won't be a problem for me personally to enter it with difficulties, if other users don't have any difficulties at the same time. I think it's possible to include a small code so that it can correct the input string right way.
Otherwise, I agree: let the numbers without the sign be absolute, with the sign "+" or "-" - relative. I don't mind even rolling up my code to such a metalanguage, as long as it can describe this functionality. Since the "/" symbol looks more like a division of objects, can it be used to indicate simultaneously rotated layers? Will it be a segmentation symbol, so to speak? And for the loop, take another symbol...
I suspect that there will be no problems with constantly rotating the fill, just enter the command "+1.56" and it will rotate each layer by 1.56CCW. "+1.56/2" - 2 adjacent layers will rotate to this angle.... etc
But there is a rotation height parameter in my code. It is quite possible to write as "+1.56@1". Then the fill will rotate at a distance of 1 cm in height at the specified angle.
I also use percentage values. For an angles is a sector of 360-degree full turn. For heights, this is the whole height of the model. This makes it very easy to set both the rotation to the desired angle for the entire height of the model, and to set the required number of turns for a unit of length. For an example "+25%/3@100%" this will mean rotating 90 degrees CCW to the height of the model every 3 layers. Or "+90@10%, -90/5@3" it will mean rotating the first 10% оf the height of model by 90CCW, the next 3 cm by 90CW in a package of 5 layers.
All that remains is to figure out how to describe the harmonic oscillations of the fill implemented in my code. Maybe just write this setting in square brackets?

One more point, in order not to generate a lot of unnecessary input fields, I suggest using the "Solid infill direction" and "Sparse infill direction" fields for patterns, because if we just write "15" in it, it will mean the angle of the infill direction.

Wow! It's hard to imagine right now, but what a powerful tool it can be in the end.

I also want to say that I am not a professional programmer. Programming is my rare hobby. Therefore, I do not know all the subtleties of writing code. Therefore, I will take the second place in the implementation of ideas. But I'd appreciate it if I could be of any help.

@pi-squared-studio

pi-squared-studio commented Jun 20, 2025

Copy link
Copy Markdown
Contributor

OK, I saw the code. Tell me, please, how can I work on it so that you can see the changes? It's just that, as I said, I'm not a professional programmer, and I still don't know much about the traditions of changing code on GitHub and this community.
It would also be nice if we approved the basics of this metalanguage in order to try its use cases. I think we need to start with the most primitive operators so that they are simple and understandable for a wide range of users.
I think we can start by implementing simple things - absolute (without signs) and relative values (using signs +/-)

@SoftFever

Copy link
Copy Markdown
Collaborator Author

OK, I saw the code. Tell me, please, how can I work on it so that you can see the changes? It's just that, as I said, I'm not a professional programmer, and I still don't know much about the traditions of changing code on GitHub and this community. It would also be nice if we approved the basics of this metalanguage in order to try its use cases. I think we need to start with the most primitive operators so that they are simple and understandable for a wide range of users. I think we can start by implementing simple things - absolute (without signs) and relative values (using signs +/-)

Awesome! I'm going to merge this PR soon. Once merged, you can fork from the latest main branch and from there you can make the necessary changes.

regarding the /, while it's used for division, it's also commonly denoted for "per", e.g. mm/s
So +10/1 stands for rotate 10 degree per layer.

@pi-squared-studio

pi-squared-studio commented Jun 21, 2025

Copy link
Copy Markdown
Contributor

So +10/1 stands for rotate 10 degree per layer.

Yes, I agree. But if you follow the logic of the pattern system, then all operations will be looped anyway. Therefore, the expressions +10/1 or just +10 are equivalent in a simple pattern. What then makes sense to consider for +10/5, a rotation of 5 times by 2 degrees or 50 degrees in 5 stages? Then can enter a * sign for the number of repetitions? Writing +10*5 will just say that this instruction should be repeated 5 times...

I'm going to merge this PR soon.

In my code, the calculations of any fill were slightly rethought, and archaic methods were ignored. All manipulations are calculated in one block. Therefore, if you have any questions, ask them.
In theory, you can completely combine 2 projects, and then throw out what you don't need after entering the pattern's system. There are also other functions like rotating the top and bottom infills, and applying the model's orientation to a infill direction. They must also be implemented.

@pi-squared-studio

pi-squared-studio commented Jun 21, 2025

Copy link
Copy Markdown
Contributor

One more remark. If the pattern is going to be looped, then will need to separate the understanding of setting the initial angle from setting it every loop. I suggest this entry +10/0 - it will show that these instructions will be applied only once.
Examples of instructions:
50 - prints the entire infill at an angle of 50
+45 - prints every time with a 45 degree rotation 0, 45, 90...
90, 0 = prints an orthogonal grid starting from an angle of 90
50, 90 = prints the grid at angles 50 and 90

more complex patterns for trained users:
50, +40 = the same action as last above
+50, +40 = 50, 90, 140, 180, 230...
50/0, +40 = prints at angles 50, 90, 130, 170, 210...
50/2, +40 = 25, 50, 90, 25, 50, 90...
50/0, +50/2, +40 = 50, 75, 100, 140, 165, 190, 230, 255...
50* 2, +40 = 50, 100, 140, 50, 100, 140...
50/0, +50*2, +40 = 50, 100, 150, 190, 240, 290...

This scheme is very simple for both ordinary users, of whom there will be 99%, and for advanced users, for special applications.

@SoftFever

Copy link
Copy Markdown
Collaborator Author

Yes, I agree. But if you follow the logic of the pattern system, then all operations will be looped anyway. Therefore, the expressions +10/1 or just +10 are equivalent in a simple pattern. What then makes sense to consider for +10/5, a rotation of 5 times by 2 degrees or 50 degrees in 5 stages? Then can enter a * sign for the number of repetitions? Writing +10*5 will just say that this instruction should be repeated 5 times...

The later one.
In this pattern, +10/5 would mean rotate 10 degree for every stage(every 5 layers), layers in each stage(5 layers here) have the same rotation angle.

One more remark. If the pattern is going to be looped, then will need to separate the understanding of setting the initial angle from setting it every loop. I suggest this entry +10/0 - it will show that these instructions will be applied only once. Examples of instructions: 50 - prints the entire infill at an angle of 50 +45 - prints every time with a 45 degree rotation 0, 45, 90... 90, 0 = prints an orthogonal grid starting from an angle of 90 50, 90 = prints the grid at angles 50 and 90

more complex patterns for trained users: 50, +40 = the same action as last above +50, +40 = 50, 90, 140, 180, 230... 50/0, +40 = prints at angles 50, 90, 130, 170, 210... 50/2, +40 = 25, 50, 90, 25, 50, 90... 50/0, +50/2, +40 = 50, 75, 100, 140, 165, 190, 230, 255... 50* 2, +40 = 50, 100, 140, 50, 100, 140... 50/0, +50*2, +40 = 50, 100, 150, 190, 240, 290...

This scheme is very simple for both ordinary users, of whom there will be 99%, and for advanced users, for special applications.

I thought about that too, but the initial angle is controlled by another parameter at the moment:
Screenshot 2025-06-22 at 11 00 05 PM

And I don't have a good idea how to keep backward compatibility while combine these parameter with the new ones. So I'm going to keep it as is for now.

There's another issue I noticed in your PR - you allow rotate infill direct along the layers for all infill patterns, which is not what Orca expected. If you look at this PR, we only allow certain infill patterns to rotate. That is because some infill types control their rotation by themself already. This is also something you need to consider.
While rotating them along the layers may look cool, I'm afraid that will cause issues and create confusion.
Most importantly, I don't know what's the use cases for this yet. Feel free to share if you have real world user cases. So for now, I'm thinking to maintain the behavior. This means only certain types of infill patterns can support rotation patterns.

@SoftFever SoftFever merged commit 88fb818 into main Jun 22, 2025
@ianalexis ianalexis mentioned this pull request Jun 22, 2025
41 tasks
@pi-squared-studio

Copy link
Copy Markdown
Contributor

In this pattern, +10/5 would mean rotate 10 degree for every stage(every 5 layers), layers in each stage(5 layers here) have the same rotation angle.

In this case, can use the # symbol, which will indicate the layers being rotated at the same time. Together with the @ symbol (as I assumed in the long run it will set the height at which the template instruction will act), will they create a certain group of rangeficators(?) instructions. And the * and / instructions will determine the quantificators, or the number of cycles of the multiplication and division instructions. Of course, this needs to be implemented at the last moment, if necessary.
Everything in this scheme turns out to be very clear, and it's quite easy to type on a standard keyboard.

That is because some infill types control their rotation by themself already. This is also something you need to consider.

Yes, I saw it. And I also came across this. I suspect that this is an archaic overall function designed to rotate any infill by 90 degrees, regardless of its pattern. At first, it was supposed to use 2 infills, the Line and the Rectilinear one, but when more appeared that didn't require rotation, this function was simply override it so that it did not work. It seems to me that it is necessary to inspect the work of the infill functions and make them determine their own rotation if they depend on such logic. In this case, the rotate_angle parameter will be superfluous, and canceling it will make the code run faster.

I don't know what's the use cases for this yet. Feel free to share if you have real world user cases.

Okay, but now there are no examples to quickly show. Previously, I achieved a beautiful effect in the powerbank case model. I used transparent PETG when I was making only 2 walls and a Gyroid 20% infill. In sunlight, it gave a very beautiful effect, when the interior infill sparkled with sparks like a car's retroreflector. If I can rotate the inner infill, then I think I can come up with even more application effects.

ianalexis added a commit to ianalexis/OrcaSlicer that referenced this pull request Jun 22, 2025
@SoftFever

Copy link
Copy Markdown
Collaborator Author

In this case, can use the # symbol, which will indicate the layers being rotated at the same time. Together with the @ symbol (as I assumed in the long run it will set the height at which the template instruction will act), will they create a certain group of rangeficators(?) instructions. And the * and / instructions will determine the quantificators, or the number of cycles of the multiplication and division instructions. Of course, this needs to be implemented at the last moment, if necessary. Everything in this scheme turns out to be very clear, and it's quite easy to type on a standard keyboard.

I'm afraid that would make things a bit too complicated and, in my opinion, it doesn't add any new functionality. Consider this: if the user wants to rotate per layer, they can specify the +2/1 pattern instead of +10/5. The # is not necessary.

This option can work alongside the height range modifier. Introducing another height range option here would make the code logic overly complex and confusing, which could lead to errors and make future maintenance more difficult.

Yes, I saw it. And I also came across this. I suspect that this is an archaic overall function designed to rotate any infill by 90 degrees, regardless of its pattern. At first, it was supposed to use 2 infills, the Line and the Rectilinear one, but when more appeared that didn't require rotation, this function was simply override it so that it did not work. It seems to me that it is necessary to inspect the work of the infill functions and make them determine their own rotation if they depend on such logic. In this case, the rotate_angle parameter will be superfluous, and canceling it will make the code run faster.

I don't know what's the use cases for this yet. Feel free to share if you have real world user cases.

Okay, but now there are no examples to quickly show. Previously, I achieved a beautiful effect in the powerbank case model. I used transparent PETG when I was making only 2 walls and a Gyroid 20% infill. In sunlight, it gave a very beautiful effect, when the interior infill sparkled with sparks like a car's retroreflector. If I can rotate the inner infill, then I think I can come up with even more application effects.

This is designed specifically that way. Considering a honeycomb infill, by design it should be laid consistently without height-based rotation. If we accidentally allow users to rotate along with the height, they might cause issues because a lot of overhang infills would be created. If users are not aware of this, it will fail their prints. So this acts as a safety measure to prevent unintended errors for common users.

One thing I'm not against is if we can add a switch in the preference settings that allows users to unlock this hidden feature, then they can enable rotation along with the layers for all infill patterns if they want to print some visually cool infills?

ianalexis added a commit to ianalexis/OrcaSlicer that referenced this pull request Jun 23, 2025
ianalexis added a commit to ianalexis/OrcaSlicer that referenced this pull request Jun 23, 2025
ianalexis added a commit to ianalexis/OrcaSlicer that referenced this pull request Jun 24, 2025
ianalexis added a commit to ianalexis/OrcaSlicer that referenced this pull request Jun 24, 2025
ianalexis added a commit to ianalexis/OrcaSlicer that referenced this pull request Jun 25, 2025
Noisyfox pushed a commit that referenced this pull request Jun 27, 2025
* Add process images

* Reorder like GUI + images

* GUI images subfolder

* MVF restandarizarion (naming pending)

Update volumetric speed calibration docs and image paths

* Improved SVGs

* Infill Wall Overlap

* Apply gap fill + Anchor

* Minor change

* Internal Solid Infill

* Images++

* Step file import image update

* Add VFA calibration documentation and images

* fix pa-tower image not visible

* Removed WIP in not implemented features.

* Added Old and New Order in xlsx

* Wall generator

* Wiki #9924

* New Zag Infills

Co-Authored-By: Rodrigo <[email protected]>

* Infill Rescaled images + sharpness

2d honeycomb image fix

* Update infill_desc_calculator.xlsx

* Rename extrusion rate smoothing references for consistency

* Add wiki and link for top/bottom shells settings

* Updated Wiki Links tab.cpp

* Update infill_desc_calculator.xlsx

* Fix indentation in top/bottom shells option group

* Fill images optimized

Removed Metadata
Reduce color bit to 16

---------

Co-authored-by: Rodrigo <[email protected]>
@pi-squared-studio

Copy link
Copy Markdown
Contributor

@SoftFever

Please, check this
#9996

In the latest edition of this metalanguage, I have collected all the experience I gained working on this implementation. The great thing is that it turns out that you can embed this metalanguage without changing the usual settings!
Not all my ideas have been realized yet, but I don't have much free time right now. I will try to optimize the code in the near future, but there are issues with changing the main code. When you work with this code, the main one changes, and the branch becomes incompatible. All that remains is to open a new branch and embed the same code into it... Okay, I'll ask about a solution to this problem when the final version of the code is available... or, please, tell me what is the best way to make these developments presentable.

By the way, you asked me how this feature can be applied. For example, I will give this screenshot from one video of using a curly open infill. This is a presentation stand printed on a large-size printer.
image

@SoftFever SoftFever deleted the feature/flex-infill-direction branch July 13, 2025 05:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi Infill Direction

4 participants