PowerMILL 2016 - Macro Programming en
PowerMILL 2016 - Macro Programming en
User Guide
Macro Programming Guide
Release issue 1
Copyright
Delcam Ltd has no control over the use made of the software
described in this manual and cannot accept responsibility for any
loss or damage howsoever caused as a result of using the software.
Users are advised that all the results from the software should be
checked by a competent person, in accordance with good quality
control procedures.
The functionality and user interface in this manual is subject to
change without notice in future revisions of the software.
The software described in this manual is furnished under licence
agreement and may be used or copied solely in accordance with the
terms of such licence.
Delcam Ltd grants permission for licensed users to print copies of
this manual or portions of this manual for personal use only.
Schools, colleges and universities that are licensed to use the
software may make copies of this manual or portions of this manual
for students currently registered for classes where the software is
used.
Acknowledgements
This documentation references a number of registered trademarks
and these are the property of their respective owners. For example,
Microsoft and Windows are either registered trademarks or
trademarks of Microsoft Corporation in the United States.
Patents
The Raceline smoothing functionality is subject to patent
applications.
Patent granted: GB 2374562 Improvements Relating to Machine
Tools
Patent granted: US 6,832,876 Machine Tools
Some of the functionality of the ViewMill and Simulation modules of
PowerMILL is subject to patent applications.
Patent granted: GB 2 423 592 Surface Finish Prediction
The Vortex machining functionality is subject to patent applications.
Patent application: 1121277.6 Adaptive Clearance
The MachineDNA functionality is subject to patent applications.
Patent application: 1204908.6 Machine Testing
Licenses
Intelligent cursor licensed under U.S. patent numbers 5,123,087
and 5,371,845 (Ashlar Inc.)
PowerMILL 2016. Published on 17 August 2015
Contents
Macros
Contents i
Index
ii Contents
123
Macros
Creating macros
You can create macros by:
Macros 1
2 Macros
Running macros
When you run a macro, the commands recorded in the macro file
are executed.
1 Expand Macros, and select the macro you want to run.
2 From the individual macro menu, select Run.
2 Click
3 Click
next to
to see the macros in this directory, which
includes the one you have just created.
Editing macros
You can edit recorded macros to troubleshoot and correct any
errors.
1 Expand Macros and select the macro you want to edit.
Macros 3
macro h400_prefs
4 Macros
macro iniblock
Macros 5
The Menu bar option Help >Parameters >Reference > Functions lists all
the standard functions you can use in macros.
To create a macro:
1 From the Menu bar, select View > Toolbar > Command to open the
command window.
2 Select Tools > Echo Commands from the Menu bar to echo the
issued commands in the command window.
b When the Block dialog opens, click Calculate, and then click
Accept.
The command window shows the commands issued:
Macros 7
8 Macros
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
PRINT
PRINT
PRINT
Macros 9
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.
When you have defined a local variable you can use it as many
times as you want in a macro.
10 Macros
INT Count = 5
// Repeat while the condition Count is greater than 0
WHILE Count > 0 {
// Print the line
PRINT $bottles
// Reduce the count by 1
$Count = Count - 1
}
// Print the last two lines
PRINT "And if 1 green bottle should accidentally fall"
PRINT "There will be 9 green bottles sitting on the wall"
$Count = Count - 1 is an assignment statement which is
why the variable ($Count) to the left of = must be prefixed
with $.
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:
Macros 11
MACRO example.mac 5
Where 5 is the value for Count. The command windows displays:
This example separates out the printing of the first line into its own
function so that the Main function is more understandable.
1 Open example.mac in your text editor and change it to:
FUNCTION PrintBottles(INT Count) {
// Create a variable to hold the first line
STRING bottles = "10 green bottles sitting on the wall"
12 Macros
Macros 13
DO - WHILE loop
1 Edit the PrintBottles function in example.mac to
FUNCTION PrintBottles(INT Count) {
// Create a variable to hold the first line
STRING bottles = "10 green bottles sitting on the wall"
// Repeat while the condition Count is greater than 0
DO {
// Print the line
PRINT $bottles
// Reduce the count by 1
$Count = Count - 1
} WHILE Count > 0
}
The main function remains unchanged:
FUNCTION Main (INT Count) {
// Print the first line Count number of times
CALL PrintBottles(Count)
// Print the last two lines
PRINT "And if 1 green bottle should accidentally fall"
PRINT "There will be 9 green bottles sitting on the wall"
}
2 Type MACRO example.mac 0 in the command window.
14 Macros
Macros 15
16 Macros
Macros 17
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).
DEFAULT is an optional step.
18 Macros
INT Bottles = 10
WHILE Bottles > 0 {
// Print the first line Count number of times
CALL PrintBottles(Count, Bottles)
// Countdown Bottles
$Bottles = $Bottles - 1
// Convert Bottles to string
STRING BottlesNumber = ''
CALL NumberStr(Bottles, BottlesNumber)
// Build the number of bottles left string
STRING bottles_left = "There will be " +
lcase(BottlesNumber) + " green bottles sitting on the
wall"
// Print the last two lines
PRINT "If one green bottle should accidentally fall"
PRINT $bottles_left
}
}
The BottlesNumber variable is declared in the WHILE loop of the
MAIN function.
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) {
// Convert Number into a string
STRING TextNumber = ''
CALL NumberStr(Number,TextNumber)
// Create a variable to hold the first line
STRING bottles = TextNumber + " green bottles sitting on
the wall"
// Repeat while the condition Count is greater than 0
WHILE Count > 0 {
// Print the line
PRINT $bottles
// Reduce the count by 1
$Count = Count - 1
}
}
FUNCTION Main (INT Count) {
Macros 19
20 Macros
CASE 3
$Text
BREAK
CASE 2
$Text
BREAK
CASE 1
$Text
BREAK
DEFAULT
$Text
BREAK
= "Three"
= "Two"
= "One"
= "No"
}
}
To run the macro:
Type MACRO example.mac 2 in the command window.
Macros 21
22 Macros
Macros 23
This gives exactly the same output as the Returning values from
macros (see page 18) example. It shows you an alternative way
of creating the same output.
24 Macros
This gives exactly the same output as the Returning values from
macros (see page 18) example. It shows you an alternative way
of creating the same output.
Macros 25
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.
There are some restrictions on the use of macro variables.
26 Macros
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
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.
Macros 27
Information dialogs
Warning dialogs
Error dialogs
28 Macros
Macros 29
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."
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
}
30 Macros
Macros 31
32 Macros
from an array.
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}
Macros 33
MyList[2]
34 Macros
Macros 35
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)
}
}
}
36 Macros
}
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
}
Macros 37
}
}
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 be
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 a entity name.
For example:
ENTITY tp = entity('toolpath','1')
ACTIVATE TOOLPATH $tp
38 Macros
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
Macros 39
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
}
}
}
ARRAY
ARRAY
ARRAY
ARRAY
VecX[] = {1,0,0}
VecY[] = {0,1,0}
VecZ[] = {0,0,1}
MVecZ[] = {0,0,-1}
Comparing variables
Comparing variables enables you to check information and defines
the course of action to take when using IF (see page 53) statements
and WHILE (see page 62) 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
40 Macros
Description
Symbol
Text
==
EQ
is equal to
!=
NE
is not equal to
<
LT
is less than
<=
LE
>
GT
is greater than
>=
GE
is greater than or
equal to
Macros 41
Logical operators
Logical operators let you to do more than one comparison at a time.
There are four logical operators:
AND
OR
XOR
NOT
Remember the result of a comparison is either true or false.
When true, the result is ; when false, the result is 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)
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)
42 Macros
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)
Operand 1
NOT Operand 1
true (1)
false (0)
false (0)
true (1)
Macros 43
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
INT Count
// Define
INT Count
a
=
a
=
44 Macros
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
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.
Macros 45
Operator
Description
Examples
addition
3+5 evaluates to 8
subtraction
5-3 evaluates to 2
multiplication
5*3 evaluates to
15
division
6/2 evaluates to 3
11%3 evaluates to
2
to the power of
For a complete list of operators, see the HTML page displayed when
you select Help > Parameters > Reference > Functions.
46 Macros
You can use this to build strings from various parts, for example:
MESSAGE "The Stepover value is: " + string(Stepover)
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.
Macros 47
Precedence
Order
Operation
Description
()
[]
+-!
cm mm um ft
in th
unit conversion
*/%
+-
== != (EQ,
NE)
10
AND
11
NOT
12
XOR
13
OR
logical
14
operator OR
Examples of precedence:
48 Macros
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 = a % b * c + d
$x = (((a % b) * c) + d)
$a = b <= c | d != e
$a = !b | c & d
$a = b mm * c in + d
Macros 49
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
51) 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
MACRO MyTool.mac "ToolName" 6
If you use FUNCTION in your macro, then all commands must be
within a function body. This means that you must have a FUNCTION
Main, which is automatically called when the macro is run.
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}
}
FUNCTION Main(string bound) {
FOREACH bou IN folder(bound) {
CALL CleanBoundary(bou.Name)
}
}
Within a function, you can create and use variables that are local to
the function, just as you can within a WHILE loop. However, a
function cannot access any variable that is defined elsewhere in the
macro, unless that variable has been passed to the function as an
argument.
50 Macros
Main function
If a macro has any functions:
Function names are not case sensitive: MAIN, main, and MaIn all
refer to the same function.
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 ;
DELETE BOUNDARY
EDIT BOUNDARY ;
EDIT BOUNDARY ;
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
Macros 51
The aOutput variable is an alias for the variable that was passed
in the CALL command, any changes to its value are actually
changing the value of the variable that was given in the CALL
command.
52 Macros
}
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.
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
}
Macros 53
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.
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
54 Macros
} ELSE {
Commands B
}
Commands C
If expression is true, then Commands A are executed followed by
Commands C.
If expression is false, then Commands B are executed followed by
Commands C.
Macros 55
Half the tool diameter if the tool is an end mill or ball nosed tool.
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.
56 Macros
Macros 57
58 Macros
Macros 59
60 Macros
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.
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 64) statement.
Jump directly to the next iteration using the CONTINUE (see page
64) statement.
Macros 61
You cannot create your own list variables, there are some built in
functions in PowerMILL that return lists (see the parameter
documentation for component, and folder).
You can use one of the inbuilt functions to get a list of entities, or
you can use arrays to create a sequence of strings or numbers to
iterate over. For example, use the inbuilt folder function to get a list
of entities.
An example of using a FOREACH loop is to batch process tool holder
profiles:
FOREACH ent IN folder('Tool') {
ACTIVATE TOOL $ent.Name
EDIT TOOL ; UPDATE_TOOLPATHS_PROFILE
}
The loop variable ent is created by the loop and destroyed
when the loop ends.
Another example is to renumber all the tools in a project:
INT nmb = 20
FOREACH t IN folder('Tool') {
$t.number.value = nmb
$t.number.userdefined = 1
$nmb = nmb + 2
}
To get the most out of these macro features, you should familiarise
yourself with the inbuilt parameter functions detailed in Help >
Parameters > Reference.
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.
62 Macros
Cancel the loop using the BREAK (see page 64) statement.
Jump directly to the next iteration using the CONTINUE (see page
64) statement.
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.
Cancel the loop using the BREAK (see page 64) statement.
Jump directly to the next iteration using the CONTINUE (see page
64) statement.
Macros 63
CONTINUE statement
The CONTINUE statement causes a jump to the conditional test of
any one of the loop constructs WHILE, DO - WHILE, and FOR EACH in
which it is encountered, and starts the next iteration, if any.
This example, calculates and offsets, all unlocked boundaries,
outwards and inwards.
FOREACH bou IN folder('Boundary') {
IF locked(bou) {
// This boundary is locked go get the next one
CONTINUE
}
REAL offset = 1 mm
EDIT BOUNDARY $bou.Name CALCULATE
EDIT BOUNDARY $bou.Name OFFSET $offset
EDIT BOUNDARY $bou.Name OFFSET ${-offset} }
The CONTINUE statement enables the selection of the next
boundary.
Creating sequences
Use the make_sequence and next_in_sequence functions to create
sequences. Sequences contain:
64 Macros
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:
FUNCTION Calculate(STRING TpName) {
Macros 65
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
}
EDIT TOOLPATH ; CALCULATE
}
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.
66 Macros
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.
Path functions (see page 91) (Folder (see page 92), Directory
(see page 92), Base (see page 93), and Project (see page 93)
names).
Macros 67
Function
Exponential
Natural logarithm
Square root
Returns either 1 or 0
depending on whether the
difference between a and b is
less than or equal to tol
Trigonometrical functions
The basic structure of the trigonometrical functions are:
Function
Trigonometric sine
Trigonometric cosine
Trigonometric tangent
Trigonometric arcsine
Trigonometric arccosine
Trigonometric arctangent
Trigonometric arctangent of
a/b, quadrant is determined
by the sign of the two
arguments
68 Macros
REAL
REAL
REAL
REAL
ARRAY
ARRAY
ARRAY
ARRAY
VecX[] = {1,0,0}
VecY[] = {0,1,0}
VecZ[] = {0,0,1}
MVecZ[] = {0,0,-1}
Macros 69
Angle
The angle() function returns the signed angle in degrees between
two vectors, providing that neither vectors have a zero length.
For example:
// Prints 90
PRINT = angle(VecX,VecY)
// Prints 90
PRINT = angle(VecY,VecX)
The apparent_angle() function returns the apparent angle
between two vectors when looking along a reference vector. If a
vector is parallel or anti-parallel to the reference vector, or if any of
the vectors have a zero length it returns an error:
// prints 270
print = apparent_angle(VecX,VecY,MVecZ)
// prints 90
print = apparent_angle(VecY,VecX,MVecZ)
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}
// set vec1 to be the same as vec2
BOOL ok = set_vector(vec1,vec2)
// make a X-axis vector
$ok = set_vector(vec2,1,0,0)
REAL
REAL
REAL
ok =
X = Block.Limits.XMax
Y = Block.Limits.YMin
Z = Block.Limits.ZMax
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)"
70 Macros
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:
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:
Function
Macros 71
72 Macros
When you run the macro, the command window displays the result,
One, Two, Three.
Function
Description
time()
The current
system time.
This is useful for
coarse timing in
macros and
getting the actual
time and date.
local_time(int
time)
A DateTime object
representing the
local time given a
number of
seconds.
utc_time(int
time)
A DateTime object
representing the
time in
Coordinated
Universal Time.
String
String value
String
year
String
month
String
day
Macros 73
String
hour
String
minute
String
second
String
timestam
p
74 Macros
Macros 75
When you run the macro, PowerMILL creates a ball nosed tool with
a diameter of 5 and gives the tool the name, ball_nosed Diam: 5.0.
Another example:
STRING One = "One"
STRING Two = "Two"
STRING CountToTwo = One + ", " + Two
PRINT = length(CountToTwo)
The command window displays the result, 8.
76 Macros
Macros 77
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.
78 Macros
Previously Draft_ConstZ was not renamed, but it is this time. All the
toolpath names are now upper case.
Macros 79
Whitespace in a string
Use the following functions to remove whitespace from a string:
For example:
STRING Original = "
What's up Doc!"
STRING Trimmed = ltrim(Original)
print = Original
print = Trimmed
Where:
print = Original displays "
window.
80 Macros
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
is_empty()
member()
remove_duplicates()
Macros 81
set_union()
intersection()
subtract()
List components
The inbuilt components function returns the components of another
object.
Currently NC Program and Group entity parameters are
supported.
The components function returns a list of all items regardless
of type. You must check the type of the variable of each item,
in the list.
The basic structure is:
list components( entity entity )
For example if you want to batch process tool holder profiles for the
tools in a group that contains toolpaths, boundaries, and tools:
FOREACH ent IN components(entity('Group', '1')) {
IF lcase(ent.RootType) == 'tool' {
EDIT TOOL $ent.Name UPDATE_TOOLPATHS_PROFILE
}
}
82 Macros
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
Macros 83
Boundary
Pattern
Featureset
Workplane
Level
Model
StockModel
Group
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) {
84 Macros
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
Macros 85
86 Macros
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
Removing items from the end of a list
The inbuilt function remove_last(list) removes an item to the end
of a list. It returns the removed item.
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 end of the list
int s = add_first(Patterns, pat.Name)
}
// Keep taking the last item from the list until
// there are no more
WHILE size(Patterns) > 0 {
STRING name = remove_last(Patterns)
PRINT $Name
}
Macros 87
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:
88 Macros
Macros 89
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'}
90 Macros
Path functions
The path functions returns part of the pathname of the entity,
The basic structure of the path functions are:
Function
project_pathname(bool
basename)
String active_folder()
String
folder_list(folder_name)
Macros 91
Folder name
The pathname function returns the full folder name of the entity,
or,if the entity does not exist, an empty string.
The basic structure is:
string pathname( entity ref )
Also,
string pathname( string type, string name)
Returns the full folder name of the entity.
For example, if you have a BN 16.0 diam tool in a Ballnosed tool
folder, then:
pathname('tool', 'BN 16.0 diam')
returns the string Tool\Ballnosed tools\BN 16.0 diam.
If the entity does not exist it returns an empty string.
You can use this function in conjunction with the dirname() (see
page 92) function to process all the toolpaths in the same folder as
the active toolpath.
STRING path = pathname('toolpath',Name)
// check that there is an active toolpath
IF path != '' {
FOREACH tp IN folder(dirname(path)) {
ACTIVATE TOOLPATH tp.Name
EDIT TOOLPATH ; CALCULATE
}
} ELSE {
MESSAGE "There is no active toolpath"
RETURN
}
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))
92 Macros
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
92) 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.
Macros 93
94 Macros
block size
active state
Conditional functions
The basic structure of conditional functions are:
Function
variant select(
conditional-expression;
expression1;expression2)
Evaluation functions
The evaluation function evaluate a string argument as an
expression.
For example:
print = evaluate("5*5")
prints 25.
Macros 95
96 Macros
Function
Function
Macros 97
- string list
values(par)
}
Check if you change a parameter
You can test whether a particular parameter is locked or not with
the inbuilt locked() function. You cannot normally edit a locked
parameter because its entity is being used as a reference by
another entity. If you try to edit a locked parameter with the EDIT
PAR command, PowerMILL displays a query dialog asking for
permission to make the change. You can suppress this message
using the EDIT PAR NOQUERY command. The locked() function
enables you to provide your own user messages and queries that
are tailored to your application.
For example:
IF locked(Tool.Diameter) {
BOOL copy = 0
$copy = QUERY "The current tool has been used do you want
to make a copy of it?"
IF NOT copy {
// cannot proceed further so get out
RETURN
}
COPY TOOL ;
}
$Tool.Diameter = 5
98 Macros
Macros 99
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:
Function
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)
100 Macros
Command
Description
entity_exists()
geometry_equal()
new_entity_name()
set_workplane()
segments()
limits()
toolpath_cut_limit
s()
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')}
// Returns the number of toolpath segments, links and leads moves
in toolpath named '1'
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
REAL
REAL
REAL
REAL
REAL
MinX
MaxX
MinY
MaxY
MinZ
MaxZ
=
=
=
=
=
=
Lims[0]
Lims[1]
Lims[2]
Lims[3]
Lims[4]
Lims[5]
Macros 101
=
=
=
=
=
=
Minimum
Maximum
Minimum
Maximum
Minimum
Maximum
X
X
Y
Y
Z
Z
value.
value.
value.
value.
value.
value
two parameters that specify the entity type and name such as
entity_exists('tool','MyTool').
For example:
IF entity_exists(Workplane) {
PRINT "An active workplane exists"
} ELSE {
PRINT "No active workplane using world coordinate system."
}
IF NOT entity_exists(entity('toolpath','')) {
PRINT "Please activate a toolpath and try again."
MACRO ABORT ALL
}
102 Macros
PRINT = new_entity_name('workplane')
DELETE WORKPLANE 2
// Prints 2
PRINT = new_entity_name('workplane')
CREATE WORKPLANE ;
// Prints 2_1
PRINT = new_entity_name('workplane', '2')
powermill.Status.MultipleSelection.Last
This enables PowerMILL to identify the last selected entity.
powermill.Status.MultipleSelection.Count
This enables PowerMILL to display the entity it is processing, for
example, 'Checking toolpath 6 for collisions'.
powermill.Status.MultipleSelection.Total == 0
This enables PowerMILL to display the total number of selected
entities.
powermill.Status.MultipleSelection.First
This enables PowerMILL to identify the first entity in a loop.
Function Main(
STRING $Selected_Toolpath
Macros 103
)
{
// Create new project parameter to store the holder
clearance
BOOL $chk = 0
$chk = ERROR $project.clearance
if $chk {
// Project variable does not exist. Create it and set it
to 5 degrees
EDIT PAR CREATE REAL "clearance"
}
// Before checking the first toolpath, PowerMILL should ask
the user to enter the holder clearance
IF ($powermill.Status.MultipleSelection.First) OR
$powermill.Status.MultipleSelection.Total == 0 {
$project.clearance = INPUT ${"Enter the holder
clearance PowerMILL uses when checking the " +
$powermill.Status.MultipleSelection.Total + " selected
toolpaths for collisions "}
}
// Now collision check toolpath with entered clearance
// Set the clearance:
EDIT COLLISION HOLDER_CLEARANCE $project.clearance
// Now check the toolpath for collisions
EDIT COLLISION TYPE COLLISION
PRINT = "Processing toolpath " +
$powermill.Status.MultipleSelection.Count
EDIT COLLISION APPLY
// Tell user all selected toolpaths have been checked
IF ($powermill.Status.MultipleSelection.Last) {
MESSAGE INFO "All toolpaths have been checked "
}
}
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)
104 Macros
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
Path
STRING
Parent
MAP
(typename:
ModelHierarchyElemen
t)
Children
ARRAY of MAPs
(typename:
ModelHierarchyElemen
t)
Compone
DATA
Macros 105
nts
{ModelCompList}
Parameter
s
MAP
(typename:
ModelMetadata)
SelectedIn
GUI
BOOL
106 Macros
Model metadata
Giving workplanes a unique name if one already exists is standard
PowerMILL behaviour. I think the point to emphasize is that the
parameter will store the original name.
Also, in the previous section, the Parameters row of the table
describing the model hierarchy nodes needs updating, as it's no
longer an empty map.
Macros 107
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:
Name A string that contains the name of the component.
Model A string that contains the name of the model containing the
component.
Parameters An object which stores the key-value pairs associated
with the component.
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.
If models are exported, all of their metadata is lost. However,
if you ave a model in a project, it retains its metadata.
Feature Parameters
You can use the inbuilt components() function to loop over the
features within a feature set. Each feature has the following
parameters:
108 Macros
Macros 109
Example
// get a list of all the files in the working directory
STRING LIST files = list_files("files",pwd())
// get all the stl files in the C:\temp directory
110 Macros
$files = list_files("files","c:\temp",".stl")
// get all the directories and subdirectories in the working
directory
$files = list_files("dirs+", pwd())
FILE CLOSE Close a file and free-up its file handle so you can
re-use it later.
FILE READ Read values from one or more lines from an open
file into an existing variable.
A file handle is the name used internally to refer to the file.
Macros 111
WRITE
WRITE
WRITE
WRITE
CLOSE
$greeting TO "out"
$errors TO "out"
$PI TO "out"
$greeting[1] TO "out"
"out"
112 Macros
If the variable is a scalar then a single line is read and the string is
converted to the required variable type using standard conversion
rules.
If the variable is an array then one line is read for each element in
the array, with values being stored in the array (starting from index
0). If the end of the file is reached before the array is reached, the
data in the remaining elements remain unchanged.
If the variable to be read is a list then all remaining lines in the file
are read with existing list elements being over-written and the list
being extended as necessary. Again, if the number of lines
remaining to be read in the file are fewer than the number of
elements currently in the list, then data in the remaining elements
is unchanged.
For example:
FILE OPEN "values.txt" FOR READ AS input
STRING product_name = ""
INT ARRAY vers[2] = {0, 0}
REAL tol = 0.0
STRING LIST rest_of_file = {}
FILE
FILE
FILE
FILE
READ
READ
READ
READ
PRINT ="Tolerance from " + prod + " v" + vers[0] + "." + vers[1]
+ ": " + tol
PRINT ="Comments:"
FOREACH line IN rest_of_file {
PRINT $line
}
Macros 113
FOREACH tp IN folder(Toolpath\semi-finishing) {
PRINT = tp.name
}
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
FOREACH tp IN folder($fld) {
IF dirname(pathname(tp)) == $fld {
PRINT = tp.name
}
}
You can also achieve the same result as above by using a complex
expression for the FOREACH loop. In some cases this may make
your code easier to understand and in other cases much harder. In
the following example, the results of the folder() function are
filtered so the IF statement can be removed.
STRING fld = Toolpath\semi-finishing
STRING filt = dirname(pathname(this)) == fld
FOREACH tp IN filter(folder($fld), $filt) {
PRINT = tp,name
}
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.
How do I loop over the items in the active folder?
The inbuilt function active_folder() returns the name of the folder
that is currently active in the Explorer.
Check the correct folder in the Explorer is active.
STRING fld = active_folder()
IF fld == "" {
// No active folder use the root instead
$fld = Boundary
} ELSEIF position(fld,Boundary\) != 0 {
MESSAGE "Active folder isnt a boundary folder"
RETURN
114 Macros
}
How can I tell if a toolpath has been calculated?
The Toolpaths parameter 'Computed' is be true if it has been
calculated. Sometimes a toolpath may have been calculated but
contain no cutting segments. If this is an issue then you should
check the number of segments as well:
IF tp.Calculated AND segments(tp) > 0 {
PRINT "Toolpath is calculated and has segments"
}
Macros 115
and
4 Click Close.
5 To load the new paths into PowerMILL, expand the Macros
branch in the Explorer.
Only the paths that contain at least one macro are shown.
For more information, see Displaying Macros in the Explorer.
116 Macros
g Click Accept.
5 From the Macros context menu, select Stop to finish recording.
Macros 117
7 Close and then restart PowerMILL to check that the settings from
the pmuser macro are activated.
118 Macros
Macros 119
From the Tools menu, select Reset Forms. This ensures that
PowerMILL uses the default parameters in the dialogs.
Your code blocks must have matching braces. They must have
the same number of opening braces ({) as closing braces (}).
The ELSEIF keyword does not have a space between the IF and
the ELSE.
Decimal points in numbers must use a full stop (.) and not a
comma (,).
120 Macros
is correct, but:
myvar = 5
is wrong as it is missing the $ prefix.
Macros 121
Index
Base name 93
Basic macro 9
Adding macro loops 10
Adding macro variables 9
Decision making in macros 13
Returning values from macros 18
Running macros with arguments 11
Using a FOREACH loop 21
Using arrays 24
Using functions in macros 15
BREAK statement 59, 64
Building a list 36
Built-in functions 67
Index 123
DOCOMMAND 49
Function values 52
Introduction 97
List components 82
List folder 83
List functons 81
Main function 51
Path functions 91
Point functions 68
E
Editing macros 3
Editing 3
Empty list 84
Enter values into macros 27
Entities in macros 29
Entity based functions 100
Entity variables 38
Equivalence 100
Limits 100
New entity name 102
Number of segments 100
Workplane origin 71
Entity variables 38
Equivalence 100
Error and warning messages, turn off
118
Euler's number 67
Evaluation functions 95
Example of programming language 8
Existing file or directory See Delete
files or directories
Exiting a function 65
Exponential 67
Expressions in macros 45
Order of operations 47
Precedence 47
Extracting data from lists 89
F
Feature parameters 108
File name in macros 31
Filtering data from a list 89
Folder
List folder 83
Folder name 92
FOREACH loop 61
Using a FOREACH loop 21
Function values 52
Functions in macros 67
Arguments in macros 50
Conditrional functions 95
Entity based functions 100
Evaluation functions 95
Exiting a function 65
124 Index
Setting a point 68
I
IF - ELSE statement 54
Decision making in macros 13
IF - ELSEIF - ELSE statement 55
IF command 53
Increase options available to user 30
Inputting values into macros 27
Entities in macros 29
Options in macros 30
L
Length of a string 76
Limits 100
List components 82
List folder 83
List functons 81
Adding items to a list 34, 86
Adding lists 85
Empty list 84
Extracting data from lists 89
M
Macro comments 7
Macro statement 6
Adding macro loops 10
Arguments in macros 50
BREAK statement 59, 64
DO - WHILE loop 63
FOREACH loop 61
IF - ELSE statement 54
IF - ELSEIF - ELSE statement 55
IF command 53
Macro statement 6
RETURN statement 65
SWITCH statement 56
Using the SWITCH statement 17
WHILE loop 62
Macro statements
Adding macro loops 10
Arguments in macros 50
BREAK statement 59, 64
DO - WHILE loop 63
FOREACH loop 61
IF - ELSE statement 54
IF - ELSEIF - ELSE statement 55
IF command 53
Macro statement 6
RETURN statement 65
SWITCH statement 56
Using a FOREACH loop 21
Using the SWITCH statement 17
WHILE loop 62
Macros
Calling from other macros 4
Compound macros 4
Creating macros 1
Editing macros 3
Expressions in macros 45
Macro comments 7
Macro statement 6
NC preference macro 119
pmuser macro 4, 116
Recording macros 2, 116, 119
Repeating commands in macros 60
Running macros 3
Setting paths 115
Variables in macros 26
Writing macros 5
Main function 51
Mathematical functions 67
Exponential 67
Logarithm 67
Mathematical functions 67
Natural logarithm 67
Square root 67
N
Natural logarithm 67
NC preference macro 119
New entity name 102
Normal vectors 68
Number of segments 100
O
Object variable 39
Operators 46
Logical operators 42
Relational operator 40
Order of operations 47
P
Parameter functions
Index 125
Sharing functions 53
Splitting a string 81
Square root 67
Statistical functions 100
Stopping macros 65
STRING function 71
Converting numerics to strings 75
Data and time 73
Length of a string 76
Position of a string 76
Replacing strings 77
Splitting a string 81
String variables 49
Substrings 76, 78
Upper case function 78
Whitespace in a string 80
String variables 49
Substrings 76, 78
SWITCH statement 56
Using the SWITCH statement 17
S
Scratchpad variables 43
Selecting a file name in macros 31
Selecting entities in macros 29
Setting paths 115
Setting up your working directories 115
126 Index
U
Upper case function 78
Using a FOREACH loop 21
Using arrays 24
Using functions in macros 15
Using lists 33
Using the SWITCH statement 17
Using variables (macros) 27
V
Variable scope (macros) 44
Variables in macros 26
Adding macro variables 9
Comparing variables 40, 42
Creating variables (macros) 26
DOCOMMAND 49
Entity variables 38
Logical operators 42
Object variables 39
Operators 46
Order of operations 47
Precedence 47
Relational operator 40
Returning values from macros 18
Scratchpad variables 43
String variables 49
Using variables (macros) 27
Variable scope (macros) 44
Vector functions 68
Angle between vectors 68
Length of a vector 68
Normal vectors 68
Parallel vectors 68
Point functions 68
Setting a vector 68
Unit vector 68
W
Warning and error messages, turn off
118
WHILE loop 62
Whitespace in a string 80
Working with files and directories 110
Workplane origin 71
Writing information to files 111
Writing macros 5
Index 127