Files
km-plot/plot.py
2025-12-28 14:10:37 -05:00

126 lines
4.2 KiB
Python

class PlotEngine:
def __init__(self, extension):
self.ext = extension
def perform_cut(self, device_path):
self.ext.debug(f"Generating HPGL and sending to {device_path}")
hpgl = self.generate_hpgl()
self.send_hpgl_serial(device_path, hpgl)
def ensure_plotter_defaults(self):
defaults = {
"serialBaudRate": "9600",
"serialByteSize": "eight",
"serialStopBits": "one",
"serialParity": "none",
"serialFlowControl": "xonxoff",
"resolutionX": 1016.0,
"resolutionY": 1016.0,
"pen": 1,
"force": 0,
"speed": 0,
"orientation": "0",
"mirrorX": False,
"mirrorY": False,
"center": False,
"overcut": 1.0,
"precut": True,
"flat": 1.2,
"autoAlign": True,
"toolOffset": 0.25,
}
for key, value in defaults.items():
if not hasattr(self.ext.options, key):
setattr(self.ext.options, key, value)
def generate_hpgl(self):
self.ensure_plotter_defaults()
try:
import hpgl_encoder
except Exception as exc:
raise RuntimeError(f"hpgl_encoder not available: {exc}") from exc
if self.ext.svg.xpath("//use|//flowRoot|//text") is not None:
self.preprocess(["flowRoot", "text"])
encoder = hpgl_encoder.hpglEncoder(self.ext)
try:
hpgl = encoder.getHpgl()
except Exception as exc:
raise RuntimeError(f"HPGL generation failed: {exc}") from exc
return self.convert_hpgl(hpgl)
def convert_hpgl(self, hpgl):
init = "IN"
return init + hpgl + ";PU0,0;SP0;IN; "
def send_hpgl_serial(self, device_path, hpgl):
try:
import serial
except Exception as exc:
raise RuntimeError(f"pyserial not available: {exc}") from exc
baud = int(getattr(self.ext.options, "serialBaudRate", 9600))
byte_size = str(getattr(self.ext.options, "serialByteSize", "eight")).lower()
stop_bits = str(getattr(self.ext.options, "serialStopBits", "one")).lower()
parity = str(getattr(self.ext.options, "serialParity", "none")).lower()
flow = str(getattr(self.ext.options, "serialFlowControl", "xonxoff")).lower()
size_map = {
"5": serial.FIVEBITS,
"five": serial.FIVEBITS,
"6": serial.SIXBITS,
"six": serial.SIXBITS,
"7": serial.SEVENBITS,
"seven": serial.SEVENBITS,
"8": serial.EIGHTBITS,
"eight": serial.EIGHTBITS,
}
stop_map = {
"1": serial.STOPBITS_ONE,
"one": serial.STOPBITS_ONE,
"1.5": serial.STOPBITS_ONE_POINT_FIVE,
"onepointfive": serial.STOPBITS_ONE_POINT_FIVE,
"2": serial.STOPBITS_TWO,
"two": serial.STOPBITS_TWO,
}
parity_map = {
"none": serial.PARITY_NONE,
"even": serial.PARITY_EVEN,
"odd": serial.PARITY_ODD,
"mark": serial.PARITY_MARK,
"space": serial.PARITY_SPACE,
}
ser = serial.Serial()
ser.port = device_path
ser.baudrate = baud
ser.bytesize = size_map.get(byte_size, serial.EIGHTBITS)
ser.stopbits = stop_map.get(stop_bits, serial.STOPBITS_ONE)
ser.parity = parity_map.get(parity, serial.PARITY_NONE)
ser.timeout = 1
ser.xonxoff = flow == "xonxoff"
ser.rtscts = flow in ("rtscts", "dsrdtrrtscts")
ser.dsrdtr = flow == "dsrdtrrtscts"
self.ext.debug(
f"Opening serial port {device_path} baud={baud} size={ser.bytesize} "
f"stop={ser.stopbits} parity={ser.parity} flow={flow}"
)
ser.open()
try:
ser.write(hpgl.encode("utf8"))
try:
ser.read(2)
except Exception:
pass
finally:
ser.close()
def preprocess(self, convert):
try:
self.ext.svg.convert_to_paths(convert)
except Exception as exc:
self.ext.debug(f"Preprocess convert_to_paths failed: {exc}")