Overview
The Additive class is used to create additive manufacturing solutions. The first solution is for Powder Bed Fusion.
PBF solutions are defined for the geometry in a STEP file. Each solution is defined as a plan that operates in four stages.
- In the first stage the geometry is sliced into layers.
- In the second stage each slice is divided into regions.
- In the third stage the regions are filled with scan paths and bounded by contours.
- In the fourth stage manufacturing processes are defined for the scan paths and contours.
The first three stages of the process are shown in the figure below. Note the small footprint of the result, about 14K of data. The solution defines how to make scan paths using a reference algorithm defined by the ISO 10303 standard. The scan paths would have a much larger data volume if they were stored, typically hundreds of gigabytes. The scan paths do not need to be stored because a 3D printer can use the reference algorthm to make the paths on demand.
Example 1
The following example reads a STEP file and defines a simple process for a part that only needs one region.
static void Example1() { Additive pbf = new Additive(); pbf.OpenSTEP("NIST_STEP_Test_v1.stp"); // Read the STEP fike pbf.PBFSlice("Test 1 part", 0.05, 90); // slice thickness = 0.05mm rotation = 90 degree pbf.PBFSliceInitialRotationPutDEG(45.0); // first slice at 45 degree long reg1 = pbf.PBFInskinRegion(); // part does NOT need upskin or downskin long op1 = pbf.PBFStripe(reg1, 10, 0.12); // width=10mm, overlap=0.12mm long op2 = pbf.PBFPreContour(op1, 0.08); // contour 1 offset=0.08mm long op3 = pbf.PBFPreContour(op1, 0.16); // contour 2 offset=0.16mm long infill = pbf.PBFInfill(op1, 0.14, 0.08); // hatch offset=0.14mm, hatch=0.08mm pbf.PBFProcess(infill, 0.25, 1000, 0.08); // infill power=0.25kw, speed=1000mmps, beam=0.08mm pbf.PBFProcess(op2, 0.09, 300, 0.08); // contour 1 power=0.09kw, speed=300mmps, beam=0.08mm pbf.PBFProcess(op3, 0.08, 300, 0.08); // contour 2 power=0.08kw, speed=300mmps, beam=0.08mm pbf.PBFMaterialSet("chunky", "chocolate standard"); // set these to "real" values pbf.SaveSTEP("NIST_STEP_Test_v1_process.stpnc"); // save the process }NIST_STEP_Test_v1.stp
NIST_STEP_Test_v1_process.stpnc
Example 2
The following example reads a STEP file and defines a process for a part that has two regions. The core of the part is made using a process similar to example 1. A second process is defined for those regions that are close to any surface that slopes at an angle greater than 48 degrees. This process reduces the heat to avoid over melting powder that is within three layers of the down slope.
static void Example2() { Additive pbf = new Additive(); pbf.OpenSTEP("TMmini_OQ_block_v2.stp"); // Read the STEP fike pbf.PBFSlice("Test 2 part", 0.1, 90); // slice thickness = 0.05mm rotation = 90 degree long reg1 = pbf.PBFInskinRegion(); // inskin uses a stripe operation long op_st = pbf.PBFStripe("inskin", 10, 0.12); // width=10mm overlap=0.12mm long op_c1 = pbf.PBFPreContour("inskin", 0.08); // contour 1 offset=0.08mm long op_c2 = pbf.PBFPreContour("inskin", 0.16); // contour 2 offset=0.16mm long op_i1 = pbf.PBFInfill("inskin", 0.14, 0.12); // hatch offset=0.14mm, space=0.12mm pbf.PBFInfillDirectionPutDegree(op_st, 45); // stripe vector direction = 45 degree pbf.PBFProcess(op_i1, 0.27, 1000, 0.08); // stripe infill power=0.27kw, speed=1000mmps, beam=0.08mm pbf.PBFProcess(op_c1, 0.136, 500, 0.08); // contour 1 power=0.135kw, speed=500mmps, beam=0.08mm pbf.PBFProcess(op_c2, 0.128, 500, 0.08); // contour 2 power=0.120kw, speed=500mmps, beam=0.08mm pbf.PBFContourSetAlternate(op_c1); // Alternate direction of contour by slice (this is default) pbf.PBFContourSetAlternate(op_c2); // Alternate direction of contour by slice (this is default) long reg2 = pbf.PBFDownskinRegion(48, 3); // downskin has 3 layers, downskin limit is 48 degree long op_mea = pbf.PBFMeander (reg2); // downskin uses a meander operation long op_i2= pbf.PBFInfill(reg2, 0.1, 0.1); // hatch offset=0.1mm, space=0.1mm pbf.PBFInfillDirectionPutDegree(reg2, 135); // stripe vector direction = 135 degree pbf.PBFProcess(op_i2, 0.135, 1000, 0.08); // meander infill power=0.120kw, speed=500mmps, beam=0.08mm pbf.PBFRegionMinAreaPutMM2(reg2, 0.04); // minimum size allowed for region pbf.PBFMaterialSet("chunky", "chocolate standard"); // set these to "real" values pbf.SaveSTEP("TMmini_OQ_block_v2_process.stpnc"); // save the process }TMmini_OQ_block_v2.stp
TMmini_OQ_block_v2_process.stpnc
Print STEP-NC
The next example reads a STEP-NC file and prints the parameters of its defined processes. The print starts by listing the parameters of the slice definition. Next for each region it lists the constraints that defines the region followed by the process selected to manufacture that region. The pre-contours are listed first. The infill is described next. The post-contours are listed last.
static void PrintSTEPNC(string file_name) { Additive pbf = new Additive(); pbf.OpenSTEPNC(file_name); double thick = pbf.PBFSliceThicknessGetMM(); double rot = pbf.PBFSliceRotationGetDEG(); double start = pbf.PBFSliceInitialRotationGetDEG(); Console.WriteLine(file_name); Console.WriteLine("Slice: Thickness = " + thick + "mm Rotation = " + rot + " degrees"); if (start != 0) Console.WriteLine("Initial rotation = " + start + " degrees"); long region_count = pbf.PBFRegionCount(); for (int rc = 0; rc < region_count; rc++) { string type = pbf.PBFRegionTypeGet(rc + 1); if (type == "inskin") { Console.WriteLine("Region " + (rc + 1) + " is inskin:"); } else if (type == "downskin") { double down_angle = pbf.PBFRegionDownskinAngleGetDeg("downskin"); long layer_count = pbf.PBFRegionLayerCountGet("downskin"); double min_area = pbf.PBFRegionMinAreaGetMM2("downskin"); Console.WriteLine("Region " + (rc + 1) + " is downskin for " + layer_count + " Layers at angle " + down_angle + " degrees:"); if (min_area != 0) Console.WriteLine("\tMinimum Area = " + min_area + " mms"); } else if (type == "upskin") { double down_angle = pbf.PBFRegionDownskinAngleGetDeg("upskin"); long layer_count = pbf.PBFRegionLayerCountGet("upskin"); double min_area = pbf.PBFRegionMinAreaGetMM2("upskin"); Console.WriteLine("Region " + (rc + 1) + " is upskin for " + layer_count + " Layers at angle " + down_angle + " degrees:"); if (min_area != 0) Console.WriteLine("\tMinimum Area = " + min_area + " mms"); } else { Console.WriteLine("Region " + (rc + 1) + " is unknown:"); } long op2d1 = pbf.PBFRegionOperationGet(rc + 1); long pre_count = pbf.PBFPreContourCount(op2d1); for (int i = 1; i <= pre_count; i++) { Console.WriteLine("Pre Contour " + i + ":"); long cn = pbf.PBFPreContourGet(op2d1, i); double cn_offset = pbf.PBFContourOffsetGetMM(cn); if (pbf.PBFContourSense(cn) == "clockwise") Console.WriteLine("\tClockwise offset = " + cn_offset + "mm"); else Console.WriteLine("\tOffset = " + cn_offset + "mm"); if (pbf.PBFProcessTechnologyGet(cn) != 0) { double power = pbf.PBFProcessPowerGetKW(cn); double diameter = pbf.PBFProcessDiameterGetMM(cn); double speed = pbf.PBFProcessSpeedGetMMPS(cn); Console.WriteLine("\tPower = " + power + "kw speed = " + speed + " mmps diameter = " + diameter + "mm"); } else Console.WriteLine("\tNO CONTOUR TECHNOLOGY"); } if (pre_count == 0) Console.WriteLine("NO PRE-CONTOURs IN REGION"); string op_type = pbf.PBFRegionOperationTypeGet(rc + 1); if (op_type == "stripe") { double width = pbf.PBFStripeWidthGetMM(op2d1); double overlap = pbf.PBFStripeOverlapGetMM(op2d1); double direction = pbf.PBFInfillDirectionGetDegree(op2d1); Console.WriteLine("Stripe:"); if (direction != 0) Console.WriteLine("\tInfill direction = " + direction + " degree"); Console.WriteLine("\tWidth = " + width + "mm, Overlap = " + overlap + " mm"); } else if (op_type == "chess") { double width = pbf.PBFChessWidthGetMM(op2d1); double length = pbf.PBFChessLengthGetMM(op2d1); double direction = pbf.PBFInfillDirectionGetDegree(op2d1); Console.WriteLine("Chess:"); if (direction != 0) Console.WriteLine("\tInfill direction = " + direction + " degree"); Console.WriteLine("\tWidth = " + width + "mm" + "Length = " + length + " mm"); } else if (op_type == "meander") { Console.WriteLine("Meander:"); double direction = pbf.PBFInfillDirectionGetDegree(op2d1); if (direction != 0) Console.WriteLine("\tInfill direction = " + direction + " degree"); } else Console.WriteLine("\tNO OPERATION DEFINED REGION"); long fill1 = pbf.PBFInfillGet(op2d1); double space = pbf.PBFInfillSpaceGetMM(fill1); // REG or INFILL double offset = pbf.PBFInfillOffsetGetMM(fill1); Console.WriteLine("Infill:"); Console.WriteLine("\tSpace = " + space + " mm offset = " + offset + " mm"); if (pbf.PBFProcessTechnologyGet(fill1) != 0) { double power = pbf.PBFProcessPowerGetKW(fill1); double diameter = pbf.PBFProcessDiameterGetMM(fill1); double speed = pbf.PBFProcessSpeedGetMMPS(fill1); Console.WriteLine("\tPower = " + power + "kw speed = " + speed + " mmps diameter = " + diameter + "mm"); } else Console.WriteLine("\tNO FILL TECHNOLOGY"); long post_count = pbf.PBFPostContourCount(op2d1); for (int i = 1; i <= post_count; i++) { Console.WriteLine("Post Contour " + i + ":"); long cn = pbf.PBFPostContourGet(op2d1, i); double cn_offset = pbf.PBFContourOffsetGetMM(cn); if (pbf.PBFContourSense(cn) == "clockwise") Console.WriteLine("\tClockwise offset = " + cn_offset + "mm"); else if (pbf.PBFContourSense(cn) == "counter_clockwise") Console.WriteLine("\tCounter Clockwise offset = " + cn_offset + "mm"); else Console.WriteLine("\tOffset = " + cn_offset + "mm"); if (pbf.PBFProcessTechnologyGet(cn) != 0) { double power = pbf.PBFProcessPowerGetKW(cn); double diameter = pbf.PBFProcessDiameterGetMM(cn); double speed = pbf.PBFProcessSpeedGetMMPS(cn); Console.WriteLine("\tPower = " + power + "kw speed = " + speed + " mmps diameter = " + diameter + "mm"); } else Console.WriteLine("\tNO CONTOUR TECHNOLOGY"); } if (post_count == 0) Console.WriteLine("NO POST-CONTOURs IN REGION"); Console.WriteLine(); } }Print Example 1
PBFSlice()
System::Int64 PBFSlice ( System::String^ solution_name, double slice_thickness_mm, double interslice_rotation_degree );
The PBFSlice() function defines the thickness and orientation of each slice. Starting at the base, the geometry is sliced into layers of the given thickness. To reduce stress, each slice is given a different orientation by the interslice rotation. Typical values for the rotation are 67 degrees and 47 degrees so that no two slices have the same rotation. If it matters the initial rotation can be set non-zero using the initial slice rotation put function.
Arguments
- solution name
- Name for the solution.
- slice thickness
- The thickness of each slice.
- interslice rotation
- The rotation increment for each layer.
Result
- The function returns the identity of the solution so that it can be edited.
Related Functions
- PBFRegion Define the regions on each slice.
- PBFStripe Define the fill strategy for each region.
- PBFContour Define pre and post contours for each infill.
- PBFInfill Define hatch vectors for each infill.
- PBFProcess Define the process data for each infill and contour.
- PBFSliceInitiatlRotationPut Define the rotation for the first slice.
- PBFSliceXxPut/Get Functions to set the slice attributes indivdually.
Common Errors
- Bad geometry. There is no geometry or too much geometry in the file.
PBFInfillRegion()/PBFDownskinRegion()/PBFUpskinRegion()
System::Int64 PBFInfillRegion ( ); System::Int64 PBFDownskinRegion ( double high_above_angle_degree, System::Int64 layer_count ); System::Int64 PBFUpskinRegion ( double high_below_angle_degree, System::Int64 layer_count );
Three kinds of regions can be defined. The infill region describes the process used for the majority of the part. The downskin region describe the process for surfaces that overhang. The upskin region describes the process for surfaces at the top of the part. For many parts there will only be an infill region. A downskin region is quite common because of melting issues. The upskin region is rare.
Arguments
- high_above_angle_degree
- The angle above the horizontal for a downskin surface. If the angle exceeds this value then the surface is not a downskin.
- high_below_angle_degree
- The angle below the horizontal for a upskin surface. If the angle exceeds this value then the surface is not an upskin.
- layer count
- The number of layers above the skin where the process applies (or below for an upskin).
Result
- The functions return the identity of the region so that it can be referenced by future infills and contours.
Related Functions
- PBFSlice Define the slices.
- PBFStripe Define the fill strategy for each region.
- PBFContour Define pre and post contours for each fill.
- PBFInfill Define hatrch vectors for each infill.
- PBFProcess Define process data for each scan path.
- PBFRegionXxPut/Get Functions to set the region attributes indivdually.
- PBFRegionGet Function to get the definition for a region.
- PBFRegionOperationGet Function to get the operation for a region.
Common Errors
- No slices. Regions cannot be defined before the part has been divided into slices.
PBFStripe()
System::Int64 PBFStripe ( System::Int64 region_id, // or System::String^ region_type double stripe_width_mm, double offset_mm, double overlap_mm, double hatch_space_mm );
The PBFStripe() function defines how a region is filled. The region is divided into stripes with the stripe width. The offset defines a border between the part edges and the first stripe. The overlap defines an overrun between consecutive stripes. The hatch space defines the distance between scan paths within the stripe.
Arguments
- region id
- The identity of the region being filled.
- region type
- The identity of the region given as a name ("inskin", "downskin, or "upskin").
- stripe width
- The width of each stripe. The stripes are laid so that the left border of one is on the y-axis of the slice.
- offset
- An offset from the part edge that will not be filled by a stripe. The area of the offset may be filled by a contour.
- overlap
- An overlap between stripes to ensure seamless melting.
- hatch space
- The distance between scan paths within a stripe.
Result
- The function return the identity of the stripe so that it can be referenced by a PBFInfill and PBFContour
Related Functions
- PBFSlice Define the slices.
- PBFRegion Define the regions on each slice.
- PBFContour Define pre and post contours for each infill.
- PBFInfill Define how to infill each stripe with hatch vectors.
- PBFChess Define a chess square strategy for the infill.
- PBFMeander Define a strategy for the infill that meanders over the region.
- PBFProcess Define the process data for each infill and contour.
- PBFStripeXxPut/Get Functions to set the stripe attributes individually.
Common Errors
- No region. A region must be defined before it can be filled.
PBFChess()
System::Int64 PBFChess ( System::Int64 region_id, // or System::String^ region_type double rectangle_width_mm, double rectangle_length_mm, double chess_overlap_mm, );
The PBFChess() function defines how a region is filled. The region is divided into chess squares with a width and length. The overlap defines an overrun between consecutive squares.
Arguments
- region id
- The identity of the region being filled.
- region type
- The identity of the region given as a name ("inskin", "downskin, or "upskin").
- rectangle width
- The width of each rectangle. The squares are laid so that the left border of one is on the y-axis of the slice.
- rectangle length
- The height of each rectangle. The squares are laid so that the the bottom border of one is on the x-axis.
- chess overlap
- An overlap between squares on the same row and/or column.
Result
- The function return the identity of the chess so that it can be referenced by a PBFInfill and PBFContour
Related Functions
- PBFSlice Define the slices.
- PBFRegion Define the regions on each slice.
- PBFContour Define pre and post contours for each infill.
- PBFInfill Define how to infill each chess square with hatch vectors.
- PBFStripe Define a stripe strategy for the infill.
- PBFMeander Define a strategy for the infill that meanders over the region.
- PBFProcess Define the process data for each infill and contour.
- PBFStripeXxPut/Get Functions to set the chess attributes indivdually.
Common Errors
- No region. A region must be defined before it can be filled.
PBFMeander()
System::Int64 PBFMeander ( System::Int64 region_id, // or System::String^ region_type );
The PBFMeander() function defines a region that is filled without making any stripes or chess squares.
Arguments
- region id
- The identity of the region being filled.
- region type
- The identity of the region given as a name ("inskin", "downskin, or "upskin").
Result
- The function return the identity of the meander so that it can be referenced by a PBFInfill and PBFContour
Related Functions
- PBFSlice Define the slices.
- PBFRegion Define the regions on each slice.
- PBFContour Define pre and post contours for each infill.
- PBFContour Define how to infill each region with hatch vectors.
- PBFStripe Define a stripe strategy for the infill.
- PBFChess Define a chess strategy for the infill.
- PBFProcess Define the process data for each infill and contour.
Common Errors
- No region. A region must be defined before it can be filled.
PBFInfill()
System::Int64 PBFInfill ( System::Int64 region_id, // or System::String^ region_type double hatch_offset_mm, double hatch_space_mm );
The PBFInfill() function defines how hatches are defined for an infill. The hatch offset defines an offset between the hatch and the edge of the part. The hatch space defines the distance between consecutive scan paths.
Arguments
- region id
- The identity of the region being filled.
- region type
- The identity of the region given as a name ("inskin", "downskin, or "upskin").
- hatch offset
- An offset from the part edge that will not be filled. The area of the offset may be filled by a contour.
- hatch space
- The distance between consecutive scan paths.
Result
- The function return the identity of the infill so that it can be referenced by a PBFProcess.
Related Functions
- PBFSlice Define the slices.
- PBFRegion Define the regions on each slice.
- PBFStripe Define a stripe strategy for the infill.
- PBFChess Define a chess square strategy for the infill.
- PBFMeander Define a strategy for the infill that meanders over the region.
- PBFProcess Define the process data for each infill and contour.
- PBFInfillXxPut/Get Functions to set the infill attributes indivdually.
Common Errors
- No operation. An stripe, chess or meander operation must be defined before it can be filled.
PBFPrecontour()/PBFPostcontour()
System::Int64 PBFPreContour() ( System::Int64 region_id, // or System::String^ region_type double offset_mm ); System::Int64 PBFPostContour() ( System::Int64 region_id, // or System::String^ region_type double offset_mm );
The PBFxxxContour() functions define how a contour is laid around the part edges within a region. The offset defines a border between the part edge and the contour. No contour is laid for edges of the region that are not on borders of the part.
The PBFPreContour() function defines contours scanned before the infill.
The PBFPostContour() function defines contours scanned after the infill.
Arguments
- region id
- The identity of the region being contoured.
- region type
- The identity of the region given as a name ("inskin", "downskin, or "upskin").
- offset
- An offset between the part edge and the contour. The area of the offset is filled by the contour.
Result
- The functions return the identity of the contour so that it can be referenced by a PBFProcess.
Related Functions
- PBFSlice Define the slices.
- PBFRegion Define the regions on each slice.
- PBFInfill Define the fill strategy for each region.
- PBFProcess Define the process data for each infill and contour.
- PBFPostContourSetClockwise() Set the direction of the contour to clockwise (default is counter clockwise).
- PBFContourXxPut/Get Functions to set the contour attributes indivdually.
Common Errors
- No region. A region must be defined before it can be contoured.
PBFProcess()
System::Int64 Additive::PBFProcess ( System::Int64 op_id, double power_kw, double speed_mmps, double beam_diameter_mm )
The PBFProcess() function defines the process parameters that are to be used when scanning an infill or contour. These parameters are chosen to ensure the process produces the correct melting to fuse the part. Too much heat will cause the powder to boil leaving voids in the material. Too little heat will allow the powder to stay solid. The conductivity of the material changes as it melts, and is less efficient near the part borders and overhangs.
Arguments
- op_id
- The identity of the infill or contour that is to be given this process.
- power kw
- The power that is to be used to melt the pool during this scanning process.
- speed mmps
- The speed of the beam while it is melting the pool.
- beam diameter mm
- The diameter (focus) of the beam while it is performing the melting.
Result
- The function returns the identity of the PBFProcess so that its attributes can be edited.
Related Functions
- PBFSlice Define the slices.
- PBFRegion Define the regions on each slice.
- PBFContour Define pre and post contours for each infill.
- PBFInfill Define hatching paths for each infill.
- PBFMaterial Define the material assumed by the process.
- PBFProcessXxPut/Get Functions to set the process attributes indivdually.
Common Errors
- No path. A hatch or contour path must be defined for each process.
PBFMaterial()
System::Int64 Additive::PBFMaterialSet ( System::String^ material_name, System::String^ standard_name ) System::String^ Additive::PBFMaterialGet ( ) System::String^ Additive::PBFMaterialStandardGet ( )
The PBFMaterial() function defines the material assumed by the process. The process expert must understand the characteristics of the material to ensure proper melting.
Arguments
- material name
- The name of the material assumed by the melting process.
- standard name
- The name of the standard that defines the characteristics of the material.
Result
- No result.
Related Functions
- PBFSlice Define the slicess.
- PBFRegion Define the regions on each slice.
- PBFStripe Define the fill strategy for each region.
- PBFContour Define pre and post contours for each infill.
- PBFProcess Define the process data for each infill and contour.
- PBFMaterial Define the material assumed by the process.
Common Errors
- No data. The STEP file is empty.
- No root. The STEP file contains multiple disconnected assemblies.
PBFPlacement()
void Additive::PBFPlacement ( double x, y, z, double i, j, k, double a, b, c )
The PBFPlacement() function changes the placement of the part to the correct position for the melting process. The part will have a native placement and orientation defined by a CAD system. The placement function changes it to the location and orientation required by the manufacturing process.
Arguments
- x, y, z
- The new origin.
- i, j, k
- The new up (Z) direction.
- a, b, c
- The new X direction.
Result
- The placement of the part is now with respect to the new origin.
Related Functions
- PBFSlice Define the slicess.
- PBFRegion Define the regions on each slice.
- PBFStripe Define the fill strategy for each region.
- PBFContour Define pre and post contours for each infill.
- PBFRead Read and write the STEP file.
Common Errors
- No data. The STEP file is empty.
- No root. The STEP file contains multiple disconnected assemblies.
PBFRead/Write()
void Additive::OpenSTEP( System::String^ filename ) void Additive::SaveSTEP( System::String^ filename )
The OpenSTEP() function reads the STEP file that will be given the fusion process. The SaveSTEP() function writes the STEP file containing the new process. The two files may have the same name because the one with the melting process will be given the extension ".stpnc". The wider library referenced in the banner includes many options for reading and writing the STEP files. The confoguration used for PBF includes many comments to help you understand the generated data.
Arguments
- filename
- The name of the STEP or STEP-NC file.
Result
- The STEP file contains an additive manufacturing process.
Related Functions
- PBFSlice Define the slices.
- PBFRegion Define the regions on each slice.
- PBFStripe Define the fill strategy for each slice.
- PBFContour Define pre and post contours for each infill.
- PBFProcess Define the process data for each infill and contour.
- PBFMaterial Define the material of the process.
- PBFPlacement Change the location and orientation of the STEP file.
Common Errors
- No data. The STEP file is empty.
- No root. The STEP file contains multiple disconnected assemblies.