Compare commits
10 Commits
52ff3e60e7
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ade1aba1b1 | ||
| 6447a11768 | |||
| a1d73a26da | |||
| fa1122b32c | |||
| f9232df233 | |||
| 20c943b73c | |||
| b4a774b2b9 | |||
| 3acbff18e7 | |||
| ac709f9925 | |||
| d3fcba9ebc |
@@ -1,21 +0,0 @@
|
||||
|
||||
class GCodeParser():
|
||||
def __init__(self, gcode_file):
|
||||
self.gcode_file = gcode_file
|
||||
self.lines = []
|
||||
self._parse_gcode()
|
||||
|
||||
def _parse_gcode(self):
|
||||
from pygcode import Line, Machine
|
||||
machine = Machine()
|
||||
positions = []
|
||||
with open(self.gcode_file, "r") as gcode_file:
|
||||
for line_text in gcode_file:
|
||||
line = Line(line_text)
|
||||
if line.block.gcodes:
|
||||
machine.process_gcodes(*line.block.gcodes)
|
||||
positions.append((machine.pos.X, machine.pos.Y, machine.pos.Z))
|
||||
self.lines = positions
|
||||
|
||||
def get_positions(self):
|
||||
return self.lines
|
||||
210
gcodeinterpreter.py
Normal file
210
gcodeinterpreter.py
Normal file
@@ -0,0 +1,210 @@
|
||||
import math
|
||||
import re
|
||||
|
||||
class GcodeInterpreter:
|
||||
"""
|
||||
A basic G-code interpreter that converts G-code commands into a list of coordinates.
|
||||
Supports G00, G01, G02, and G03 commands.
|
||||
|
||||
Attributes:
|
||||
current_position (list): The current position in 3D space [X, Y, Z].
|
||||
feed_rate (float): The current feed rate.
|
||||
coordinates (list): The list of calculated coordinates.
|
||||
segment_multiplier (float): Multiplier for distance to determine number of segments.
|
||||
max_segments (int): Maximum number of segments allowed.
|
||||
"""
|
||||
|
||||
def __init__(self, initial_position=[0, 0, 0], initial_feed_rate=0, segment_multiplier=2, max_segments=50):
|
||||
"""
|
||||
Initializes the GcodeInterpreter with the initial position, feed rate, segment multiplier, and maximum segments.
|
||||
|
||||
Args:
|
||||
initial_position (list, optional): The initial position [X, Y, Z]. Defaults to [0, 0, 0].
|
||||
initial_feed_rate (float, optional): The initial feed rate. Defaults to 0.
|
||||
segment_multiplier (float, optional): Multiplier for distance to determine number of segments. Defaults to 10.0
|
||||
max_segments (int, optional): Maximum number of segments allowed. Defaults to 100.
|
||||
"""
|
||||
self.current_position = initial_position[:] # Use a copy to avoid modifying the original
|
||||
self.feed_rate = initial_feed_rate
|
||||
self.coordinates = [initial_position[:]] # Store the initial position
|
||||
self.segment_multiplier = segment_multiplier # Added segment multiplier
|
||||
self.max_segments = max_segments # Added max segments
|
||||
|
||||
def parse_file(self, filename):
|
||||
"""
|
||||
Parses a G-code file and processes each line.
|
||||
|
||||
Args:
|
||||
filename (str): The path to the G-code file.
|
||||
|
||||
Returns:
|
||||
GcodeInterpreter: The instance of the GcodeInterpreter with processed coordinates.
|
||||
"""
|
||||
with open(filename, 'r') as file:
|
||||
for line in file:
|
||||
self.parse_line(line)
|
||||
return self
|
||||
|
||||
def parse_line(self, line):
|
||||
"""
|
||||
Parses a single line of G-code.
|
||||
|
||||
Args:
|
||||
line (str): The G-code line to parse.
|
||||
"""
|
||||
line = line.strip()
|
||||
if not line or line.startswith('%') or line.startswith('('): # Skip empty lines and lines starting with '%'
|
||||
return
|
||||
|
||||
# Use regular expression for more robust parsing
|
||||
parts = re.findall(r'([A-Za-z])([-+]?\d*\.?\d*)', line) # Find all letter-number pairs
|
||||
if not parts:
|
||||
return # Skip lines without any recognized G-code commands
|
||||
|
||||
command = parts[0][0].upper() + parts[0][1]
|
||||
args = {}
|
||||
for part in parts:
|
||||
if part[0].upper() != command:
|
||||
try:
|
||||
args[part[0].upper()] = float(part[1]) if part[1] else 0.0 # convert the number part to float
|
||||
except ValueError:
|
||||
print(f"Warning: Could not convert value '{part[1]}' to float for argument {part[0]}. Skipping.")
|
||||
args[part[0].upper()] = 0.0
|
||||
self.process_command(command, args)
|
||||
|
||||
def process_command(self, command, args):
|
||||
"""
|
||||
Processes a G-code command and calls the appropriate function.
|
||||
|
||||
Args:
|
||||
command (str): The G-code command (e.g., 'G00', 'G01', 'G02', 'G03').
|
||||
args (dict): A dictionary of arguments for the command (e.g., {'X': 10, 'Y': 20}).
|
||||
"""
|
||||
if not command: # Add this check
|
||||
return
|
||||
if command in ('G00', 'G01'):
|
||||
self.process_g00_g01(command, args)
|
||||
elif command == 'G02':
|
||||
self.process_g02_g03(command, args, clockwise=True)
|
||||
elif command == 'G03':
|
||||
self.process_g02_g03(command, args, clockwise=False)
|
||||
elif command == 'G04':
|
||||
self.process_g04(args)
|
||||
elif command == 'F':
|
||||
self.feed_rate = args.get('F', self.feed_rate) # Keep the current feed rate if not provided
|
||||
# Add other G-code commands as needed (e.g., G02, G03, G28, etc.)
|
||||
else:
|
||||
print(f"Unsupported G-code command: {command}")
|
||||
|
||||
def process_g00_g01(self, command, args):
|
||||
"""
|
||||
Processes G00 (Rapid Linear Move) and G01 (Controlled Linear Move) commands.
|
||||
|
||||
Args:
|
||||
command (str): The G-code command ('G00' or 'G01').
|
||||
args (dict): A dictionary of arguments for the command (e.g., {'X': 10, 'Y': 20, 'Z': 5}).
|
||||
"""
|
||||
new_position = [args.get('X', self.current_position[0]),
|
||||
args.get('Y', self.current_position[1]),
|
||||
args.get('Z', self.current_position[2])]
|
||||
|
||||
# Calculate the distance between the current position and the new position
|
||||
distance = math.sqrt(
|
||||
(new_position[0] - self.current_position[0]) ** 2 +
|
||||
(new_position[1] - self.current_position[1]) ** 2 +
|
||||
(new_position[2] - self.current_position[2]) ** 2
|
||||
)
|
||||
|
||||
# Number of segments. Increase for smoother lines, but use a reasonable maximum.
|
||||
segments = int(distance * self.segment_multiplier) + 1
|
||||
segments = min(segments, self.max_segments) # Limit the maximum number of segments
|
||||
|
||||
for i in range(segments + 1):
|
||||
x = self.current_position[0] + (new_position[0] - self.current_position[0]) * i / segments
|
||||
y = self.current_position[1] + (new_position[1] - self.current_position[1]) * i / segments
|
||||
z = self.current_position[2] + (new_position[2] - self.current_position[2]) * i / segments
|
||||
self.current_position = [x, y, z]
|
||||
self.coordinates.append([x, y, z])
|
||||
|
||||
def process_g02_g03(self, command, args, clockwise=True):
|
||||
"""
|
||||
Processes G02 (Clockwise Circular Interpolation) and G03 (Counter-Clockwise Circular Interpolation) commands.
|
||||
|
||||
Args:
|
||||
command (str): The G-code command ('G02' or 'G03').
|
||||
args (dict): A dictionary of arguments for the command.
|
||||
clockwise (bool): True for G02 (clockwise), False for G03 (counter-clockwise).
|
||||
"""
|
||||
new_position = [args.get('X', self.current_position[0]),
|
||||
args.get('Y', self.current_position[1]),
|
||||
args.get('Z', self.current_position[2])]
|
||||
center = [self.current_position[0] + args.get('I', 0),
|
||||
self.current_position[1] + args.get('J', 0),
|
||||
self.current_position[2] + args.get('K', 0)]
|
||||
|
||||
radius = math.sqrt((self.current_position[0] - center[0]) ** 2 +
|
||||
(self.current_position[1] - center[1]) ** 2 +
|
||||
(self.current_position[2] - center[2]) ** 2)
|
||||
# Handle the case where the radius is zero
|
||||
if radius == 0:
|
||||
print(f"Warning: Radius is zero for {command}. No interpolation performed.")
|
||||
return
|
||||
|
||||
# Calculate the angle between the current point and the target point
|
||||
start_angle = math.atan2(self.current_position[1] - center[1], self.current_position[0] - center[0])
|
||||
end_angle = math.atan2(new_position[1] - center[1], new_position[0] - center[0])
|
||||
|
||||
# Ensure angles are between 0 and 2*pi
|
||||
if start_angle < 0:
|
||||
start_angle += 2 * math.pi
|
||||
if end_angle < 0:
|
||||
end_angle += 2 * math.pi
|
||||
|
||||
# Calculate the total angle
|
||||
total_angle = end_angle - start_angle
|
||||
if clockwise:
|
||||
if total_angle > 0:
|
||||
total_angle -= 2 * math.pi
|
||||
else:
|
||||
if total_angle < 0:
|
||||
total_angle += 2 * math.pi
|
||||
|
||||
# Number of segments. Increase for smoother curves.
|
||||
arc_length = radius * abs(total_angle)
|
||||
segments = int(arc_length * self.segment_multiplier) + 1 # Dynamic segments, at least 1.
|
||||
segments = min(segments, self.max_segments) # Limit max segments
|
||||
angle_increment = total_angle / segments
|
||||
|
||||
for i in range(segments + 1):
|
||||
angle = start_angle + i * angle_increment
|
||||
x = center[0] + radius * math.cos(angle)
|
||||
y = center[1] + radius * math.sin(angle)
|
||||
z = (self.current_position[2] + (new_position[2] - self.current_position[2]) * i / segments)
|
||||
self.current_position = [x, y, z]
|
||||
self.coordinates.append([x, y, z])
|
||||
|
||||
def process_g04(self, args):
|
||||
"""Processes G04 (Dwell) command. For now, just prints a message.
|
||||
|
||||
Args:
|
||||
args (dict): A dictionary of arguments, containing 'P' for the dwell time in milliseconds
|
||||
"""
|
||||
dwell_time = args.get('P', 0)
|
||||
print(f"G04 Dwell for {dwell_time} milliseconds")
|
||||
# In a real implementation, you would pause execution here. For this example, we just print.
|
||||
pass
|
||||
|
||||
def get_coordinates(self):
|
||||
"""
|
||||
Returns the list of calculated coordinates.
|
||||
|
||||
Returns:
|
||||
list: The list of coordinates.
|
||||
"""
|
||||
return self.coordinates
|
||||
|
||||
def reset(self):
|
||||
"""Resets the interpreter to its initial state."""
|
||||
self.current_position = [0, 0, 0]
|
||||
self.feed_rate = 0
|
||||
self.coordinates = [[0,0,0]]
|
||||
16
main.py
16
main.py
@@ -1,6 +1,7 @@
|
||||
#! /usr/bin/env python
|
||||
from argparse import ArgumentParser
|
||||
from gcode_parser import GCodeParser
|
||||
from gcodeinterpreter import GcodeInterpreter
|
||||
from pwm_driver import PWMDriver
|
||||
from visualizer import Visualizer
|
||||
|
||||
# A4
|
||||
@@ -12,12 +13,19 @@ if __name__ == "__main__":
|
||||
argparser.add_argument("-f", "--file", type=str)
|
||||
argparser.add_argument("-W", "--width", type=float, default=WIDTH_MM, required=False)
|
||||
argparser.add_argument("-H", "--height", type=float, default=HEIGHT_MM, required=False)
|
||||
argparser.add_argument("-V", "--visualize", action="store_true", default=False, required=False)
|
||||
argparser.add_argument("-P", "--port", type=str, default=None)
|
||||
|
||||
args = argparser.parse_args()
|
||||
|
||||
parser = GCodeParser(args.file)
|
||||
positions = parser.get_positions()
|
||||
parser = GcodeInterpreter().parse_file(args.file)
|
||||
positions = parser.get_coordinates()
|
||||
|
||||
screen_dimensions = (1024*1.5, 1024*1.5 * HEIGHT_MM/WIDTH_MM)
|
||||
if args.visualize:
|
||||
screen_dimensions = (1024*1.5, 1024*1.5 * args.height/args.width)
|
||||
visualizer = Visualizer(positions, screen_dimensions, (args.width, args.height))
|
||||
visualizer.visualize()
|
||||
|
||||
if args.port:
|
||||
pwm = PWMDriver(positions, (args.width, args.height), args.port)
|
||||
pwm.run()
|
||||
18
port-finder.py
Executable file
18
port-finder.py
Executable file
@@ -0,0 +1,18 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
import serial.tools.list_ports
|
||||
from serial.tools.list_ports_common import ListPortInfo
|
||||
|
||||
if __name__ == "__main__":
|
||||
ports = serial.tools.list_ports.comports()
|
||||
for port in ports:
|
||||
if port.interface and port.interface.startswith("CircuitPython CDC2"): # CDC2 is the data-port
|
||||
print(f"Port: {port.device}")
|
||||
print(f" Description: {port.description}")
|
||||
print(f" Manufacturer: {port.manufacturer}")
|
||||
print(f" VID: {port.vid}")
|
||||
print(f" PID: {port.pid}")
|
||||
print(f" Serial Number: {port.serial_number}")
|
||||
print(f" Location: {port.location}")
|
||||
print(f" Interface: {port.interface}")
|
||||
print()
|
||||
39
pwm_driver.py
Normal file
39
pwm_driver.py
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
class PWMDriver():
|
||||
def __init__(self, positions : list[tuple[float, float, float]], gcode_size : tuple[float, float], port : str, baudrate : int = 115200) -> None:
|
||||
self.positions = positions
|
||||
self.gcode_size = gcode_size
|
||||
self.port = port
|
||||
self.baudrate = baudrate
|
||||
self._init_pwm()
|
||||
|
||||
def _init_pwm(self) -> None:
|
||||
from serial import Serial
|
||||
self.serial = Serial(self.port, self.baudrate)
|
||||
|
||||
def _send_position(self, pos : tuple[float, float, float]) -> None:
|
||||
x, y, z = pos
|
||||
# Convert coordinates to PWM values
|
||||
precision = ((2 ** 16) - 1)
|
||||
pwm_x : int = int(x / self.gcode_size[0] * precision)
|
||||
pwm_y : int = int(y / self.gcode_size[1] * precision)
|
||||
pen : int = 1 if z < 0 else 0
|
||||
|
||||
# Send PWM values to the serial port
|
||||
print(f"Sending PWM values: X={pwm_x:<5}, Y={pwm_y:<5}, Pen={pen}")
|
||||
self.serial.write(f"{pwm_x},{pwm_y},{pen}\n".encode())
|
||||
|
||||
def _position_reached(self) -> bool:
|
||||
# Check if the position has been reached
|
||||
return self.serial.readline().decode().strip() == "OK"
|
||||
|
||||
def _wait_for_position(self) -> None:
|
||||
# Wait until the position is reached
|
||||
while not self._position_reached():
|
||||
pass
|
||||
|
||||
def run(self) -> None:
|
||||
for pos in self.positions:
|
||||
self._send_position(pos)
|
||||
self._wait_for_position()
|
||||
print("All positions sent successfully.")
|
||||
@@ -1,2 +1,3 @@
|
||||
pygame==2.6.1
|
||||
pygcode==0.2.1
|
||||
colorama==0.4.6
|
||||
pyserial
|
||||
26
set_pos.py
Executable file
26
set_pos.py
Executable file
@@ -0,0 +1,26 @@
|
||||
#! /usr/bin/env python3
|
||||
import serial
|
||||
import argparse
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Set the position of the PWM driver.")
|
||||
parser.add_argument("x", type=float, help="X coordinate [0 - 1]")
|
||||
parser.add_argument("y", type=float, help="Y coordinate [0 - 1]")
|
||||
parser.add_argument("pen", type=int, help="pen down (True) or pen up (False)")
|
||||
parser.add_argument("-p", "--port", type=str, required=True, help="Serial port")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Open the serial port
|
||||
ser = serial.Serial(args.port, 115200)
|
||||
|
||||
# Saturate values to [0, 1]
|
||||
args.x = int(max(0, min(1, args.x)) * 0xFFFF)
|
||||
args.y = int(max(0, min(1, args.y)) * 0xFFFF)
|
||||
args.z = int(max(0, min(1, args.pen)))
|
||||
|
||||
# Send the position
|
||||
print(f"{args.x},{args.y},{args.z}\n")
|
||||
ser.write(f"{args.x},{args.y},{args.z}\n".encode())
|
||||
|
||||
# Close the serial port
|
||||
ser.close()
|
||||
3669
test/gothenburg.gcode
Normal file
3669
test/gothenburg.gcode
Normal file
File diff suppressed because it is too large
Load Diff
217
test/test_arc.gcode
Normal file
217
test/test_arc.gcode
Normal file
@@ -0,0 +1,217 @@
|
||||
%
|
||||
(Header)
|
||||
(Generated by gcodetools from Inkscape.)
|
||||
(Using default header. To add your own header create file "header" in the output dir.)
|
||||
M3
|
||||
(Header end.)
|
||||
G21 (All units in mm)
|
||||
|
||||
(Start cutting path id: path686)
|
||||
(Change tool to Cylindrical cutter)
|
||||
|
||||
G00 Z4.000000
|
||||
G00 X14.552637 Y93.606430
|
||||
|
||||
G01 Z-0.100000 F100.0(Penetrate)
|
||||
G02 X20.744531 Y97.132218 Z-0.100000 I58.837019 J-96.128067 F400.000000
|
||||
G02 X25.716552 Y99.525614 Z-0.100000 I34.485847 J-65.279503
|
||||
G02 X30.860300 Y101.491015 Z-0.100000 I23.790996 J-54.550899
|
||||
G02 X34.959887 Y102.600926 Z-0.100000 I12.260142 J-37.158180
|
||||
G02 X39.150265 Y103.209091 Z-0.100000 I6.697716 J-31.408261
|
||||
G02 X42.532580 Y103.224539 Z-0.100000 I1.795934 J-22.932442
|
||||
G02 X45.870181 Y102.713250 Z-0.100000 I-1.404588 J-20.318145
|
||||
G02 X48.684570 Y101.788627 Z-0.100000 I-4.188822 J-17.495591
|
||||
G02 X51.317759 Y100.411842 Z-0.100000 I-7.068443 J-16.725319
|
||||
G02 X53.665796 Y98.685361 Z-0.100000 I-11.078526 J-17.526859
|
||||
G02 X55.775079 Y96.652958 Z-0.100000 I-15.188138 J-17.873400
|
||||
G02 X57.726196 Y94.306916 Z-0.100000 I-23.584596 J-21.598798
|
||||
G02 X59.470711 Y91.791387 Z-0.100000 I-30.810456 J-23.229671
|
||||
G02 X61.115709 Y89.045465 Z-0.100000 I-50.136040 J-31.900659
|
||||
G02 X62.630031 Y86.220124 Z-0.100000 I-67.202070 J-37.837378
|
||||
G02 X64.084273 Y83.293181 Z-0.100000 I-144.036213 J-73.388621
|
||||
G02 X65.494590 Y80.343272 Z-0.100000 I-291.514429 J-141.180087
|
||||
G03 X66.881828 Y77.442236 Z-0.100000 I283.572929 J133.817113
|
||||
G03 X68.313824 Y74.564333 Z-0.100000 I137.241882 J66.494060
|
||||
G03 X69.758311 Y71.884805 Z-0.100000 I61.141728 J31.231317
|
||||
G03 X71.336939 Y69.288112 Z-0.100000 I44.576782 J25.321713
|
||||
G03 X72.963662 Y67.013060 Z-0.100000 I26.152579 J16.980690
|
||||
G03 X74.802248 Y64.922485 Z-0.100000 I19.649002 J15.426825
|
||||
G03 X76.747819 Y63.219174 Z-0.100000 I12.369484 J12.165982
|
||||
G03 X78.923535 Y61.857370 Z-0.100000 I9.054792 J12.047641
|
||||
G03 X81.360720 Y60.895321 Z-0.100000 I6.109585 J11.909471
|
||||
G03 X83.931304 Y60.421258 Z-0.100000 I3.758224 J13.172327
|
||||
G03 X87.052305 Y60.433674 Z-0.100000 I1.492311 J17.147166
|
||||
G03 X90.141616 Y60.965854 Z-0.100000 I-1.957952 J20.598780
|
||||
G03 X94.072512 Y62.226406 Z-0.100000 I-7.883990 J31.344689
|
||||
G03 X97.849430 Y63.933050 Z-0.100000 I-15.102771 J38.456045
|
||||
G03 X102.671280 Y66.665690 Z-0.100000 I-30.887708 J60.123069
|
||||
G02 X107.455492 Y69.516107 Z-0.100000 I76.319751 J-122.656834
|
||||
G02 X111.778145 Y71.864657 Z-0.100000 I59.849304 J-105.004055
|
||||
G02 X116.195789 Y74.026840 Z-0.100000 I50.953186 J-98.510484
|
||||
G02 X120.197678 Y75.765423 Z-0.100000 I39.542572 J-85.544426
|
||||
G02 X124.277762 Y77.309185 Z-0.100000 I32.945222 J-80.908914
|
||||
G02 X127.992363 Y78.503646 Z-0.100000 I25.153027 J-71.849106
|
||||
G02 X131.764395 Y79.500062 Z-0.100000 I20.181063 J-68.759565
|
||||
G02 X135.224685 Y80.214984 Z-0.100000 I14.823846 J-63.017244
|
||||
G02 X138.719390 Y80.736201 Z-0.100000 I10.923189 J-61.262385
|
||||
G02 X141.957129 Y81.035094 Z-0.100000 I7.031183 J-58.479198
|
||||
G02 X145.206983 Y81.153633 Z-0.100000 I3.741895 J-57.979350
|
||||
G02 X148.252179 Y81.099633 Z-0.100000 I0.492298 J-58.128277
|
||||
G02 X151.291365 Y80.887398 Z-0.100000 I-2.594382 J-59.017970
|
||||
G02 X154.172321 Y80.544259 Z-0.100000 I-6.004970 J-62.682596
|
||||
G02 X157.036011 Y80.071812 Z-0.100000 I-9.343840 J-65.551964
|
||||
G02 X159.780039 Y79.504629 Z-0.100000 I-14.036409 J-74.829451
|
||||
G02 X162.503404 Y78.841104 Z-0.100000 I-18.436483 J-81.591141
|
||||
G02 X165.137818 Y78.116401 Z-0.100000 I-27.191313 J-103.995462
|
||||
G02 X167.755226 Y77.329975 Z-0.100000 I-35.376756 J-122.491044
|
||||
G02 X170.308142 Y76.515232 Z-0.100000 I-63.095750 J-202.111153
|
||||
G02 X172.852727 Y75.673769 Z-0.100000 I-100.985659 J-309.649100
|
||||
G03 X175.353497 Y74.836779 Z-0.100000 I824.726160 J2459.974416
|
||||
G03 X177.856967 Y74.008305 Z-0.100000 I145.131966 J434.360678
|
||||
G03 X180.336368 Y73.216701 Z-0.100000 I52.878481 J161.343222
|
||||
G03 X182.828867 Y72.469528 Z-0.100000 I38.111423 J122.605193
|
||||
G03 X185.319239 Y71.790655 Z-0.100000 I23.905804 J82.788507
|
||||
G03 X187.829219 Y71.193050 Z-0.100000 I18.410824 J71.756814
|
||||
G03 X190.364594 Y70.694298 Z-0.100000 I12.556310 J57.135618
|
||||
G03 X192.918913 Y70.313651 Z-0.100000 I9.134546 J52.536396
|
||||
G03 X195.534920 Y70.063287 Z-0.100000 I5.730078 J46.080297
|
||||
G03 X198.159586 Y69.965048 Z-0.100000 I2.965597 J44.121682
|
||||
G03 X200.892700 Y70.033280 Z-0.100000 I0.322653 J41.849195
|
||||
G03 X203.634685 Y70.214064 Z-0.100000 I-9.642083 J167.128071
|
||||
G03 X206.734190 Y70.468208 Z-0.100000 I-14.808021 J199.624135
|
||||
G03 X209.828711 Y70.768943 Z-0.100000 I-19.054664 J212.141427
|
||||
G03 X213.185728 Y71.144851 Z-0.100000 I-23.944887 J229.015273
|
||||
G03 X216.536369 Y71.569433 Z-0.100000 I-27.820491 J232.982259
|
||||
G03 X220.054927 Y72.068144 Z-0.100000 I-31.235128 J233.035128
|
||||
G03 X223.565116 Y72.620309 Z-0.100000 I-34.247524 J229.149691
|
||||
G03 X227.149400 Y73.243018 Z-0.100000 I-35.615483 J215.627772
|
||||
G03 X230.722353 Y73.926542 Z-0.100000 I-37.577673 J206.108108
|
||||
G03 X234.276760 Y74.674407 Z-0.100000 I-36.862694 J184.019161
|
||||
G03 X237.815350 Y75.493254 Z-0.100000 I-37.806210 J171.432212
|
||||
G03 X241.244620 Y76.367245 Z-0.100000 I-35.310162 J145.710840
|
||||
G03 X244.651119 Y77.325701 Z-0.100000 I-35.390941 J132.317698
|
||||
G03 X247.860593 Y78.326465 Z-0.100000 I-31.591268 J106.960795
|
||||
G03 X251.036164 Y79.429240 Z-0.100000 I-31.024541 J94.462390
|
||||
G03 X253.932293 Y80.556999 Z-0.100000 I-26.474034 J72.268933
|
||||
G03 X256.775961 Y81.809146 Z-0.100000 I-25.498067 J61.762086
|
||||
G03 X259.267331 Y83.063781 Z-0.100000 I-20.772732 J44.350028
|
||||
G03 X261.673924 Y84.469733 Z-0.100000 I-19.631861 J36.366877
|
||||
G03 X263.673323 Y85.851744 Z-0.100000 I-15.307078 J24.282539
|
||||
G03 X265.530243 Y87.411006 Z-0.100000 I-14.246357 J18.851271
|
||||
G03 X266.957880 Y88.925821 Z-0.100000 I-10.886437 J11.690065
|
||||
G03 X268.146784 Y90.619795 Z-0.100000 I-10.156820 J8.392689
|
||||
G03 X268.928616 Y92.290945 Z-0.100000 I-8.308777 J4.905647
|
||||
G03 X269.357297 Y94.072485 Z-0.100000 I-8.181325 J2.910968
|
||||
G03 X269.393144 Y95.952050 Z-0.100000 I-8.386143 J1.100063
|
||||
G03 X269.027656 Y97.799340 Z-0.100000 I-9.115328 J-0.843674
|
||||
G03 X268.159077 Y99.914069 Z-0.100000 I-11.976068 J-3.683172
|
||||
G03 X266.946743 Y101.867828 Z-0.100000 I-13.731658 J-7.167668
|
||||
G03 X265.034028 Y104.181934 Z-0.100000 I-19.881289 J-14.485266
|
||||
G03 X262.873021 Y106.280809 Z-0.100000 I-22.835912 J-21.349997
|
||||
G03 X259.825610 Y108.760580 Z-0.100000 I-32.852748 J-37.260623
|
||||
G03 X256.476576 Y110.709846 Z-0.100000 I-10.010231 J-13.346960
|
||||
G03 X252.773344 Y111.883993 Z-0.100000 I-7.493702 J-17.207922
|
||||
G03 X248.877241 Y112.327664 Z-0.100000 I-4.407126 J-21.372573
|
||||
G03 X244.450008 Y112.121603 Z-0.100000 I-0.742684 J-31.706144
|
||||
G03 X240.060530 Y111.353088 Z-0.100000 I4.553065 J-38.925229
|
||||
G03 X235.163093 Y109.981508 Z-0.100000 I13.543583 J-57.788781
|
||||
G03 X230.378159 Y108.229403 Z-0.100000 I22.565424 J-69.035121
|
||||
G03 X225.220090 Y105.971807 Z-0.100000 I40.057628 J-98.543426
|
||||
G03 X220.174534 Y103.464869 Z-0.100000 I54.183655 J-115.382898
|
||||
G03 X214.928487 Y100.600598 Z-0.100000 I84.046615 J-160.171681
|
||||
G03 X209.770717 Y97.577215 Z-0.100000 I106.036659 J-186.805411
|
||||
G03 X204.595777 Y94.375981 Z-0.100000 I159.527010 J-263.666062
|
||||
G03 X199.478162 Y91.081669 Z-0.100000 I201.070883 J-317.979798
|
||||
G03 X194.529447 Y87.806053 Z-0.100000 I348.426084 J-531.768904
|
||||
G03 X189.605017 Y84.491293 Z-0.100000 I534.035069 J-798.681601
|
||||
G02 X185.036990 Y81.398913 Z-0.100000 I-3409.804231 J5032.001950
|
||||
G02 X180.458155 Y78.318762 Z-0.100000 I-623.481769 J921.900652
|
||||
G02 X176.425895 Y75.662661 Z-0.100000 I-186.252784 J278.363925
|
||||
G02 X172.343973 Y73.079173 Z-0.100000 I-119.461839 J184.233742
|
||||
G02 X169.003652 Y71.105394 Z-0.100000 I-52.095598 J84.350515
|
||||
G02 X165.571823 Y69.298462 Z-0.100000 I-32.343612 J57.266406
|
||||
G02 X163.077751 Y68.235212 Z-0.100000 I-11.428252 J23.350514
|
||||
G02 X160.502116 Y67.547415 Z-0.100000 I-5.104505 J13.948698
|
||||
G02 X158.955683 Y67.560212 Z-0.100000 I-0.737926 J4.270941
|
||||
G02 X157.731476 Y68.200123 Z-0.100000 I0.444587 J2.341498
|
||||
G02 X156.944937 Y69.588495 Z-0.100000 I2.023651 J2.063417
|
||||
G02 X156.801982 Y71.348238 Z-0.100000 I5.571122 J1.338259
|
||||
G02 X157.353005 Y74.828158 Z-0.100000 I21.087233 J-1.555446
|
||||
G02 X158.370785 Y78.264326 Z-0.100000 I36.642233 J-8.984475
|
||||
G02 X160.487376 Y83.787300 Z-0.100000 I91.589403 J-31.933101
|
||||
G02 X162.889369 Y89.212416 Z-0.100000 I134.487773 J-56.300725
|
||||
G02 X166.655540 Y96.974020 Z-0.100000 I267.631027 J-125.068347
|
||||
G03 X170.453824 Y104.728830 Z-0.100000 I-353.386875 J177.895474
|
||||
G03 X173.157092 Y110.620878 Z-0.100000 I-203.339069 J96.858011
|
||||
G03 X175.655698 Y116.592772 Z-0.100000 I-151.906226 J67.065324
|
||||
G03 X177.230787 Y120.906722 Z-0.100000 I-80.003800 J31.655140
|
||||
G03 X178.518148 Y125.298438 Z-0.100000 I-56.752677 J19.020677
|
||||
G03 X179.092855 Y128.259078 Z-0.100000 I-26.514778 J6.683036
|
||||
G03 X179.249550 Y131.234152 Z-0.100000 I-17.602420 J2.418768
|
||||
G03 X178.959525 Y133.105472 Z-0.100000 I-7.748214 J-0.242714
|
||||
G03 X178.164821 Y134.770613 Z-0.100000 I-5.274347 J-1.495021
|
||||
G03 X177.047028 Y135.873431 Z-0.100000 I-3.627994 J-2.559367
|
||||
G03 X175.594363 Y136.576383 Z-0.100000 I-3.048814 J-4.447978
|
||||
G03 X173.571592 Y136.990480 Z-0.100000 I-3.105214 J-10.020832
|
||||
G03 X171.471477 Y137.068245 Z-0.100000 I-1.635210 J-15.763692
|
||||
G03 X168.749449 Y136.884146 Z-0.100000 I1.048042 J-35.711634
|
||||
G03 X166.037085 Y136.527390 Z-0.100000 I5.761018 J-54.289385
|
||||
G03 X162.796828 Y135.981956 Z-0.100000 I23.329119 J-148.488603
|
||||
G03 X159.565658 Y135.385276 Z-0.100000 I59.156603 J-329.394985
|
||||
G02 X155.929958 Y134.711435 Z-0.100000 I-80.995633 J426.866156
|
||||
G02 X152.288355 Y134.082554 Z-0.100000 I-41.132700 J227.325234
|
||||
G02 X148.365069 Y133.500111 Z-0.100000 I-20.596158 J125.229171
|
||||
G02 X144.427460 Y133.053734 Z-0.100000 I-13.792412 J104.075983
|
||||
G02 X140.318392 Y132.775508 Z-0.100000 I-7.322865 J77.668032
|
||||
G02 X136.205438 Y132.728765 Z-0.100000 I-2.839383 J68.865364
|
||||
G02 X132.006156 Y132.965154 Z-0.100000 I1.029488 J55.704941
|
||||
G02 X127.846119 Y133.531548 Z-0.100000 I4.767945 J50.579969
|
||||
G02 X123.644591 Y134.496575 Z-0.100000 I7.714789 J43.217395
|
||||
G02 X119.569924 Y135.877058 Z-0.100000 I11.283147 J40.007304
|
||||
G02 X115.449927 Y137.797297 Z-0.100000 I14.557774 J36.614621
|
||||
G02 X111.583891 Y140.175584 Z-0.100000 I18.672319 J34.684253
|
||||
G02 X107.638393 Y143.294847 Z-0.100000 I24.065426 J34.494836
|
||||
G02 X104.081169 Y146.849471 Z-0.100000 I29.795594 J33.374617
|
||||
G02 X100.426220 Y151.416750 Z-0.100000 I39.923690 J35.694859
|
||||
G03 X96.861751 Y156.067796 Z-0.100000 I-70.859008 J-50.613537
|
||||
G03 X93.897268 Y159.392445 Z-0.100000 I-42.365964 J-34.792383
|
||||
G03 X90.647615 Y162.421331 Z-0.100000 I-30.882655 J-29.875911
|
||||
G03 X87.974250 Y164.392723 Z-0.100000 I-16.928804 J-20.158463
|
||||
G03 X85.062213 Y165.954787 Z-0.100000 I-11.208750 J-17.400236
|
||||
G03 X82.631681 Y166.757136 Z-0.100000 I-5.489126 J-12.545506
|
||||
G03 X80.100449 Y167.054290 Z-0.100000 I-2.630925 J-11.481487
|
||||
G03 X77.844074 Y166.825240 Z-0.100000 I-0.087721 J-10.364200
|
||||
G03 X75.677709 Y166.114652 Z-0.100000 I2.251124 J-10.520571
|
||||
G03 X73.585940 Y164.936589 Z-0.100000 I5.495451 J-12.203832
|
||||
G03 X71.703619 Y163.417209 Z-0.100000 I8.984648 J-13.056514
|
||||
G03 X69.831793 Y161.430738 Z-0.100000 I15.706928 J-16.675572
|
||||
G03 X68.181100 Y159.244563 Z-0.100000 I21.305085 J-17.802887
|
||||
G03 X66.556147 Y156.647241 Z-0.100000 I33.052975 J-22.485788
|
||||
G03 X65.116782 Y153.938128 Z-0.100000 I41.144863 J-23.597379
|
||||
G03 X63.733513 Y150.925653 Z-0.100000 I58.201905 J-28.548995
|
||||
G03 X62.495117 Y147.849036 Z-0.100000 I68.612114 J-29.405211
|
||||
G03 X61.338406 Y144.605528 Z-0.100000 I90.031382 J-33.935324
|
||||
G03 X60.292015 Y141.323793 Z-0.100000 I101.989494 J-34.327319
|
||||
G03 X59.345337 Y138.026420 Z-0.100000 I125.607517 J-37.846608
|
||||
G03 X58.481449 Y134.705405 Z-0.100000 I137.732403 J-37.600881
|
||||
G03 X57.728820 Y131.527885 Z-0.100000 I160.170234 J-39.615880
|
||||
G03 X57.037175 Y128.335124 Z-0.100000 I170.460702 J-38.598048
|
||||
G03 X56.463368 Y125.449476 Z-0.100000 I187.118800 J-38.708174
|
||||
G03 X55.428496 Y119.545207 Z-0.100000 I195.277299 J-37.270122
|
||||
G03 X54.883711 Y115.911257 Z-0.100000 I188.415983 J-30.104235
|
||||
G03 X54.641709 Y114.113864 Z-0.100000 I168.111543 J-23.549653
|
||||
G03 X54.518532 Y113.130555 Z-0.100000 I126.811802 J-16.384825
|
||||
G03 X54.451092 Y112.564881 Z-0.100000 I135.732881 J-16.469000
|
||||
G03 X54.402469 Y112.128198 Z-0.100000 I38.359439 J-4.492203
|
||||
G00 Z4.000000
|
||||
|
||||
(End cutting path id: path686)
|
||||
|
||||
|
||||
(Footer)
|
||||
M5
|
||||
G00 X0.0000 Y0.0000
|
||||
M2
|
||||
(Using default footer. To add your own footer create file "footer" in the output dir.)
|
||||
(end)
|
||||
%
|
||||
364
test/test_arc.svg
Normal file
364
test/test_arc.svg
Normal file
@@ -0,0 +1,364 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
sodipodi:docname="test_arc.svg"
|
||||
id="svg5"
|
||||
version="1.1"
|
||||
viewBox="0 0 297 210"
|
||||
height="210mm"
|
||||
width="297mm"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.81512706"
|
||||
inkscape:cx="222.05127"
|
||||
inkscape:cy="435.51492"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1368"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs2">
|
||||
<rect
|
||||
x="204.85658"
|
||||
y="194.19897"
|
||||
width="876.10419"
|
||||
height="315.01569"
|
||||
id="rect244" />
|
||||
<marker
|
||||
id="CheckToolsAndOPMarker"
|
||||
orient="auto"
|
||||
refX="-4"
|
||||
refY="-1.687441"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
d="m 4.588864,-1.687441 0.0,0.0 L 9.177728,0.0 c -0.73311,-0.996261 -0.728882,-2.359329 0.0,-3.374882"
|
||||
style="fill:#000044;fill-rule:evenodd;stroke:none"
|
||||
id="path5372" />
|
||||
</marker>
|
||||
<marker
|
||||
id="DrawCurveMarker"
|
||||
orient="auto"
|
||||
refX="-4"
|
||||
refY="-1.687441"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
d="m 4.588864,-1.687441 v 0 L 9.177728,0 c -0.73311,-0.996261 -0.728882,-2.359329 0,-3.374882"
|
||||
style="fill:#000044;fill-rule:evenodd;stroke:none"
|
||||
id="path5375" />
|
||||
</marker>
|
||||
<marker
|
||||
id="DrawCurveMarker_r"
|
||||
orient="auto"
|
||||
refX="4"
|
||||
refY="-1.687441"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
d="m -4.588864,-1.687441 0.0,0.0 L -9.177728,0.0 c 0.73311,-0.996261 0.728882,-2.359329 0.0,-3.374882"
|
||||
style="fill:#000044;fill-rule:evenodd;stroke:none"
|
||||
id="path5378" />
|
||||
</marker>
|
||||
<marker
|
||||
id="InOutPathMarker"
|
||||
orient="auto"
|
||||
refX="-4"
|
||||
refY="-1.687441"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
d="m 4.588864,-1.687441 0.0,0.0 L 9.177728,0.0 c -0.73311,-0.996261 -0.728882,-2.359329 0.0,-3.374882"
|
||||
style="fill:#0072a7;fill-rule:evenodd;stroke:none"
|
||||
id="path5381" />
|
||||
</marker>
|
||||
</defs>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1">
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.264583"
|
||||
d="m 14.552637,116.39357 c 65.106764,-39.849838 37.604718,58.37159 88.118643,26.94074 50.51392,-31.43086 69.03563,-1.68378 98.22142,-3.36759 29.1858,-1.68381 92.60881,-13.47034 58.93291,-38.7273 C 226.14969,75.982452 125.1219,195.53198 166.65554,113.02598 208.18918,30.519984 136.90844,109.65839 100.42622,58.58325 63.944003,7.5081061 54.402469,97.871802 54.402469,97.871802"
|
||||
id="path686" />
|
||||
<g
|
||||
gcodetools="Gcodetools orientation group"
|
||||
id="g748">
|
||||
<g
|
||||
gcodetools="Gcodetools orientation point (2 points)"
|
||||
id="g738">
|
||||
<path
|
||||
style="stroke:none;fill:#000000;"
|
||||
gcodetools="Gcodetools orientation point arrow"
|
||||
d="m 0 210 l 2.9375 -6.34375 l 0.8125 1.90625 l 6.84375 -6.84375 l 0 0 l 0.6875 0.6875 l -6.84375 6.84375 l 1.90625 0.8125 z"
|
||||
id="path732" />
|
||||
<text
|
||||
x="10.0"
|
||||
y="200.0"
|
||||
style="font-family:DejaVu Sans;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:DejaVu Sans;fill:#000000;fill-opacity:1;stroke:none;font-size:10.000000px;"
|
||||
gcodetools="Gcodetools orientation point text"
|
||||
xml:space="preserve"
|
||||
id="text736"><tspan
|
||||
x="10.0"
|
||||
y="200.0"
|
||||
sodipodi:role="line"
|
||||
id="tspan734">(0.0; 0.0; 0.00000)</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
gcodetools="Gcodetools orientation point (2 points)"
|
||||
id="g746">
|
||||
<path
|
||||
style="stroke:none;fill:#000000;"
|
||||
gcodetools="Gcodetools orientation point arrow"
|
||||
d="m 100 210 l 2.9375 -6.34375 l 0.8125 1.90625 l 6.84375 -6.84375 l 0 0 l 0.6875 0.6875 l -6.84375 6.84375 l 1.90625 0.8125 z"
|
||||
id="path740" />
|
||||
<text
|
||||
x="110.0"
|
||||
y="200.0"
|
||||
style="font-family:DejaVu Sans;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:DejaVu Sans;fill:#000000;fill-opacity:1;stroke:none;font-size:10.000000px;"
|
||||
gcodetools="Gcodetools orientation point text"
|
||||
xml:space="preserve"
|
||||
id="text744"><tspan
|
||||
x="110.0"
|
||||
y="200.0"
|
||||
sodipodi:role="line"
|
||||
id="tspan742">(100.0; 0.0; -0.10000)</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
gcodetools="Gcodetools tool definition"
|
||||
transform="translate(-398.17915,30.917996)"
|
||||
id="g915">
|
||||
<path
|
||||
gcodetools="Gcodetools tool background"
|
||||
style="fill:#00ff00;fill-opacity:0.5;stroke:#444444"
|
||||
d="M -20,-20 H 380 V 155 H -20 Z"
|
||||
id="path833" />
|
||||
<g
|
||||
gcodetools="Gcodetools tool parameter"
|
||||
id="g843">
|
||||
<text
|
||||
x="0"
|
||||
y="0"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field name"
|
||||
xml:space="preserve"
|
||||
id="text837"><tspan
|
||||
x="0"
|
||||
y="0"
|
||||
sodipodi:role="line"
|
||||
id="tspan835">name</tspan></text>
|
||||
<text
|
||||
x="150"
|
||||
y="0"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field value"
|
||||
xml:space="preserve"
|
||||
id="text841"><tspan
|
||||
x="150"
|
||||
y="0"
|
||||
sodipodi:role="line"
|
||||
id="tspan839">Cylindrical cutter</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
gcodetools="Gcodetools tool parameter"
|
||||
id="g853">
|
||||
<text
|
||||
x="0"
|
||||
y="20"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field name"
|
||||
xml:space="preserve"
|
||||
id="text847"><tspan
|
||||
x="0"
|
||||
y="20"
|
||||
sodipodi:role="line"
|
||||
id="tspan845">id</tspan></text>
|
||||
<text
|
||||
x="150"
|
||||
y="20"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field value"
|
||||
xml:space="preserve"
|
||||
id="text851"><tspan
|
||||
x="150"
|
||||
y="20"
|
||||
sodipodi:role="line"
|
||||
id="tspan849">Cylindrical cutter 0001</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
gcodetools="Gcodetools tool parameter"
|
||||
id="g863">
|
||||
<text
|
||||
x="0"
|
||||
y="35"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field name"
|
||||
xml:space="preserve"
|
||||
id="text857"><tspan
|
||||
x="0"
|
||||
y="35"
|
||||
sodipodi:role="line"
|
||||
id="tspan855">diameter</tspan></text>
|
||||
<text
|
||||
x="150"
|
||||
y="35"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field value"
|
||||
xml:space="preserve"
|
||||
id="text861"><tspan
|
||||
x="150"
|
||||
y="35"
|
||||
sodipodi:role="line"
|
||||
id="tspan1039">1</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
gcodetools="Gcodetools tool parameter"
|
||||
id="g873">
|
||||
<text
|
||||
x="0"
|
||||
y="50"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field name"
|
||||
xml:space="preserve"
|
||||
id="text867"><tspan
|
||||
x="0"
|
||||
y="50"
|
||||
sodipodi:role="line"
|
||||
id="tspan865">feed</tspan></text>
|
||||
<text
|
||||
x="150"
|
||||
y="50"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field value"
|
||||
xml:space="preserve"
|
||||
id="text871"><tspan
|
||||
x="150"
|
||||
y="50"
|
||||
sodipodi:role="line"
|
||||
id="tspan869">400</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
gcodetools="Gcodetools tool parameter"
|
||||
id="g883">
|
||||
<text
|
||||
x="0"
|
||||
y="65"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field name"
|
||||
xml:space="preserve"
|
||||
id="text877"><tspan
|
||||
x="0"
|
||||
y="65"
|
||||
sodipodi:role="line"
|
||||
id="tspan875">penetration angle</tspan></text>
|
||||
<text
|
||||
x="150"
|
||||
y="65"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field value"
|
||||
xml:space="preserve"
|
||||
id="text881"><tspan
|
||||
x="150"
|
||||
y="65"
|
||||
sodipodi:role="line"
|
||||
id="tspan879">90</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
gcodetools="Gcodetools tool parameter"
|
||||
id="g893">
|
||||
<text
|
||||
x="0"
|
||||
y="80"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field name"
|
||||
xml:space="preserve"
|
||||
id="text887"><tspan
|
||||
x="0"
|
||||
y="80"
|
||||
sodipodi:role="line"
|
||||
id="tspan885">penetration feed</tspan></text>
|
||||
<text
|
||||
x="150"
|
||||
y="80"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field value"
|
||||
xml:space="preserve"
|
||||
id="text891"><tspan
|
||||
x="150"
|
||||
y="80"
|
||||
sodipodi:role="line"
|
||||
id="tspan889">100</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
gcodetools="Gcodetools tool parameter"
|
||||
id="g903">
|
||||
<text
|
||||
x="0"
|
||||
y="95"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field name"
|
||||
xml:space="preserve"
|
||||
id="text897"><tspan
|
||||
x="0"
|
||||
y="95"
|
||||
sodipodi:role="line"
|
||||
id="tspan895">depth step</tspan></text>
|
||||
<text
|
||||
x="150"
|
||||
y="95"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field value"
|
||||
xml:space="preserve"
|
||||
id="text901"><tspan
|
||||
x="150"
|
||||
y="95"
|
||||
sodipodi:role="line"
|
||||
id="tspan899">1</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
gcodetools="Gcodetools tool parameter"
|
||||
id="g913">
|
||||
<text
|
||||
x="0"
|
||||
y="110"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field name"
|
||||
xml:space="preserve"
|
||||
id="text907"><tspan
|
||||
x="0"
|
||||
y="110"
|
||||
sodipodi:role="line"
|
||||
id="tspan905">tool change gcode</tspan></text>
|
||||
<text
|
||||
x="150"
|
||||
y="110"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:'DejaVu Sans';fill:#000000;fill-opacity:1;stroke:none"
|
||||
gcodetools="Gcodetools tool definition field value"
|
||||
xml:space="preserve"
|
||||
id="text911"><tspan
|
||||
x="150"
|
||||
y="110"
|
||||
sodipodi:role="line"
|
||||
id="tspan909">(None)</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g2335" />
|
||||
<g
|
||||
id="g3000" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 14 KiB |
1561
test/test_hatch_fill.gcode
Normal file
1561
test/test_hatch_fill.gcode
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,6 @@
|
||||
import pygame
|
||||
import sys
|
||||
from colorama import Fore, Style
|
||||
|
||||
class Visualizer:
|
||||
def __init__(self, positions : list[tuple[float, float, float]], screen_dimensions : tuple[int, int], gcode_size : tuple[float, float]):
|
||||
@@ -30,6 +32,26 @@ class Visualizer:
|
||||
self.screen = pygame.display.set_mode(self.screen_dimensions)
|
||||
self.clock = pygame.time.Clock()
|
||||
|
||||
def _print_status(self) -> None:
|
||||
normalized_x = self.prev_x / self.screen.get_width()
|
||||
normalized_y = self.prev_y / self.screen.get_height()
|
||||
pen_active = self.prev_z < 0
|
||||
|
||||
# Clear the terminal with ANSI code
|
||||
print("\033c", end="")
|
||||
|
||||
# X-axis bar
|
||||
x_bar = f"{Fore.GREEN}{'#'*int(normalized_x*100)}{Style.RESET_ALL}{' '*int((1.0-normalized_x)*100)}"
|
||||
print(f"X: |{x_bar}| {(normalized_x*100):.2f}%")
|
||||
|
||||
# Y-axis bar
|
||||
y_bar = f"{Fore.BLUE}{'#'*int(normalized_y*100)}{Style.RESET_ALL}{' '*int((1.0-normalized_y)*100)}"
|
||||
print(f"Y: |{y_bar}| {(normalized_y*100):.2f}%")
|
||||
|
||||
# Pen status
|
||||
pen_status = f"{Fore.GREEN}Active{Style.RESET_ALL}" if pen_active else f"{Fore.RED}Inactive{Style.RESET_ALL}"
|
||||
print(f"Pen: {pen_status}")
|
||||
|
||||
def visualize(self) -> None:
|
||||
running = True
|
||||
while running:
|
||||
@@ -61,5 +83,7 @@ class Visualizer:
|
||||
x1, y1, x2, y2 = drawn_line
|
||||
pygame.draw.line(self.screen, (255, 255, 255), (int(x1), int(y1)), (int(x2), int(y2)), 2)
|
||||
|
||||
self._print_status()
|
||||
|
||||
pygame.display.flip()
|
||||
self.clock.tick(60)
|
||||
self.clock.tick(10)
|
||||
Reference in New Issue
Block a user