pyGCodeDecode API Reference

pyGCodeDecode.abaqus_file_generator

Module for generating Abaqus .inp files for AMSIM.

generate_abaqus_event_series

def generate_abaqus_event_series(simulation: gcode_interpreter.simulation,
                                 filepath: str
                                 | Path = "pyGcodeDecode_abaqus_events.inp",
                                 tolerance: float = 1e-12,
                                 output_unit_system: str | None = None,
                                 return_tuple: bool = False) -> tuple

Generate abaqus event series.

Arguments:

  • simulation gcode_interpreter.simulation - simulation instance
  • filepath string, default = "pyGcodeDecode_abaqus_events.inp" - output file path
  • tolerance float, default = 1e-12 - tolerance to determine whether extrusion is happening
  • output_unit_system str, optional - Unit system for the output. The one from the simulation is used, in None is specified.
  • return_tuple bool, default = False - return the event series as tuple.

Returns:

(optional) tuple: the event series as a tuple for use in ABAQUS-Python

pyGCodeDecode.cli

The pyGCodeDecode CLI Module.

Interact with pyGCodeDecode via the command line to run examples and plot GCode files.

Features:

  • Run built-in examples: brace, benchy
  • Plot GCode files with printer presets and output options
  • Save simulation summaries, metrics, screenshots, and VTK files

Usage Examples:

  • pygcd --help
  • pygcd run_example brace
  • pygcd plot -g myfile.gcode
  • pygcd plot -g myfile.gcode -p presets.yaml -pn my_printer
  • pygcd plot -g myfile.gcode -o ./outputs -lc ";LAYER"

pyGCodeDecode.gcode_interpreter

GCode Interpreter Module.

find_current_segment

def find_current_segment(
        path: list[segment],
        t: float,
        last_index: int | None = None,
        keep_position: bool = False) -> tuple[segment | None, int | None]

Find the current segment.

Arguments:

  • path - (list[segment]) all segments to be searched
  • t - (float) time of search
  • last_index - (int) last found index for optimizing search
  • keep_position - (bool) keeps position of last segment, use this when working with gaps of no movement between segments

Returns:

  • segment - (segment) the segment which defines movement at that point in time
  • last_index - (int) last index where something was found, search speed optimization possible

generate_planner_blocks

def generate_planner_blocks(
        states: list[state],
        firmware: str | None = None) -> list[planner_block]

Convert list of states to trajectory repr. by planner blocks.

Arguments:

  • states - (list[state]) list of states
  • firmware - (string, default = None) select firmware by name

Returns:

block_list (list[planner_block]) list of all planner blocks to complete travel between all states

setup Objects

class setup()

Setup for printing simulation.

setup.__getattr__

def __getattr__(name: str) -> object

Access to setup_dict content.

setup.__init__

def __init__(presets_file: Path | str,
             printer: str | None = None,
             verbosity_level: int | None = None,
             **kwargs: object) -> None

Initialize the setup for the printing simulation.

Arguments:

  • presets_file Path or str - Path to the YAML file containing printer presets.
  • printer str, optional - Name of the printer to select from the preset file. Defaults to None.
  • verbosity_level int, optional - Verbosity level for logging
  • (0 - no output, 1: warnings, 2: info, 3: debug). Defaults to None.
  • **kwargs - Additional properties to set or override in the setup.

Raises:

  • ValueError - If multiple printers are found in the preset file but none is selected.

setup.__setattr__

def __setattr__(name: str, value: object) -> None

Set setup_dict keys.

setup.check_initial_setup

def check_initial_setup() -> None

Check the printer Dict for typos or missing parameters and raise errors if invalid.

setup.get_dict

def get_dict() -> dict

Return the setup for the selected printer.

Returns:

  • return_dict - (dict) setup dictionary

setup.get_scaling_factor

def get_scaling_factor(input_unit_system: str | None = None) -> float

Get a scaling factor to convert lengths from mm to another supported unit system.

Arguments:

  • input_unit_system str, optional - Wanted input unit system. Uses the one specified for the setup if None is specified.

Returns:

  • float - scaling factor

setup.load_setup

def load_setup(filepath: Path | str, printer: str | None = None) -> None

Load setup from file.

Arguments:

  • filepath - (string or Path) specify path to setup file

setup.set_initial_position

def set_initial_position(initial_position: tuple | dict | str,
                         input_unit_system: str | None = None) -> None

Set initial Position.

Arguments:

  • initial_position - (tuple, dict or str) set initial position as tuple of len(4) or "first" or dictionary with keys: {X, Y, Z, E} or "first" to use first occurring absolute position in GCode.
  • input_unit_system str, optional - Wanted input unit system. Uses the one specified for the setup if None is specified.

Example:

setup.set_initial_position((1, 2, 3, 4))
setup.set_initial_position({"X": 1, "Y": 2, "Z": 3, "E": 4})
setup.set_initial_position("first") # use first GCode position

setup.set_property

def set_property(property_dict: dict) -> None

Overwrite or add a property to the printer dictionary.

Arguments:

  • property_dict - (dict) set or add property to the setup

Example:

setup.set_property({"layer_cue": "LAYER_CHANGE"})

simulation Objects

class simulation()

Simulation of .gcode with given machine parameters.

simulation.__getattr__

def __getattr__(name: str) -> object

Get result by name.

simulation.__init__

def __init__(gcode_path: Path,
             machine_name: str | None = None,
             initial_machine_setup: setup | None = None,
             output_unit_system: str = "SI (mm)",
             verbosity_level: int | None = None) -> None

Initialize the Simulation of a G-code with initial machine setup or default machine.

  • Generate all states from GCode.
  • Connect states with planner blocks, consisting of segments
  • Self correct inconsistencies.

Arguments:

  • gcode_path - (Path) path to GCode
  • machine_name - (string, default = None) name of the default machine to use
  • initial_machine_setup - (setup, default = None) setup instance
  • output_unit_system - (string, default = "SI (mm)") available unit systems: SI, SI (mm) & inch
  • verbosity_level - (int, default = None) set verbosity level (0: no output, 1: warnings, 2: info, 3: debug)

Example:

gcode_interpreter.simulation(gcode_path=r"path/to/a.gcode", initial_machine_setup=setup)

simulation.calc_results

def calc_results() -> None

Calculate the results.

simulation.calculate_averages

def calculate_averages() -> None

Calculate averages for averageable results.

simulation.extrusion_extent

def extrusion_extent(output_unit_system: str | None = None) -> np.ndarray

Return scaled xyz min & max while extruding.

Arguments:

  • output_unit_system str, optional - Unit system for the output. The one from the simulation is used, in None is specified.

Raises:

  • ValueError - if nothing is extruded

Returns:

  • np.ndarray - extent of extruding positions

simulation.extrusion_max_vel

def extrusion_max_vel(output_unit_system: str | None = None) -> np.float64

Return scaled maximum velocity while extruding.

Arguments:

  • output_unit_system str, optional - Unit system for the output. The one from the simulation is used, in None is specified.

Returns:

  • max_vel - (np.float64) maximum travel velocity while extruding

simulation.get_scaling_factor

def get_scaling_factor(output_unit_system: str | None = None) -> float

Get a scaling factor to convert lengths from mm to another supported unit system.

Arguments:

  • output_unit_system str, optional - Wanted output unit system. Uses the one specified for the simulation on None is specified.

Returns:

  • float - scaling factor

simulation.get_values

def get_values(
        t: float,
        output_unit_system: str | None = None
) -> tuple[list[float], list[float]]

Return unit system scaled values for vel and pos.

Arguments:

  • t - (float) time
  • output_unit_system str, optional - Unit system for the output. The one from the simulation is used, in None is specified.

Returns:

  • list - [vel_x, vel_y, vel_z, vel_e] velocity
  • list - [pos_x, pos_y, pos_z, pos_e] position

simulation.get_width

def get_width(t: float,
              extrusion_h: float,
              filament_dia: float | None = None) -> float

Return the extrusion width for a certain extrusion height at time.

Arguments:

  • t float - time
  • extrusion_h float - extrusion height / layer height
  • filament_dia float - filament_diameter

Returns:

  • float - width

simulation.print_summary

def print_summary(start_time: float) -> None

Print simulation summary to console.

Arguments:

  • start_time float - time when the simulation run was started

simulation.refresh

def refresh(new_state_list: list[state] | None = None) -> None

Refresh simulation. Either through new state list or by rerunning the self.states.

Arguments:

  • new_state_list - (list[state], default = None) new list of states, if None is provided, existing states get resimulated

simulation.save_summary

def save_summary(filepath: Path | str) -> None

Save summary to .yaml file.

Arguments:

  • filepath Path | str - path to summary file

Saved data keys: - filename (string, filename) - t_end (float, end time) - x/y/z _min/_max (float, extent where positive extrusion) - max_extrusion_travel_velocity (float, maximum travel velocity where positive extrusion)

simulation.trajectory_self_correct

def trajectory_self_correct() -> None

Self correct all blocks in the blocklist with self_correction() method.

unpack_blocklist

def unpack_blocklist(blocklist: list[planner_block]) -> list[segment]

Return list of segments by unpacking list of planner blocks.

Arguments:

  • blocklist - (list[planner_block]) list of planner blocks

Returns:

  • path - (list[segment]) list of all segments

pyGCodeDecode.helpers

Helper functions.

custom_print

def custom_print(*args: object, lvl: int = 2, **kwargs: object) -> None

Sanitize outputs for ABAQUS and print them if the log level is high enough.

Arguments:

  • *args - arguments to be printed
  • lvl - verbosity level of the print (1 = WARNING, 2 = INFO, 3 = DEBUG)
  • **kwargs - keyword arguments to be passed to print

get_verbosity_level

def get_verbosity_level() -> int

Get the current global verbosity level.

ProgressBar Objects

class ProgressBar()

A simple progress bar for the console.

ProgressBar.__init__

def __init__(name: str = "Percent",
             barLength: int = 4,
             verbosity_level: int = 2) -> None

Initialize a progress bar.

ProgressBar.update

def update(progress: float) -> None

Display or update a console progress bar.

Arguments:

  • progress - float between 0 and 1, < 0 represents a 'halt', > 1 represents 100%

set_verbosity_level

def set_verbosity_level(level: int | None) -> None

Set the global verbosity level.

pyGCodeDecode.helpers.VERBOSITY_LEVEL

default to INFO

pyGCodeDecode.junction_handling

Junction handling module for calculating the velocity at junctions.

get_handler

def get_handler(firmware_name: str) -> type[junction_handling]

Get the junction handling class for the given firmware name.

Arguments:

  • firmware_name - (str) name of the firmware

Returns:

  • junction_handling - (type[junction_handling]) junction handling class

junction_deviation Objects

class junction_deviation(junction_handling)

Marlin specific junction handling with Junction Deviation.

Reference: 1: Developer Blog 2: Kynetic CNC Blog

junction_deviation.__init__

def __init__(state_A: state, state_B: state) -> None

Marlin specific junction velocity calculation with Junction Deviation.

Arguments:

  • state_A - (state) start state
  • state_B - (state) end state

junction_deviation.calc_JD

def calc_JD(vel_0: velocity, vel_1: velocity,
            p_settings: state.p_settings) -> float

Calculate junction deviation velocity from 2 velocities.

Arguments:

  • vel_0 - (velocity) entry
  • vel_1 - (velocity) exit
  • p_settings - (state.p_settings) print settings

Returns:

  • velocity - (float) velocity abs value

junction_deviation.get_junction_vel

def get_junction_vel() -> float

Return junction velocity.

Returns:

  • junction_vel - (float) junction velocity

junction_handling Objects

class junction_handling()

Junction handling super class.

junction_handling.__init__

def __init__(state_A: state, state_B: state) -> None

Initialize the junction handling.

Arguments:

  • state_A - (state) start state
  • state_B - (state) end state

junction_handling.connect_state

def connect_state(state_A: state, state_B: state) -> velocity

Connect two states and generates the velocity for the move from state_A to state_B.

Arguments:

  • state_A - (state) start state
  • state_B - (state) end state

Returns:

  • velocity - (float) the target velocity for that travel move

junction_handling.get_junction_vel

def get_junction_vel() -> int

Return default junction velocity of zero.

Returns:

  • 0 - zero for default full stop junction handling

junction_handling.get_target_vel

def get_target_vel() -> velocity

Return target velocity.

marlin Objects

class marlin(junction_handling)

Marlin classic jerk specific junction handling.

Code reference: Marlin/src/module/planner.cpp

// ...
float v_factor = 1.0f;
LOOP_LOGICAL_AXES(i) {
  // Jerk is the per-axis velocity difference.
  const float jerk = ABS(speed_diff[i]), maxj = max_j[i];
  if (jerk * v_factor > maxj) v_factor = maxj / jerk;
}
vmax_junction_sqr = sq(vmax_junction * v_factor);
// ...

marlin.__init__

def __init__(state_A: state, state_B: state) -> None

Marlin classic jerk specific junction velocity calculation.

Arguments:

  • state_A - (state) start state
  • state_B - (state) end state

marlin.calc_j_vel

def calc_j_vel() -> None

Calculate the junction velocity.

marlin.get_junction_vel

def get_junction_vel() -> float

Return the calculated junction velocity.

Returns:

  • junction_vel - (float) junction velocity

mka Objects

class mka(prusa)

Anisoprint Composer models using MKA Firmware junction handling.

The MKA firmware uses a similar approach to Prusa's classic jerk handling.

Code reference: anisoprint/MKA-firmware/src/core/planner/planner.cpp

// ...
float v_exit = previous_speed[axis] * smaller_speed_factor,
        v_entry = current_speed[axis];
  if (limited) {
    v_exit *= v_factor;
    v_entry *= v_factor;
  }

  // Calculate jerk depending on whether the axis is coasting in the same direction or reversing.
  const float jerk = (v_exit > v_entry)
      ? //                                  coasting             axis reversal
        ( (v_entry > 0 || v_exit < 0) ? (v_exit - v_entry) : max(v_exit, -v_entry) )
      : // v_exit <= v_entry                coasting             axis reversal
        ( (v_entry < 0 || v_exit > 0) ? (v_entry - v_exit) : max(-v_exit, v_entry) );

  const float maxj = mechanics.max_jerk[axis];
  if (jerk > maxj) {
    v_factor *= maxj / jerk;
    ++limited;
  }
}
if (limited) vmax_junction *= v_factor;
// ...

prusa Objects

class prusa(junction_handling)

Prusa specific classic jerk junction handling (validated on Prusa Mini).

Code reference: Prusa-Firmware-Buddy/lib/Marlin/Marlin/src/module/planner.cpp

// ...
// Factor to multiply the previous / current nominal velocities to get componentwise limited velocities.
  float v_factor = 1;
  limited = 0;

  // The junction velocity will be shared between successive segments. Limit the junction velocity to their minimum.
  // Pick the smaller of the nominal speeds. Higher speed shall not be achieved at the junction during coasting.
  vmax_junction = _MIN(block->nominal_speed, previous_nominal_speed);

  // Now limit the jerk in all axes.
  const float smaller_speed_factor = vmax_junction / previous_nominal_speed;
  `if` HAS_LINEAR_E_JERK
    LOOP_XYZ(axis)
  `else`
    LOOP_XYZE(axis)
  `endif`
  {
    // Limit an axis. We have to differentiate: coasting, reversal of an axis, full stop.
    float v_exit = previous_speed[axis] * smaller_speed_factor,
          v_entry = current_speed[axis];
    if (limited) {
      v_exit *= v_factor;
      v_entry *= v_factor;
    }

    // Calculate jerk depending on whether the axis is coasting in the same direction or reversing.
    const float jerk = (v_exit > v_entry)
        ? //                                  coasting             axis reversal
          ( (v_entry > 0 || v_exit < 0) ? (v_exit - v_entry) : _MAX(v_exit, -v_entry) )
        : // v_exit <= v_entry                coasting             axis reversal
          ( (v_entry < 0 || v_exit > 0) ? (v_entry - v_exit) : _MAX(-v_exit, v_entry) );

    if (jerk > settings.max_jerk[axis]) {
      v_factor *= settings.max_jerk[axis] / jerk;
      ++limited;
    }
  }
  if (limited) vmax_junction *= v_factor;
  // Now the transition velocity is known, which maximizes the shared exit / entry velocity while
  // respecting the jerk factors, it may be possible, that applying separate safe exit / entry velocities will achieve faster prints.
  const float vmax_junction_threshold = vmax_junction * 0.99f;
  if (previous_safe_speed > vmax_junction_threshold && safe_speed > vmax_junction_threshold)
    vmax_junction = safe_speed;
}
// ...

prusa.__init__

def __init__(state_A: state, state_B: state) -> None

Marlin classic jerk specific junction velocity calculation.

Arguments:

  • state_A - (state) start state
  • state_B - (state) end state

prusa.calc_j_vel

def calc_j_vel() -> None

Calculate the junction velocity.

prusa.get_junction_vel

def get_junction_vel() -> float

Return the calculated junction velocity.

Returns:

  • junction_vel - (float) junction velocity

ultimaker Objects

class ultimaker(junction_handling)

Ultimaker specific junction handling.

Code reference: UM2.1-Firmware/Marlin/planner.cpp

// ...
float vmax_junction = max_xy_jerk/2;
float vmax_junction_factor = 1.0;
if(fabs(current_speed[Z_AXIS]) > max_z_jerk/2)
    vmax_junction = min(vmax_junction, max_z_jerk/2);
if(fabs(current_speed[E_AXIS]) > max_e_jerk/2)
    vmax_junction = min(vmax_junction, max_e_jerk/2);
vmax_junction = min(vmax_junction, block->nominal_speed);
float safe_speed = vmax_junction;

if ((moves_queued > 1) && (previous_nominal_speed > 0.0001)) {
    float xy_jerk = sqrt(square(current_speed[X_AXIS]-previous_speed[X_AXIS])+square(current_speed[Y_AXIS]-previous_speed[Y_AXIS]));
    //    if((fabs(previous_speed[X_AXIS]) > 0.0001) || (fabs(previous_speed[Y_AXIS]) > 0.0001)) {
    vmax_junction = block->nominal_speed;
    //    }
    if (xy_jerk > max_xy_jerk) {
    vmax_junction_factor = (max_xy_jerk / xy_jerk);
    }
    if(fabs(current_speed[Z_AXIS] - previous_speed[Z_AXIS]) > max_z_jerk) {
    vmax_junction_factor= min(vmax_junction_factor, (max_z_jerk/fabs(current_speed[Z_AXIS] - previous_speed[Z_AXIS])));
    }
    if(fabs(current_speed[E_AXIS] - previous_speed[E_AXIS]) > max_e_jerk) {
    vmax_junction_factor = min(vmax_junction_factor, (max_e_jerk/fabs(current_speed[E_AXIS] - previous_speed[E_AXIS])));
    }
    vmax_junction = min(previous_nominal_speed, vmax_junction * vmax_junction_factor); // Limit speed to max previous speed
}
// Max entry speed of this block equals the max exit speed of the previous block.
block->max_entry_speed = vmax_junction;
// ...

ultimaker.__init__

def __init__(state_A: state, state_B: state) -> None

Ultimaker specific junction velocity calculation.

Arguments:

  • state_A - (state) start state
  • state_B - (state) end state

ultimaker.calc_j_vel

def calc_j_vel() -> None

Calculate the junction velocity.

ultimaker.get_junction_vel

def get_junction_vel() -> float

Return the calculated junction velocity.

Returns:

  • junction_vel - (float) junction velocity

pyGCodeDecode.planner_block

Planner block Module.

planner_block Objects

class planner_block()

Planner Block Class.

planner_block.__init__

def __init__(state: state,
             prev_block: planner_block,
             firmware: str | None = None) -> None

Calculate and store planner block consisting of one or multiple segments.

Arguments:

  • state - (state) the current state
  • prev_block - (planner_block) previous planner block
  • firmware - (string, default = None) firmware selection for junction

planner_block.__repr__

def __repr__() -> str

Represent planner block.

planner_block.__str__

def __str__() -> str

Create a visually aligned ASCII art string for planner block.

planner_block.calc_results

def calc_results(*additional_calculators: abstract_result) -> None

Calculate the result of the planner block.

planner_block.extrusion_block_max_vel

def extrusion_block_max_vel() -> np.ndarray | None

Return max vel from planner block while extruding.

Returns:

  • block_max_vel - (np.ndarray 1x4) maximum axis velocity while extruding in block or None if no extrusion is happening

planner_block.get_block_travel

def get_block_travel() -> float

Return the travel length of the planner block.

planner_block.get_segments

def get_segments() -> list[segment]

Return segments, contained by the planner block.

planner_block.inverse_time_at_pos

def inverse_time_at_pos(dist_local: float) -> float

Get the global time, at which the local length is reached.

Arguments:

  • dist_local - (float) local (relative to planner block start) distance

Returns:

  • time_global - (float) global time when the point will be reached.

planner_block.move_maker

def move_maker(v_end: float) -> None

Calculate the correct move type and generate the corresponding segments.

(trapezoidal,triangular or singular)

Arguments:

  • v_end - (velocity) target velocity for end of move

planner_block.next_block

@property
def next_block() -> planner_block | None

Define next_block as property.

planner_block.prev_block

@property
def prev_block() -> planner_block | None

Define prev_block as property.

planner_block.self_correction

def self_correction(tolerance: float = float("1e-12")) -> None

Check for interfacing vel and self correct.

planner_block.timeshift

def timeshift(delta_t: float) -> None

Shift planner block in time.

Arguments:

  • delta_t - (float) time to be shifted

pyGCodeDecode.plotter

This module provides functionality for 3D plotting of G-code simulation data using PyVista.

plot_2d

def plot_2d(sim: simulation,
            filepath: pathlib.Path = pathlib.Path("trajectory_2D.png"),
            colvar: str = "Velocity",
            show_points: bool = False,
            colvar_spatial_resolution: int = 1,
            dpi: int = 400,
            scaled: bool = True,
            show: bool = False) -> None

Plot 2D position (XY plane) with matplotlib (unmaintained).

plot_3d

def plot_3d(sim: simulation,
            extrusion_only: bool = True,
            scalar_value: str = "velocity",
            screenshot_path: pathlib.Path | None = None,
            camera_settings: dict | None = None,
            vtk_path: pathlib.Path | None = None,
            mesh: pv.MultiBlock = None,
            layer_select: int | None = None,
            z_scaler: float | None = None,
            window_size: tuple = (2048, 1536),
            mpl_subplot: bool = False,
            mpl_rcParams: dict | None = None,
            solid_color: str = "black",
            transparent_background: bool = True,
            parallel_projection: bool = False,
            lighting: bool = True,
            block_colorbar: bool = False,
            extra_plotting: callable | None = None,
            overwrite_labels: dict | None = None,
            scalar_value_bounds: tuple[float, float] | None = None,
            return_type: str = "mesh") -> pv.MultiBlock

Plot a 3D visualization of G-code simulation data using PyVista.

Arguments:

  • sim simulation - The simulation object containing blocklist and segment data.
  • extrusion_only bool, optional - If True, plot only segments where extrusion occurs. Defaults to True.
  • scalar_value str, optional - Scalar value to color the plot. Options: "velocity", "rel_vel_err", "acceleration", or None. Defaults to "velocity".
  • screenshot_path pathlib.Path, optional - If provided, saves a screenshot to this path and disables interactive plotting. Defaults to None.
  • camera_settings dict, optional - Camera settings for the plotter. Keys: "camera_position", "elevation", "azimuth", "roll". Defaults to None.
  • vtk_path pathlib.Path, optional - If provided, saves the mesh as a VTK file to this path. Defaults to None.
  • mesh pv.MultiBlock, optional - Precomputed PyVista mesh to use instead of generating a new one. Defaults to None.
  • layer_select int, optional - If provided, only plot the specified layer. Defaults to None (all layers).
  • z_scaler float, optional - Scaling factor for the z-axis layer squishing (z_scaler = width/height of extrusion). Defaults to None (automatic scaling).
  • window_size tuple, optional - Size of the plot window in pixels. Defaults to (2048, 1536).
  • mpl_subplot bool, optional - If True, use matplotlib for screenshot and colorbar. Defaults to False.
  • mpl_rcParams dict or None, optional - Custom matplotlib rcParams for styling. Defaults to None.
  • solid_color str, optional - Background color for the plot. Defaults to "black".
  • transparent_background bool, optional - If True, screenshot background is transparent. Defaults to True.
  • parallel_projection bool, optional - If True, enables parallel projection in PyVista. Defaults to False.
  • lighting bool, optional - If True, enables lighting in the plot. Defaults to True.
  • block_colorbar bool, optional - If True, removes the scalar colorbar from the plot. Defaults to False.
  • extra_plotting callable, optional - Function to add extra plotting to the PyVista plotter. Signature: (plotter, mesh). Defaults to None.
  • overwrite_labels dict or None, optional - Dictionary to overwrite colorbar labels. Defaults to None.
  • scalar_value_bounds tuple or None, optional - Tuple (min, max) to set scalar colorbar range. Defaults to None.
  • return_type str, optional - Return type, "mesh" or "image". Defaults to "mesh".

Returns:

  • pv.MultiBlock - The PyVista mesh used for plotting. or
  • np.ndarray - The screenshot image if screenshot_path is provided and return_type is "image".

plot_vel

def plot_vel(sim: simulation,
             axis: tuple[str] = ("x", "y", "z", "e"),
             show: bool = True,
             show_planner_blocks: bool = True,
             show_segments: bool = False,
             show_jv: bool = False,
             time_steps: int | str = "constrained",
             filepath: pathlib.Path | None = None,
             dpi: int = 400) -> Figure

Plot axis velocity with matplotlib.

Arguments:

  • axis - (tuple(string), default = ("x", "y", "z", "e")) select plot axis
  • show - (bool, default = True) show plot and return plot figure
  • show_planner_blocks - (bool, default = True) show planner_blocks as vertical lines
  • show_segments - (bool, default = False) show segments as vertical lines
  • show_jv - (bool, default = False) show junction velocity as x
  • time_steps - (int or string, default = "constrained") number of time steps or constrain plot vertices to segment vertices
  • filepath - (Path, default = None) save fig as image if filepath is provided
  • dpi - (int, default = 400) select dpi

Returns:

(optionally) - fig - (figure)

pyGCodeDecode.result

Result calculation for segments and planner blocks.

abstract_result Objects

class abstract_result(ABC)

Abstract class for result calculation.

abstract_result.calc_pblock

@abstractmethod
def calc_pblock(pblock: "planner_block", **kwargs: object) -> None

Calculate the result for a planner block.

abstract_result.calc_segm

@abstractmethod
def calc_segm(segm: "segment", **kwargs: object) -> None

Calculate the result for a segment.

abstract_result.name

@property
@abstractmethod
def name() -> str

Name of the result. Has to be set in the derived class.

acceleration_result Objects

class acceleration_result(abstract_result)

The acceleration.

acceleration_result.calc_pblock

def calc_pblock(pblock: "planner_block", **kwargs: object) -> None

Calculate the acceleration for a planner block.

acceleration_result.calc_segm

def calc_segm(segm: "segment", **kwargs: object) -> None

Calculate the acceleration for a segment.

get_all_result_calculators

def get_all_result_calculators() -> list["abstract_result"]

Get all results.

get_result_info

def get_result_info() -> dict

Get information about available result calculators.

has_private_results

def has_private_results() -> bool | None

Check if private results are available.

velocity_result Objects

class velocity_result(abstract_result)

The velocity.

velocity_result.calc_pblock

def calc_pblock(pblock: "planner_block", **kwargs: object) -> None

Calculate the velocity for a planner block.

velocity_result.calc_segm

def calc_segm(segm: "segment", **kwargs: object) -> None

Calculate the velocity for a segment.

pyGCodeDecode.state

State module with state.

state Objects

class state()

State contains a Position and Printing Settings (p_settings).

Used to apply for the corresponding move to this State.

state.__init__

def __init__(state_position: position = None,
             state_p_settings: p_settings = None) -> None

Initialize a state.

Arguments:

  • state_position - (position) state position
  • state_p_settings - (p_settings) state printing settings

state.__repr__

def __repr__() -> str

Call str() for representation.

state.__str__

def __str__() -> str

Generate string for representation.

state.line_number

@property
def line_number() -> int | None

Define property line_number.

state.line_number

@line_number.setter
def line_number(nmbr: int | None) -> None

Set line number.

Arguments:

  • nmbr - (int) line number

state.next_state

@property
def next_state() -> state | None

Define property next_state.

state.next_state

@next_state.setter
def next_state(state: state) -> None

Set next state.

Arguments:

  • state - (state) next state

p_settings Objects

class p_settings()

Store Printing Settings.

p_settings.__init__

def __init__(p_acc: float,
             jerk: float,
             vX: float,
             vY: float,
             vZ: float,
             vE: float,
             speed: float,
             units: str = "SI (mm)") -> None

Initialize printing settings.

Arguments:

  • p_acc - (float) printing acceleration
  • jerk - (float) jerk or similar
  • vX - (float) max x velocity
  • vY - (float) max y velocity
  • vZ - (float) max z velocity
  • vE - (float) max e velocity
  • speed - (float) default target velocity
  • units - (string, default = "SI (mm)") unit settings

p_settings.__repr__

def __repr__() -> str

Define representation.

p_settings.__str__

def __str__() -> str

Create summary string for p_settings.

state.prev_state

@property
def prev_state() -> state | None

Define property prev_state.

state.prev_state

@prev_state.setter
def prev_state(state: state) -> None

Set previous state.

Arguments:

  • state - (state) previous state

state.state_p_settings

@property
def state_p_settings() -> p_settings | None

Define property state_p_settings.

state.state_position

@property
def state_position() -> position | None

Define property state_position.

pyGCodeDecode.state_generator

State generator module.

generate_states

def generate_states(filepath: Path,
                    initial_machine_setup: dict) -> list[state]

Generate state list from GCode file.

Arguments:

  • filepath - (Path) filepath to GCode
  • initial_machine_setup - (dict) dictionary with machine setup

Returns:

  • states - (list[states]) all states in a list

pyGCodeDecode.tools

Tools for pyGCD.

save_layer_metrics

def save_layer_metrics(
        simulation: simulation,
        filepath: Path | None = Path("./layer_metrics.csv"),
        locale: str | None = None,
        delimiter: str = ";") -> tuple[list, list, list, list] | None

Print out print times, distance traveled and the average travel speed to a csv-file.

Arguments:

  • simulation - (simulation) simulation instance
  • filepath - (Path , default = "./layer_metrics.csv") file name
  • locale - (string, default = None) select locale settings, e.g. "en_US.utf8", None = use system locale
  • delimiter - (string, default = ";") select delimiter

Layers are detected using the given layer cue.

write_submodel_times

def write_submodel_times(simulation: simulation,
                         sub_orig: list,
                         sub_side_x_len: float,
                         sub_side_y_len: float,
                         sub_side_z_len: float,
                         filename: Path | None = Path("submodel_times.yaml"),
                         **kwargs: object) -> dict

Write the submodel entry and exit times to a yaml file.

Arguments:

  • simulation - (simulation) the simulation instance to analyze
  • sub_orig - (list with [xcoord, ycoord, zcoord]) the origin of the submodel control volume
  • sub_side_len - (float) the side length of the submodel control volume
  • filename - (string or Path) yaml filename
  • **kwargs - (any) provide additional info to write into the yaml file

pyGCodeDecode.utils

Utilities.

Utils for the GCode Reader contains: - vector 4D - velocity - position

acceleration Objects

class acceleration(vector_4D)

4D - Acceleration object for (Cartesian) 3D printer.

acceleration.__mul__

def __mul__(other: seconds | float | int) -> velocity | acceleration

Multiply acceleration by a time to get velocity, or by scalar.

acceleration.__str__

def __str__() -> str

Print out acceleration.

acceleration.__truediv__

def __truediv__(other: float | int) -> acceleration

Divide acceleration by scalar.

position Objects

class position(vector_4D)

4D - Position object for (Cartesian) 3D printer.

position.__str__

def __str__() -> str

Print out position.

position.__truediv__

def __truediv__(other: seconds | float | int) -> velocity | vector_4D

Divide position by seconds to get velocity.

position.get_t_distance

def get_t_distance(other: position | None = None,
                   withExtrusion: bool = False) -> float

Calculate the travel distance between self and other position.

If none is provided, zero will be used.

Arguments:

  • other - (4D vector, 1x4 'list', 1x4 'tuple' or 1x4 'numpy.ndarray', default = None)
  • withExtrusion - (bool, default = False) use or ignore extrusion

Returns:

  • travel - (float) travel or extrusion and travel distance

position.is_extruding

def is_extruding(other: position, ignore_retract: bool = True) -> bool

Return True if there is extrusion between self and other position.

Arguments:

  • other - (4D vector, 1x4 'list', 1x4 'tuple' or 1x4 'numpy.ndarray')
  • ignore_retract - (bool, default = True) if true ignore retract movements else retract is also extrusion

Returns:

  • is_extruding - (bool) true if between self and other is extrusion

position.is_travel

def is_travel(other: position) -> bool

Return True if there is travel between self and other position.

Arguments:

  • other - (4D vector, 1x4 'list', 1x4 'tuple' or 1x4 'numpy.ndarray')

Returns:

  • is_travel - (bool) true if between self and other is distance

seconds Objects

class seconds(float)

A float subclass representing a time duration in seconds.

Arguments:

  • value float or int - The time duration in seconds.

Examples:

>>> from pyGCodeDecode.utils import seconds
>>> t = seconds(5)
>>> str(t)
'5.0 s'
>>> t.seconds
5.0

seconds.__add__

def __add__(other: float | seconds) -> seconds

Add seconds or float and return a new seconds instance.

seconds.__new__

def __new__(cls, value: float) -> seconds

Create a new instance of seconds.

seconds.__repr__

def __repr__() -> str

Return a string representation of the seconds object.

seconds.__str__

def __str__() -> str

Return string representation of the time in seconds.

seconds.__sub__

def __sub__(other: float | seconds) -> seconds

Subtract seconds or float and return a new seconds instance.

seconds.seconds

@property
def seconds() -> float

Return the float value of the seconds instance.

segment Objects

class segment()

Store Segment data for linear 4D Velocity function segment.

contains: time, position, velocity Supports - str

Additional methods - move_segment_time: moves Segment in time by a specified interval - get_velocity: returns the calculated Velocity for all axis at a given point in time - get_position: returns the calculated Position for all axis at a given point in time - get_segm_len: returns the length of the segment.

Class method - create_initial: returns the artificial initial segment where everything is at standstill, intervall length = 0 - self_check: returns True if all self checks have been successfull

segment.__init__

def __init__(t_begin: float | seconds,
             t_end: float | seconds,
             pos_begin: position,
             vel_begin: velocity,
             pos_end: position = None,
             vel_end: velocity = None) -> None

Initialize a segment.

Arguments:

  • t_begin - (float) begin of segment
  • t_end - (float) end of segment
  • pos_begin - (position) beginning position of segment
  • vel_begin - (velocity) beginning velocity of segment
  • pos_end - (position, default = None) ending position of segment
  • vel_end - (velocity, default = None) ending velocity of segment

segment.__repr__

def __repr__() -> str

Segment representation.

segment.__str__

def __str__() -> str

Create string from segment.

segment.create_initial

@classmethod
def create_initial(cls, initial_position: position | None = None) -> segment

Create initial static segment with (optionally) initial position else start from Zero.

Arguments:

  • initial_position - (postion, default = None) position to begin segment series

Returns:

  • segment - (segment) initial beginning segment

segment.get_position

def get_position(t: float | seconds) -> position

Get current position of segment at a certain time.

Arguments:

  • t - (float) time

Returns:

  • pos - (position) position at time t

segment.get_result

def get_result(key: str) -> float | list[float]

Return the requested result.

Arguments:

  • key - (str) choose result

Returns:

  • result - (list)

segment.get_segm_duration

def get_segm_duration() -> seconds

Return the duration of the segment.

segment.get_segm_len

def get_segm_len() -> float

Return the length of the segment.

segment.get_velocity

def get_velocity(t: float | seconds) -> velocity

Get current velocity of segment at a certain time.

Arguments:

  • t - (float) time

Returns:

  • current_vel - (velocity) velocity at time t

segment.get_velocity_by_dist

def get_velocity_by_dist(dist: float) -> float

Return the velocity magnitude at a certain local segment distance.

Arguments:

  • dist - (float) distance from segment start

segment.is_extruding

def is_extruding() -> bool

Return true if the segment is pos. extruding.

Returns:

  • is_extruding - (bool) true if positive extrusion

segment.move_segment_time

def move_segment_time(delta_t: float | seconds) -> None

Move segment in time.

Arguments:

  • delta_t - (float) time to be shifted

segment.self_check

def self_check(p_settings: state.p_settings = None) -> bool

Check the segment for self consistency.

Raises:

  • ValueError - if self check fails

Arguments:

  • p_settings - (p_settings, default = None) printing settings to verify

Returns:

True if all checks pass

vector_4D Objects

class vector_4D()

The vector_4D class stores 4D vector in x,y,z,e.

Supports: - str - add - sub - mul (scalar) - truediv (scalar) - eq

vector_4D.__add__

def __add__(other: vector_4D | list | tuple | np.ndarray) -> vector_4D

Add functionality for 4D vectors.

Arguments:

  • other - (4D vector, 1x4 'list', 1x4 'tuple' or 1x4 'numpy.ndarray')

Returns:

  • add - (self) component wise addition

vector_4D.__eq__

def __eq__(other: object) -> bool

Check for equality and return True if equal.

Arguments:

  • other - (4D vector, 1x4 'list', 1x4 'tuple' or 1x4 'numpy.ndarray')

Returns:

  • eq - (bool) true if equal

vector_4D.__gt__

def __gt__(other: object) -> bool

Check for greater than and return True if greater.

Arguments:

  • other - (4D vector, 1x4 'list', 1x4 'tuple' or 1x4 'numpy.ndarray')

Returns:

  • gt - (bool) true if greater

vector_4D.__init__

def __init__(*args: float | list | tuple | np.ndarray) -> None

Store 3D position + extrusion axis.

Arguments:

  • args - coordinates as arguments x,y,z,e or (tuple or list) [x,y,z,e]

vector_4D.__mul__

def __mul__(other: float | int) -> vector_4D

Scalar multiplication functionality for 4D vectors.

Arguments:

  • other - (float or int)

Returns:

  • mul - (self) scalar multiplication, scaling

vector_4D.__repr__

def __repr__() -> str

Return a string representation of the 4D vector.

vector_4D.__str__

def __str__() -> str

Return string representation.

vector_4D.__sub__

def __sub__(other: vector_4D | list | tuple | np.ndarray) -> vector_4D

Sub functionality for 4D vectors.

Arguments:

  • other - (4D vector, 1x4 'list', 1x4 'tuple' or 1x4 'numpy.ndarray')

Returns:

  • sub - (self) component wise subtraction

vector_4D.__truediv__

def __truediv__(other: float | int) -> vector_4D

Scalar division functionality for 4D Vectors.

Arguments:

  • other - (float or int)

Returns:

  • div - (self) scalar division, scaling

vector_4D.get_norm

def get_norm(withExtrusion: bool = False) -> float

Return the 4D vector norm. Optional with extrusion.

Arguments:

  • withExtrusion - (bool, default = False) choose if norm contains extrusion

Returns:

  • norm - (float) length/norm of 3D or 4D vector

vector_4D.get_vec

def get_vec(withExtrusion: bool = False) -> list[float]

Return the 4D vector, optionally with extrusion.

Arguments:

  • withExtrusion - (bool, default = False) choose if vec repr contains extrusion

Returns:

  • vec - (list[3 or 4]) with (x,y,z,(optionally e))

velocity Objects

class velocity(vector_4D)

4D - Velocity object for (Cartesian) 3D printer.

velocity.__mul__

def __mul__(other: seconds | float | int) -> position | velocity

Multiply velocity by a time to get position, or by scalar.

velocity.__str__

def __str__() -> str

Print out velocity.

velocity.__truediv__

def __truediv__(other: seconds | float | int) -> acceleration | vector_4D

Divide velocity by scalar.

velocity.get_norm_dir

def get_norm_dir(withExtrusion: bool = False) -> np.ndarray | None

Get normalized direction vector as numpy array.

If only extrusion occurs and withExtrusion=True, normalize to the extrusion length.

Returns None if both travel and extrusion are zero.

velocity.is_extruding

def is_extruding() -> bool

Return True if extrusion velocity is greater than zero.

Returns:

  • is_extruding - (bool) true if positive extrusion velocity

velocity.not_zero

def not_zero() -> bool

Return True if velocity is not zero.

Returns:

  • not_zero - (bool) true if velocity is not zero