-
Notifications
You must be signed in to change notification settings - Fork 2k
PrusaSlicer Macro Language
Up-to-date documentation of PrusaSlicer macro language can be found in the respective article of Prusa Knowledge Base.
============================
The custom G-code interpreter has been significantly extended in PrusaSlicer 2.6.0-alpha6.
- Custom local and global variables are newly supported
- It is newly possible to exchange state of the printer (machine position, z-hop, extruder position and retract) between the custom G-code and PrusaSlicer.
- Multiple expressions may be placed inside a single {} block separated by semicolons for readability.
- New helper functions
interpolate_table()
,one_of()
,size()
andempty()
were added. - New placeholders were added for accessing the amount of material extruded
Please note that a 3MF produced using the new G-code interpreter features will fail to slice with older PrusaSlicer by reporting custom G-code errors. It is recommended to warn the receiving party of such 3MF about such incompatibility.
Local and global variables may newly be defined and used in custom G-code blocks. Local variables are only valid until the end of a custom G-code block in which they are defined, while global variables may be referred to by any custom G-code block processed after the block they are defined in. These variables are defined with the following syntax:
(global|local) variable_name =(scalar_expression|vector_variable|array_expr|initializer_list)
where
array_expr := repeat(repeat_cnt, value)
initializer_list := (value, value, value, ...)
One may assign to a user defined variable or to a special variable (see the next section for special variables) using the following syntax:
variable_name =(scalar_expression|vector_variable|array_expr|initializer_list)
The type of the newly created variable is defined by the type of the right hand side inititializer. All elements of a vector variable are of the same type, thus if one mixes different types inside a single initializer_list expression, those elements are converted to the same type: When mixing ints with floats, ints will be converted to floats. If any of the initializer list elements is a string, all elements are converted to strings.
A newly declared variable must not override an existing variable. A duplicate (global|local)
variable definition is considered an assignment and as such it must neither change variable type nor its scope (local vs. global).
Newly each custom G-code block may exchange state of the printer with the slicing engine by reading from and writing to a set of new special variables. Currently two groups of such variables are available: For G-code position and for extruder state.
The following special variables are newly available for exchanging printer position and z-hop control:
position
(read/write) - 3 element vector (X, Y, Z) of current G-code position
zhop
(read only)- initial z-hop value
The following special variables are newly available for exchanging extruder state:
e_position
(read/write) - absolute E position, only available with absolute extruder addressing
e_retracted
(read/write) - current retraction state
e_restart_extra
(read/write) - currently planned extra extruder priming after deretraction
For example, the following block may be used for extra retraction:
{
local long_retract = 0.6;
local extra_retract = long_retract - e_retracted[current_tool];
if extra_retract > 0 then
"G1 E" + extra_retract + "
";
e_retracted[current_tool] = long_retract;
endif
}
Similarly, the following block may be used for extra Z-hop:
{
local long_zhop = 2;
local extra_zhop = long_zhop - zhop;
if extra_zhop > 0 then
local new_z = position[2] + extra_zhop;
"G1 Z" + new_z + "
";
position[2] = new_z;
endif
}
The existing custom G-code macro processor syntax was designed for simple macro processing tasks. Now with introduction of custom variables, one is invited to write complex custom G-code blocks. While complex custom G-codes could be written using the old macro processing syntax, a newly introduced syntax is often better readable.
With the old syntax, each expression must be enclosed in {}. Newly multiple expressions may be enclosed in single pair of braces {} separated by a semicolon.
Similarly, the {if condition} ... {endif condition} ... {else} ... {endif}
expression could newly be written inside a single pair of {} and ifs may be nested, for example:
{if condition then
statement;
statement
elsif condition then
if condition then
statement
else
statement
endif
else
statement
endif}
The old syntax may be mixed with the new syntax in a single expression if needed:
{if condition
}some text{
else
statement
endif}
Semicolons are only required between multiple statements and no semicolon is required at the end of an if block (after endif).
In constrast to older PrusaSlicer, the inactive if / else / endif blocks are just parsed, but no more evaluated, thus the inactive branches may contain code which is not valid, such as referencing undefined variables.
The following new functions were introduced: interpolate_table()
, one_of()
, size()
and empty()
- interpolate_table(x, (x0, y0), (x1, y1), (x2, y2), ...) interpolates a piecewise linear function at point x
- one_of(sample, pattern1, pattern2, ...) returns true if sample matches against one of the patterns. Patterns are considered regular expressions if enclosed in // or if an expression is prefixed with ~. For example /.a./ or ~".a." are patterns matching anything containing a single "a" character.
- size(vector_variable) returns number of its elements.
- empty(vector_variable) returns true if the vector variable has zero elements.
The following placeholders provide the volume and weight of plastic extruded by a particular extruder at the time the placeholder is evaluated: extruded_volume
, extruded_weight
The following placeholders provide volume and weight of plastic extruded by all extruders at the time the placeholder is evaluated: extruded_volume_total
, extruded_weight_total