{"id":809,"date":"2024-06-13T00:58:27","date_gmt":"2024-06-13T00:58:27","guid":{"rendered":"http:\/\/tgaw.com\/wp\/?p=809"},"modified":"2025-12-28T23:51:46","modified_gmt":"2025-12-28T23:51:46","slug":"coding-custom-infills-for-the-slic3r-based-slicers-prusaslicer-bambu-studio-etc","status":"publish","type":"post","link":"https:\/\/tgaw.com\/wp\/coding-custom-infills-for-the-slic3r-based-slicers-prusaslicer-bambu-studio-etc\/","title":{"rendered":"Coding Custom Infills for the Slic3r Based Slicers (PrusaSlicer, Bambu Studio, Orca, etc.)"},"content":{"rendered":"\r\n<p>Prusa Slicer and Bambu Studio are built over the Slic3r code base. In a meeting proceeding the 2023 East Coast RepRap Festival (ERRF), the board members made a joke about making our own ERRF infill pattern. It got me wondering, what would be involved with making a custom infill? I downloaded the <a href=\"https:\/\/github.com\/prusa3d\/PrusaSlicer\/tree\/master\">PrusaSlicer code from GitHub<\/a> and it turned out and it is pretty do-able with the Visual Studio 2022 I already use for other projects.<\/p>\r\n\r\n\r\n\r\n<p>Here&#8217;s how I approached it. I&#8217;ve only done this in PrusaSlicer, but I believe the steps should be similar in other Slic3r-based slicers like Bambu Studio and Orca. I&#8217;ve done three infills now &#8211; the original ERRF, one for 3DPrintopia, and my favorite some tessellated hearts!<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/HeartInfillPreview.png\" alt=\"\" \/>\r\n<figcaption>Heart Infill!<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>Note: Not everything in this giant post is going to apply to you, but the information is there for those who will find it handy. If you need a TL;DR, the most basic steps would be:<\/p>\r\n\r\n\r\n\r\n<ol class=\"wp-block-list\">\r\n<li><a href=\"#GettingSourceCode\">Get the source code<\/a> on your development machine.<\/li>\r\n<li>Plan out the &#8220;output points&#8221; for your pattern. This could be low-tech like <a href=\"#GraphPaper\">graph paper<\/a> or you could <a href=\"#Blender\">use a tool like Blender<\/a>.<\/li>\r\n<li><a href=\"#Code\">Update the code<\/a>. The impacted files would be:\r\n<ol>\r\n<li><strong>libslic3r\\Fill\\FillPlanePath.cpp <\/strong>&#8211; Add your logic to define all your output points.<\/li>\r\n<li><strong>libslic3r\\Fill\\FillPlanePath.hpp<\/strong> &#8211; Add declarations for your new infill functions in FillPlanePath.cpp.<\/li>\r\n<li><strong>libslic3r\\Fill\\Fill.cpp<\/strong> &#8211; Add in a new case into the surface_fill.params.pattern switch statement.<\/li>\r\n<li><strong>libslic3r\\Fill\\FillBase.cpp<\/strong> &#8211; Add a new case into the new_from_type switch statement.<\/li>\r\n<li><strong> libslic3r\\PrintConfig.cpp<\/strong> &#8211; Add new values into:\r\n<ol>\r\n<li>s_keys_map_InfillPattern.<\/li>\r\n<li>Fill pattern options in PrintConfigDef.<\/li>\r\n<\/ol>\r\n<\/li>\r\n<li><strong> libslic3r\\PrintConfig.hpp<\/strong> &#8211; Add a new value into the InfillPattern enum.<\/li>\r\n<li><strong>libslic3d\\PrintObject.cpp <\/strong>&#8211; Optional &#8211; you can add in a new case for determine_bridging_angle.<\/li>\r\n<\/ol>\r\n<\/li>\r\n<li><a href=\"#Test\">Test your infill.<\/a><\/li>\r\n<li><a href=\"#Print\">Print<\/a>!<\/li>\r\n<\/ol>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id=\"GettingSourceCode\">Getting and Building the Source Code<\/h2>\r\n\r\n\r\n\r\n<p>I think for me, the longest step was getting the source code ready and initially compiled on my machine.You can get the source code of the slicer you want from GitHub:<\/p>\r\n\r\n\r\n\r\n<p><a href=\"https:\/\/github.com\/prusa3d\/PrusaSlicer\/tree\/master\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"PrusaSlicer Souce Code (opens in a new tab)\">PrusaSlicer Souce Code<\/a><br \/><a href=\"https:\/\/github.com\/bambulab\/BambuStudio\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Bambu Studio Source Code (opens in a new tab)\">Bambu Studio Source Code<\/a><br \/><a href=\"https:\/\/github.com\/slic3r\/Slic3r\/tree\/master\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Slic3r Source Code (opens in a new tab)\">Slic3r Source Code<\/a><\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Building On Your Development Machine<\/h3>\r\n\r\n\r\n\r\n<p>The <a href=\"https:\/\/github.com\/prusa3d\/PrusaSlicer\/tree\/master\/doc\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"PrusaSlicer doc folder on GitHub (opens in a new tab)\">PrusaSlicer doc folder on GitHub<\/a> has &#8220;How to Build&#8221; instructions for Windows, Linux and MacOS. Like everything Prusa does, the documentation was thorough and helpful! I&#8217;m working on a Windows machine, so I used the &#8220;<a href=\"https:\/\/github.com\/prusa3d\/PrusaSlicer\/blob\/master\/doc\/How%20to%20build%20-%20Windows.md\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Building PrusaSlicer on Windows (opens in a new tab)\">Building PrusaSlicer on Windows<\/a>&#8221; instructions. I think the instructions did a great job of highlighting the prerequisites and walking me through the process.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Planning The Infill<\/h2>\r\n\r\n\r\n\r\n<p>The code is in C++ which I hadn&#8217;t worked with in <em>over two decades<\/em>. Luckily, one can be rusty in C++ and still copy and paste! I started by looking through the infill code in the libslicer\\Fill directory. The <strong>FillPlanePath.cpp<\/strong> is where I ran across the <strong>Hilbert Curve<\/strong>. It was pretty much just making a large collection of points for the infill, like connect the dots. That meant I just needed logic to come up with my points. Once I make all my output points, all the existing code does the rest.<\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\" id=\"GraphPaper\">Planning with Graph Paper<\/h3>\r\n\r\n\r\n\r\n<p>I decided on my points for the ERRF infill and the 3DPrintopia Infill in a decidedly low-tech way. I got out graph paper, I drew what I wanted and planned my points.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/ERRF Graph Paper - Dots.png\" alt=\"\" \/>\r\n<figcaption>Drawing my ERRF Infill<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><strong><em>Tip &#8211; One best practice I learned is if you are doing text and you want it readable from the top of your print, you&#8217;ll want to plot your points backwards (a mirror image of what you want). <\/em><\/strong><\/p>\r\n\r\n\r\n\r\n<p>When you are planning your infill, think about it as one continuous line. This also means considering how you are going to start a brand new line of your pattern. You don&#8217;t want the printer to draw (or collide!) with lines that were already printed.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/WhyYouCantJustGoToNextLine.png\" alt=\"\" \/>\r\n<figcaption>An example of what you *don&#8217;t* want.<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>You could address it like a typewriter where at the end of each line, you add in some points that get you back to the beginning for the next line. With the ERRF and 3DPrintopia text, that journey back to the start gave me an opportunity to refine my letters more. With a continuous path the R&#8217;s were pretty basic, but on my way back to start a new line, I could take a quick &#8220;detour&#8221; and draw some little holes in my R&#8217;s.<\/p>\r\n\r\n\r\n\r\n<p>If you look again at my ERRF graph paper, you&#8217;ll see two sections of points. First, I have my points that draw my base letters which can be repeated as much as necessary.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/ERRF Graph Paper - Original Pattern.png\" alt=\"ERRF Points - Initial Pass\" \/>\r\n<figcaption>ERRF Points &#8211; Initial Pass<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>Then for the return back to the start of the beginning of the &#8220;page&#8221;, I have my points to fill in extra details for the letters to come.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/ERRF Graph Paper - Connect to First Line.png\" alt=\"ERRF Points - Return Pass\" \/>\r\n<figcaption>ERRF Points &#8211; Return pass<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n\r\n\r\n<p>I translated both of those to x\/y coordinates using the graph paper as a guide.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/ERRF Graph Paper - Points.png\" alt=\"\" \/>\r\n<figcaption>Figuring out the coordinates to draw a single ERRF<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/ERRF Graph Paper - Connector.png\" alt=\"\" \/>\r\n<figcaption>Coordinate points for my &#8220;connector&#8221; line for the ERRF Infill<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\" id=\"Blender\">Planning The Infill (With Blender and Python)<\/h3>\r\n\r\n\r\n\r\n<p>The heart infill, I expected to be more complicated and with more points, so I attacked that in a different way. In Blender, I used a Bezier Curve to draw my heart (with an Array modifier to give me an idea of how it would look with repetition). Once I was satisfied with the shape, I <strong>right clicked<\/strong> on it and chose <strong>Convert To<\/strong> <strong>-&gt; Mesh. <\/strong><\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/Blender - Convert to Mesh.png\" alt=\"\" \/>\r\n<figcaption>Converting a curve to a mesh in Blender<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>That converted my curve to vertices\/points. Instead of graph paper, I could then refer to Blender&#8217;s coordinate system to get my output points.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/Blender - Manual Point Coordinates - Marked Up.png\" alt=\"\" \/>\r\n<figcaption>Planning my output points using Blender&#8217;s coordinate system<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>The heart was a lot of points and it was going to be a wee tedious to grab the X and Y coordinate of all 106 vertices. In this case, I decided to speed up the process using a Python script. Under the <strong>Scripting<\/strong> tab, I ran the following code to not only get my coordinates, but write out the lines of C++ code I would ultimately need for the slicer (more later):<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/Blender - Python Code.png\" alt=\"\" \/>\r\n<figcaption>The Python script in Blender to get the coordinates of all the vertices<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/VickyTGAW\/1fde14cb0d44e8226f04cd4ec406673d.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<h4 class=\"wp-block-heading\">Viewing Results in the Blender System Console<\/h4>\r\n\r\n\r\n\r\n<p>If you are new to Python scripting for Blender and are wondering how to see the results of all your &#8220;print&#8221; commands, go to the <strong>Window<\/strong> main menu and hit <strong>Toggle System Console<\/strong>.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/Blender - Toggle System Console - Marked Up.png\" alt=\"\" \/>\r\n<figcaption>How to view the System Console in Blender<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>This will give you access to a Command window where you can see the fruit of your labor.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/Blender - Output Points.png\" alt=\"\" \/>\r\n<figcaption>The code produced by the Python script<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<h4 class=\"wp-block-heading\">Sorting the Vertices in Blender for the Python Script<\/h4>\r\n\r\n\r\n\r\n<p>I was so excited when my code worked but when I started spot checking I noticed my vertices were <em>not <\/em>in order. This was going to be an issue because I&#8217;m aiming for a continuous line for the slicer to draw. My vision is not going to come to life if the tool path isn&#8217;t going in order. I needed to figure out a way to control the order of the output points. <br \/><br \/>In Blender, vertices are assigned an index as they are created. In <strong>Overlays<\/strong>, if you check <strong>Text Info<\/strong>, you can see those indexes.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/Blender - Overlays - Text Order - Marked Up.png\" alt=\"\" \/>\r\n<figcaption>Using overlaps to see vertex index numbers<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>Doing so revealed that my vertices were dreadfully out of the order and that was trickling down to the output points my Python script was so helpfully making for me.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/Blender - Points Out of Order.png\" alt=\"\" \/>\r\n<figcaption>Oh no, my vertices are terribly out of order!<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>I could have considered changing my Python code, but I ended up using a nice <a href=\"https:\/\/blender.stackexchange.com\/questions\/191649\/how-can-i-sort-vertex-positions-sequentially-indices-in-a-closed-area\/191656#191656\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"&quot;Shape Keys&quot; Hack my StackOverflow user leander (opens in a new tab)\">&#8220;Shape Keys&#8221; Hack by StackOverflow user leander<\/a>. Once I did that, my points where going from 0 to 101 in the order that I wanted the slicer to draw them.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/02\/Blender - Points Sorted.png\" alt=\"\" \/>\r\n<figcaption>Corrected order of the vertices<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">Using ChatGPT to Reverse the Points<\/h3>\r\n\r\n\r\n\r\n<p>With the ERRF and 3DPrintopia infill when the nozzle was traveling back to the starting X coordinate to start a new line, I was using it to fill out the letters more. I didn&#8217;t need that for the hearts, so on the way back, I just wanted to draw another row of hearts&#8230;but in reverse. I got that code by pasting in my original code and asking ChatGPT to reverse it for me. It did a good job!<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/ChatGPT Help.png\" alt=\"\" \/>\r\n<figcaption>Using ChatGPT to reverse my output points code.<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><br \/>Arguably a better way to approach that would be to create an array of all the points then it would be easy to print them forward or backwards. But hey, this way I finally got to use ChatGPT for some coding. \ud83d\ude42<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id=\"Code\">Coding the Infill<\/h2>\r\n\r\n\r\n\r\n<p>With the actual coding of the infill, there are seven files in the PrusaSlicer-master solution that are updated. <strong>If you don&#8217;t want to hash through this blog post, another thing you could do is simply search for &#8220;hilbert&#8221; in the code to locate the spots you need to revise. That&#8217;s what I originally did!<\/strong><\/p>\r\n\r\n\r\n\r\n<p>I&#8217;m including marked up screenshots of the code changes and then I&#8217;m also including GitHub Gist excerpts where you can copy and paste. <br \/><br \/><em><strong>Tip &#8211; With the GitHub Gist examples, if you click on the filename at the bottom of the code and then click on Revisions, you can see what lines were changed (with existing functions).<\/strong><\/em><\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/ChangedFilesFromGit.png\" alt=\"\" \/>\r\n<figcaption>List of Changed Files for Infill<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>&#8216;<\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">libslic3r\\Fill\\FillPlanePath.cpp<\/h3>\r\n\r\n\r\n\r\n<p>This is the file where all the action is. I pretty much copied two functions, renamed them, and updated them for the infill I was working on:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>void FillHilbertCurve::generate<\/li>\r\n<li>static void generate_hilbert_curve<\/li>\r\n<li>\u00a0<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p><strong>FillHearts::generate<\/strong><br \/>This function is a straight copy of the FillHilbertCurve::generate. The only difference is it is renamed.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/FillPlanePathscppGenerate.png\" alt=\"\" \/>\r\n<figcaption>New FillHearts::generate<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><strong>generate_hearts<\/strong><\/p>\r\n\r\n\r\n\r\n<p>Thanks to the hard work of all the code contributers before me, the generate_hearts function first determines how many columns and rows of hearts we&#8217;ll want to print. This is based off the object_width and object_height variables which I set according to the size of the pattern. With the Hearts example, one heart section is 12.4334 mm wide and 13.7993 mm high. My code added just a little padding to the height for aesthetic purposes, but for the most part, you can fill in the dimensions of your pattern block.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/SettingObjectWidthAndHeight.png\" alt=\"\" \/>\r\n<figcaption>Relationship between the pattern size and the object_width and object_height variables.<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>The generate_hearts function already receives the minimum and maximum x and y coordinates for the 3D model. It is simple division to determine how many rows and columns of hearts would be needed.<\/p>\r\n\r\n\r\n\r\n<p>Once we know how many columns and rows of hearts we&#8217;ll need, it is two nested loops to go through and add all our &#8220;output points&#8221;. The first goes through all the &#8220;rows&#8221; of hearts and the second one goes through all the &#8220;columns&#8221; of hearts.<\/p>\r\n\r\n\r\n\r\n<p>When we are determining the y coordinate of a single heart block, we are adjusting the coordinates from Blender based on what row the heart is in.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/IllustratingLoop2Cropped.png\" alt=\"\" width=\"580\" height=\"650\" \/>\r\n<figcaption>The row the heart is in determines its Y position<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>Similarly, the x coordinate is adjusted based on the column the heart is in.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image is-resized\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/IllustratingLoop1Cropped.png\" alt=\"\" \/>\r\n<figcaption>The column the heart is in determines its X position<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>To keep one continuous line, the rows of hearts alternate whether they are going forwards or backwards. The even rows, including the very first one (Row #0) draw forwards. The next row, an odd row, also loops through the columns, but it goes backwards to draw the hearts in the opposite order.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image is-resized\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/IllustratingLoopDirectionsCropped.png\" alt=\"\" \/>\r\n<figcaption>The row the heart is in determines is Y position<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/FillPlanePathscppGenerate_Hearts.png\" alt=\"\" \/>\r\n<figcaption>New generate_hearts function<br \/><br \/><br \/><\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/VickyTGAW\/a67fbb47fdf94dc2b36a27165cada0ed.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\" id=\"mce_20\">libslic3r\\Fill\\FillPlanePath.hpp<\/h3>\r\n\r\n\r\n\r\n<p>In this header file, we are going to put in declarations for our new infill pattern. Here I shamelessly copied the FillHilbertCurve code and adjusted it for Hearts.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/FillPlanePathhppChanges.png\" alt=\"\" \/>\r\n<figcaption>List of Changed Files for Infill<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/VickyTGAW\/7456da8756cc539ea8f7120976eb1f12.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\" id=\"mce_20\">libslic3r\\Fill\\Fill.cpp<\/h3>\r\n\r\n\r\n\r\n<p>In the switch statement for surface_fill.params.pattern, we add in a case for the new infill pattern (ip).<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/FillcppChanges.png\" alt=\"\" \/>\r\n<figcaption>Changes to Fill.cpp<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/VickyTGAW\/2bb21c849428fbeed7507856f90e4979.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\" id=\"mce_24\">libslic3r\\Fill\\FillBase.cpp<\/h3>\r\n\r\n\r\n\r\n<p>In the switch statement in the new_from_type put in a case for your new infill pattern (ip) and return a call to your new function for drawing the infill.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/FillBasecppChanges.png\" alt=\"\" \/>\r\n<figcaption>Changes to FillBase.cpp<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/VickyTGAW\/303ae848f6c5a93249984a126f3f5b7a.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">libslic3r\\PrintConfig.cpp<\/h3>\r\n\r\n\r\n\r\n<p>There are two changes in the PrintConfig.cpp file.<\/p>\r\n\r\n\r\n\r\n<p><strong>s_keys_map_InfillPattern<\/strong><br \/>In s_keys_map_InfillPattern, we are setting up a new enum with our option.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/PrintConfigcppChanges1.png\" alt=\"\" \/>\r\n<figcaption>Adding a new s_keys_map_InfillPattern to PrintConfig.cpp<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/VickyTGAW\/71b4d65c10a091d346d487b179e69c08.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p><strong>Low-fill infill density<\/strong><\/p>\r\n\r\n\r\n\r\n<p>Under PrintConfigDef function, we are adding a new entry to the low-fill infill density pattern.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/PrintConfigcppChanges2.png\" alt=\"\" \/>\r\n<figcaption>Adding a new low-density infill to PrintConfig.cpp<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/VickyTGAW\/9e371b293d3dd791f31b1a4eab521adc.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<p><strong>Solid\/Top Infill<\/strong><br \/>You do not have to make any changes to the solid\/top infill section.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/PrintConfigcppChangesNoSolidInfill.png\" alt=\"\" \/>\r\n<figcaption>You don&#8217;t need to add to the solid-fill-pattern<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\">libslic3r\\PrintConfig.hpp<\/h3>\r\n\r\n\r\n\r\n<p>Update the InfillPattern enum to include our new infill pattern (ip).<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/PrintConfighppChanges.png\" alt=\"\" \/>\r\n<figcaption>Changes to PrintConfig.hpp<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/VickyTGAW\/821e2bcb8e43332df8d08b09fbbfcc7e.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\" id=\"mce_36\">libslic3r\\PrintObject.cpp<\/h3>\r\n\r\n\r\n\r\n<p>Optional &#8211; in the determine_bridging_angle function, add logic for the new infill pattern. I just copied and pasted from, you&#8217;ve guessed it, the Hilbert Curve. \ud83d\ude42<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/PrintObjectcppChanges.png\" alt=\"\" \/>\r\n<figcaption>Changes to PrintObject.cpp<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><script src=\"https:\/\/gist.github.com\/VickyTGAW\/21f7b053828427c7cc1180ca02bc02b8.js\"><\/script><\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id=\"Test\">Testing the Infill<\/h2>\r\n\r\n\r\n\r\n<p>One of the most crucial steps is <strong>testing your infill<\/strong>. One easy way to do this is once your code is running and your PrusaSlicer comes up, <strong>right click<\/strong> on the bed and choose <strong>Add Shape <\/strong>and add a quick Cylinder or Box. Update your infill setting and give it a whirl!<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/TestingInfillAddShape.png\" alt=\"\" \/>\r\n<figcaption>A quick way to test is to Add Shape<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>Just like any other code, you may have some debugging opportunities. These could just be benign like a missing point in your logic.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/BadCode-MissingPointsInT.png\" alt=\"\" \/>\r\n<figcaption>Whoops &#8211; I&#8217;m missing some points in my T and my A<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p>But they could also be things that are detrimental to the health and happiness of your printer.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/BadCode-OverlappingPoints.png\" alt=\"\" \/>\r\n<figcaption>Whoops&#8211; my row of hearts is overlapping.<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><strong>When you slice, if PrusaSlicer gives you a &#8220;Detected print stability issues&#8221; warning, pay attention.<\/strong><\/p>\r\n\r\n\r\n\r\n<p>One neat thing about the code is it already handles the different infill percentages. You don&#8217;t have to write any code for that&#8230; though I think it is all relative. I don&#8217;t think the percentages are going to be an accurate assessment of how filled your object is. \ud83d\ude42<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/90Percent5Percent.png\" alt=\"\" \/>\r\n<figcaption>Heart Infill &#8211; 90% and 5%<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id=\"Print\">Print Your Infill!<\/h2>\r\n\r\n\r\n\r\n<p>Admittedly, there are not a lot of practical applications as infill is usually hidden away inside the print. That said, there are a lot of aesthetic applications when you start removing top and bottom layers and even more so when you start to use modifiers to only expose infill on certain parts of your object!<br \/><br \/>Desktop Makes has some great examples of <a href=\"https:\/\/www.youtube.com\/watch?v=EvUvpxDGCuI\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"exposed infill ornaments (opens in a new tab)\">exposed infill ornaments<\/a> and this <a href=\"https:\/\/www.youtube.com\/watch?v=6PVeh43Or-g\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"video from Prusa3D (opens in a new tab)\">video from Prusa3D<\/a> is a great illustration of what can be done with modifiers.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/PrintingInfill.jpg\" alt=\"\" \/>\r\n<figcaption>Printing the ERRF Infill.<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/tgaw.com\/wp\/wp-content\/uploads\/2024\/03\/ExposedHeartInfill.png\" alt=\"\" \/>\r\n<figcaption>Printing the ERRF Infill.<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<p><br \/>Good luck and enjoy!<\/p>\r\n","protected":false},"excerpt":{"rendered":"<p>How I Made My Own Custom Infills in PrusaSlicer Code.<\/p>\n","protected":false},"author":1,"featured_media":912,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,4,221,231,222],"tags":[],"class_list":["post-809","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-3d-modeling","category-3d-printing","category-blender","category-projects","category-prusaslicer"],"_links":{"self":[{"href":"https:\/\/tgaw.com\/wp\/wp-json\/wp\/v2\/posts\/809","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tgaw.com\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tgaw.com\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tgaw.com\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tgaw.com\/wp\/wp-json\/wp\/v2\/comments?post=809"}],"version-history":[{"count":30,"href":"https:\/\/tgaw.com\/wp\/wp-json\/wp\/v2\/posts\/809\/revisions"}],"predecessor-version":[{"id":913,"href":"https:\/\/tgaw.com\/wp\/wp-json\/wp\/v2\/posts\/809\/revisions\/913"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tgaw.com\/wp\/wp-json\/wp\/v2\/media\/912"}],"wp:attachment":[{"href":"https:\/\/tgaw.com\/wp\/wp-json\/wp\/v2\/media?parent=809"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tgaw.com\/wp\/wp-json\/wp\/v2\/categories?post=809"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tgaw.com\/wp\/wp-json\/wp\/v2\/tags?post=809"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}