Move Z up and down between shapes on one layer

Lets say I want to engrave some word on my material. I need to start Z from 0 and travel to the first character, then move Z to 10mm (Z Offset setting on layer settings) then engrave this character and then move Z to 0 back before move to second character, otherwise the bit will be damaged.
So now I put each character to separate level and put additional levels between them with Z offset = 0.
It works, but takes a lot of time to make such design.
Maybe there some easiest way to do such things?
Many thanks!

I don’t think so. That’s not a common use case for lasers. I know there are cases where the laser needs to avoid the workpiece while travelling, but that’s not really integrated into LB, since it’s rather rare, I think.
If you have a grbl machine, you could try to configure it as a custom GCode machine and then set some extra GCode that is executed around the travel moves. I didn’t check this closely yet.

1 Like

I tried this and it did work but didn’t like the results. I found if after moving the Z axis on a layer if the layer had different design elements it would reset itself for each design element so it took a long time to complete the layer. Its easier to just run each layer separately and adjust the Z axis manually

1 Like

I made python script which gets gcode file and adds Z traveling between all the XY travelings:

import sys
import os

def is_g0_no_z(line):
    stripped = line.strip().upper()
    return (stripped.startswith("G0") or stripped.startswith("G00")) and "Z" not in stripped

def is_g0_with_z(line):
    stripped = line.strip().upper()
    return (stripped.startswith("G0") or stripped.startswith("G00")) and "Z" in stripped

def process_gcode(file_path, z_offset):
    z_offset = float(z_offset)
    new_lines = []
    valid_g0_indices = []

    with open(file_path, 'r') as f:
        lines = f.readlines()

    # Find all G0/G00 without Z
    for i, line in enumerate(lines):
        if is_g0_no_z(line):
            valid_g0_indices.append(i)

    # Filter based on skipping first 3 and last 2
    g0s_to_check = valid_g0_indices[3:-2]

    # Final list of lines to modify
    to_modify = []

    for idx in g0s_to_check:
        prev = lines[idx - 1] if idx > 0 else ""
        next = lines[idx + 1] if idx + 1 < len(lines) else ""

        if not (is_g0_with_z(prev) and is_g0_with_z(next)):
            to_modify.append(idx)

    to_modify_set = set(to_modify)

    # Process and insert extra Z moves
    for i, line in enumerate(lines):
        if i in to_modify_set:
            new_lines.append(f"G0 Z{z_offset}\n")
            new_lines.append(line)
            new_lines.append(f"G0 Z-{z_offset}\n")
        else:
            new_lines.append(line)

    # Save modified G-code
    base, ext = os.path.splitext(file_path)
    new_file_path = f"{base}_FIX{ext}"

    with open(new_file_path, 'w') as f:
        f.writelines(new_lines)

    print(f"Modified G-code saved to: {new_file_path}")

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: python script.py  ")
    else:
        process_gcode(sys.argv[1], sys.argv[2])

run: python3 fixer.py foo.gcode 3
where 3 is 3mm for Z traveling before each G0 XY traveling

2 Likes

yes, this is what I did, but use just G0 Z{offset} and then G0 Z-{offset} around each GO XY traveling