Overview

The Generate class makes a string description, usually machine codes, for a process seen by an Adaptive object. To generate a G-code program, select the machine style and then traverse a STEP-NC process, stopping at each event, and print the string returned by the format_event() function. It is easy to substitute your own logic for tool changes, program start, etc. Simply watch for the event and emit your own codes instead of the ones returned by the Generate object.

There are several built-in styles: G-Code for Fanuc, Haas, Heidenhain, Okuma, Siemens style controls, five axis via TCP with IJK, AC, BC, or AB moves, Renishaw and native probing cycles, as well as other languages like APT, DMIS, or CRCL. Call set_style() to start with a base style and modify many different aspects of the output.

You can provide your own behavior for parts of the code generation with the set_event_fn(), set_type_fn(), and set_other_fn() hooks. Formatting functions use an Adaptive object that holds the position in the process, and a GenerateState object that keeps the current commanded state of machine tool axes and modal variables.

Examples

The simple example below reads a STEP-NC file and calls export_cncfile() to print Haas-style codes for the entire process to the program.nc file.

from steptools import step

# Read a STEP-NC file
DESIGN = step.open_project(datafile.stpnc);

GEN = step.Generate()
GEN.set_style(haas)   # use HAAS style
GEN.export_cncfile(DESIGN,program.nc)   # export codes

The example below replaces export_cncfile() with its own loop with the Adaptive cursor for more control over the output. It prints Haas-style codes to the console and adds custom functions for handling the start of the program and tool changes.

from steptools import step

def my_proj_start(gen,gs,cur):
    ret = gen.format_comment(gs,My great program)
    ret += gen.format_block(gs,*** My program start logic here ***)
    return ret

def my_tool_change(gen,gs,cur):
    # print tool description and follow with our logic
    ret = gen.format_other(GS,CUR,tool-comment)
    ret += gen.format_block(gs,*** My tool change logic here ***)
    return ret

# Read a STEP-NC file
DESIGN = step.open_project(datafile.stpnc);

CUR = step.Adaptive()
GEN = step.Generate()
GS = step.GenerateState()

CUR.start_project(DESIGN)
CUR.set_wanted_all()

GEN.set_style(haas);
GEN.set_event_fn(step.CtlEvent.PROJECT_START, my_proj_start)
GEN.set_event_fn(step.CtlEvent.TOOL_CHANGE, my_tool_change)
GEN.set_unit_system(CUR);

SRC = Path("data/tp2d.stpnc")

# Format calls may returns 'None', so print an empty string if that happens. 
# Also, make print() omit ending newline since the strings returned by the
# format calls already have them where needed.
#
while CUR.next():
    print(GEN.format_event(GS,CUR) or , end=)

When run against a sample process, the program generates the following. The custom program start and tool change portions are highlighted.

(MY GREAT PROGRAM)
*** My program start logic here ***
(WORKINGSTEP: LINE 33 WS 1)
(TOOL CHANGE: TOOL 1)
( DIAMETER: 25.4MM)
( CORNER RADIUS: 0.508MM)
( TAPER: 0DEG)
( TIP ANGLE: 0DEG)
*** My tool change logic here ***
M3S2000
M08
G0X0.Y0.Z-2.54
X-184.15Y143.51Z-55.88
Z-80.772
G1X-152.4F1016.
X152.4
Y124.46
X-152.4
[ ... and so on ... ]

If we change the style string from haas to heidenhain, our program will produce different output:

; My great program
*** My program start logic here ***
; Workingstep: line 33 WS 1
; TOOL CHANGE: TOOL 1
;  diameter: 25.4mm
;  corner radius: 0.508mm
;  taper: 0deg
;  tip angle: 0deg
*** My tool change logic here ***
N1 S2000 M3
N2 M08
N3 G0 X0 Y0 Z-2.54 A0 C0
N4 X-184.15 Y143.51 Z-55.88
N5 Z-80.772
N6 G1 X-152.4 F1016
N7 X152.4
N8 Y124.46
N9 X-152.4
[ ... and so on ... ]

cat_number()

def cat_number(self,
	txt: str,
	num: float,
	max_digits: int = None,
	min_digits: int = None
	) -> str:

The cat_number() function formats a floating point number as a string with a given maximum and minimum digits of precision. The result is concatenated to the end of the supplied string object and returned from the function.

CNC systems usually have a maximum number of digits, but some may also require a minimum number. A minimum digits value of -1 removes the trailing decimal point for integer values. If this is 0, the decimal point is retained.

If no max/min digits are given, the function uses the values from get_digits() and get_min_digits().

input 1.234567
max=5, min=-1 => 1.23457
max=2, min=-1 => 1.23

input 1.2
max=5, min=-1 => 1.2
max=2, min=0  => 1.2
max=2, min=2  => 1.20

input 1
max=5, min=-1 => 1
max=2, min=0  => 1.
max=2, min=2  => 1.00

cat_number_as_angle()

def cat_number_as_angle(self,
	txt: str,
	num: float
	) -> str:

The cat_number_as_angle() function is a wrapper around cat_number() that formats an angle value with the get_angle_digits() and get_angle_min_digits() precision values.

cat_number_as_feed()

def cat_number_as_feed(self,
	txt: str,
	num: float
	) -> str:

The cat_number_as_feed() function is a wrapper around cat_number() that formats a feedrate value with the get_feed_digits() and get_feed_min_digits() precision values.

cat_number_as_ijk()

def cat_number_as_ijk(self,
	txt: str,
	num: float
	) -> str:

The cat_number_as_ijk() function is a wrapper around cat_number() that formats an IJK direction component value with the get_ijk_digits() and get_ijk_min_digits() precision values.

cat_number_as_spindle()

def cat_number_as_spindle(self,
	txt: str,
	num: float
	) -> str:

The cat_number_as_spindle() function is a wrapper around cat_number() that formats a spindle speed value with the get_spindle_digits() and get_spindle_min_digits() precision values.

cat_param()

def cat_param(self,
	txt: str,
	name: str,
	num: float = None,
	max_digits: int = None,
	min_digits: int = None
	) -> str:

The cat_param() function appends a string for a parameter name and possibly a formatted number, separated by whitespace if the get_use_whitespace() preference is true. This function is simply a more concise way equivalent to add optional whitespace, add the parameter string, and then a number formatted with cat_number().

cat_param_as_angle()

def cat_param_as_angle(self,
	txt: str,
	name: str,
	num: float
	) -> str:

The cat_param_as_angle() function is a wrapper around cat_param() that formats an angle value with the get_angle_digits() and get_angle_min_digits() precision values.

cat_param_as_feed()

def cat_param_as_feed(self,
	txt: str,
	name: str,
	num: float
	) -> str:

The cat_param_as_feed() function is a wrapper around cat_param() that formats a feedrate value with the get_feed_digits() and get_feed_min_digits() precision values.

cat_param_as_ijk()

def cat_param_as_ijk(self,
	txt: str,
	name: str,
	num: float
	) -> str:

The cat_param_as_ijk() function is a wrapper around cat_param() that formats an IJK direction component value with the get_ijk_digits() and get_ijk_min_digits() precision values.

cat_param_as_spindle()

def cat_param_as_spindle(self,
	txt: str,
	name: str,
	num: float
	) -> str:

The cat_param_as_spindle() function is a wrapper around cat_param() that formats a spindle speed value with the get_spindle_digits() and get_spindle_min_digits() precision values.

cat_required_space()

def cat_required_space(self,
	txt: str
	) -> str:

The cat_required_space() function is a low-level function used to construct formatted text. It appends whitespace to the end of a string if the original string is not empty. This function is used for separating parameters when whitespace is always required.

cat_space()

def cat_space(self,
	txt: str
	) -> str:

The cat_space() function is a low-level function used to construct formatted text. It appends whitespace to the end of a string if the original string is not empty and if the get_use_whitespace() flag is true. This function is used to separate parameters that may or may not have space between them, like coordinates in a G-code block.

export_cncfile()

def export_cncfile(self,
	d: Design,
	filename: StrOrBytesPath
	) -> bool:

The export_cncfile() function is a simple wrapper that writes a file containing the output returned by format_event() for the contents of the current STEP-NC file. The output will be generated for all enabled executables using the current format settings of the Generate object. The function returns true if the file was exported successfully.

The sample program at the top of this page shows an alternative way of making codes, where you handle the loop yourself for customized output.

format_block()

def format_block(self,
	gs: GenerateState,
	block: str
	) -> str:

The format_block() function is a low-level function used to construct formatted text. This takes a string, adds a newline, and prepends a block number (eg. N1234) if the get_use_blocknums() flag is true. The block number is given by gs.get_next_blocknum(). The function returns the resulting string.

format_block_nonum()

def format_block_nonum(self,
	gs: GenerateState,
	block: str
	) -> str:

The format_block_nonum() function is a low-level function used to construct formatted text. This takes a string and adds a newline. It is used for things that must never have a block number. The function returns the resulting string.

format_comment()

def format_comment(self,
	gs: GenerateState,
	s1: str,
	s2: str = 
	) -> str:

The format_comment() function is a low-level function that encodes the input string as a comment in the manner appropriate for the output style. If two strings are given, they are concatenated with a colon separator as s1: s2. The function returns an empty string if an empty input string is given.

The comment formatting may convert the strings to uppercase, strip unsupported characters, and wrap the string with delimiters.

format_event()

def format_event(self,
	gs: GenerateState,
	cursor: Adaptive
	) -> Optional[str]:

The format_event() function is the main formatting function. It examines the most recent event() in the cursor and calls one or more formatting functions to build a string that represents it. The function may return None if nothing is needed.

Usually the cursor position is not changed, but sometimes formatting will advance the cursor. For example, when starting a probing operation, the formatting may iterate over the entire operation and return all of the moves necessary for the approach, touch and retract of the probe. The generate state object is updated.

Note that the strings returned by this and other format functions already include any necessary newlines, so if calling print() on the return value, you should include an end='' parameter to avoid double spacing the output.

You can provide your own formatting function for an event with set_event_fn().

CUR = step.Adaptive()
GEN = step.Generate()
GS = step.GenerateState()

CUR.start_project(DESIGN)   # design from apt or finder open
CUR.set_wanted_all()

GEN.set_style(okuma);
GEN.set_unit_system(CUR);

# print empty string when the format returns None, do not end with a
# newline since the format strings already have them where needed.
while CUR.next():
    print(GEN.format_event(GS,CUR) or '', end='')

format_move_xyz()

def format_move_xyz(self,
	gs: GenerateState,
	cursor: Adaptive,
	x: float, y: float, z: float
	) -> str:

The format_move_xyz() function returns a move command as if processing a CtlType.MOVE action, but the given position is supplied by the caller rather than taken from a toolpath curve. The tool axis is not changed - use format_move_xyz_ijk() to change the tool direction.

The position is given in program units and the generate state is updated. The position is used exactly as passed in, no destination transform is applied. The feed rate is not changed.

The function may return None if no move is needed.

format_move_xyz_ijk()

def format_move_xyz_ijk(self,
	gs: GenerateState,
	cursor: Adaptive,
	x: float, y: float, z: float,
	i: float, j: float, k: float
	) -> str:

The format_move_xyz_ijk() function returns a move command as if processing a CtlType.MOVE action, but the given position and tool axis direction is supplied by the caller rather than taken from a toolpath curve.

The position is given in program units and the generate state is updated. The position is used exactly as passed in, no destination transform is applied. The feed rate is not changed.

The function may return None if no move is needed.

format_other()

def format_other(self,
	gs: GenerateState,
	cursor: Adaptive,
	name: str
	) -> Optional[str]:

The format_other() function keeps a dictionary of functions used by format_event() to construct parts of the result text from the active state of the adaptive and generate state objects. The functions update generate state as necessary and may advance the cursor. The function may return an empty string if no move is needed.

Use set_other_fn() to replace the behavior associated with a name with your own function, or to add new names and associated functions to the dictionary beyond the ones listed below.

In our earlier example we called the tool-comment function. A partial list of available functions is shown below:

coolant
Turns flood, mist, or through-spindle coolant on or off as necessary based on the coolant state held by generate state and the values of get_move_is_coolant(), get_move_is_mist_coolant(), and get_move_is_thru_coolant(). Calls coolant-off if needed to turn everything off. Called by the toolpath start event handling.
coolant-off
Turns off all coolant. Called by the tool change and program end event handling.
filename
Returns the name of the STEP-NC file as a comment. Usually called by the program start event handling.
move-contact
This is called by the MOVE event handling. If the cursor is currently traversing a cutter contact toolpath, this function examines the tool axis, movement direction, and surface normal direction. If it determines that the tool is contacting left or right, it will return the result of calling refpoint-left or refpoint-right respectively.
move-feed
This is called by the MOVE event handling. It examines the get_move_feed() and any speed override settings and if the feedrate has changed, it returns a new feed command. Depending on the value of get_feed_is_standalone(), this is either returned on a separate line or appended to the end of the move command.
move-ijk
This is called by the MOVE event handling. It examines the tool axis direction returned by get_out_dirz() and formats the tool axis portion of the movement command. This function may be set to versions that Format the direction as Fanic TCP IJK components, Siemens TRAORI A3/B3/C3 components, or AC/BC/AB angles for use with Okuma or Heidenhain TCP modes. It returns null if the tool axis has not changed from the last known direction held by the generate state. The WCS tool axis is used, which has all setup and toolpath transforms applied. In addition the get_dst_xform() transform is applied if required by get_use_xform().
move-xyz
This is called by the MOVE event handling. It examines the tool position returned by get_out_xyz() and formats the position portion of the movement command. This function returns null if the tool axis has not changed from the last known direction held by the generat state. The WCS position is used, which has all setup and toolpath transforms applied. In addition the get_dst_xform() transform is applied if required by get_use_xform().
ncfun-exchange-pallet
This is called by the EXEC_NCFUN event handling for an exchange pallet NC function.
ncfun-extended
This is called by the EXEC_NCFUN event handling for an extended NC function.
ncfun-index-pallet
This is called by the EXEC_NCFUN event handling for an index pallet NC function.
ncfun-index-table
This is called by the EXEC_NCFUN event handling for an index table NC function.
ncfun-message
This is called by the EXEC_NCFUN event handling for a message NC function.
ncfun-optional-stop
This is called by the EXEC_NCFUN event handling for an optional stop NC function. It is also called durning the workingstep end event handling if required by get_stop_after_workingstep().
ncfun-stop
This is called by the EXEC_NCFUN event handling for a stop NC function.
op-approach-paths
This advances the cursor through the toolpaths in an operation until it finds a toolpath that is not marked as an approach path and required. It returns all formatted MOVE events that it iterated over. This is used when processing an operation of type OP_PROBE to command the probe approach.
op-lift-paths
This advances the cursor through the toolpaths in an operation until it is finished or finds a toolpath that is not marked as an lift path and required. It returns all formatted MOVE events that it iterated over. This is used when processing an operation of type OP_PROBE to command the probe departure after measurement.
probe-comments
This is used when processing an operation of type OP_PROBE. It returns a series of comments that describe the start, end, direction, and expected value of a probe.
probe-datums
This is only used during DMIS output to declare workpiece datums at the start of a program.
refpoint-center
This is called when processing the toolpath start event for a cutter loCation toolpath. By default, it adds a G40 to the next move if previously in cutter contact mode. If needed, it registers the G40 as a prefix for the next move with vars.AddMovePrefix() and calls vars.set_refpoint_center()
refpoint-contact
This is called when processing the toolpath start event for a cutter contact toolpath. By default, it and calls vars.set_refpoint_contact()
refpoint-left
This is called by move-contact after it has determined where the cutter is in contact. If currently not vars.is_refpoint_left(), the function calls vars.set_refpoint_left() and returns G41.
refpoint-right
This is called by move-contact after it has determined where the cutter is in contact. If currently not vars.is_refpoint_right(), the function calls vars.set_refpoint_right() and returns G42.
spindle
Returns codes to turn the spindle on or off as necessary based on the value of get_move_spindle(). The spindle is Set to counter clockwise if the number is positive, clockwise if the number is negative, or spindle-off is called if the number is zero. Called by the toolpath start event handling.
spindle-off
Returns codes to turn off the spindle. Called by the tool change and program end event handling.
tap-first
This us called when processing an operation of type OP_TAP. It returns the starting portion of the tapping.
tap-last
This us called when processing an operation of type OP_TAP. It returns the concluding portion of the tapping.
tap-point
This us called when processing an operation of type OP_TAP. It is called with a get_pos_end() position for each loCation that must be tapped.
timestamp
Returns the current time in ISO date format as a comment. Usually called by the program start event handling.
tool-comment
This is called by the tool change event handling to build a series of comments describing the parameters of the new tool.
workoffset
This is called by the project start event handling to declare the work offset frame requested by get_workoffset_frame().
workplan-probe-end
This is called by the workplan start event handling to add additional commands at the beginning of workplans that contain OP_PROBE operations.
workplan-probe-start
This is called by the workplan end event handling to add additional commands at the completion of workplans that contain OP_PROBE operations.

format_rapid_xyz()

def format_rapid_xyz(self,
	gs: GenerateState,
	cursor: Adaptive,
	x: float, y: float, z: float
	) -> str:

The format_rapid_xyz() function returns a move command as if processing a MOVE event at rapid feed, but the given position is supplied by the caller rather than taken from a toolpath curve. The tool axis is not changed - use format_rapid_xyz_ijk() to change the tool direction.

The position is given in program units and the generate state is updated. The position is used exactly as passed in, no destination transform is applied. The feed rate will return to its previous value on the next move.

The function may return None if no move is needed.

format_rapid_xyz_ijk()

def format_rapid_xyz_ijk(self,
	gs: GenerateState,
	cursor: Adaptive,
	x: float, y: float, z: float,
	i: float, j: float, k: float
	) -> str:

The format_rapid_xyz_ijk() function returns a move command as if processing a MOVE event at rapid feed, but the given position and tool axis direction is supplied by the caller rather than taken from a toolpath curve.

The position is given in program units and the generate state object is updated. The position is used exactly as passed in, no destination transform is applied. The feed rate will return to its previous value on the next move.

The function may return None if no move is needed.

format_type()

def format_type(self,
	gs: GenerateState,
	cursor: Adaptive
	) -> Optional[str]:

The format_type() function calls a formatting function based on the CtlType returned by the get_active_type() of the process cursor. Typically this is done for MOVE and OPERATION_START events. The function may return None if no output is appropriate or no formatting function is registered for a particular type.

You can provide your own formatting function for a type with set_type_fn()

get_angle_digits()

def get_angle_digits(self) -> int:

The get_angle_digits() function returns the maximum digits of precision used when formatting angle values. This is typically defined by the output format but may be changed to different values using the set_angle_digits() function. The get_angle_min_digits() function controls how many digits are always used and whether the trailing decimal point is left on integer values.

get_angle_min_digits()

def get_angle_min_digits(self) -> int:

The get_angle_min_digits() function returns the minimum number of decimal digits that will be used for angle value. If this value is zero, integer values will have a trailing decimal point, if negative the decimal point will be stripped. See cat_number() for examples.

get_blocknum_limit()

def get_blocknum_limit(self) -> int:

The get_blocknum_limit() function returns the upper limit of block numbers, or zero if there is no limit. When numbering is turned on, the block numbers will wrap around if they reach the limit. The GenerateState get_last_blocknum() function returns the last assigned number.

get_chord_tolerance()

def get_chord_tolerance(self) -> float:

The get_chord_tolerance() function returns the chordal tolerance used to break arcs and helixes into line segments when the get_linearize_all_curves() flag is set. This is the maximum distance that the line segment is allowed to be from the original mathematical curve. The default is 0.001 and can be changed by set_chord_tolerance()

get_digits()

def get_digits(self) -> int:

The get_digits() function returns the maximum digits of precision used when formatting coordinate values. This is typically defined by the output format but may be changed to different values using the set_digits() function depending on whether output is in inch, mm, etc. The get_min_digits() function controls how many digits are always used and whether the trailing decimal point is left on integer values

get_dst_xform()

def get_dst_xform(self) -> List[float]:

The get_dst_xform() function returns a coordinate system transform for the output coordinates. This is applied only if get_use_xform() is true. The set_dst_xform() function changes the destination transform.

When outputting moves, the Adaptive object tracks and applies all setup and toolpath transforms present in the STEP-NC process to get the coordinates into the WCS. The destination transform is an extra transform that can be applied afterwards to modify the output for probing results or a machine-specific transform.

get_dst_xform_is_left()

def get_dst_xform_is_left(self) -> bool:

The get_dst_xform_is_left() function returns true if the transform returned by get_dst_xform() uses a left-handed coordinate system. Any transform derived from STEP data will, by definition, only use a right-handed coordinate system.

A left-handed transform, might be used by some machines, like a left-handed lathe. This will also reverse the direction of circular motion and spindle rotation.

get_feed_digits()

def get_feed_digits(self) -> int:

The get_feed_digits() function returns the maximum digits of precision used when formatting feedrate values. This is typically defined by the output format but may be changed to different values using the set_feed_digits() function. The get_feed_min_digits() function controls how many digits are always used and whether the trailing decimal point is left on integer values.

get_feed_is_standalone()

def get_feed_is_standalone(self) -> bool:

The get_feed_is_standalone() function returns true if feedrate changes should be formatted on a separate line and false if they should be appended to the end of the move command to which they apply. Use set_feed_standalone() and set_feed_inline() to change this value.

get_feed_min_digits()

def get_feed_min_digits(self) -> int:

The get_feed_min_digits() function returns the minimum number of decimal digits that will be used for feedrate value. If this value is zero, integer values will have a trailing decimal point, if negative the decimal point will be stripped. See cat_number() for examples.

get_feed_unit()

def get_feed_unit(self) -> Unit:

The get_feed_unit() function returns the velocity unit used for feed rate values.

This value will be set to inch/min or millimeter/min by set_unit_system() depending on whether get_len_unit() is set to Inch or MM. The value may be also be changed with the set_feed_unit() function.

get_file_ext()

def get_file_ext(self) -> str:

The get_file_ext() function returns the preferred filename extension. The values set by the pre-defined styles include the dot separator. For example, .nc, .min, etc. This value can be used by the caller to construct a filename.

get_ijk_digits()

def get_ijk_digits(self) -> int:

The get_ijk_digits() function returns the maximum digits of precision used when formatting IJK direction components. This is typically defined by the output format but may be changed to different values using the set_ijk_digits() function. The get_ijk_min_digits() function controls how many digits are always used and whether the trailing decimal point is left on integer values.

get_ijk_min_digits()

def get_ijk_min_digits(self) -> int:

The get_ijk_min_digits() function returns the minimum number of decimal digits that will be used for IJK direction components. If this value is zero, integer values will have a trailing decimal point, if negative the decimal point will be stripped. See cat_number() for examples.

get_len_unit()

def get_len_unit(self) -> Unit:

The get_len_unit() function returns the length unit used for all coordinate values and for the G70/G71-style units declaration that may appear at the start of a program.

This value is usually initialized from the get_program_unit() and process data by set_unit_system() but may be manually changed with the set_len_unit() function.

If the program unit has a value of AS-IS, the length unit will be a more specific value of INCH/MM found by looking at the toolpath units used by the process. Otherwise the two values will be the same.

get_linearize_all_curves()

def get_linearize_all_curves(self) -> bool:

The get_linearize_all_curves() function returns a boolean flag indicating how arcs and helixes will be treated in the output. If true, the output functions will break arcs and helixes into a series of linear moves. The number of segments is controlled by the get_chord_tolerance() value.

The default is false, and arcs and helixes are output using the circular interpolation appropriate to the format, like G2 or G3 codes. This may be changed by set_linearize_all_curves()

get_min_digits()

def get_min_digits(self) -> int:

The get_min_digits() function returns the minimum number of decimal digits that will be used for coordinate value. If this value is zero, integer values will have a trailing decimal point, if negative the decimal point will be removed. See cat_number() for examples.

get_move_is_modal()

def get_move_is_modal(self) -> bool:

The get_move_is_modal() function returns a boolean value indicating if the movement mode (typically G0 or G1) is only specified once at the start of a series of similar commands (true, modal) or whether it must be specified for each move, regardless of whether the moves are the same type (false, non-modal).

The default is true. The set_move_is_modal() function changes this value.

# codes where move modal = true
G1 X0. Y0. Z0. F20.
Y3.
X1.
Y0.
X2.

# codes where move modal = false
G1 X0. Y0. Z0. F20.
G1 Y3.
G1 X1.
G1 Y0.
G1 X2.

get_out_arc_axis()

def get_out_arc_axis(self,
	cursor: Adaptive,
	pos: int
	) -> tuple[float, float, float]:

The get_out_arc_axis() function is a convenience wrapper for Adaptive::get_arc_axis() that applies the destination transform to the value if needed.

get_out_arc_center()

def get_out_arc_center(self,
	cursor: Adaptive,
	pos: int,
	u: Unit = Unit.AS_IS
	) -> tuple[float, float, float]:

The get_out_arc_center() function is a convenience wrapper for Adaptive::get_arc_center() that applies the destination transform to the value if needed. If a length unit is given, the coordinates will be converted to that unit.

get_out_dirx()

def get_out_dirx(self,
	cursor: Adaptive,
	pos: int
	) -> tuple[float, float, float]:

The get_out_dirx() function is a convenience wrapper for Adaptive::get_pos_dirx() that calls get_pos_default_dirx() if no tool reference direction is defined, and then applies the destination transform to the value if needed.

get_out_dirz()

def get_out_dirz(self,
	cursor: Adaptive,
	pos: int
	) -> tuple[float, float, float]:

The get_out_dirz() function is a convenience wrapper for Adaptive::get_pos_dirz() that calls get_pos_default_dirz() if no tool axis direction is defined, and then applies the destination transform to the value if needed.

get_out_move_dir()

def get_out_move_dir(self,
	cursor: Adaptive,
	pos: int
	) -> tuple[float, float, float]:

The get_out_move_dir() function is a convenience wrapper for Adaptive::get_pos_move_dir() that applies the destination transform to the value if needed.

get_out_snorm_dir()

def get_out_snorm_dir(self,
	cursor: Adaptive,
	pos: int
	) -> tuple[float, float, float]:

The get_out_snorm_dir() function is a convenience wrapper for Adaptive::get_pos_snorm_dir() that applies the destination transform to a the value if needed.

get_out_xformed_dir()

def get_out_xformed_dir(self,
	i: float, j: float, k: float
	) -> tuple[float, float, float]:

The get_out_xformed_dir() function is a convenience wrapper that applies the destination transform to a direction vector if needed.

get_out_xformed_point()

def get_out_xformed_point(self,
	x: float, y: float, z: float
	) -> tuple[float, float, float]:

The get_out_xformed_point() function is a convenience wrapper that applies the destination transform to a coordinate position if needed.

get_out_xyz()

def get_out_xyz(self,
	cursor: Adaptive,
	pos: int,
	u: Unit = Unit.AS_IS
	) -> tuple[float, float, float]:

The get_out_xyz() function is a convenience wrapper for Adaptive::get_pos_xyz() that gets a tuple of coordinate values for a position and applies the destination transform to the value if needed.

get_probe_tool_number()

def get_probe_tool_number(self) -> int:

The get_probe_tool_number() function returns the preferred number that should be used when get_tool_number() is called on a probing tool without a numeric name. Many machine tools are set up with a probe in a fixed location in the changer. Use set_probe_tool_number() to change this value.

get_program_number()

def get_program_number(self) -> int:

The get_program_number() function returns the preferred number that should be used for the program when generating Fanuc-like codes. Use set_program_number() to change this value.

get_program_unit()

def get_program_unit(self) -> Unit:

The get_program_unit() function returns the preferred unit system that should be used for generating output. Call set_program_unit() to change this.

The INCH value Unit.IN implies lengths in inches, feeds in inches per minute, and spindle speeds in RPM. The MILLIMETER value Unit.MM lengths in mm, feeds in mm per minute, and spindle speeds in RPM.

Calling set_unit_system() before beginning to set the actual units for length, feed, and spindle based on your preference. If the program unit is Unit.AS_IS, this will search for the first toolpath units seen and set the unit system from that.

get_spindle_digits()

def get_spindle_digits(self) -> int:

The get_spindle_digits() function returns the maximum digits of precision used when formatting spindle speed values. This is typically defined by the output format but may be changed to different values using the set_spindle_digits() function. The get_spindle_min_digits() function controls how many digits are always used and whether the trailing decimal point is left on integer values.

get_spindle_min_digits()

def get_spindle_min_digits(self) -> int:

The get_spindle_min_digits() function returns the minimum number of decimal digits that will be used for spindle speed values. If this value is zero, integer values will have a trailing decimal point, if negative the decimal point will be stripped. See cat_number() for examples.

get_spindle_unit()

def get_spindle_unit(self) -> Unit:

The get_spindle_unit() function returns the angular velocity unit used for spindle speed values.

This value will be set to revolution/min by set_unit_system(). The value may be also be changed with the set_spindle_unit() function.

get_stop_after_workingstep()

def get_stop_after_workingstep(self) -> bool:

The get_stop_after_workingstep() function returns true if the workingstep end event handling should insert an optional stop code into the output. Call set_stop_after_workingstep() to change this value.

get_supress_x/y/zpos()

def get_supress_xpos(self) -> bool:
def get_supress_ypos(self) -> bool:
def get_supress_zpos(self) -> bool:

The get_supress_x/y/zpos() functions return a flag for each axis. When true, the move formatting code supresses all mention of that axis. This can be used to suppress the Z axis, for example, for 2D output. It is used to suppress the Y axis for lathe output. You can change these values with the set_supress_x/y/zpos functions.

get_tool_number()

def get_tool_number(self,
	tool: Object
	) -> int:

The get_tool_number() function takes a machining tool STEP instance, such as that returned by the process cursor get_active_tool() function, and returns a tool number parsed from the name or description of the tool. If no value is found and the tool is a probing tool the get_probe_tool_number() value will be returned.

get_trace_comments()

def get_trace_comments(self) -> TraceComments:

The get_trace_comments() function returns an enum value that describes where comments are placed in the output. See set_trace_comments() for more description of how this works.

get_use_blocknums()

def get_use_blocknums(self) -> bool:

The get_use_blocknums() function returns true if individual commands in the output should be preceedded by a "N" number. The format_block function looks at this setting and prepends the number if needed.

This setting can be changed for most styles by set_use_blocknums(). Some output styles, like heidenhain, force this value to true because they require block numbers.

FMT.format_block(vars,HELLO WORLD);  // use blocknums = false
=> HELLO WORLD

FMT.format_block(vars,HELLO WORLD);  // use blocknums = true
=> N1234 HELLO WORLD

get_use_speed_override()

def get_use_speed_override(self) -> bool:

The get_use_speed_override() function returns true if speed profile curves in the data will be used to continuously modify the feed rates over the course of a toolpath. These override speeds are computed by a feed speed optimizer instead of the base speeds stored in the STEP-NC data.

A value of false means that the speed profile curve is ignored and toolpaths will use the base feed over its entire length.

A speed profile curve is a one dimensional curve that gives a ratio (value 0 to 1 or more) that is multiplied by the base feedrate to give the feed at each point in the toolpath. The curve has same parameterization as the toolpath, which usually means it is a polyline with the same number of points.

The set_use_speed_override() function is used to control this behavior.

get_use_tcp()

def get_use_tcp(self) -> bool:

The get_use_tcp() function returns true if five-axis moves will be generated using TCP codes. This is a legacy function and should be replaced by separate code generation styles. The set_use_tcp() function changes this value.

get_use_tool_constchip()

def get_use_tool_constchip(self) -> bool:

The get_use_tool_constchip() function returns true if codes will be generated using a constant chip load optimization when a tool has a different actual flute count than the planned one.

The set_use_tool_constchip() function is used to control this behavior.

get_use_whitespace()

def get_use_whitespace(self) -> bool:

The get_use_whitespace() function returns true if parameters assembled by the cat_param() function should be separated by space characters. The cat_space() also appends a space to non-empty inputs if this value is true. This setting can be changed by set_use_whitespace().

FMT = step.Generate();

RET = G1;
RET = FMT.cat_param(RET, X, 1.23);
RET = FMT.cat_param(RET, Y, 4.56);
RET = FMT.cat_param(RET, Z, 7.89);

=> G1X1.23Y4.56Z7.89      # use whitespace = false

=> G1 X1.23 Y4.56 Z7.89   # use whitespace = true

get_use_xform()

def get_use_xform(self) -> bool:

The get_use_xform() function returns true if the destination transform given by get_dst_xform() should be applied to all coordinates and directions. This value can be changed by set_use_xform() and affects the behavior of all of the "get_out" prefixed functions.

get_workoffset_frame()

def get_workoffset_frame(self) -> int:

The get_workoffset_frame() function returns the preferred number of the work offset frame that should be selected by the project start event handling. The actual command may change from style to style, but typical usage is G54 for frame #1, G55 for frame #2, etc. This value can be changed by the set_workoffset_frame() function.

is_formatted_ijk()

def is_formatted_ijk(self,
	i1: float, j1: float, k1: float,
	i2: float, j2: float, k2: float
	) -> bool:

The is_formatted_ijk() function returns true if the two direction vectors are equal when formatted to the digits of precision given by the get_digits() value.

is_formatted_number()

def is_formatted_number(self,
	num1: float,
	num2: float,
	max_digits: int = None
	) -> bool:

The is_formatted_number() function returns true if the two numbers equal when formatted to the digits of precision given by the get_digits() value. A different formatting specification can be passed in as an optional parameter.

is_formatted_xyz()

def is_formatted_xyz(self,
	x1: float, y1: float, z1: float,
	x2: float, y2: float, z2: float
	) -> bool:

The is_formatted_xyz() function returns true if the two coordinates are equal when formatted to the digits of precision given by the GetDigits() value.

reset()

def reset(self) -> None:

The reset() function restores the default settings for all values, including user preferences like get_workoffset_frame(), get_program_unit(), etc.

set_angle_digits()

def set_angle_digits(self,
	cnt: int
	) -> None:

The set_angle_digits() function sets the maximum digits of precision used when formatting angle values. See get_angle_digits() for discussion.

set_angle_min_digits()

def set_angle_min_digits(self,
	cnt: int
	) -> None:

The set_angle_min_digits() function sets the minimum number of digits of precision used when formatting angle values. See get_angle_min_digits() for discussion.

set_blocknum_limit()

def set_blocknum_limit(self,
	num: int
	) -> None:

The set_blocknum_limit() function sets the upper limit of block numbers for the output. Set to zero to indicate no limit. See get_blocknum_limit() for more discussion on this use.

set_chord_tolerance()

def set_chord_tolerance(self,
	tol: float
	) -> None:

The set_chord_tolerance() function changes the chordal tolerance used to break arcs and helixes into line segments when the get_linearize_all_curves() flag is true. This is the maximum distance that the line segment is allowed to be from the original mathematical curve.

set_digits()

def set_digits(self,
	cnt: int
	) -> None:

The set_digits() function sets the maximum digits of precision used when formatting coordinate values. You can control the precision of other values with set_angle_digits(), set_feed_digits(), set_ijk_digits(), and set_spindle_digits(). See get_digits() for more discussion.

set_dst_xform()

def set_dst_xform(self,
	xf: Sequence[float]
	) -> None:

The set_dst_xform() function sets a a coordinate system transform that is applied to the output coordinates. This is applied in addition to any setup transform that may be included in the STEP-NC process, and is generally used for adjusting for something unique to the machine tool.

set_event_fn()

def set_event_fn(self,
	e: CtlEvent,
	fn: GenerateFn
	) -> None:

# Where the callback function has the form:
#  def GenerateFn(
#     gen: Generate,
#     gs: GenerateState,
#     cur: Adaptive
#     ) -> Optional[str]
     

The set_event_fn() function associates a callback function to be used when format_event() is called for a given event. The callback function is passed an argument list with Generate, GenerateState, and Adaptive objects, and should return a string containing codes, or None.

The set_style() function assigns builtin callbacks for a given kind of output. You can replace these with your own variations or different builtins.

set_feed_digits()

def set_feed_digits(self,
	cnt: int
	) -> None:

The set_feed_digits() function sets the maximum digits of precision used when formatting feedrate values. See get_feed_digits() for discussion.

set_feed_inline()

def set_feed_inline(self) -> None:

The set_feed_inline() function sets the value returned by get_feed_is_standalone() to false. This means that feedrate changes should be appended to the end of the move command to which they apply. This is the opposite of set_feed_standalone()

set_feed_min_digits()

def set_feed_min_digits(self,
	cnt: int
	) -> None:

The set_feed_min_digits() function sets the minimum number of digits of precision used when formatting feedrate values. See get_feed_min_digits() for discussion.

set_feed_standalone()

def set_feed_standalone(self) -> None:

The set_feed_standalone() function sets the value returned by get_feed_is_standalone() to true. This means that feedrate changes should be formatted on a separate line preceeding the move command to which they apply. This is the opposite of set_feed_inline()

set_feed_unit()

def set_feed_unit(self,
	u: Unit
	) -> None:

The set_feed_unit() function changes the linear velocity unit used for feed rate values. This value will be overwritten every time set_unit_system() is called. See get_feed_unit() for more discussion.

set_file_ext()

def set_file_ext(self,
	ext: str
	) -> None:

The set_file_ext() function sets the preferred filename extension. See get_file_ext() for more discussion.

set_ijk_digits()

def set_ijk_digits(self,
	cnt: int
	) -> None:

The set_ijk_digits() function sets the maximum digits of precision used when formatting IJK values. See get_ijk_digits() for discussion.

set_ijk_min_digits()

def set_ijk_min_digits(self,
	cnt: int
	) -> None:

The set_ijk_min_digits() function sets the minimum number of digits of precision used when formatting IJK values. See get_ijk_min_digits() for discussion.

set_len_unit()

def set_len_unit(self,
	u: Unit
	) -> None:

The set_len_unit() function changes the length unit used for all coordinate values. This value will be overwritten every time set_unit_system() is called. See get_len_unit() for more discussion.

set_linearize_all_curves()

def set_linearize_all_curves(self,
	yn: bool
	) -> None:

The set_linearize_all_curves() function changes how arcs and helixes will be treated in the output.

If true, the output functions will break arcs and helixes into a series of linear moves. The number of segments is controlled by the get_chord_tolerance() value.

If false, and arcs and helixes are output using the circular interpolation appropriate to the format, like G2 or G3 codes. See get_linearize_all_curves() for more information.

set_min_digits()

def set_min_digits(self,
	cnt: int
	) -> None:

The set_min_digits() function sets the minimum number of digits of precision used when formatting feedrate values. See get_min_digits() for discussion.

set_move_is_modal()

def set_move_is_modal(self,
	yn: bool
	) -> None:

The set_move_is_modal() function controls whether the movement mode (typically G0 or G1) is only specified once at the start of a series of similar commands (true, modal) or whether it must be specified for each move, regardless of whether the moves are the same type (false, non-modal). See get_move_is_modal() for more information.

set_other_fn()

def set_other_fn(self,
	nm: str,
	fn: GenerateFn
	) -> None:

# Where the callback function has the form:
#  def GenerateFn(
#     gen: Generate,
#     gs: GenerateState,
#     cur: Adaptive
#     ) -> Optional[str]
     

The set_other_fn() function associates a function with a given name in a dictionary of callbacks kept by the Generate object and used by the format_other() function. You are free to replace the function for a given name or add functions with your own unique names. The names used by the builtin styles are documented with format_other().

The callback function is passed an argument list with Generate, GenerateState, and Adaptive objects, and should return a string containing codes, or None.

set_probe_tool_number()

def set_probe_tool_number(self,
	tool: int
	) -> None:

The set_probe_tool_number() function changes the preferred number that should be used when get_tool_number() is called on a probing tool without a numeric name. See get_probe_tool_number() for more discussion.

set_program_number()

def set_program_number(self,
	pn: int
	) -> None:

The set_program_number() function sets the program number used for the program when generating Fanuc-like codes. See get_program_number() for more discussion.

set_program_unit()

def set_program_unit(self,
	u: Unit
	) -> None:

The set_program_unit() function sets the preferred unit system that should be used for generating output.

The MILLIMETER value Unit.MM always creates with lengths in mm, feeds in mm per minute, and spindle speeds in RPM. Values are converted as needed.

The INCH value Unit.IN creates with lengths in inches, feeds in inches per minute, and spindle speeds in RPM. Values are converted as needed.

The AS-IS value Unit.AS_IS creates with the unit system (MM or INCH) that is present in the file.

GEN = step.Generate();
GEN.set_style(haas);

GEN.set_program_unit(step.Unit.MM)    # use millimeters OR
GEN.set_program_unit(step.Unit.IN)    # use inches OR
GEN.set_program_unit(step.Unit.AS_IS) # use units from the file

GEN.export_cncfile(filename.nc);

set_spindle_digits()

def set_spindle_digits(self,
	cnt: int
	) -> None:

The set_spindle_digits() function sets the maximum digits of precision used when formatting spindle speed values. See get_spindle_digits() for discussion.

set_spindle_min_digits()

def set_spindle_min_digits(self,
	cnt: int
	) -> None:

The set_spindle_min_digits() function sets the minimum number of digits of precision used when formatting spindle speed values. See get_spindle_min_digits() for discussion.

set_spindle_unit()

def set_spindle_unit(self,
	u: Unit
	) -> None:

The set_spindle_unit() function changes the angular velocity unit used for spindle speed values. This value will be overwritten every time set_unit_system() is called. See get_spindle_unit() for more discussion.

set_stop_after_workingstep()

def set_stop_after_workingstep(self,
	yn: bool
	) -> None:

The set_stop_after_workingstep() function controls whether the workingstep end event handling inserts an optional stop code into the output at the end of each workingstep.

This is independent of the any STEP-NC stop or optional stop NC functions that may already be in the code and gives the operator more control when testing a program on a new machine.

See get_stop_after_workingstep() for more discussion.

set_style()

def set_style(self,
	name: str
	) -> bool:

The set_style() function configures the output to the built-in style with a given name. The function returns true if the style was found and false otherwise. Refer to the list of built-in styles other formatting functions for more information.

Most styles begin by calling reset() so any prior settings will be lost.

The following example prints Haas machine tool control codes for a STEP-NC process.

CUR = step.Adaptive()
GEN = step.Generate()
GS = step.GenerateState()

CUR.start_project(DESIGN)   # design from apt or finder open
CUR.set_wanted_all()

GEN.set_style(haas);
GEN.set_unit_system(CUR);

# print empty string when the format returns None, do not end with a
# newline since the format strings already have them where needed.
while CUR.next():
    print(GEN.format_event(GS,CUR) or '', end='')

set_supress_x/y/zpos()

def set_supress_xpos(self, yn: bool) -> None:
def set_supress_ypos(self, yn: bool) -> None:
def set_supress_zpos(self, yn: bool) -> None:

The set_supress_x/y/zpos() functions supress mention of particular axis. This may be useful for 2D output, lathes, etc. See get_supress_x/y/zpos for more details.

set_trace_comments()

def set_trace_comments(self,
	cmt: TraceComments
	) -> None:

class TraceComments(IntEnum):
    NONE
    WORKPLAN		# before each workplan
    WORKINGSTEP		# before each workingstep
    TOOLPATH		# before each toolpath
    POINT		# at each point
    ALL_STEP		# all possible comments

The set_trace_comments() function controls where descriptive comments are placed in the output. The levels go from less descriptive to more detailed, with one including the comments of the previous level. The default value is before each workingstep. The get_trace_comments returns the current setting.

set_type_fn()

def set_type_fn(self,
	e: CtlType,
	fn: GenerateFn
	) -> None:

# Where the callback function has the form:
#  def GenerateFn(
#     gen: Generate,
#     gs: GenerateState,
#     cur: Adaptive
#     ) -> Optional[str]
     

The set_type_fn() function associates a callback function to be used when format_type() is called for a given type of STEP-NC element. The callback function is passed an argument list with Generate, GenerateState, and Adaptive objects, and should return a string containing codes, or None.

The set_style() function assigns builtin callbacks for a given kind of output. You can replace these with your own variations or different builtins.

set_unit_system()

def set_unit_system(self,
	cursor: Adaptive
	) -> None:

The set_unit_system() function sets the system of length, feed, and spindle speed units. These are set to match to match the program unit preference. If the preference is AS-IS, the function will use the supplied cursor to find the length units of the toolpaths in the process. The unit system values are returned by the get_len_unit(), get_feed_unit() and get_spindle_unit() functions.

set_use_blocknums()

def set_use_blocknums(self,
	yn: bool
	) -> None:

The set_use_blocknums() function controls whether the format_block function should prefix every line with a "N" number. See get_use_blocknums() for more discussion.

set_use_speed_override()

def set_use_speed_override(self,
	yn: bool
	) -> None:

The set_use_speed_override() function controls whether speed profile curves in the data will be used to continuously modify the feed rates over the course of a toolpath. See get_use_speed_override() for more discussion.

set_use_tcp()

def set_use_tcp(self,
	yn: bool
	) -> None:

The set_use_tcp() function controls whether five-axis moves will be generated using TCP codes. This is a legacy function and should be replaced by separate code generation styles. See get_use_tcp() for more discussion.

set_use_tool_constchip()

def set_use_tool_constchip(self,
	yn: bool
	) -> None:

The set_use_tool_constchip() function controls whether codes will be generated using a constant chip load optimization when a tool has a different actual flute count than the planned one. See get_use_tool_constchip() for more discussion.

set_use_whitespace()

def set_use_whitespace(self,
	yn: bool
	) -> None:

The set_use_whitespace() function sets a flag that indicates whether numeric parameters should be separated by space characters in the output. See get_use_whitespace() for more discussion and examples.

set_use_xform()

def set_use_xform(self, yn: bool) -> None:

The set_use_xform() function controls whether the destination transform given by get_dst_xform() is applied to all coordinates and directions. This affects the behavior of all of the "get_out" prefixed functions. You can query this value with get_use_xform() and you can set the destination transform with set_dst_xform().

set_workoffset_frame()

def set_workoffset_frame(self,
	ofs: int
	) -> None:

The set_workoffset_frame() function sets the preferred number of the work offset frame that should be selected by the PROJECT_START event handling. A value of -1 means "as-is", do not emit any offset settings. See get_workoffset_frame() for more discussion.