Share
 
 

Creating a Buildstyle

The path where the examples are stored has changed. They are now at C:\ProgramData\Autodesk\ATU\ATU-Examples\.

Post-processor tutorial

This tutorial leads you through the creation of a new post-processor starting with a project template. You will define parameters, create a toolpath, and export the result for a 3D printer.

Creating a Post-Processor Project

Choose File > New > New Project.

Enter a Project Name.

Browse to select a path for the new project, create a new empty folder, and click Select Folder.

Click Finish.

A new project is created containing several script files. Once a project is loaded several new windows may open. The windows can be arranged freely. The program will save the window layout for future sessions. If a window is closed, open it from the View menu.

In the Project Explorer, the script files, which are part of the project, are listed. At the moment there is just one file.

The file main.js contains the implementations of the different entry points.

Double-click main.js to open it.

You can get information about the entry point functions by right-clicking a function’s name and choosing Show help for....

Choose Project > Compile (or press F7) to compile the project. See the Build Style Log window to check for errors. If the window is closed, choose View > Build Style Log.

Add Geometry Input Files to Your Project

Now we need to specify some input geometry so that the program is able to apply our post-processor to the layers of that geometry.

In the Input Geometry Files window, click Load to import one or more files. Supported file formats are STL, PLY, and OBJ. Any number of files can be loaded. Demonstration files can be located here: C:\ProgramData\Autodesk\ATU\ATU-Examples\Geometry files

Extract the tree_sample.zip and tree_sample_support.zip files located here: C:\ProgramData\Autodesk\ATU\ATU-Examples\Geometry files and move the extracted files to the geometry folder.

Tip: If you add multiple geometry input files to your project, those files will be passed to your post-processor as a single part.

In the geometry folder, select tree_sample_part.stl and tree_sample_support.stl and click Open.

Now you will be asked for the layer thickness which should be applied to the input geometry. This thickness should match the layer thickness at which your post-processor is intended to work on.

Enter 200 and click OK.

While importing 3D geometry, you can specify a type for every geometry object. Later on, it is possible to treat each type differently.

Option Description
part Geometry for a part
solid support Support geometry, that will be printed solid
hollow/wall support Geometry for a support structure, that is hollow or does not have empty space inside

For tree_sample_part.stl, select part.

For tree_sample_support.stl, select hollow/wall support.

The Input Geometry Files window should now look like this:

Watch the Input Geometry in the 3D View

In the 3D View window, you’ll see the input geometry. Use the mouse-wheel to zoom in and out. Hold down the middle mouse button to rotate. Hold down the middle mouse button and Shift key to pan. A transparent plane shows the current position of the 2D exposure preview.

Watch the Input Geometry in 2D

In the Exposure Preview window, you’ll see one layer of the input geometry. The slider on the right lets you navigate through the layers. On the left side the view options are accessible. For example, you could choose Controls > Ruler to check the dimensions of your input geometry. The view options can be hidden/shown by clicking the button on the bottom left.

Red lines are island borders to be filled with material. Orange lines are open polylines are usually supports because the part should only have closed polygons. Later on, you will also see green lines. These will be the exposure data generated by the script.

Use the mouse wheel to zoom. Press and hold the left mouse button to pan. Double-click the left mouse button to reset the view.

Configure the Post-Processor for a Machine

If necessary, use the Project Explorer window to open the file, main.js. Find the function declareMachine. To see which options are available, open the help page bsMachineConfig. The function declareMachine will specify for which machine, material, and layer thickness the post-processor can be used. Now change the defaults so that the function looks like this:

exports.declareMachine = function(machineConfig)
{
   machineConfig.setBuildstyleName("test01"); // set buildstyle name
   machineConfig.setMachineName("Generic Open Machine"); // set machine name
   machineConfig.addMaterialName("Gold"); // set name of first material
   machineConfig.addMaterialName("Steel"); // set name of second material
   machineConfig.addLayerThickness(200); // set layer thickness option
};

Press F7 to compile and check the Build Style Log for errors.

The script should compile without any errors.

In the Exposure Preview window, you should be able to switch the material between Gold and Steel. Each time the script is compiled, the preview will be updated by calling the post-processor for the selected layer and the selected material.

Creating a Toolpath/Slicing

Add the following lines to the top of the main.js file to make modules available that we’ll use in the next step:

var HATCH = requireBuiltin("bsHatch");
var ISLAND = requireBuiltin("bsIsland");

Until now we have not defined any toolpath data at all. The Exposure Preview window is only showing the layer contours of the input geometry. We will now create our first toolpath.

In the main.js file, find the function makeExposureLayer. This is the main entry function to create the toolpath.

You could open the help pages for bsIsland and bsHatch to see how these classes can be used.

Type in the following code:

exports.makeExposureLayer = function(modelData, hatchResult, nLayerNr)
{
   var iter = modelData.getFirstIsland(nLayerNr);
 
   while(iter.isValid())
   {
      var island = new ISLAND.bsIsland();
      iter.getIsland().createOffset(island, -0.15); // the offset is a path parallel to the island border
 
      var hatchData = new HATCH.bsHatch();
      island.hatch(hatchData, 0.1, 45.0, 0); // this step creates the hatch pattern for the inner part of the island
      hatchResult.moveDataFrom(hatchData);
       
      iter.next();
   }
};

It takes the given island, creates a hatch pattern on it, and pushes the result to hatchResult.

Press F7 to compile.

Now, look at the Exposure Preview window.

Move the Z-position to 15000.

The part-area is filled with a hatch pattern.

On the left side of the Exposure Preview window, click Hatch.

Click Skips.

The skip vectors are drawn additionally.

Choose Controls > Animate.

An additional slider occurs below the Exposure Preview window. Move the slider to see how the area is filled.

The hatch filling can be optimized by enabling the block-sort feature. Change this one line in the script code:

island.hatch(hatchData, 0.1, 45.0, HATCH.nHatchFlagBlocksort);

Press F7 to compile.

Move the animate slider again to see how the filling strategy has changed. You could also combine different flags like this to optimize the path even more:

island.hatch(hatchData, 0.1, 45.0, HATCH.nHatchFlagBlocksort | HATCH.nHatchFlagAlternating);

We will now create an additional border path. Change the code like this:

exports.makeExposureLayer = function(modelData, hatchResult, nLayerNr)
{
   var iter = modelData.getFirstIsland(nLayerNr);
  
   while(iter.isValid())
   {
      var off1 = new ISLAND.bsIsland();
      iter.getIsland().createOffset(off1, -0.15); // first border path parallel to the island border
 
      var off2 = new ISLAND.bsIsland();
      iter.getIsland().createOffset(off2, -0.30); // second border path parallel to the island border
 
      var hatchData = new HATCH.bsHatch();
      off2.hatch(hatchData, 0.1, 45.0, HATCH.nHatchFlagBlocksort | HATCH.nHatchFlagAlternating); // this step creates the hatch pattern filling the inner border path (off2)
 
      hatchResult.moveDataFrom(hatchData);
 
      var borderPath = new HATCH.bsHatch();
      off1.borderToHatch(borderPath);   // generates a toolpath for the outer border path, without adding a hatch pattern
 
      hatchResult.moveDataFrom(borderPath);
 
      iter.next();
   }
};

After compiling again the preview should look like this (zoomed into a detail):

You may have noticed that the support geometry was sliced, but it’s displayed in orange. Also, it doesn’t seem to be affected by the hatching code, we have added before.

Geometry marked as hollow supports, remember that we selected hollow/wall supports while we imported the STL file, will be sliced to polylines. Parts and solid supports are sliced to islands, which are affected by the current JavaScript code. Islands always have to be closed 2D geometry, while polylines allow to be path, where start and end aren’t connected.

To use the polyline tools, include:

var POLY_IT = requireBuiltin("bsPolylineIterator");

Add the following code to your function to simply translate the support structure’s polylines to a toolpath:

exports.makeExposureLayer = function(modelData, hatchResult, nLayerNr)
{
   var iter = modelData.getFirstIsland(nLayerNr);
   while(iter.isValid())
   {
      var off1 = new ISLAND.bsIsland();
      iter.getIsland().createOffset(off1, -0.15);
 
      var off2 = new ISLAND.bsIsland();
      iter.getIsland().createOffset(off2, -0.30);
 
      var hatchData = new HATCH.bsHatch();
      off2.hatch(hatchData, 0.1, 45.0, HATCH.nHatchFlagBlocksort | HATCH.nHatchFlagAlternating);
      hatchResult.moveDataFrom(hatchData);
 
      var borderPath = new HATCH.bsHatch();
      off1.borderToHatch(borderPath);
      hatchResult.moveDataFrom(borderPath);
 
      iter.next();
   }
 
   iter = modelData.getFirstLayerPolyline(nLayerNr, POLY_IT.nLayerOpenPolylines); // create second iterator for support structures
   while(iter.isValid())
   {
      var polylineHatch = new HATCH.bsHatch();
      iter.polylineToHatch(polylineHatch);       // uses the polyline to generate the toolpath
 
      hatchResult.moveDataFrom(polylineHatch);
      iter.next();
   }
};

Press F7 to compile.

The orange support polylines in the hatch preview should become green, because now a toolpath was created.

Assigning Attributes to Toolpaths

An arbitrary number of attributes can be assigned to a toolpath. This information can be accessed later on while exporting the data to a file where it may be necessary to store special processing parameters for the machine. Attributes can be assigned to a polyline, to a separate segment, or a separate point within a polyline.

Find the function declareBuildAttributes.

Declare two attributes.

exports.declareBuildAttributes = function(buildAttrib)
{
   buildAttrib.declareAttributeInt("power"); // beam laser power (W)
   buildAttrib.declareAttributeReal("speed"); // exposure speed (mm/s)
};

Now these attributes are available within the toolpath generation. We can assign values to each bsHatch.

Add the following lines to the function makeExposureLayer:

exports.makeExposureLayer = function(modelData, hatchResult, nLayerNr)
{
   var iter = modelData.getFirstIsland(nLayerNr);
   while(iter.isValid())
   {
      var off1 = new ISLAND.bsIsland();
      iter.getIsland().createOffset(off1, -0.15);
 
      var off2 = new ISLAND.bsIsland();
      iter.getIsland().createOffset(off2, -0.30);
 
      var hatchData = new HATCH.bsHatch();
      off2.hatch(hatchData, 0.1, 45.0, HATCH.nHatchFlagBlocksort | HATCH.nHatchFlagAlternating);
 
      hatchData.setAttributeInt("power", 120);                        // set integer attribute "power"
      hatchData.setAttributeReal("speed", 515.0);                    // set floating point attribute "speed"
 
      hatchResult.moveDataFrom(hatchData);
 
      var borderPath = new HATCH.bsHatch();
      off1.borderToHatch(borderPath);
 
      borderPath.setAttributeInt("power", 60);                   // set integer attribute "power"
      borderPath.setAttributeReal("speed", 390.5);              // set floating point attribute "speed"
 
      hatchResult.moveDataFrom(borderPath);
      iter.next();
   }
   iter = modelData.getFirstLayerPolyline(nLayerNr, POLY_IT.nLayerOpenPolylines);
   while(iter.isValid())
   {
      var polylineHatch = new HATCH.bsHatch();
      iter.polylineToHatch(polylineHatch);
 
      polylineHatch.setAttributeInt("power", 175);      // set integer attribute "power"
      polylineHatch.setAttributeReal("speed", 625.5);  // set floating point attribute "speed"
 
      hatchResult.moveDataFrom(polylineHatch);
      iter.next();
   }
};

Open the Exposure Preview window.

Click any green toolpath segment to select it.

Right-click and choose Attribute Info.

Now you can watch the attributes of each segment while you move the mouse from segment to segment.

Exporting to CLI

The next thing we want to do is to export the calculated toolpath to a file. For example, we can export the data to a CLI file. (Other formats can be used. Examples are pictures for the ember machine or binary formats for Renishaw machines.)

In the Project Explorer window, right-click the root node test01 and choose Add Existing File.

From the Scripts folder, select the file export_cli.js.

Your project should look like this:

Add these lines to the top of main.js to make CLI and the export filter available.

var EXPORT_FILTER = requireBuiltin("bsExportFilter");
var CLI = require("export_cli.js");

A compile error may occur because the file export_cli.js cannot be found. Choose Project > Properties.

Adding locations to the Module Search Path, tells the toolpath processor to look for JavaScript include files in all specified locations. In the sample code above, the require function includes the JavaScript code of the file export_cli.js to you current file. You can create JavaScript libraries, that can be reused in different buildstyles, and store them in central locations. The toolpath processor finds these file, if you set the Module Include Path to that central location.

In the main.js file, find the function declareExportFilter.

Declare the CLI export filter like this:

exports.declareExportFilter = function(exportFilter)
{
   exportFilter.declareFilter("CLI", "CLI File", "cli",
      CLI.version.major, CLI.version.minor,
      EXPORT_FILTER.nExportFilterSingleFile);
}; 
	 

Find the function exportToFile and implement the CLI export as follows:

exports.exportToFile = function(
  exportFile,
  sFilter,
  modelData,
  progress)
{
    if(sFilter == "CLI")
    {
      // export to cli format
      var exporter = new CLI.cliExport(1.0,
        CLI.options.ascii | CLI.options.exposure |
        CLI.options.buildPart | CLI.options.support);

      exporter.addExportAttributeInt("power", "POWER");
      exporter.addExportAttributeReal("speed", "SPEED");

      exporter.exportCli(exportFile, modelData, progress);
      return;
   }
   process.printError("unsupported export filter " + sFilter);
   return;
};

The post-processor is now able to export the toolpath to a CLI file.

Declaring External Parameter

Though most configuration settings should be kept internally, a post-processor is able to declare parameters which are configurable by the calling program. This is especially useful to create test platforms where the same part is built multiple times while certain parameters are modified slightly to identify the best parameter settings for a post-processor.

To make the parameter module available, add the following line to the top of the main.js file:

var PARAM = process.binding("bsParam");

In the main.js file, find the function declareParameters.

Declare the following two parameters.

exports.declareParameters = function(parameter)
{
   parameter.declareParameterGroup("exposure", "Exposure");
   parameter.declareParameterReal("exposure", "_bcomp", "Beam Compensation", 0.001, 2.0, 0.15);
   parameter.declareParameterInt("exposure", "_hatchAngle", "Hatching angle", 0, 359, 0);
}; 
	 

In the main.js file, change the function makeExposureLayer like this:

exports.makeExposureLayer = function(modelData, hatchResult, nLayerNr)
{
 var iter = modelData.getFirstIsland(nLayerNr);
 while(iter.isValid())
 {
    var fBeamComp = PARAM.getParamReal("exposure", "_bcomp");
    var nAngle = PARAM.getParamInt("exposure", "_hatchAngle");
 
    var off1 = new ISLAND.bsIsland();
    iter.getIsland().createOffset(off1, -fBeamComp);
 
    var off2 = new ISLAND.bsIsland();
    iter.getIsland().createOffset(off2, -fBeamComp-0.15);
 
    var hatchData = new HATCH.bsHatch();
    off2.hatch(hatchData, 0.1, nAngle, HATCH.nHatchFlagBlocksort | HATCH.nHatchFlagAlternating);
 
    hatchData.setAttributeInt("power", 120);
    hatchData.setAttributeReal("speed", 515.0);
 
    hatchResult.moveDataFrom(hatchData);
 
    var borderPath = new HATCH.bsHatch();
    off1.borderToHatch(borderPath);
 
    borderPath.setAttributeInt("power", 60);
    borderPath.setAttributeReal("speed", 390.5);
 
    hatchResult.moveDataFrom(borderPath);
 
    iter.next();
 }
 iter = modelData.getFirstLayerPolyline(nLayerNr, POLY_IT.nLayerOpenPolylines);
 while(iter.isValid())
 {
    var polylineHatch = new HATCH.bsHatch();
    iter.polylineToHatch(polylineHatch);
 
    polylineHatch.setAttributeInt("power", 175);
    polylineHatch.setAttributeReal("speed", 625.5);
 
    hatchResult.moveDataFrom(polylineHatch);
 
    iter.next();
 }
};

Exporting a Test Build

Last but not least, we can now export a test build by setting up a build platform of parts in a 2-by-2 pattern and vary the beam compensation and hatching angle from part to part. Before that, we have to check that the machine as well, as the materials are known to the program: Open the Materials dialog box, and add the materials Gold and Steel, in case they are not already there. Do the same with the Generic Open Machine by checking the Machines dialog box. If either the machine or the materials are not specified, you would get an error message in the next step.

From the Machines window, click Add New.

In the opening dialog box, set the machine name Generic Open Machine.

In the blank platforms area, right-click to create a new platform.

Double-click the new platform to open the Platform dialog box.

On the Zones tab, select the Box zone to see the zone settings.

Set the Min and Max values to -125/+125, respectively, to define a build envelope large enough for our test. Then close the Platform dialog box and the Machine dialog box.

Now we are ready to export a test build. Choose Netfabb > Export Test Build.

Click New to create a setup.

Enter a name, such as 2x2, and set the Rows and Columns to 2.

Drag the mouse over the table view so that all four cells are selected.

Then right-click and choose New Variation....

The Parameter dialog box will open.

Configure the parameters so that the beam compensation will change from column A to column B.

Then click OK.

Mouse over the table cells to verify that the parameter is assigned properly.

Repeat the step to add a variation of the hatching angle. This time let it vary over the rows.

If all values are acceptable, click OK.

Set a spacing of 10 mm so that there is a distance between the parts on the test platform.

Then click Export. Enter a file name and click Save.

The test platform will be calculated and written to the specified file. If you open the CLI file with a text editor, you can see the specified attributes POWER and SPEED are written before each polyline.

Was this information helpful?