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.

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 core = pbf.PBFCoreIdentification();		    // part does NOT need upskin or downskin
   long op1 = pbf.PBFStripe(core, 10, 0.12);               // width=10mm, overlap=0.12mm
   long op2 = pbf.PBFContour(op1, 0.08);	            // contour 1 offset=0.08mm
   long op3 = pbf.PBFContour(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("melt pool", "melt 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 core = pbf.PBFCoreIdentification();		    // core uses a stripe operation
    long op_st = pbf.PBFStripe(core, 10, 0.12);             // width=10mm overlap=0.12mm
    long op_c1 = pbf.PBFContour(op_st, 0.08);	            // contour 1 offset=0.08mm
    long op_c2 = pbf.PBFContour(op_st, 0.16);               // contour 2 offset=0.16mm
    long op_i1 = pbf.PBFInfill(op_st, 0.14, 0.12);          // hatch offset=0.14mm, space=0.12mm
    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 layer (this is default)
    pbf.PBFContourSetAlternate(op_c2);                      // Alternate direction of contour by layer (this is default)

    long down = pbf.PBFDownskinIdentification(48, 3);       // downskin has 3 layers, downskin limit is 48 degree
    long op_mea = pbf.PBFMeander (down);                    // downskin uses a meander operation
    long op_i2= pbf.PBFInfill(op_mea, 0.1, 0.1);            // hatch offset=0.1mm, space=0.1mm
    pbf.PBFProcess(op_i2, 0.135, 1000, 0.08);               // meander infill power=0.120kw, speed=500mmps, beam=0.08mm 
    pbf.PBFIdentificationMinAreaPutMM2(down, 0.04);         // minimum size allowed for region

    pbf.PBFMaterialSet("melt pool", "melt 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 operation_count = pbf.PBFTwodOperationCount();
    for (int rc = 0; rc < operation_count; rc++)
    {
        long op2d = pbf.PBFTwodOperationGet(rc);
        long iden = pbf.PBFTwodOperationIdentificationGet(op2d);
        String type = pbf.PBFIdentificationTypeGet(iden);
        if (type == "core")
        {
            Console.WriteLine("Identification " + (rc + 1) + " is core:");
        }
        else if (type == "downskin")
        {
            double down_angle = pbf.PBFIdentificationDownskinAngleGetDeg(iden);
            long layer_count = pbf.PBFIdentificationLayerCountGet(iden);
            double min_area = pbf.PBFIdentificationMinAreaGetMM2(iden);
            Console.WriteLine("Identification" + (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.PBFIdentificationDownskinAngleGetDeg(iden);
            long layer_count = pbf.PBFIdentificationLayerCountGet(iden);
            double min_area = pbf.PBFIdentificationMinAreaGetMM2(iden);
            Console.WriteLine("Identification " + (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:");
        }

        string op_type = pbf.PBFTwodOperationTypeGet(op2d);
        if (op_type == "stripe")
        {
            double width = pbf.PBFStripeWidthGetMM(op2d);
            double overlap = pbf.PBFStripeOverlapGetMM(op2d);
            Console.WriteLine("Stripe:");
            Console.WriteLine("\tWidth = " + width + "mm, Overlap = " + overlap + " mm");
        }
        else if (op_type == "chess")
        {
            double width = pbf.PBFChessWidthGetMM(op2d);
            double length = pbf.PBFChessLengthGetMM(op2d);
            Console.WriteLine("Chess:");
            Console.WriteLine("\tWidth = " + width + "mm" + "Length = " + length + " mm");
        }
        else if (op_type == "meander")
        {
            Console.WriteLine("Meander:");
        }
        else
            Console.WriteLine("\tNO OPERATION DEFINED REGION");

        long op1d_count = pbf.PBFOnedOperationCount(op2d);
        for (long j = 0; j < op1d_count; j++)
        {
             long op1d = pbf.PBFOnedOperationGet(op2d, j);
             String oned_type = pbf.PBFOnedOperationTypeGet(op1d);
             if (oned_type == "hatch")
             {
                long fill = op1d;
                double space = pbf.PBFInfillSpaceGetMM(fill); // REG or INFILL
                double offset = pbf.PBFInfillOffsetGetMM(fill);
                Console.WriteLine("Infill:");
                Console.WriteLine("\tSpace = " + space + " mm offset = " + offset + " mm");

                if (pbf.PBFProcessTechnologyGet(fill) != 0)
                {
                    double power = pbf.PBFProcessPowerGetKW(fill);
                    double diameter = pbf.PBFProcessDiameterGetMM(fill);
                    double speed = pbf.PBFProcessSpeedGetMMPS(fill);
                    Console.WriteLine("\tPower = " + power + "kw speed = " + speed + " mmps diameter = " + diameter + "mm");
                }
                else
                    Console.WriteLine("\tNO FILL TECHNOLOGY");
             }
             else if (oned_type == "contour")
             {
                Console.WriteLine("Contour:");
                long cn = op1d;
                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");
             }
             else
                Console.WriteLine("Unknow oned process: " + oned_type);
        }
        Console.WriteLine();
    }
}
Print Example 1

Print Example 2

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

Related Functions

Common Errors

PBFCoreIdentification()/PBFDownskinIdentification()/PBFUpskinIdentification()

System::Int64 PBFCoreIdentification (
	);

System::Int64 PBFDownskinIdentification (
	double high_above_angle_degree,
	System::Int64 layer_count
	);

System::Int64 PBFUpskinIdentification (
	double high_below_angle_degree,
	System::Int64 layer_count
	);

Three kinds of identifications can be defined. The core identification identifies the process used for the majority of the part. The downskin identification describe the process for surfaces that overhang. The upskin identification describes the process for surfaces at the top of the part. For many parts there will only be a core identification. A downskin 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

Related Functions

PBFStripe()

System::Int64 PBFStripe (
        System::Int64 identification,	
        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

identification
The identity of the region being filled.
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

Related Functions

Common Errors

PBFChess()

System::Int64 PBFChess (
        System::Int64 identification,	
        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

identification
The identity of the region being filled.
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

Related Functions

Common Errors

PBFMeander()

System::Int64 PBFMeander (
        System::Int64 identification
	);

The PBFMeander() function defines a region that is filled without making any stripes or chess squares.

Arguments

identification
The identity of the region being filled.

Result

Related Functions

Common Errors

PBFInfill()

System::Int64 PBFInfill (
        System::Int64 stripe_or_chess_or_meander_id,
        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

stripe_or_chess_or_meander id
The identity of the operation being filled.
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

Related Functions

Common Errors

PBFContour()

System::Int64 PBFContour() (
        System::Int64 stripe_or_chess_or_meander_id,	
        double offset_mm 
	);

The PBFContour() 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.

Arguments

stripe_or_chess_or_meander id
The identity of the operation being contoured.
offset
An offset between the part edge and the contour. The area of the offset is filled by the contour.

Result

Related Functions

Common Errors

PBFProcess()

System::Int64 Additive::PBFProcess (
        System::Int64 infill_or_contour_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

infill_or_contour_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

Related Functions

Common Errors

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

Related Functions

Common Errors

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

Related Functions

Common Errors

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

Related Functions

Common Errors

PBFTwodOperationGet()

System::Int64 PBFTwodOperationGet (
	System::Int64 index
	);
System::Int64 PBFTwodOperationCount (
	System::Int64 index
	);
System::String^ PBFTwodOperationTypeGet (
	System::Int64 index
	);
System::String^ PBFIdentificationTypeGet (
	System::Int64 op2d_id
	);

The PBFTwodOperationGet() function returns each of the operations that fill a slice. The PBFTwodOperationCount() function returns the number of operations that have been defined to fill a slice. The PBFTwodOperationAll() function returns all of the operations in a list.

The PBFTwodOperationTypeGet() function returns one of the followong types for each of the operations.

"stripe"
If the operation defines a striping solution.
"chess"
If the operation defines a chessing solution.
"meander"
if the operation defines a meandering solution.

The PBFIdentificationTypeGet() function returns one of the following types for each of the operations.

"core"
If the operation defines a solution for the core region.
"inskin"
If the operation defines a solution for an inskin region.
"upskin"
If the operation defines a solution for an upskin region.

Arguments

index
Index into the list of operations.
op2d_id
Identifier for one of the solutions.

Result

Related Functions

Common Errors

PBFOnedOperationGet()

System::Int64 PBFOnedOperationGet (
	System::Int64 op2d_id,
	System::Int64 index
	);
System::Int64 PBFOnedOperationCount (
	System::Int64 op2d_id,
	System::Int64 index
	);
System::String^ PBFOnedOperationTypeGet (
	System::Int64 op2d_id,
	System::Int64 index
	);

A region is filled by a list of operations that define hatch and contour processes. The PBFOnedOperationGet() function returns one of the operations. The PBFOnedOperationCount() function returns the number of processes that have been defined to fill a region. The PBFOnedOperationAll() function returns all the operations in a list.

The PBFOnedOperationTypeGet() function returns one of the followong types for each of the operations.

"hatch"
If the operation defines a hatch process.
"contour"
If the operation defines a contour process.

Arguments

op2d_id
Identifier for one of the regions.
index
Index into the list of operations.

Result

Related Functions

Common Errors