Delcam - PowerMILL 2017 MacroProgramming - 2016
Delcam - PowerMILL 2017 MacroProgramming - 2016
Index 125
Creating macros
You can create macros by:
Recording (see page 2) a sequence of commands within
PowerMill.
Writing your own macro (see page 5) using a text editor.
Editing macros
You can edit recorded macros to troubleshoot and correct any
errors.
1 Expand Macros and select the macro you want to edit.
Basic macro
This shows you how to create and run a basic macro using
PowerMill's programming language.
1 In a text editor such as WordPad enter:
PRINT "10 green bottles sitting on the wall"
PRINT "10 green bottles sitting on the wall"
PRINT "And if 1 green bottle should accidentally fall"
10 • Macro Programming
You must define all local variables before they are used, in this
case STRING bottles = "10 green bottles sitting on the
wall" defines the local variable bottles.
The variable bottles is a local variable, so is only valid within the
macro where it is defined. It is not a PowerMill variable. Typing it
into the command window gives an error.
When you have defined a local variable you can use it as many
times as you want in a macro.
You can define as many local variables as you want in a macro.
The empty lines are not necessary, but they make it easier
to read the macro.
2 Save the file as example.mac.
3 In PowerMill, Run the Macro. The command windows displays:
12 • Macro Programming
// Print the last two lines
PRINT "If 1 green bottle should accidentally fall"
PRINT "There will be 9 green bottles sitting on the
wall"
}
2 Save the file as example.mac.
3 To run the macro you cannot select Run from the Macro context
menu, as you need to give a value for Count. Therefore, in the
command window type:
MACRO example.mac 5
Where 5 is the value for Count. The command windows displays:
DO - WHILE loop
1 Edit the PrintBottles function in example.mac to
14 • Macro Programming
FUNCTION PrintBottles(INT Count) {
IF statement
You can use an IF statement to ensure the 10 green bottles sitting on
the wall line is printed at least twice.
1 Edit the Main function in example.mac to:
FUNCTION Main (INT Count) {
16 • Macro Programming
// Print the line
PRINT $bottles
// Reduce the count by 1
$Count = Count - 1
}
}
This adds a second argument to the PrintBottles function. It then
uses a parameter function to convert the Number to a string
value, STRING (Number). It is then concatenated (+)with green
bottles sitting on the wall to make up the bottles string.
2 Edit the Main function in example.mac to:
FUNCTION Main (INT Count) {
// Make sure that Count is at least two
IF Count < 2 {
$Count = 2
}
18 • Macro Programming
BREAK
CASE 1
$Text = "One"
BREAK
DEFAULT
$Text = "No"
BREAK
}
The switch statement matches the value of its argument (in this
case Number) with a corresponding case value and executes all the
subsequent lines until it encounters a BREAK statement. If no
matching value is found the DEFAULT is selected (in this case No).
Each code block or function can define its own set of local
variables; the scope of the variable is from its declaration
to the end of the enclosing block or function.
4 Add the NumberStr function into example.mac.
FUNCTION PrintBottles(INT Count, INT Number) {
20 • Macro Programming
WHILE Count > 0 {
// Print the line
PRINT $bottles
// Reduce the count by 1
$Count = Count - 1
}
}
22 • Macro Programming
}
24 • Macro Programming
DEFAULT
$Text = "No"
BREAK
}
}
This gives exactly the same output as the Returning values from
macros (see page 19) example. It shows you an alternative way
of creating the same output.
This gives exactly the same output as the Returning values from
macros (see page 19) example. It shows you an alternative way
of creating the same output.
26 • Macro Programming
CREATE BOUNDARY ; SELECTED
STRING Msg = "Select surfaces for boundary, and
press"+crlf+"RESUME when ready to continue"
EDIT BLOCK RESET
MACRO PAUSE $Msg
EDIT BOUNDARY ; CALCULATE
If you do not enter a string after MACRO PAUSE the macro pauses
but does not display a RESUME dialog. To resume the macro either
type MACRO RUN or provide another mechanism to continue the
macro.
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.
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
28 • Macro Programming
REAL X = INPUT "Enter a number"
For more information see User selection of entities in macros (see
page 31).
30 • Macro Programming
produces this query dialog:
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:
32 • Macro Programming
} ELSEIF $C==1 {
MACRO "Collision_Check.mac"
} ELSEIF $C==2 {
MACRO "Gouge_Check.mac"
MACRO "Collision_Check.mac"
}
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
34 • Macro Programming
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}
FUNCTION Main() {
INT LIST MyList = {10,20,30,40}
CALL PrintArray(MyList)
}
FOREACH tp IN folder('Toolpath\MyFolder') {
INT Size = add_last(TpNames, tp.name)
}
For more information see Adding comments to macros (see page
88).
36 • Macro Programming
$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 (see page 88)
or Removing duplicate items in a list (see page 87).
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) {
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)
38 • Macro Programming
}
}
FUNCTION Main() {
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
}
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 a 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)
40 • Macro Programming
}
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
}
}
}
42 • Macro Programming
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
(see page 81) or upper case (see page 80) 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.Thick
ness)
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
44 • Macro Programming
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.
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.
46 • Macro Programming
// 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.
// Assignments
$Stepover = Tool.Diameter * factor
$factor = 0.75
Operator precedence
The order in which various parts of an expression are evaluated
affects the result. The operator precedence unambiguously
determines the order in which sub-expressions are evaluated.
Multiplication and division are performed before addition and
subtraction.
For example, 3 * 4 +2 is the same as 2 + 3 * 4 and gives the
answer 14.
Exponents and roots are performed before multiplication and
addition.
For example, 3 + 5 ^ 2 is the same as 3 + 5 and gives the
answer 28.
-3 ^ 2 is the same as -3 and gives the answer -9.
Use brackets (parentheses) to avoid confusion.
For example, 2 + 3 * 4 is the same as 2 + (3 * 4) and gives the
answer 14.
48 • Macro Programming
Parentheses change the order of precedence as terms inside in
parentheses are performed first.
For example, (2 + 3) * 4 gives the answer 20.
or, (3 + 5) ^2 is the same as (3 + 5) and gives the answer 64.
You must surround the arguments of a function with
parentheses.
For example, y = sqrt(2), y = tan(x), y = sin(x + z).
Relational operators are performed after addition and
subtraction.
For example, a+b >= c+d is the same as (a+b) >= (c+d).
Logical operators are performed after relational operators,
though parentheses are often added for clarity.
For example:
5 == 2+3 OR 10 <= 3*3
is the same as:
(5 == (2+3)) OR (10 <= (3*3))
but is normally written as
(5 == 2+3) OR (10 <= 3*3).
Precedence
Order Operation Description
1 () function call, operations
grouped in parentheses
2 [] operations grouped in square
brackets
3 +-! unary prefix (unary operations
have only one operand, such
as, !x, -y)
4 cm mm um ft unit conversion
in th
5 ^ exponents and roots
6 */% multiplication, division, modulo
7 +- addition and subtraction
8 < <= > >= relational comparisons: less
(LT, LE, GT, than, less than or equal,
GE) greater than, greater than or
equal
Examples of precedence:
Expression Equivalent
a*-2 a * (- 2)
!x == 0 (!x) == 0
$a = -b + c * d – e $a = ((-b) + (c * d)) – e
$a = b + c % d – e $a = (b + (c % d)) – e
$x = y == z $x = (y == z)
$x = -t + q * r / c $x = ((-t) + ((q * r) / c))
$x = a % b * c + d $x = (((a % b) * c) + d)
$a = b <= c | d != e $a = ((b <= c) | (d != e))
$a = !b | c & d $a = ((!b) | (c & d))
$a = b mm * c in + d $a = (((b mm) * (c in)) + d)
50 • Macro Programming
If you then want to use the same function to copy a pattern and
then fit arcs to the copy. You can replace all instances of 'boundary'
with 'pattern' when you give the function a pattern entity.
Unfortunately you cannot do this by using variables directly because
the PowerMill command syntax does not allow variable substitution
in network KEYWORDS for example you cannot use $Type like this:
COPY $Type $Ent
However, you can build the command as a string and then use
DOCOMMAND to execute the resulting string as a command:
FUNCTION CopyAndArcFit(Entity Ent) {
STRING $NewName = new_entity_name(Ent.RootType)
STRING Cmd = "COPY "+ Ent.RootType + " " + Ent.name
DOCOMMAND $Cmd
$Cmd = "EDIT " + Ent.RootType + " " + Newname + "
ARCFIT 0.01"
DOCOMMAND $Cmd
}
You can use this technique whenever you find that a variable value
cannot be used in a particular point in a command.
Macro functions
When you run a macro you can use arguments, such as the name
of a toolpath, tool, or a tolerance. You must structure the macro to
accept arguments by creating a FUNCTION called Main (see page
52) then specify the arguments and their type.
For example, a macro to polygonise a boundary to a specified
tolerance is:
FUNCTION Main(REAL tol) {
EDIT BOUNDARY ; SMASH $tol
}
A macro to set the diameter of a named tool is:
FUNCTION Main(
STRING name
REAL diam
)
{
EDIT TOOL $name DIAMETER $dia
}
To run these macros with arguments add the arguments in the
correct order to the end of the MACRO command:
MACRO MyBoundary.mac 0.5
Main function
If a macro has any functions:
It must have one, and only one, FUNCTION called Main.
The Main function must be the first function called.
Function names are not case sensitive: MAIN, main, and MaIn all
refer to the same function.
52 • Macro Programming
Running a macro where the Main function is called with either the
wrong number of arguments or with types of arguments that do not
match, causes an error. For example:
MACRO MyTool.mac 6 "ToolName"
generates an error since the macro expects a string and then a
number, but is given a number and then a string.
If you want to repeat a sequence of commands at different points
within a macro, you can use a FUNCTION.
For example, if you want to remove any small islands that are
smaller than the tool diameter and smooth out any minor kinks
after a boundary calculation. One solution is to repeat the same
commands after each boundary calculation:
EDIT BOUNDARY ; SELECT AREA LT Boundary.Tool.Diameter
DELETE BOUNDARY ; SELECTED
EDIT BOUNDARY ; OFFSET "1 mm"
EDIT BOUNDARY ; OFFSET "-1 mm"
This is fine if you have a macro that creates one boundary, but if it
creates a number of boundaries you end up with a macro with
excessive repetition. However by using a FUNCTION you can define
the sequence once:
FUNCTION CleanBoundary(string name) {
REAL offset = 1 mm
REAL diam = entity('boundary';name).Tool.Diameter
// Delete segments smaller than tool diameter
EDIT BOUNDARY $name SELECT AREA LT $diam
DELETE BOUNDARY $name SELECTED
//Offset outwards and inwards to smooth boundary
EDIT BOUNDARY $name OFFSET $offset
EDIT BOUNDARY $name OFFSET ${-offset}
}
Then call it whenever it is needed:
FOREACH bou IN folder('boundary') {
CALL CleanBoundary(bou.Name)
}
CREATE BOUNDARY Shallow30 SHALLOW
EDIT BOUNDARY Shallow30 CALCULATE
CALL CleanBoundary('Shallow30')
FUNCTION Main() {
REAL Par1 = 2
REAL Par2 = 1
CALL Test(Par1, Par2)
// Prints 2 - value is unchanged
PRINT $Par1
// Prints 0 - value has been changed
PRINT $Par2
}
When the CALL command is executed in the MAIN function:
1 PowerMill creates a new REAL variable called aInput. It is
assigned the value of Par1, and passed into Test.
2 PowerMill passes Par2 directly into Test where it is known as
aOutput.
54 • Macro Programming
Sharing functions between macros
You can share functions between macros by using the INCLUDE
statement. You can put all your common functions in a file which
you then INCLUDE within other macros. For example, if you put the
CleanBoundary function into a file called common.inc you could
rewrite the macro as:
INCLUDE common.inc
FUNCTION Main(input string bound) {
FOREACH bou IN folder(bound) {
CALL CleanBoundary(bou.Name)
}
}
To call this macro from PowerMill:
IF statement
The IF statement executes a series of commands when a certain
condition is met.
The basic control structure is:
IF <expression> {
Commands A
}
Commands B
If expression is true then Commands A are executed, followed by
Commands B.
If expression is false, then only Commands B are executed.
The first brace must be the last item on the line and on the
same line as the IF.
The closing brace must be on a line by itself.
IF - ELSE statement
The IF - ELSE statement executes a series of commands when a
certain condition is met and a different series of commands
otherwise.
The basic control structure is:
IF <expression> {
Commands A
} ELSE {
Commands B
}
Commands C
If expression is true, then Commands A are executed followed by
Commands C.
56 • Macro Programming
If expression is false, then Commands B are executed followed by
Commands C.
SWITCH statement
When you compare a variable with a number of possible values and
each value determines a different outcome, it is advisable to use the
SWITCH statement.
The SWITCH statement enables you to compare a variable against a
list of possible values. This comparison determines which
commands are executed.
The basic control structure is:
58 • Macro Programming
SWITCH variable
{ CASE
(constant_A)
Commands A
CASE (constant_B)
Commands B
DEFAULT
Commands C
}
Commands D
If condition_A is true then Commands A, B, C, and D are executed.
If condition_B is true then Commands B, C, and D are executed.
If condition_A and condition_B are false then Commands C, and D are
executed.
60 • Macro Programming
Running macros without displaying GUI items
The NOGUI statement enables you to use PowerMill modes without
displaying GUI items, for example, toolbars, mode-toolbars, dialogs
or graphics.
To use Workplane macros without displaying GUI items, enter NOGUI
after MODE, for example:
MODE NOGUI WORKPLANE_EDIT START "1"
To use Curve editor macros without displaying GUI items, enter
NOGUI after CURVEEDITOR, for example:
EDIT PATTERN ; CURVEEDITOR NOGUI START
62 • Macro Programming
FOREACH loop
A FOREACH loop repeatedly executes a block of commands for each
item in a list or array.
The basic control structure is:
FOREACH item IN sequence{
Commands A
}
Commands B
where:
item is an automatically created variable that PowerMill initialises
for each iteration of the loop;
sequence is either a list or an array.
Commands A are executed on the first item in the list.
Commands A are executed on the next item in the list. This step is
repeated until there are no more items in the list.
At the end of the list, Commands B are executed.
For example,
FOREACH item IN folder("path") {
Commands A
}
Commands B
Where <path> is a folder in the Explorer such as, Toolpath, Tool, Toolpath\
Finishing.
Within FOREACH loops, you can:
Cancel the loop using the BREAK (see page 66) statement.
Jump directly to the next iteration using the CONTINUE (see page
66) statement.
WHILE loop
A WHILE loop repeatedly executes a block of commands until its
conditional test is false.
The basic control structure is:
WHILE condition {
Commands A
}
Commands B
If condition is true, then Commands A are executed.
While condition remains true, then Commands A are executed.
64 • Macro Programming
When condition is false, Commands B are executed.
DO - WHILE loop
The DO - WHILE loop executes a block of commands and then
performs its conditional test, whereas the WHILE loop checks its
conditional test first to decide whether to execute its commands or
not.
The basic control structure is:
DO {
Commands A
} WHILE condition
Commands B
Commands A are executed.
While condition remains true, then Commands A are executed.
When condition is false, Commands B are executed.
Creating sequences
Use the make_sequence and next_in_sequence functions to create
sequences. Sequences contain:
66 • Macro Programming
a starting value. This defines the first element in the sequence.
an incremental value. This returns the next element in the
sequence.
an optional padding value. This adds extra zeros before the
returned elements .
To create a new sequence, use the make_sequence function. The
basic structure is:
OBJECT make_sequence( int start_value, [, int increment,
int padding])
For example:
OBJECT seq = make_sequence(10, 5, 4)
//Returns a sequence which starts at 10, increments by 5
and is padded by 4 characters:
To increment a value in a specified sequence, use the
next_in_sequence function. The basic structure
is: string next_in_sequence(object sequence)
For example:
OBJECT seq = make_sequence(10, 5, 4)
// Makes a new sequence starting from 10, incremented by
5 and padded to 4 characters
STRING n = next_in_sequence(seq)
// n = "0010"
STRING nn = next_in_sequence(seq)
// nn = "0015"
STRING nnn = next_in_sequence(seq)
// nnn = "0020"
RETURN statement
If a macro contains functions, the RETURN statement immediately
exits the function. If the macro does not contain functions, the
RETURN statement immediately terminates the current macro. This
is useful if an error is detected and you do not want to continue with
the remaining commands in the macro.
The basic control structure is:
EDIT TOOLPATH $tp.Name CALCULATE
IF NOT Computed {
// terminate if toolpath did not calculate
RETURN
}
To immediately exit from a function:
IF NOT active(entity('toolpath',TpName).Tool.TipRadius)
{
// Error if toolpath does not use a tipradius tool
PRINT "Toolpath does not have TipRadius tool"
RETURN
}
FUNCTION Main() {
FOREACH tp IN folder('Toolpath')
{ ACTIVATE TOOLPATH $tp.Name)
}
}
Terminating macros
The command MACRO ABORT immediately terminates the current
macro.
The command MACRO ABORT ALL terminates the all the macros that
are currently running. If you call MACRO ABORT ALL from within a
macro that has been called by another macro, then both macros are
terminated.
68 • Macro Programming
Constants
PowerMill has a small number of useful constant values that you can
use in expressions and macros these include:
REAL PI = 3.141593
REAL E = 2.718282
BOOL TRUE = 1
BOOL FALSE = 0
STRING CRLF = newline
Use these values to make your macros more readable. For example,
use CRLF constant to build up multi-line messages and prompts:
STRING msg = "This is line one."+CRLF+"This is line two."
MESSAGE INFO $msg
Displays the message:
This is line one.
This is line two.
Built-in functions
This section details all the built-in functions that you can use in your
macros.
General mathematical functions (see page 69).
Trigonometrical functions (see page 70).
Vector and point functions (see page 70).
Workplane functions (see page 73).
String functions (see page 73).
List creation functions (see page 83).
Path functions (see page 93) (Folder (see page 94), Directory
(see page 94), Base (see page 95), and Project (see page 95)
names).
Conditional functions (see page 97).
Evaluation functions (see page 97).
Type conversion functions (see page 99).
Parameter functions (see page 99).
Statistical functions (see page 102).
Trigonometrical functions
The basic structure of the trigonometrical functions are:
Description of return value Function
Trigonometric sine real sin( angle )
70 • Macro Programming
REAL ARRAY VecX[] = {1,0,0}
REAL ARRAY VecY[] = {0,1,0}
REAL ARRAY VecZ[] = {0,0,1}
REAL ARRAY MVecZ[] = {0,0,-1}
Length
The length() function returns the length of a vector.
For example:
REAL ARRAY V[] = {3,4,0}
// Prints 5.0
PRINT = length(V)
The inbuilt function unit() returns a vector that points in the same
direction as the input vector, but has a length of 1:
PRINT PAR "unit(V)"
// [0] (REAL) 0.6
// [1] (REAL) 0.8
// [2] (REAL) 0.0
// prints 1.0
PRINT = length(unit(V))
Parallel
The parallel() function returns TRUE if two vectors are either
parallel (pointing in the same direction) or anti-parallel (pointing in
the opposite direction) to each other.
For example:
// prints 0
PRINT = parallel(VecX,Vecy)
// prints 1
PRINT = parallel(VecX,VecX)
Print = parallel(MVecZ,VecZ)
Normal
The normal() function returns a vector that is normal to the plane
containing its two input vectors. If either vector is zero it returns an
error. If the input vectors are either parallel or anti-parallel a vector
of zero length is returned.
For example:
REAL ARRAY norm = normal(VecX,VecY)
Setting
The set_vector() and set_point() functions return the value 1 if
the vector or point is set.
For example:
REAL ARRAY Vec1[3] = {0,0,1}
REAL ARRAY Vec2[3] = {0,1,0}
REAL X = Block.Limits.XMax
REAL Y = Block.Limits.YMin
REAL Z = Block.Limits.ZMax
ok = set_point(ToolAxis.Origin, X,Y,Z)
Unit vector
The unit() function returns the unit vector equivalent of the given
vector.
For example:
REAL ARRAY V[3] = {3,4,5}
PRINT PAR "unit(V)"
BOOL ok = set_vector(V,0,0,6)
PRINT PAR "unit(V)"
72 • Macro Programming
Workplane functions
You can use the inbuilt function set_workplane() to define the
origin and axis of a workplane entity. You can call the function:
with two workplanes, where the values from the second
workplane are copied into the first:
bool ok =
set_workplane(Workplane,entity('workplane','3'))
which sets the active workplane to have the same values as
workplane 3.
with a workplane, two vectors, and an origin:
REAL ARRAY YAxis[] = {0,1,0}
REAL ARRAY ZAxis[] = {0,0,1}
REAL ARRAY Origin = {10,20,30}
bool ok =
set_workplane(entity('workplane','reference'), YAxis,
Zaxis,Origin)
String functions
PowerMill parameters and variables can contain strings of
characters. There are a number of inbuilt functions that you can use
to test and manipulate strings.
The basic structure of string functions are:
Description of return value Function
Returns the number of int length( string str )
characters in the string.
For more information see
Length function in a string
(see page 78).
Returns the position of the int position( string str,
string target from the start of string target[, numeric
the string str, or -1 if the start] )
target string is not found.
If you use the optional
argument start then scanning
begins from that position in
the string.
For more information see
Position function in a string
(see page 78).
74 • Macro Programming
When you run the macro, the command window displays the result,
One, Two, Three.
String
month The month of the year (01-12)
String
day The day of the month (01-31)
Example
The following example shows how to use the time() function to
measure how long an activity takes:
INT old_time = time()
EDIT TOOLPATH ; CALCULATE
INT cumulative_time = time() - old_time
STRING msg = "Toolpath calculation took " +
(cumulative_time) + "secs"
MESSAGE INFO $msg
Example
Getting and formatting the current time:
INT tm=time()
STRING ARRAY $timestamp[] =
tokens(utc_time($tm).timestamp, "-") STRING clock =
$timestamp[3] + ":" + $timestamp[4] $clock = $clock + ":"
+ $timestamp[5] PRINT $clock
76 • Macro Programming
Returning the user ID string
Use the user_id() function to return the user ID string. This can
save you time when entering pathnames in macros and user menus.
To use the user_id() function:
PRINT PAR $USER_ID()
STRING user = USER_ID()
PRINT $user
Another example:
STRING One = "One"
STRING Two = "Two"
STRING CountToTwo = One + ", " + Two
PRINT = length(CountToTwo)
The command window displays the result, 8.
78 • Macro Programming
For example:
PRINT = position("Scooby doo", "oo")
The command window displays the result, 2. PowerMill finds the first
instance of oo and works out what its position is (S is position 0, c
position 1 and o position 2).
position("Scooby doo", "oo", 4)
The command window displays the result, 8. PowerMill finds the first
instance of oo after position 4 and works out what its position is (b
is position 4, y position 5, " "is position 7 and o position 8).
position("Scooby doo", "aa")
The command window displays the result, -1 as PowerMill cannot
find any instances of aa.
You can use this function to check whether a substring exists within
another string. For example, if you have a part that contains a
cavity and you machined it using various strategies with a coarse
tolerance and each of these toolpaths has CAVITY in its name. You
have toolpaths with names such as, CAVITY AreaClear, CAVITY flats.
To recalculate those toolpath with a finer tolerance use the macro
commands:
// loop over all the toolpaths
FOREACH tp IN folder('Toolpath') {
// if toolpath has 'CAVITY' in its name
IF position(tp.Name, "CAVITY") >= 0 {
// Invalidate the toolpath
INVALIDATE TOOLPATH $tp.Name
$tp.Tolerance = tp.Tolerance/10
}
}
BATCH PROCESS
Substrings
The substring function returns part of the string. You can define
where the substring starts and its length. The original string is
unchanged.
The basic structure is:
string substring( string str, int start, int length)
For example:
PRINT = substring("Scooby doo", 2, 4)
The command window displays the result, ooby.
80 • Macro Programming
The basic structure is:
string ucase( string str)
For example:
PRINT = ucase("Scooby doo")
The command window displays the result, SCOOBY DOO.
In the Replace one string with another (see page 79) example
instances of DRAFT are replaced with FINAL, but instances of Draft
are not.
Previously Draft_ConstZ was not renamed, but it is this time. All the
toolpath names are now upper case.
Whitespace in a string
Use the following functions to remove whitespace from a string:
ltrim()— Removes leading whitespace.
rtrim() — Removes trailing whitespace.
trim() — Removes leading and trailing whitespace.
82 • Macro Programming
Splitting a string
The tokens() function splits a string into a list of strings that were
separated by the separator characters. By default the separator
characters are spaces and tabs.
For example:
STRING InputStr = "One Two Three"
STRING LIST Tokens = tokens(InputStr)
FOREACH Tok IN Tokens {
PRINT = Tok
}
You can also give the tokens() function an optional extra argument
that changes the separator character.
For example:
STRING InputStr = "10:20:30:40"
STRING LIST Tokens = tokens(InputStr,':')
FOREACH Tok IN Tokens {
PRINT = Tok
}
List functions
List functions control the content of a list or array.
The basic structure of list functions are:
Description Function
Returns the components (see list components( entity
page 84) of another object. entity )
Returns a list of specified size list fill (int size, object
containing elements with value )
specified value.
Returns a list of all the list folder( string folder
entities in the folder (see page )
85).
Determines if the list has any is_empty()
content (see page 86).
Determines if the list contains member()
a specific value (see page 86).
Adding (see page 87) a list or +
array to another list or array
Removes duplicate (see page remove_duplicates()
87) items from a list.
List components
The inbuilt components function returns the components of another
object.
84 • Macro Programming
An example, to ensure that all the area clearance toolpaths in an NC
program have flood coolant turned on and that mist is set for all the
others:
FOREACH item IN components(entity('ncprogram','')) {
// only check nctoolpath items
IF lcase(item.RootType) == 'nctoolpath' {
// If the area clearance parameter is active then use
flood
IF active(entity('toolpath',item.Name).AreaClearance)
{
$item.Coolant.Value = "flood"
} else {
$item.Coolant.Value = "mist"
}
}
}
List fill
The fill() function returns a list of a specified size, which
contains elements of a specified value.
The basic structure is:
list fill(int size, object value)
For example, if you wanted to create a list in which abc was
repeated three times:
STRING ARRAY str_arr[] = fill(3, "abc")
// str_arr = {"abc", "abc", "abc"}
If you wanted to create a list in which 5 was repeated five times:
INT LIST int_ls = fill(5, 5)
// int_ls = {5, 5, 5, 5, 5}
List folder
The folder() function returns a list of all entities within a folder,
including those in subfolders.
The basic structure is:
list folder( string folder )
The names of the root folders are:
MachineTool
NCProgram
Toolpath
Tool
The name of the folder is case sensitive, so you must use Tool
and not tool.
You can use a FOREACH loop to process all of the entities within a
folder. For example, to batch process tool holder profiles:
FOREACH tool IN folder ('Tool'){
EDIT TOOL $tool.Name UPDATE_TOOLPATHS_PROFILE
}
An example, to batch process all the boundaries in your project:
FOREACH bou IN folder('Boundary') {
EDIT BOUNDARY $bou.Name CALCULATE
}
Empty list
The is_empty() function queries a list to determine whether it is
empty or not.
REAL LIST MyList = {}
IF is_empty(MyList)
{ PRINT "Empty List"
}
List member
The member() function returns TRUE if the given value is one of the
items in the list. For example, to check that a toolpath does not
occur in more than one NC program, you can loop over all
NCProgram and check that each toolpath is only seen once. Do this
by building a list of toolpath names and checking that each time you
add a name you have not already seen it.
// Create an empty list
STRING List names = {}
// Cycle through the NC programs
FOREACH ncp IN folder('NCProgram') {
// loop over the components in the nc program
FOREACH item IN components(ncp) {
86 • Macro Programming
// Check that it is a toolpath
IF item.RootType == 'nctoolpath' {
// Use MEMBER to check that we have not seen this
name before
IF NOT member(names, item.Name)
{ bool ok = add_last(names,
item.Name)
} else {
// We have already added this name
STRING msg = "Toolpath: "+item.Name+crlf+" in
more than one NCProgram"
MESSAGE ERROR $msg
MACRO ABORT
}
}
}
}
Adding lists
The + function adds a list or array to another list or array. For
example, you can add two lists together to get a list of all the tools
used by the toolpaths and boundaries:
STRING LIST UsedToolNames = ToolpathTools + BoundaryTools
88 • Macro Programming
For example, to print the names of patterns in a list:
// Print the names of the Patterns in reverse order
// Create a list of the pattern names
STRING LIST Patterns = {}
FOREACH pat IN folder('Pattern') {
// Add the name of the pattern to start of the list
int s = add_first(Patterns, pat.Name)
}
// Keep taking the first item from the list until
// there are no more
WHILE size(Patterns) > 0 {
STRING name = remove_first(Patterns)
PRINT $Name
}
If you have three patterns in the Explorer:
The FOREACH loop adds each item to the start of the list. As the
add_first command adds the next pattern to the start of the list.
So you end up with a list
{"Pattern_3","Pattern_2,"Pattern_1"}.
The WHILE loop takes the first item in the list, removes it from the
list and pints it. This gives:
Pattern_3
Pattern_2
Pattern_1
The FOREACH loop adds each item to the end of the list. As the
add_last command adds the next pattern to the end of the list. So
you end up with a list {"Pattern_1","Pattern_2,"Pattern_3"}.
The WHILE loop takes the last item in the list, removes it from the
list and pints it. This gives:
Pattern_3
Pattern_2
Pattern_1
To end up with the patterns in the same order as they are in the
Explorer either:
In the FOREACH loop use the add_last command and in the
WHILE loop use the remove_first command; or
In the FOREACH loop use the add_first command and in the
WHILE loop use the remove_last command.
90 • Macro Programming
STRING Msg = "There are "+Count+" toolpaths using
"+diam+" tools"
PRINT $msg
}
Sorted list
The sort function sorts lists and arrays of scalars (numerics or
strings) or objects and entities. By default, the functions sort a list
in ascending order. If you want to sort the list in descending order,
you can apply the reverse function to the list.
If you are sorting a list of objects and entities, you must provide a
field name for the sort.
The following examples sort lists of scalar values (numerics and
strings):
STRING LIST l1 = {"The","Twelth","Night"}
$l1 = sort(l1)
// returns the list {"Night", "The", "Twelth"}
REAL ARRAY a1 = {23, 12, 4, 52, 32}
$a1 = sort(a1)
// Returns the list {4, 12, 23, 32, 52}
When sorting non-scalar values, such as entities or objects, you
must provide a sort field that is a scalar value:
CREATE TOOL ; BALLNOSED
EDIT TOOL ; DIAMETER 2.0
CREATE TOOLPATH 'bbb' RASTER
CREATE TOOL ; BALLNOSED
EDIT TOOL ; DIAMETER 1.0
CREATE TOOLPATH 'ccc' RASTER
CREATE TOOL ; BALLNOSED
EDIT TOOL ; DIAMETER 1.5
CREATE TOOLPATH 'aaa' RASTER
For example:
ENTITY LIST ents = sort(folder('toolpath'),'name')
// Returns the list of toolpath {'aaa','bbb','ccc'}
92 • Macro Programming
ENTITY LIST ents_diam =
sort(folder('toolpath'),'Tool.Diameter')
// Returns the list of toolpath {'ccc','aaa','bbb'}
You can reverse the order of a list by using the inbuilt function
reverse(). The example above sorts the toolpaths based on tool
diameter and returns the entries in ascending order, with the
smallest diameter listed first. To sort the list in descending order,
you can reverse the results.
ENTITY LIST ents_diam =
reverse(sort(folder('toolpath'),'Tool.Diameter'))
// Returns the list of toolpaths {'bbb','aaa','ccc'}
Path functions
The path functions returns part of the pathname of the entity,
The basic structure of the path functions are:
Description of return value Function
The Folder name (see page string pathname( entity
94) function returns the full ref )
folder name of the entity, or
an empty string if the entity
does not exist.
The Folder name (see page string pathname( string
94) function can also be used type, string name)
to return the full folder name
of the entity.
The Directory name (see page string dirname( string
94) function returns the path)
directory prefix from the path.
The Base name (see page 95) string basename( string
function returns the non- path)
directory suffix from the path.
The Project name (see page project_pathname(bool
95) functions returns the basename)
pathname of the current
project on disk.
The Active folder (see page String active_folder()
96) functions returns folder
names of active entities.
The Folder list (see page 96) String
functions returns the names folder_list(folder_name)
of folders in the PowerMill
project.
Directory name
The directory name function returns the directory prefix from the
path.
The basic structure is:
string dirname( string path)
For example you can use this to obtain the argument for the inbuilt
folder() function.
STRING folder = dirname(pathname('toolpath',Name))
94 • Macro Programming
Base name
The base name function returns the non-directory suffix from the
path.
The basic structure is:
string basename( string path)
Usually basename(pathname('tool',tp.Name)) is the same as
tp.Name, but you can use this in conjunction with dirname (see page
94) to split apart the folder names.
For example, suppose your toolpaths are split in folders: Toolpath\Feature1\
AreaClear
Toolpath\Feature1\Rest Toolpath\
Feature1\Finishing Toolpath\Feature2\
AreaClear Toolpath\Feature2\Rest
Toolpath\Feature2\Finishing
You can rename all your toolpaths so that they contain the feature
name and the area clearance, rest, or finishing indicator.
FOREACH tp in folder('Toolpath') {
// Get the pathname
STRING path = pathname(tp)
// Get the lowest folder name from the path
STRING type = basename(dirname(path))
// get the next lowest folder name
STRING feat = basename(dirname(dirname(path)))
// Get the toolpath name
STRING base = basename(path)
// Build the new toolpath name
STRING NewNamePrefix = feat + "-" + type
// Check that the toolpath has not already been renamed
IF position(base,NewNamePrefix) < 0 {
RENAME TOOLPATH $base ${NewNamePrefix+" " + base}
}
}
Project name
The project pathname function returns the pathname of the current
project on disk.
The basic structure is:
project_pathname(bool basename)
The argument dirname_only gives a different result if it is true to if
it is false.
96 • Macro Programming
The basic structure is:
PRINT PAR "entity('stockmodel','stockmodel name').States"
This can be extended to print specific parameters, for example:
PRINT PAR "entity('stockmodel','stockmodel
name').States[0].Locked"
PRINT PAR "entity('stockmodel','stockmodel
name').States[1].References[1]"
Conditional functions
The basic structure of conditional functions are:
Description of return value Function
Returns the value of variant select(
expression 1 if the conditional conditional-expression;
expression is true, otherwise expression1;expression2)
it returns the value of
expression 2.
Evaluation functions
The evaluation function evaluate a string argument as an
expression.
For example:
print = evaluate("5*5")
prints 25.
FUNCTION Main() {
/Set up some data
REAL ARRAY Data[] = {9,10,3,4,1,7,2,8,5,6}
// Sort in increasing value
CALL SortReals("List[Idx] > List[Idx+1]", Data)
PRINT PAR "Data"
REAL ARRAY Data1[] = {9,10,3,4,1,7,2,8,5,6}
// Sort in decreasing order
CALL SortReals("List[Idx] < List[Idx+1]", Data1)
PRINT PAR "Data1"
}
98 • Macro Programming
Type conversion functions
The type conversion functions enable you to temporarily convert a
variable from one type to another within an expression.
The basic structure of the type conversion functions are:
Description of return value Function
Convert to integer value. int int( scalar a)
Enumerator parameter
The values() function returns a list of display names for an
enumerator parameter, such as Tool.Type, CutDirection, or
Strategy. The names are translated into the current language that a
user is working in. This list can be used to gather input from the
user with the CHOICE dialog. For example, to ask the user which
cut direction they would like to use, you can use the following code:
// Get names for the choices the user can make for this
parameter
STRING ARRAY Opts[] = values(CutDirection)
Parent parameter
The parent() function enables you to access and specigy machine
tool parameters in a more user friendly way. For example:
//To change the opacity of a machine tool/Robot table
with AXIS ADDRESS T, the following syntax can be used
EDIT PAR "parent(machine_axis('T')).ModelList.Opacity"
"25"
//Check the way the 'parent' function works...
CREATE TOOL ; BALLNOSED
EDIT TOOL "1" DIAMETER "20"
real error = 0
$error = ERROR parent(Tool)
print $error
//returns 1.0 as it fails finding the parent of a root -
'TOOL' is the root
$error = ERROR parent(Tool.Diameter)
print $error
//returns 0 as it finds the parent Tool of Tool.Diameter
Statistical functions
The statistical functions enable you to return the minimum and
maximum values of any number of numeric arguments.
The basic structure of the statistical functions are:
Description of return value Function
Returns the largest value in a real max( list numeric a
list of numbers. )
Returns the smallest value in real min( list numeric a
a list of numbers. )
This example finds the maximum and minimum block height of the
toolpaths in the active NC program.
REAL maxz = -100000
REAM minz = abs(maxz)
FOREACH item IN components(entity('ncprogram','')) {
IF item.RootType == 'nctoolpath' {
$maxz = max(maxz,entity('toolpath',item.Name))
$minz - min(minz,entity('toolpath',item.Name))
}
}
MESSAGE "Min = " + string(minz) + ", max = " +
string(maxz)
Equivalence
You can use the inbuilt function geometry_equal() to test
whether two tools, or two workplanes are geometrically
equivalent. For a tool the test is based on the cutting geometry of
the tool.
Number of segments
The inbuilt function segments() returns the number of segments in
a pattern or boundary:
IF segments(Pattern) == 0 {
PRINT "The pattern is empty"
}
To return the number of segments in a toolpath, use:
function toolpath_component_count(toolpath,type)
For example:
print par ${toolpath_component_count('toolpath', '1',
'links')}
print par ${toolpath_component_count('toolpath', '1',
'leads')}
print par ${toolpath_component_count('toolpath', '1',
'segments')}
Limits
The inbuilt function limits() returns an array of six elements
containing the XYZ limits of the given entity. The supported entities
are: pattern, boundary, toolpath, feature set, or model.
REAL ARRAY Lims[] = limits('model','MyModel')
The values in the array are:
REAL MinX = Lims[0]
REAL MaxX = Lims[1]
REAL MinY = Lims[2]
REAL MaxY = Lims[3]
REAL MinZ = Lims[4]
REAL MaxZ = Lims[5]
IF NOT entity_exists(entity('toolpath','')) {
PRINT "Please activate a toolpath and try again."
MACRO ABORT ALL
}
// Prints 4
PRINT = new_entity_name('workplane')
DELETE WORKPLANE 2
// Prints 2
PRINT = new_entity_name('workplane')
// Prints 2_1
PRINT = new_entity_name('workplane', '2')
Function Main(
STRING $Selected_Toolpath
)
{
// Create new project parameter to store the holder
clearance
BOOL $chk = 0
$chk = ERROR $project.clearance
Enter line and line without line breaks. The lines only
appear to include line breaks because of the limited page
width.
Model hierarchy
Model Component Functions
INT select_components(DATA components)
INT deselect_components(DATA components)
These functions select or deselect all of the components in the
passed-in data parameter. The data parameter must store a
ModelCompList or ModelCompSet. The return value is numeric, but
carries no information.
Model Hierarchies
Some CAD systems store models in a hierarchical structure. When
PowerMILL reads these CAD files it creates a parameterised
representation of this structure. This structure can be navigated as
a tree, and there are two helper functions, one to retrieve a node
from the hierarchy by its path, and the other to retrieve the
hierarchy (or a subsection of the hierarchy) as a list that can be
filtered or iterated over.
Nodes
The hierarchy of a model is made up of nodes. These are maps with
typename "ModelHierarchyElement". They have the following
properties:
Property Type Description
Name STRING The name associated with the node
in the hierarchy. The root node’s
name will be the same as the
model’s name.
Path STRING The path to the node. It consists of
the names of the node’s ancestors,
starting with the root node,
separated by backslashes. It
includes the node’s name.
Parent MAP The parent of this node in the
(typename: hierarchy. The root node’s Parent is
ModelHierarchyElemen always an error. For all other
t) nodes, it will be a map of this type.
Children ARRAY of MAPs A list of the children of the node in
(typename: the hierarchy. Each child node is a
ModelHierarchyElemen map of this type.
t)
Compone DATA A list of the model components
nts {ModelCompList} associated with the node.
Parameter MAP Key-Value pairs associated with the
s (typename: node.
ModelMetadata)
SelectedIn BOOL This parameter is not currently
Model metadata
Exchange can extract the metadata from 3rd party CAD files and
communicate them to PowerMill during the translation process.
Metadata is accessible through parameters which are associated
with groups, workplanes and geometries. These are used to store
information relevant to the machining of an item.
Metadata on geometry
The components() parameter function is extended to include a
data parameter which stores a list of model components, including
surfaces, and returns a list of the components in a parameterised
form.
The parameterized components are objects with the following
properties:
Metadata on workplanes
There are are parameters to represent workplanes in the hierarchy.
These are maps with the following properties:
Name — The name of the workplane.
Origin — The origin of the workplane. This is an array of 3 REALs.
XAxis — The X axis of the workplane. This is an array of 3 REALs.
YAxis — The Y axis of the workplane. This is an array of 3 REALs.
ZAxis — The Z axis of the workplane. This is an array of 3 REALs.
Parameters — A map of the metadata associated with the
workplane.
If a workplane in an imported model has the same name as an
existing workplane in PowerMill but a different origin or orientation,
the parameter will store the original name.
Feature Parameters
You can use the inbuilt components() function to loop over the
features within a feature set. Each feature has the following
parameters:
Name — Name of Feature.
ID — Id of Feature.
RootType — 'feature' as a string.
num_items — Number of sub-holes.
Type — Type of feature (pocket, slot, hole, boss).
Top — Top of feature, z-value relative to Origin.
Bottom — Bottom of feature, z-value relative to Origin.
Depth — Depth of feature, from top to bottom.
Diameter — Diameter of feature.
Draft — Draft angle.
Example
// get a list of all the files in the working directory
STRING LIST files = list_files("files",pwd())
How do I only loop over the items in a parent folder (and exclude any
subfolders)?
As described above, the folder() function returns items from a
parent folder and any subfolders. If you only want to loop over the
items in the parent folder, you need to filter the results. For
example, if you have the folder 'Semi-finishing' and the subfolder
'Not used', which contains temporary or alternative toolpaths, then
to access the toolpaths only in the 'Semi-finishing' folder, you need
to use the pathname and dirname functions:
STRING fld = ‘Toolpath\semi-finishing’
Note the use of ‘this’ in the $filt expression: when used in the
filter function, ‘this’ is an alias for the current list item that is
being filtered. In cases where you need to explicitly use the
list item, such as the one above, you should refer to it as
‘this’ in the expression.
2 To create a macro path, click , and use the Select Path dialog
to select the desired location. The path is added to the top of the
list.
Only the paths that contain at least one macro are shown.
For more information, see Displaying Macros in the Explorer.
e Click on the Main toolbar to display the Safe area tab of the
Toolpath connections dialog.
f Enter a Safe Z of 10 and Start Z of 5.
g Click Accept.
5 From the Macros context menu, select Stop to finish recording.
6 Expand the Macros node. The pmuser.mac macro is added under
pmill4.
7 Close and then restart PowerMill to check that the settings from
the pmuser macro are activated.
Graphics
When you run a macro, PowerMill updates the screen every time a
change is made. If PowerMill updates the screen frequently, this
amount of screen activity can look unpleasant. Use the following to
instruct PowerMill not to update the screen while the commands are
in progress, and instead to update the screen (just the once) after
the commands are complete.
GRAPHICS UNLOCK
GRAPHICS LOCK
A
Active folder name • 95
C
Adding items to a list • 35, 87 Calling from other macros • 4
Adding lists • 86 Carriage returns in dialogs • 30
Adding macro loops • 11 Comparing variables • 41, 43
Adding macro variables • 10 Components
Arguments in macros • 51 List components • 83
Function values • 53 Compound macros • 4
Running macros with arguments • 12 Conditrional functions • 96
Sharing functions • 54 Constants • 68
Arrays • 33 Euler's number • 68
Lists • 33 Pi • 68
Points • 41 Converting numerics to strings • 76
Using arrays • 25 Creating macros • 1
Vectors • 41 Basic macro • 9
Automate a sequence of edits or actions Creating variables (macros) • 27
• 101
D
B Date and time functions • 74
Base name • 94 Decision making in macros • 14
Basic macro • 9 Decisions in macros
Adding macro loops • 11 BREAK statement • 60, 65
Adding macro variables • 10 IF - ELSE statement • 55
Decision making in macros • 14 IF - ELSEIF - ELSE statement • 56
Returning values from macros • 18 IF command • 54
Running macros with arguments • 12 SWITCH statement • 57
Using a FOREACH loop • 22 Decrease options available to user • 31
Using arrays • 25 Delete files or directories • See Working
Using functions in macros • 16 with files and directories
BREAK statement • 60, 65 Dialogs in macros • 28
Building a list • 37 Carriage returns in dialogs • 30
Built-in functions • 68 Directory name • 93
DO - WHILE loop • 64
Decision making in macros • 14
W
Warning and error messages, turn off •
119
WHILE loop • 63
Whitespace in a string • 81
Working with files and directories • 111
Workplane origin • 72
Writing information to files • 112
Writing macros • 5