Share

Variables in macros

You can create variables in macros just as you can in a PowerMill project. When you create a variable in a macro, it has the same properties as a PowerMill parameter, and can store either a value or an expression.

Note: There are some restrictions on the use of macro variables.
  • Variable names must start with an alphabetic character (a-z, A-Z) and may contain any number of subsequent alphanumeric characters (a-z, A-Z, 1-9, _). For example, you can name a variable Count1 but not 1Count.

  • Variable names are case insensitive. For example, Count, count, and CoUnT all refer to the same variable.

  • All variables must have a type, which can be:

    INT — Integer numbers. For example, 1, 21, 5008.

    REAL — Real numbers. For example, 201, -70.5, 66.0.

    STRING — A sequence of characters. For example, hello.

    BOOL — Truth values, either 0 (false) or 1 (true).

    ENTITY — A unique value that references an existing PowerMill entity.

    Object — A collection of parameters that PowerMill groups together, such as Block, or Connections.

  • You must declare the variable type, for example:

      INT Count = 5
      REAL Diameter = 2.5
      STRING Tapefile = "MyFile.tap"
  • You can access any of the PowerMill parameters in variable declarations, expressions, or assignments.

  • Any variables you create in a macro are only accessible from within the macro. When the macro has finished the variable is no longer accessible and cannot be used in expressions or other macros.

  • If you need to create a variable that can be used at any time in a PowerMill project then you should create a User Parameter.

Assigning parameters

When you assign a value to a variable the expression is evaluated and the result is assigned, the actual expression is not retained. This is the same as using the EVAL modifier in the PowerMill parameter EDIT PAR command. These two statements are equivalent:

EDIT PAR "Stepover" EVAL "Tool.Diameter * 0.6"
$Stepover = Tool.Diameter * 0.6
Note: Variable and parameter names may optionally be prefixed with a $ character. In most cases, you can omit the $ prefix, but it MUST be used when you assign a value to either a variable or parameter within a macro.

Inputting values into macros

An input dialog enables you to enter specific values into a macro.

The basic structure is:

$<variable> = INPUT <string-prompt>

This displays an input dialog with a specified prompt as its title which enables you to enter a value.

Note: If you add an input dialog you should consider adding an error function to check the value entered is reasonable.

For example:

string prompt = "Enter a number"
    $i = input $prompt
    $err = ERROR i
    }

produces this dialog:

image

You can also use INPUT in the variable definition.

For example:

REAL X = INPUT "Enter a number"

Asking a Yes/No question

A Yes/No query dialog is a very simple dialog.

Selecting Yes assigns 1 to the variable.

Selecting No assigns 0 to the variable.

The basic structure is:

$<variable> = QUERY <string-prompt>

For example:

string yesnoprompt = "You entered 5. Would you like to have another go?"
bool carryon = 0
$carryon = query $yesnoprompt

produces this dialog:

image

Creating a message dialog

There are three types of message dialogs:

  • Information dialogs

  • Warning dialogs

  • Error dialogs

The basic structure is:

MESSAGE INFO|WARN|ERROR <expression>

For example, an input dialog to enter a number into a macro:

real i = 3
string prompt = "Enter a number"
do {
    bool err = 0
    do {
        $i = input $prompt
        $err = ERROR i
        if err {
            $prompt = "Please 'Enter a number'"
        }
    } while err
    string yesnoprompt = "You entered " + string(i) + ". Would you like to have another go?"
    bool carryon = 0
    $carryon = query $yesnoprompt
} while $carryon
message info "Thank you!"

An example to find out if a named toolpath exists:

string name = ""
$name = input "Enter the name of a toolpath"
if pathname('toolpath',name) == "" {
    message error "Sorry. Couldn't find toolpath " + name
} else {
    message info "Yes! Toolpath " + name + " exists!"
}

Carriage return in dialogs

You can specify a carriage return to control the formatting of the text in a message dialog using crlf.

For example, looking at the input dialog to enter a number into a macro:

real i = 3
string prompt = "Enter a number"
do {
    bool err = 0
    do {
        $i = input \$prompt
        $err = ERROR i
        if err {
            $prompt = "Please 'Enter a number'"
        }
    } while err
    string yesnoprompt = "You entered " + string(i) + "." + crlf + " Would you like to have another go?"
    bool carryon = 0
    $carryon = query $yesnoprompt
} while $carryon
message info "Thank you!"

produces this query dialog:

image

User selection of entities in macros

Use the INPUT command to prompt the user to select a specific entity in PowerMill, such as a toolpath or a tool. You can use this to:

  • Display a list of available entities

  • Prompt the user to select one of them.

For example, to list all the available tools and then ask the user to select one:

STRING ToolName = INPUT ENTITY TOOL "Please select a Tool."
Note: This command returns the name of the tool the user selected.

This example creates two folders, creates two tool in each folder, then asks the user to select one of the tools:

// Create some tools in folders
CREATE FOLDER 'Tool' 'Endmills'
CREATE IN 'Tool\\Endmills' TOOL 'End 20' ENDMILL
EDIT TOOL ; DIAMETER 20
CREATE IN 'Tool\\Endmills' TOOL 'End 10' ENDMILL
EDIT TOOL ; DIAMETER 10
CREATE FOLDER 'Tool' 'Balls'
CREATE IN 'Tool\\Balls' TOOL 'Ball 12' BALLNOSED
EDIT TOOL ; DIAMETER 12
CREATE IN 'Tool\\Balls' TOOL 'Ball 10' BALLNOSED
EDIT TOOL ; DIAMETER 10
// Prompt user to pick one
STRING ToolName = ''
$ToolName = INPUT ENTITY TOOL "Please select a Tool."

You can also ask for the selection of a number of entities. The result is the list of entities selected, which can be assigned to either a list of strings, or list of entities.

ENTITY LIST $Selected_Toolpaths = INPUT ENTITY MULTIPLE toolpath "which toolpaths do you want to check?"
STRING LIST ToolpathNames = INPUT ENTITY MULTIPLE TOOLPATH "Select toolpaths to check"

You can then iterate over the user selection with a FOREACH loop:

FOREACH $tp in ToolpathNames {
    ACTIVATE TOOLPATH \$tp.Name
    EDIT COLLISION APPLY
}

User selection from a list of options

You can use the INPUT command to prompt the user to select from a list of options that your macro supplies. The syntax for this is:

INT value = INPUT CHOICE <string-array> <prompt>

For example, suppose you have a machining macro where everything is setup except that you want to give the user the choice of cut direction to use. You can do this by using a CHOICE input as follows:

// Create an array of strings from the CutDirection parameter
    STRING ARRAY Opts[] = values(CutDirection)
        INT C = INPUT CHOICE $Opts "Choose the Cut Direction you want"
    $CutDirection = $C
}

Or for another example, you can increase or decrease the number of options the user can select. You can limit the options available to only one, such as Gouge Check or Collision Check a toolpath, or you can increase the options available so the user can choose between the two options. To create this list, enter the following:

STRING ARRAY Opts[] = {"Gouge check only", "Collision check only", "Gouge and Collision check"} INT C = INPUT CHOICE $Opts "Pick an option"
SWITCH $C {
    CASE 0:
        MACRO "Gouge_Check.mac"
        BREAK
    CASE 2:
        MACRO "Gouge_Check.mac"
        // Intended fall through to next command
    CASE 1:
        MACRO "Collision_Check.mac"
        BREAK
}
Note: The above example uses the 'fall through' behavior of cases within a switch block. If you are not used to using the switch statement you can use an IFELSE statement instead:
IF $C==0 {
    MACRO "Gouge_Check.mac"
} ELSEIF $C==1 {
    MACRO "Collision_Check.mac"
} ELSEIF $C==2 {
    MACRO "Gouge_Check.mac"
    MACRO "Collision_Check.mac"
}

User selection of a file name

You can prompt your user for a filename with Use the FILESELECT command to prompt the user for a file name. This command displays an Open dialog which enables user to browse for a file.

For example:

STRING Filename = ''
$Filename = FILESELECT "Please select a pattern file"

Arrays and lists

Arrays

In addition to simple variables of type INT, REAL, or STRING you can also have arrays of these types. When you declare an array you must initialise all of its members using an initialisation list. When you have specified an array you cannot change its size. The syntax for an array is:

BASIC-TYPE ARRAY name[n] = {…}

For example, to declare an array of three strings:

STRING ARRAY MyArray[3] = {'First','Second','Third'}

All the items in the initialisation list must be the same BASIC-TYPE as the array.

You can access the items of the array by subscripting. The first item in the array is subscript 0. For example:

INT Index = 0
WHILE Index < size(MyArray) {
    PRINT MyArray[Index]
    $Index = Index + 1
}

Prints:

First

Second

Third

If you leave the size of the array empty, then PowerMill determines its size from the number of elements in the initialisation list. For example:

STRING ARRAY MyArray[] = 
{'First','Second','Third','Fourth'}
PRINT = size(MyArray)

Prints:

4

Lists

PowerMill also has a LIST type. The main difference between a list and an array is that the list does not have a fixed size, so you can add and remove items to it. You can create lists:

  • that are empty to start with

  • from an initialisation list

  • from an array.

      // Create an empty list
      STRING LIST MyStrings = {}
      // Create a list from an array
      STRING LIST MyList = MyArray
      // Create a list using an initialisation list
      STRING LIST MyListTwo = {'First','Second'}

You can use two inbuilt functions add_first() and add_last() to add items to a list.

For example using the inbuilt function add_last():

CREATE PATTERN Daffy
CREATE PATTERN Duck
// Create an empty list of strings
STRING LIST Patterns = {}
FOREACH pat IN folder('Pattern') {
    // Add the name of the pattern to the list
    int s = add_last(Patterns, pat.Name)
}
FOREACH name IN Patterns {
    PRINT = $name
}

Prints:

Daffy

Duck

You can also add items to the front of a list by using the inbuilt function add_first():

CREATE PATTERN Daffy
CREATE PATTERN Duck
// Create an empty list of strings
STRING LIST Patterns = {}
FOREACH pat IN folder('Pattern') {
    // Add the name of the pattern to the list
    int s = add_first(Patterns, pat.Name)
}
FOREACH name IN Patterns {
    PRINT = $name
}

Prints:

Duck

Daffy

Using lists

A list, like an array, contains multiple values. You can create a list with initial values:

INT LIST MyList = {1,2,3,4}
Note: Unlike an ARRAY, you do not use the [] syntax.

You can specify an empty list:

INT LIST MyEmptyList = {}

You can use lists anywhere you might use an array. For instance, you can use a list in a FOREACH loop:

FOREACH i IN MyList {
    PRINT = i
}

or to initialise an array:

INT ARRAY MyArray[] = MyList

You can also use an array to initialise a list:

INT LIST MyList2 = MyArray

You can pass a list to macro functions that expect an array:

FUNCTION PrintArray(INT ARRAY MyArray) {
    FOREACH i IN Myarray {
        PRINT = i
    }
}

FUNCTION Main() {
    INT LIST MyList = {10,20,30,40}
    CALL PrintArray(MyList)
}

You can access the elements of a list with a FOREACH loop, or you can use the array subscripting notation:

INT Val = MyList[2]

Adding items to a list summary

The main differences between a list and an array is that a list can have items added to it and removed from it.

To add an item to a list you can use either of the inbuilt functions add_first() or add_last().

For example, to collect the names of all the toolpaths in a folder:

// Create an empty list
STRING LIST TpNames = {}

FOREACH tp IN folder('Toolpath\\MyFolder') {
    INT Size = add_last(TpNames, tp.name)
}

For more information see Adding comments to macros.

Removing items from a list summary

The main differences between a list and an array is that a list can have items added to it and removed from it.

To remove an item from a list you can use either of the inbuilt functions remove_first() or remove_last().

For example, if you have a list of toolpath names some of which are batched and you want to ask the user whether they want them calculated now. You can use a function which removes calculated toolpaths from the list and creates a query message for the rest.

FUNCTION CalculateNow(STRING LIST TpNames) {
    // Cycle through the list
    FOREACH Name IN TpNames {
        IF entity('toolpath',Name).Calculated {
            // Toolpath already calculated so
            // remove name from list
            BOOL success = remove(TpNames,Name)
        }
    }
    // Do we have any names left
    IF size(TpNames) > 0 {
        // Build the prompt string
        STRING Msg = "These toolpaths are uncalculated"
        FOREACH name IN TpNames {
            $Msg = Msg + CRLF + name
        }
        $Msg = Msg + CRLF + "Do you want to calculate them now?"
        // Ask the user if they want to proceed
        bool yes = 0
        $yes = QUERY \$msg
        IF yes {
            // Loop through the toolpaths and calculate them
            WHILE size(TpNames) > 0 {
                STRING Name = remove_first(TpNames)
                ACTIVATE TOOLPATH $Name
                EDIT TOOLPATH ; CALCULATE
            }
        }
    }
}

You could use a FOREACH loop rather than a WHILE loop:

FOREACH Name IN TpNames {
    ACTIVATE TOOLPATH \$Name
    EDIT TOOLPATH ; CALCULATE
}

PowerMill has an inbuilt function which enables you to remove duplicate items from a list: remove_duplicates. For example, to determine how many different tool diameters there are in your toolpaths you could add the tool diameters from each toolpath and then remove the duplicates:

REAL LIST Diameters = {}
FOREACH tp IN folder('toolpath') {
    INT s = add_first(Diameters, tp.Tool.Diameter)
}
INT removed = remove_duplicates(Diameters)

For more information, see Removing items from a list or Removing duplicate items in a list.

Building a list

You can use the inbuilt member() function in a macro function to build a list of tool names used by toolpaths or boundaries without any duplicates:

FUNCTION ToolNames(STRING FolderName, OUTPUT STRING LIST ToolNames) {

    // loop over all the items in FolderName
        FOREACH item IN folder(FolderName) {

        // Define local working variables
        STRING Name = ''
        INT size = 0

        // check that the item's tool exists
        // it might not have been set yet
        IF entity_exists(item.Tool) {
            // get the name and add it to our list
            $Name = item.Tool.Name
            IF NOT member(FolderName, Name) {
                $dummy = add_last(FolderName, Name)
            }
        }

        // Check whether this item has a reference tool
        // and that it has been set
        IF active(item.ReferenceTool) AND entity_exists(item.ReferenceTool) {
            // get the name and add it to our list
            $Name = item.ReferenceTool.Name
            IF NOT member(FolderName, Name) {
                $dummy = add_last(FolderName, Name)
            }
        }
    }
}

As this function can work on any toolpath or boundary folder, you can collect all the tools used by the toolpaths in one list and all of the tools used by boundaries in another list. You can do this by calling the macro function twice:

STRING LIST ToolpathTools = {}
STRING LIST BoundaryTools = {}
CALL ToolNames('Toolpath',ToolpathTools)
CALL ToolNames('Boundary',BoundaryTools)

To return a list containing the items from both sets with any duplicates removed:

STRING LIST UsedToolNames = set_union(ToolpathTools, BoundaryTools)

Subtract function

You can use the subtract() function to determine what happened after carrying out a PowerMill command. For example, suppose you to find out if any new toolpaths are created during a toolpath verification. If you get the list of toolpath names before the operation, and the list of names after the operation, and then subtract the ‘before’ names from the ‘after’ names you are left with the names of any new toolpaths.

FUNCTION GetNames(STRING FolderName, OUTPUT STRING LIST Names) {
    FOREACH item IN folder(FolderName) {
        INT n = add_last(Names, item.Name)
    }
}

FUNCTION Main() {

    STRING LIST Before = {}
    CALL GetNames('toolpath',Before)

    EDIT COLLISION APPLY

    STRING LIST After = {}
    CALL GetNames('toolpath',After)
    STRING LIST NewNames = subtract(After, Before)

    IF is_empty(NewNames) {
        PRINT "No new toolpaths were created."
        } ELSE {
        PRINT "The new toolpaths created are:"
        FOREACH item IN NewNames {
            PRINT = item
        }
    }
}

Entity variables

PowerMill has a special variable type ENTITY. You can use ENTITY variables to refer to existing PowerMill entities such as toolpaths, tools, boundaries, patterns, workplanes, and so on. You cannot use this command to create new entities.

For example:

// create an entity variable that references boundary entity 'Duck'
ENTITY Daffy = entity('boundary','Duck')

The inbuilt functions, such as folder() return lists of entities so you can store the result of the call in your own list and array variables:

For example:

ENTITY List Toolpaths = folder('toolpath')

When looping over folder items in a FOREACH the loop variable that is automatically created has the type ENTITY. Therefore the following code is syntactically correct:

FOREACH tp IN folder('toolpath') {
    ENTITY CurrentTP = tp
    PRINT = CurrentTP.Name
}

You can also pass ENTITY variables to functions (and passed back from function) by using an OUTPUT argument:

For example:

FUNCTION Test(OUTPUT ENTITY Ent) {
    $Ent = entity('toolpath','2')
}

FUNCTION Main() {
    ENTITY TP = entity('toolpath','1')
    CALL Test(TP)
    PRINT = TP.Name
}

Additionally, you can use an ENTITY variable anywhere in PowerMill that is expecting an entity name.

For example:

ENTITY tp = entity('toolpath','1')
ACTIVATE TOOLPATH $tp

Object variables

PowerMill has a variable type called OBJECT which can hold any collection of variables that PowerMill pre-defines, such as Block or Connections.

For example:

// Get the current set of block parameters
OBJECT myObject = Block
// Activate a toolpath (this may change the block)
ACTIVATE TOOLPATH "Daffy"
// Reset the block to its old state
$Block = myObject

Whilst you cannot create an ARRAY of OBJECT you can create a LIST of OBJECTs:

For example:

OBJECT LIST myObjects = {Block,Connections}
FOREACH ob IN myObjects {
PRINT PAR "ob"
}

As you can see from the above example, each object in a list may be different. It is the responsibility of the macro writer to keep track of the different types of OBJECT. PowerMill has an inbuilt function get_typename() to help with this.

For example:

OBJECT LIST myObjects = {Block,Connections}
FOREACH ob IN myObjects {
PRINT = get_typename(ob)
}

Which prints:

Block
ToolpathConnections

As with all lists, you can also access the elements by index:

PRINT = get_typename(myObjects[0])
PRINT = get_typename(myObjects[1])

Objects can also be passed to and from macro FUNCTIONs.

For example:

FUNCTION myBlkFunction(OBJECT blk) {
    IF get_typename(blk) != "Block" {
        MESSAGE ERROR "Expecting a Block object"
        MACRO ABORT
    }
    // Code that works on block objects
}
// Find block with maximum zrange
FUNCTION myZrangeBlockFunc(OUTPUT OBJECT Blk) {
    // The
    REAL zrange = 0
    FOREACH tp IN folder('toolpath') {
        // find zlength of this block
        REAL z = tp.Block.Limits.ZMax - tp.Block.Limits.ZMin
        IF z > zrange {
            // Copy if longer than previously
            $Blk = Block
            $zrange = z
        }
    }
}

Vectors and points

In PowerMill vectors and points are represented by an array of three reals.

PowerMill contains point and vector parameters, for example the Workplane.Origin, Workplane.ZAxis, ToolAxis.Origin, and ToolAxis.Direction. You can create your own vector and point variables:

REAL ARRAY VecX[] = {1,0,0}
REAL ARRAY VecY[] = {0,1,0}
REAL ARRAY VecZ[] = {0,0,1}
REAL ARRAY MVecZ[] = {0,0,-1}

REAL ARRAY Orig[] = {0,0,0}

For more information, see the inbuilt Vectors and points functions.

Comparing variables

Comparing variables enables you to check information and defines the course of action to take when using IF statements and WHILE statements.

The result of a comparison is either true or false. When true the result is 1, when false the result is 0.

A simple comparison may consist of two variables with a relational operator between them:

Relational operator Description
Symbol Text
== EQ is equal to
!= NE is not equal to
< LT is less than
<= LE is less than or equal to
> GT is greater than
>= GE is greater than or equal to
Note: You can use either the symbol or the text in a comparison.

For example,

BOOL C = (A == B)

is the same as:

BOOL C = (A EQ B)

C is assigned 1 (true) if A equals B and . If A does not equal B, then C is 0 (false).

Note: The operators = and == are different. The single equal operator, =, assigns the value on the right-hand side to the left-hand side. The double equals operator, ==, compares two values for equality.

If you compare the values of two strings, you must use the correct capitalisation.

For example, if you want to check that the tool is an end mill, then you must use:

Tool.Type == 'end_mill'

and not:

Tool.Type == 'End_Mill

If you are unsure about the case of a string then you can use one of the inbuilt functions lcase() or ucase() to test against the lower case or upper case version of the string:

lcase(Tool.Type) == 'end_mill'
ucase(Tool.Type) == 'END_MILL'

For example, comparing variables:

BOOL bigger = (Tool.Diameter+Thickness
>=ReferenceToolpath.Tool.Diameter+ReferenceToolpath.Thickness)

gives a result of 1 (true) when the Tool.Diameter + Thickness is greater than or equal to the ReferenceToolpath.Tool.Diameter + ReferenceToolpath.Thickness and a result of 0 (false) otherwise.

Logical operators

Logical operators let you to do more than one comparison at a time. There are four logical operators:

  • AND

  • OR

  • XOR

  • NOT

Note: Remember the result of a comparison is either true or false. When true, the result is 1; when false, the result is 0.

Using the logical operator AND

The result is true (1) if all operands are true, otherwise the result is false (0).

Operand 1 Operand 2 Operand 1 AND Operand 2
true (1) true (1) true (1)
true (1) false (0) false (0)
false (0) true (1) false (0)
false (0) false (0) false (0)

Using the logical operator OR

The result is true (1) if at least one operand is true. If all the operands are false (0) the result is false.

Operand 1 Operand 2 Operand 1 OR Operand 2
true (1) true (1) true (1)
true (1) false (0) true (1)
false (0) true (1) true (1)
false (0) false (0) false (0)

Using the logical operator XOR

The result is true (1) if exactly one operand is true. If all the operands are false the result is false (0). If more than one operand is true the result is false (0).

Operand 1 Operand 2 Operand 1 XOR Operand 2
true (1) true (1) false (0)
true (1) false (0) true (1)
false (0) true (1) true (1)
false (0) false (0) false (0)

Using the logical operator NOT

The result is the inverse of the input.

Operand 1 NOT Operand 1
true (1) false (0)
false (0) true (1)

Advance variable options

Scratchpad variables

It is possible to create and manipulate variables in the command line window. These are called scratchpad variables as you can use them to test the results of parameter evaluation without having to write a macro.

For example, to test some code, in the command line window type:

STRING Test = Tool.Name
DEACTIVATE TOOL
ACTIVATE TOOL $Test

image

To clear the scratchpad, in the command line window type:

RESET LOCALVARS

If you do not issue the RESET LOCALVARS command, the local variable, Test, remains defined until you exit from PowerMill.

Using variables and parameters in macro commands

You can substitute the value of a variable or parameter in a command wherever the command expects a number or a string. To do this, prefix the variable or parameter name with a $.

Note: The EDIT PAR command only accepts $variable input when the $variable has a numeric value. You cannot use the $variable syntax for STRING parameters.

For example, to create a tool with a diameter that is half that of the active tool.

// Calculate the new diameter and name of tool
REAL HalfDiam = Tool.Diameter/2
STRING NewName = string(Tool.Type) + " D-" + string(HalfDiam)

// Create a new tool and make it the active one
COPY TOOL ;
ACTIVATE TOOL #

// Now rename the new tool and edit its diameter
RENAME TOOL ; $NewName
EDIT TOOL $NewName DIAMETER $HalfDiam

This creates a tool with half the diameter.

Scope of variables

A variable exists from the time it is declared until the end of the block of code within which it is declared. Blocks of code are macros and control structures (WHILE, DO - WHILE, SWITCH, IF-ELSEIF-ELSE, and FOREACH).

A variable, with a specific name, can only be defined once within any block of code.

For example,

// Define a local variable 'Count'
INT Count = 5
// Define a second local variable 'Count'
INT Count = 2

Gives an error since Count is defined twice.

However, within an inner block of code you can define another variable with the same name as a variable (already defined) in an outer block:

INT Count = 5
IF Count > 0 {
    // Define a new local variable 'Count'
    INT Count = 3
    // Print 3
    PRINT $Count
// The local Count is no longer defined
}
// Print 5
PRINT $Count

A variable defined within an inner block of code hides any variable declared in an outer block. This is also important if you use a name for a variable which matches one of PowerMill’s parameters. For example, if the toolpath stepover is 5 and in your macro you have:

// 'Hide' the global stepover by creating your own variable
REAL Stepover = 2
// Print Stepover
PRINT $Stepover

The value printed is 2 not 5, and the toolpath stepover value is unchanged. To access the current toolpath's stepover parameter you must use toolpath.Stepover.

// 'Hide' the global stepover by creating your own variable
REAL Stepover = 2
// Print 2
PRINT $Stepover
// Print the value of the toolpath's stepover - which is 5
PRINT $toolpath.Stepover
Note: As macro variables cease to exist at the end of a macro or block of code, you should not use a variable defined in a macro within a retained expression. You can use assignments, as the value is computed immediately. Do not use a macro variable in an EDIT PAR expression without EVAL as this causes an expression error when PowerMill tries to evaluate it.
REAL Factor = 0.6
// The next two commands are OK as the expression is evaluated immediately.
$Stepover = Tool.Diameter * Factor
EDIT PAR "Stepover" EVAL "Tool.Diameter * Factor"
// The next command is not OK because the expression is retained.
EDIT PAR "Stepover" "Tool.Diameter * Factor"

The Factor variable ceases to exist at the end of the macro, so Stepover evaluates as an error.

Was this information helpful?