First gerber2gcode tests, work in progress!
parent
e88354183e
commit
8b0a4634b9
|
@ -36,7 +36,7 @@ wall_extraWidth_right = 5;
|
|||
|
||||
totalWallWidth = wall_width+wall_extraWidth_left+wall_extraWidth_right;
|
||||
|
||||
module motorHoles() {
|
||||
module motorHolesY() {
|
||||
// Hole for the motor shaft
|
||||
hull() {
|
||||
translate([0,motor_adjust_margin/2,0])
|
||||
|
@ -72,7 +72,7 @@ difference() {
|
|||
translate([motor_width/2,motor_width/2,wall_thickness/2]) {
|
||||
|
||||
if(with_motor)
|
||||
motorHoles();
|
||||
motorHolesY();
|
||||
|
||||
// Bearing holes
|
||||
rotate([0,0,15]) translate([0,axis_distance,0]) {
|
||||
|
|
|
@ -0,0 +1,288 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
###### Cyclone PCB console v0.2 ######
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Controller for the Cyclone PCB Factory:
|
||||
# "a 3D printable CNC machine for PCB manufacture" (http://www.thingiverse.com/thing:49484)
|
||||
# This software has been tested with a Sanguinololu board running a modified Marlin firmware
|
||||
# that supports the G30 probing G-code.
|
||||
#
|
||||
# AUTHOR:
|
||||
# Carlosgs (http://carlosgs.es)
|
||||
# LICENSE:
|
||||
# Attribution - Share Alike - Creative Commons (http://creativecommons.org/licenses/by-sa/3.0/)
|
||||
#
|
||||
# DISCLAIMER:
|
||||
# This software is provided "as is", and you use the software at your own risk. Under no
|
||||
# circumstances shall Carlosgs be liable for direct, indirect, special, incidental, or
|
||||
# consequential damages resulting from the use, misuse, or inability to use this software,
|
||||
# even if Carlosgs has been advised of the possibility of such damages.
|
||||
#
|
||||
# CREDIT:
|
||||
# This script was created using as a base:
|
||||
# "Upload GCode to SpereBot" by Tgfuellner http://www.thingiverse.com/thing:9941 (CC-BY-SA)
|
||||
# Please refer to http://carlosgs.es for more information on this probing method
|
||||
#
|
||||
# REQUISITE:
|
||||
# http://pyserial.sourceforge.net
|
||||
# Installation on Ubuntu: sudo aptitude install python-serial
|
||||
#
|
||||
######################################
|
||||
|
||||
# Begin configuration
|
||||
BAUDRATE = 115200
|
||||
DEVICE = "/dev/ttyUSB0"
|
||||
# End configuration
|
||||
|
||||
import sys
|
||||
import serial
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
#fileToFeed = sys.argv[1] # Will use this later on to load
|
||||
gcode = open("/home/carlosgs/GitRepos/Cyclone-PCB-Factory/Software/Send/pyGerber2Gcode_CUI/out/printshield_drill.gcode", "r")
|
||||
|
||||
millis_wait = 0.5 # Delay used when re-trying to send/receive from the serial port [seconds]
|
||||
serial_timeout = 5 # Timeout for the serial port [seconds]
|
||||
|
||||
OK_response = "ok" # First two characters of an OK response (case insensitive)
|
||||
|
||||
def getCurrentTime():
|
||||
timeNow = datetime.now()
|
||||
print "Time:", str(timeNow)
|
||||
return timeNow
|
||||
|
||||
def emptyMachineRecvBuffer(): # We could also use flushInput(), but showing the data that is being discarded is useful for debugging
|
||||
while CNC_Machine.inWaiting() > 0:
|
||||
response = CNC_Machine.readline()
|
||||
if response != '':
|
||||
print "IGNO: ", response
|
||||
time.sleep(millis_wait) # Wait some milliseconds between attempts
|
||||
|
||||
def sendToMachine(line):
|
||||
emptyMachineRecvBuffer()
|
||||
CNC_Machine.write(line)
|
||||
print "SENT: ", line
|
||||
|
||||
def recvFromMachine():
|
||||
response = CNC_Machine.readline()
|
||||
if response != '':
|
||||
print "RECV: ", response
|
||||
else:
|
||||
print "RECV: Receive timed out!"
|
||||
return response
|
||||
|
||||
def machineSaysOK():
|
||||
response = recvFromMachine()
|
||||
if response[:2].lower() == OK_response.lower():
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def waitForOK(): # This is a blocking function
|
||||
print "Waiting for confirmation"
|
||||
while machineSaysOK() != 1:
|
||||
print " Checking again..."
|
||||
time.sleep(millis_wait) # Wait some milliseconds between attempts
|
||||
|
||||
def sendCommandToMachine(command): # Send command and wait for OK
|
||||
if len(command) > 2:
|
||||
sendToMachine(command)
|
||||
waitForOK()
|
||||
|
||||
def checkConnection():
|
||||
print "Checking the connection..."
|
||||
sendToMachine("G21\n") # We check the connection setting millimiters as the unit and waiting for the OK response
|
||||
time.sleep(0.5)
|
||||
while machineSaysOK() != 1:
|
||||
sendToMachine("G21\n")
|
||||
time.sleep(millis_wait) # Wait some milliseconds between attempts
|
||||
|
||||
print "Connecting to Cyclone..."
|
||||
|
||||
CNC_Machine = serial.Serial(DEVICE, BAUDRATE, timeout = serial_timeout)
|
||||
|
||||
print "Serial port opened, checking connection..."
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
checkConnection();
|
||||
|
||||
print "CONNECTED"
|
||||
|
||||
sendCommandToMachine("G90\n") # Set absolute positioning
|
||||
|
||||
def machineHomeZXY():
|
||||
print "Homing all axis..."
|
||||
sendCommandToMachine("G28 Z0\n") # move Z to min endstop
|
||||
sendCommandToMachine("G28 X0\n") # move X to min endstop
|
||||
sendCommandToMachine("G28 Y0\n") # move Y to min endstop
|
||||
|
||||
machineHomeZXY() # Home all the axis
|
||||
|
||||
|
||||
F_slowMove = 200 # Move speed [mm/min?]
|
||||
F_fastMove = 700
|
||||
|
||||
def floats(val): # This is used to convert a float value to a string (avoiding exponent notation)
|
||||
return '{:.3f}'.format(float(val)) # It truncates the decimals that aren't used
|
||||
|
||||
def machineToCoords(X, Y, Z, F):
|
||||
print "Moving to:"
|
||||
sendCommandToMachine("G1 X"+floats(X)+" Y"+floats(Y)+" Z"+floats(Z)+" F"+floats(F)+"\n")
|
||||
|
||||
def machineToCoordsXY(X, Y, F):
|
||||
print "Moving to:"
|
||||
sendCommandToMachine("G1 X"+floats(X)+" Y"+floats(Y)+" F"+floats(F)+"\n")
|
||||
|
||||
def machineToCoordsZ(Z, F):
|
||||
print "Moving Z absolute:"
|
||||
sendCommandToMachine("G1 Z"+floats(Z)+" F"+floats(F)+"\n")
|
||||
|
||||
def machineToCoordsZrelative(Z, F):
|
||||
print "Moving Z relative:"
|
||||
sendCommandToMachine("G91\n") # Set relative positioning
|
||||
sendCommandToMachine("G1 Z"+floats(Z)+" F"+floats(F)+"\n")
|
||||
sendCommandToMachine("G90\n") # Set absolute positioning
|
||||
|
||||
'''
|
||||
|
||||
grid_origin_X = float(0) # Initial point of the grid [mm]
|
||||
grid_origin_Y = float(0)
|
||||
|
||||
grid_len_X = float(135) #135 # Distance to probe [mm]
|
||||
grid_len_Y = float(84) #84
|
||||
|
||||
grid_N_X = int(12) #12 # Number of points
|
||||
grid_N_Y = int(6) #6
|
||||
|
||||
grid_inc_X = grid_len_X/float(grid_N_X-1) # [mm]
|
||||
grid_inc_Y = grid_len_Y/float(grid_N_Y-1)
|
||||
|
||||
probe_grid = [ [ 0 for i in range(grid_N_X) ] for j in range(grid_N_Y) ]
|
||||
|
||||
# Show our grid (initialised as zeros)
|
||||
for row in probe_grid:
|
||||
print row
|
||||
|
||||
print "Probing begins!"
|
||||
print "WARNING: Keep an eye on the machine, unplug if something goes wrong!"
|
||||
beginTime = getCurrentTime() # Store current time in a variable, will be used to measure duration of the probing
|
||||
|
||||
# Move to grid's origin
|
||||
machineToCoordsXY(grid_origin_X, grid_origin_Y, F_fastMove)
|
||||
|
||||
# Warning: Do not lower too much or you will potentially cause damage!
|
||||
initial_Z_lowering_distance = -15
|
||||
sendCommandToMachine("M121\n") # Enable endstops (for protection! it should tap the copper SLOWLY)
|
||||
machineToCoordsZrelative(initial_Z_lowering_distance,F_slowMove) # Move Z towards the PCB (saves some probing time for the first coord)
|
||||
sendCommandToMachine("M120\n") # Disable endstops (we only use them for homing)
|
||||
|
||||
def machineProbeZ():
|
||||
print "Probing Z"
|
||||
sendToMachine("G30\n") # Launch probe command
|
||||
response = recvFromMachine() # Read the response, it is a variable run time so we may need to make multiple attempts
|
||||
while response == '':
|
||||
#print "."
|
||||
time.sleep(millis_wait) # Wait some milliseconds between attempts
|
||||
response = recvFromMachine()
|
||||
response_vals = response.split() # Split the response (i.e. "ok Z:1.23")
|
||||
if response_vals[0][:2].lower() == OK_response.lower():
|
||||
Zres = response_vals[1][2:] # Ignore the "Z:" and read the coordinate value
|
||||
print "Result is Z=",Zres
|
||||
return float(Zres)
|
||||
return 400 # Error case, don't worry: it has never happened :)
|
||||
|
||||
def isOdd(number):
|
||||
if number % 2 == 0:
|
||||
return 0 # Even number
|
||||
else:
|
||||
return 1 # Odd number
|
||||
|
||||
Z_probing_lift = 0.5 # lift between Z probings [mm]
|
||||
# Note: The lift is relative to the PCB board, you can usually set a low value to speedup the process.
|
||||
# But PLEASE keep an eye for possible collisions!
|
||||
|
||||
for x_i in range(grid_N_X): # For each point on the grid...
|
||||
x_val = float(x_i)*grid_inc_X + grid_origin_X; # Calculate X coordinate
|
||||
optimal_range = range(grid_N_Y)
|
||||
if isOdd(x_i): # This optimises a bit the probing path
|
||||
optimal_range = reversed(optimal_range)
|
||||
for y_i in optimal_range:
|
||||
y_val = float(y_i)*grid_inc_Y + grid_origin_Y; # Calculate Y coordinate
|
||||
machineToCoordsXY(x_val, y_val, F_fastMove) # Move to position
|
||||
probe_grid[y_i][x_i] = machineProbeZ() # Do the Z probing
|
||||
machineToCoordsZrelative(Z_probing_lift, F_fastMove/2) # Lift the probe
|
||||
|
||||
# Once we have all the points, we set the origin as (0,0) and offset the rest of values
|
||||
ZoffsetOrigin = probe_grid[0][0]
|
||||
print "The origin Z height is", ZoffsetOrigin
|
||||
probe_grid = [[elem - ZoffsetOrigin for elem in row] for row in probe_grid]
|
||||
|
||||
# Return to the grid's origin
|
||||
machineToCoordsZrelative(10, F_slowMove) # Lift Z
|
||||
machineToCoordsXY(grid_origin_X, grid_origin_Y, F_fastMove) # Move to grid's origin
|
||||
|
||||
|
||||
# Show our grid
|
||||
print "Result:"
|
||||
print probe_grid # Right now I am copying this to an Octave script for the visualizations
|
||||
|
||||
# TODO:
|
||||
# - Export results to a file with a standarized format
|
||||
# -
|
||||
|
||||
print "Finished probing!"
|
||||
getCurrentTime()
|
||||
print "Probing duration:", str(datetime.now() - beginTime)
|
||||
'''
|
||||
|
||||
initial_Z_lowering_distance = -15
|
||||
machineToCoordsZrelative(initial_Z_lowering_distance,F_slowMove)
|
||||
|
||||
currentLine = 0.0
|
||||
lines = gcode.readlines()
|
||||
totalLines = len(lines)
|
||||
for line in lines:
|
||||
currentLine = currentLine + 1
|
||||
print line, "({0:.1f}%)".format((currentLine / totalLines)*100)
|
||||
sendCommandToMachine(line)
|
||||
|
||||
gcode.close()
|
||||
|
||||
# IMPORTANT: Before closing the serial port we must make a blocking move in order to wait for all the buffered commands to end
|
||||
sendCommandToMachine("G28 Z0\n") # move Z to min endstop
|
||||
|
||||
CNC_Machine.close() # Close the serial port connection
|
||||
|
||||
|
||||
# Bilinear interpolation code by Raymond Hettinger from http://stackoverflow.com/a/8662355
|
||||
def bilinear_interpolation(x, y, points):
|
||||
'''Interpolate (x,y) from values associated with four points.
|
||||
|
||||
The four points are a list of four triplets: (x, y, value).
|
||||
The four points can be in any order. They should form a rectangle.
|
||||
|
||||
>>> bilinear_interpolation(12, 5.5,
|
||||
... [(10, 4, 100),
|
||||
... (20, 4, 200),
|
||||
... (10, 6, 150),
|
||||
... (20, 6, 300)])
|
||||
165.0
|
||||
'''
|
||||
# See formula at: http://en.wikipedia.org/wiki/Bilinear_interpolation
|
||||
|
||||
points = sorted(points) # order points by x, then by y
|
||||
(x1, y1, q11), (_x1, y2, q12), (x2, _y1, q21), (_x2, _y2, q22) = points
|
||||
|
||||
if x1 != _x1 or x2 != _x2 or y1 != _y1 or y2 != _y2:
|
||||
raise ValueError('points do not form a rectangle')
|
||||
if not x1 <= x <= x2 or not y1 <= y <= y2:
|
||||
raise ValueError('(x, y) not within the rectangle')
|
||||
|
||||
return (q11 * (x2 - x) * (y2 - y) +
|
||||
q21 * (x - x1) * (y2 - y) +
|
||||
q12 * (x2 - x) * (y - y1) +
|
||||
q22 * (x - x1) * (y - y1)
|
||||
) / ((x2 - x1) * (y2 - y1) + 0.0)
|
||||
|
|
@ -0,0 +1,845 @@
|
|||
#!/usr/bin/python
|
||||
# coding: UTF-8
|
||||
|
||||
import wx
|
||||
from string import *
|
||||
from math import *
|
||||
#from struct import *
|
||||
import os
|
||||
import sys
|
||||
#import datetime
|
||||
import locale
|
||||
import re
|
||||
#import time
|
||||
#Global Constant
|
||||
HUGE = 1e10
|
||||
TINY = 1e-6
|
||||
#MERGINE = 1e-6
|
||||
INCH = 25.4 #mm
|
||||
MIL = INCH/1000
|
||||
WINDOW_X = 800
|
||||
WINDOW_Y = 600
|
||||
CENTER_X=200.0
|
||||
CENTER_Y=200.0
|
||||
|
||||
#For file
|
||||
IN_INCH_FLAG = 0
|
||||
GCODE_EXT = '*.gcode'
|
||||
|
||||
#View
|
||||
DEF_COLOR = 'BLACK' #black
|
||||
|
||||
#Global variable
|
||||
gXMIN = HUGE
|
||||
gXMAX = -HUGE
|
||||
gYMIN = HUGE
|
||||
gYMAX = -HUGE
|
||||
gZMIN = HUGE
|
||||
gZMAX = -HUGE
|
||||
gXSHIFT = 0
|
||||
gYSHIFT = 0
|
||||
gGCODE_DATA = ""
|
||||
gGCODES = []
|
||||
gUNIT = 1
|
||||
|
||||
#For Drawing
|
||||
gTHETA = pi/4.0
|
||||
gPHI = pi/4.0
|
||||
gPSI = 0.0
|
||||
gVIEW_POINT = 0
|
||||
gPATTERNS = []
|
||||
gDRAWCONTOUR = []
|
||||
gMAG = 1.0
|
||||
gPRE_X = CENTER_X
|
||||
gPRE_Y = CENTER_X
|
||||
gMAG_MIN = 0.1
|
||||
gMAG_MAX = 500.0
|
||||
gDRAW_XSHIFT = 0.0
|
||||
gDRAW_YSHIFT = 0.0
|
||||
gDRAW_ZSHIFT = 0.0
|
||||
gCENTER_X = 0.0
|
||||
gCENTER_Y = 0.0
|
||||
gCENTER_Z = 0.0
|
||||
gDISP_GERBER = 1
|
||||
gDISP_DRILL = 0
|
||||
gDISP_EDGE = 0
|
||||
gDISP_CONTOUR = 0
|
||||
|
||||
gMOVE_COLOR = 'BLUE'
|
||||
|
||||
gCOLORS = [
|
||||
'AQUAMARINE','BLACK','BLUE','BLUE VIOLET','BROWN',
|
||||
'CADET BLUE','CORAL','CORNFLOWER BLUE','CYAN','DARK GREY',
|
||||
'DARK GREEN', 'DARK OLIVE GREEN', 'DARK ORCHID', 'DARK SLATE BLUE', 'DARK SLATE GREY',
|
||||
'DARK TURQUOISE', 'DIM GREY', 'FIREBRICK', 'FOREST GREEN', 'GOLD',
|
||||
'GOLDENROD', 'GREY', 'GREEN', 'GREEN YELLOW', 'INDIAN RED',
|
||||
'KHAKI', 'LIGHT BLUE', 'LIGHT GREY', 'LIGHT STEEL BLUE', 'LIME GREEN',
|
||||
'MAGENTA', 'MAROON', 'MEDIUM AQUAMARINE', 'MEDIUM BLUE', 'MEDIUM FOREST GREEN',
|
||||
'MEDIUM GOLDENROD', 'MEDIUM ORCHID', 'MEDIUM SEA GREEN', 'MEDIUM SLATE BLUE', 'MEDIUM SPRING GREEN',
|
||||
'MEDIUM TURQUOISE', 'MEDIUM VIOLET RED', 'MIDNIGHT BLUE', 'NAVY', 'ORANGE',
|
||||
'ORANGE RED', 'ORCHID', 'PALE GREEN', 'PINK', 'PLUM',
|
||||
'PURPLE', 'RED', 'SALMON', 'SEA GREEN', 'SIENNA',
|
||||
'SKY BLUE', 'SLATE BLUE', 'SPRING GREEN', 'STEEL BLUE', 'TAN',
|
||||
'THISTLE ', 'TURQUOISE', 'VIOLET', 'VIOLET RED', 'WHEAT',
|
||||
'WHITE', 'YELLOW', 'YELLOW GREEN'
|
||||
]
|
||||
|
||||
gMouseLeftDown = [0]*3
|
||||
gMouseRightDown = [0]*3
|
||||
|
||||
#Window
|
||||
class MainFrame(wx.Frame):
|
||||
def __init__(self, parent, id, title):
|
||||
global WINDOW_X, WINDOW_Y, gVIEW_POINT
|
||||
wx.Frame.__init__(self, parent, id, title, size=(WINDOW_X, WINDOW_Y))
|
||||
# Setting up the menu.
|
||||
filemenu= wx.Menu()
|
||||
menuOpen = filemenu.Append(wx.ID_OPEN,"&Open"," Open files")
|
||||
menuReload = filemenu.Append(wx.ID_REVERT,"&Reload"," Reload files")
|
||||
menuExit = filemenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")
|
||||
#setupmenu = wx.Menu()
|
||||
#menuMachine = setupmenu.Append(wx.ID_SETUP,"&Machine setup"," Setup Machine")
|
||||
#menuConv = setupmenu.Append(wx.ID_VIEW_LIST,"&Convert setup"," Convert setup")
|
||||
# Creating the menubar.
|
||||
menuBar = wx.MenuBar()
|
||||
menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar
|
||||
#menuBar.Append(setupmenu,"&Setup") # Adding the "filemenu" to the MenuBar
|
||||
self.SetMenuBar(menuBar) # Adding the MenuBar to the Frame content.
|
||||
|
||||
#Event for Menu bar
|
||||
self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
|
||||
self.Bind(wx.EVT_MENU, self.OnReload, menuReload)
|
||||
self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
|
||||
#self.Bind(wx.EVT_MENU, self.OnConvSet, menuConv)
|
||||
#self.Bind(wx.EVT_MENU, self.OnSetup, menuMachine)
|
||||
|
||||
|
||||
panel = wx.Panel(self, -1)
|
||||
#panel.SetBackgroundColour('WHITE')
|
||||
vbox = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
#Display set
|
||||
panel1 = wx.Panel(panel, -1)
|
||||
#box1 = wx.StaticBox(panel1, -1, 'Display data')
|
||||
#sizer1 = wx.StaticBoxSizer(box1, orient=wx.VERTICAL)
|
||||
#grid1 = wx.GridSizer(2, 5, 0, 5)
|
||||
#self.cb1 = wx.CheckBox(panel1, -1, 'Pattern data')
|
||||
#self.cb1.SetValue(gDISP_GERBER)
|
||||
#grid1.Add(self.cb1)
|
||||
#self.cb2 = wx.CheckBox(panel1, -1, 'Drill data')
|
||||
#self.cb2.SetValue(gDISP_DRILL)
|
||||
#grid1.Add(self.cb2)
|
||||
#self.cb3 = wx.CheckBox(panel1, -1, 'Edge data')
|
||||
#self.cb3.SetValue(gDISP_EDGE)
|
||||
#grid1.Add(self.cb3)
|
||||
|
||||
#self.cb4 = wx.CheckBox(panel1, -1, 'Contour data')
|
||||
#self.cb4.SetValue(gDISP_CONTOUR)
|
||||
#grid1.Add(self.cb4)
|
||||
|
||||
vbox_view = wx.BoxSizer(wx.VERTICAL)
|
||||
radioList = ['XY', 'XZ', 'YZ', 'XYZ']
|
||||
rb1 = wx.RadioBox(panel1, label="View plain", choices=radioList, majorDimension=5, style=wx.RA_SPECIFY_COLS)
|
||||
rb1.SetSelection(int(gVIEW_POINT))
|
||||
vbox_view.Add(rb1, 0, wx.BOTTOM | wx.TOP, 9)
|
||||
|
||||
#sizer1.Add(grid1)
|
||||
#panel1.SetSizer(sizer1)
|
||||
panel1.SetSizer(vbox_view)
|
||||
vbox.Add(panel1, 0, wx.BOTTOM | wx.TOP, 9)
|
||||
|
||||
#Draw data
|
||||
panel2 = wx.Panel(panel, -1)
|
||||
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
#vbox1 = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
paint = Paint(panel2)
|
||||
#paint = Paint(hbox1)
|
||||
#sw = wx.ScrolledWindow(panel2)
|
||||
#paint = Paint(sw)
|
||||
#sw.SetScrollbars(20,20,55,40)
|
||||
|
||||
#hbox1.Add(sw, 1, wx.LEFT | wx.RIGHT | wx.EXPAND, 2)
|
||||
hbox1.Add(paint, 1, wx.EXPAND | wx.ALL, 2)
|
||||
#vbox1.Add(paint, 0, wx.EXPAND | wx.ALL, 15)
|
||||
panel2.SetSizer(hbox1)
|
||||
#panel2.SetSizer(vbox1)
|
||||
vbox.Add(panel2, 1, wx.LEFT | wx.RIGHT | wx.EXPAND, 2)
|
||||
#vbox.Add((-1, 25))
|
||||
|
||||
hbox5 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
#btn0 = wx.Button(panel, -1, 'Generate contour', size=(150, 30))
|
||||
#hbox5.Add(btn0, 0)
|
||||
#btn1 = wx.Button(panel, -1, 'Convert and Save', size=(150, 30))
|
||||
#hbox5.Add(btn1, 0)
|
||||
btn2 = wx.Button(panel, -1, 'Close', size=(70, 30))
|
||||
hbox5.Add(btn2, 0, wx.LEFT | wx.BOTTOM , 5)
|
||||
vbox.Add(hbox5, 0, wx.ALIGN_RIGHT | wx.RIGHT, 10)
|
||||
|
||||
#vbox1 = wx.BoxSizer(wx.VERTICAL)
|
||||
#self.progress1 = wx.StaticText(panel, -1, 'Progress')
|
||||
#vbox1.Add(self.progress1, 0, wx.LEFT)
|
||||
#self.gauge = wx.Gauge(panel, -1, 100, size=(500, 15))
|
||||
#vbox1.Add(self.gauge, 0, wx.LEFT)
|
||||
#vbox.Add(vbox1, 0, wx.ALIGN_LEFT | wx.LEFT, 10)
|
||||
|
||||
panel.SetSizer(vbox)
|
||||
#status = self.CreateStatusBar()
|
||||
#rect = status.GetFieldRect(1)
|
||||
#self.gauge = wx.Gauge(status, -1, 100, wx.Point(rect.x + 2, rect.y + 2),wx.Size(rect.width - 4, rect.height - 4))
|
||||
self.Centre()
|
||||
self.Show(True)
|
||||
|
||||
#Event
|
||||
#self.Bind(wx.EVT_CHECKBOX, self.OnGeber,self.cb1)
|
||||
#self.Bind(wx.EVT_CHECKBOX, self.OnDrill,self.cb2)
|
||||
#self.Bind(wx.EVT_CHECKBOX, self.OnEdge,self.cb3)
|
||||
#self.Bind(wx.EVT_CHECKBOX, self.OnContour,self.cb4)
|
||||
self.Bind(wx.EVT_BUTTON, self.OnExit, btn2)
|
||||
#self.Bind(wx.EVT_BUTTON, self.OnGenerate, btn0)
|
||||
#self.Bind(wx.EVT_BUTTON, self.OnConvert, btn1)
|
||||
self.Bind(wx.EVT_RADIOBOX, self.EvtRadioBox1, rb1)
|
||||
|
||||
#functions
|
||||
def EvtRadioBox1(self,e):
|
||||
global gVIEW_POINT
|
||||
gVIEW_POINT = e.GetInt()
|
||||
self.Refresh(1)
|
||||
def OnGeber(self,e):
|
||||
global gDISP_GERBER
|
||||
gDISP_GERBER = int(self.cb1.IsChecked())
|
||||
self.Refresh(1)
|
||||
def OnDrill(self,e):
|
||||
global gDISP_DRILL, gDISP_EDGE
|
||||
gDISP_DRILL = int(self.cb2.IsChecked())
|
||||
self.Refresh(1)
|
||||
def OnEdge(self,e):
|
||||
global gDISP_EDGE
|
||||
gDISP_EDGE = int(self.cb3.IsChecked())
|
||||
self.Refresh(1)
|
||||
def OnContour(self,e):
|
||||
global gDISP_CONTOUR, gDRAWCONTOUR
|
||||
if(len(gDRAWCONTOUR) > 0):
|
||||
gDISP_CONTOUR = int(self.cb4.IsChecked())
|
||||
else:
|
||||
gDISP_CONTOUR = 0
|
||||
self.cb4.SetValue(0)
|
||||
self.Refresh(1)
|
||||
def OnExit(self,e):
|
||||
self.Close(True) # Close the frame.
|
||||
def OnOpen(self,e):
|
||||
setup = OpenFiles(None, -1, 'Open Files')
|
||||
setup.ShowModal()
|
||||
setup.Destroy()
|
||||
self.Refresh(1)
|
||||
def OnReload(self,e):
|
||||
readGcodeFile()
|
||||
#class Paint(wx.Panel):
|
||||
class Paint(wx.ScrolledWindow):
|
||||
def __init__(self, parent):
|
||||
#wx.Panel.__init__(self, parent)
|
||||
wx.ScrolledWindow.__init__(self, parent,-1,style=wx.HSCROLL|wx.VSCROLL)
|
||||
global gDRAW_XSHIFT, gDRAW_YSHIFT, gDRAW_ZSHIFT
|
||||
self.SetBackgroundColour('WHITE')
|
||||
|
||||
#print self.GetScaleX()
|
||||
#print self.GetSize()
|
||||
#print self.GetScrollPageSize(wx.VERTICAL)
|
||||
#print self.GetScrollPageSize(wx.HORIZONTAL)
|
||||
#print self.GetViewStart()
|
||||
#print self.GetVirtualSize()
|
||||
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||
|
||||
#panel.Bind(wx.EVT_SCROLLWIN, self.OnScroll)
|
||||
self.SetScrollbars(10, 10, 100,100);
|
||||
#self.Bind(wx.EVT_SCROLLWIN, self.OnScroll)
|
||||
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
|
||||
|
||||
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||
self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
|
||||
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.OnDrag)
|
||||
self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
|
||||
self.Bind(wx.EVT_RIGHT_DOWN, self.OnMouseRightDown)
|
||||
#self.Bind(wx.EVT_LEFT_DCLICK , self.OnMouseLeftDClick)
|
||||
#self.Bind(wx.EVT_RIGHT_DCLICK , self.OnMouseRightDClick)
|
||||
self.Bind(wx.EVT_LEFT_UP, self.OnMouseLeftUp)
|
||||
self.Bind(wx.EVT_RIGHT_UP, self.OnMouseRightUp)
|
||||
self.Bind(wx.EVT_MOTION , self.OnMouseMove)
|
||||
paint_size = self.GetSize()
|
||||
gDRAW_XSHIFT =int(paint_size.x/2)
|
||||
gDRAW_YSHIFT =int(paint_size.y/2)
|
||||
self.Centre()
|
||||
self.Show(True)
|
||||
|
||||
def OnKeyDown(self, event):
|
||||
keycode = event.GetKeyCode()
|
||||
print keycode
|
||||
#if keycode == wx.WXK_UP:
|
||||
|
||||
#gerber
|
||||
def OnPaint(self, e):
|
||||
global gMAG, gDRAW_XSHIFT, gDRAW_YSHIFT, gDRAW_ZSHIFT, gCENTER_X, gCENTER_Y, gCENTER_Z, gPATTERNS, gMOVE_COLOR,gVIEW_POINT, CENTER_X, CENTER_Y
|
||||
dc = wx.PaintDC(self)
|
||||
#print self.GetViewStart()
|
||||
#print self.GetVirtualSize()
|
||||
#print self.GetSize()
|
||||
paint_size = self.GetSize()
|
||||
CENTER_X =int(paint_size.x/2)
|
||||
CENTER_Y =int(paint_size.y/2)
|
||||
#veiw_start = self.GetViewStart()
|
||||
veiw_start = self.CalcUnscrolledPosition(0,0)
|
||||
#print "Center x=" + str(CENTER_X) + ", Center x="+ str(CENTER_Y)
|
||||
#print "pos=" + str(veiw_start)
|
||||
#print 'Mag' + str(gMAG) + ", x shift=" + str(gDRAW_XSHIFT-veiw_start[0]) + ", y shift=" + str(gDRAW_YSHIFT-veiw_start[1])
|
||||
#c=POINT(gCENTER_X, gCENTER_Y, gCENTER_Z)
|
||||
c=POINT(0.0, 0.0, 0.0) #center of view point
|
||||
|
||||
#
|
||||
coorc = POINT(gDRAW_XSHIFT-veiw_start[0],gDRAW_YSHIFT-veiw_start[1],gDRAW_ZSHIFT)
|
||||
coorx = POINT(gDRAW_XSHIFT-veiw_start[0]+20,gDRAW_YSHIFT-veiw_start[1],gDRAW_ZSHIFT)
|
||||
coory = POINT(gDRAW_XSHIFT-veiw_start[0],gDRAW_YSHIFT-veiw_start[1]-20,gDRAW_ZSHIFT)
|
||||
coorz = POINT(gDRAW_XSHIFT-veiw_start[0],gDRAW_YSHIFT-veiw_start[1],gDRAW_ZSHIFT+20)
|
||||
if(len(gPATTERNS) > 0):
|
||||
for patterns in gPATTERNS:
|
||||
#color = patterns.color
|
||||
for pattern in patterns.patterns:
|
||||
#print len(pattern.points)
|
||||
#print pattern.points
|
||||
if(gVIEW_POINT==0): #XY
|
||||
p1x = pattern.points[0].x
|
||||
p1y = pattern.points[0].y
|
||||
p2x = pattern.points[1].x
|
||||
p2y = pattern.points[1].y
|
||||
#Draw coor
|
||||
dc.SetPen(wx.Pen('BLACK', 1, wx.SOLID))
|
||||
dc.DrawLines(([coorc.x,coorc.y],[coorx.x,coorx.y])) #X axis
|
||||
dc.DrawLines(([coorc.x,coorc.y],[coory.x,coory.y])) #Y axis
|
||||
elif(gVIEW_POINT==1): #XZ
|
||||
p1x = pattern.points[0].x
|
||||
p1y = pattern.points[0].z
|
||||
p2x = pattern.points[1].x
|
||||
p2y = pattern.points[1].z
|
||||
dc.SetPen(wx.Pen('BLACK', 1, wx.SOLID))
|
||||
dc.DrawLines(([coorc.x,coorc.y],[coorx.x,coorx.y])) #X axis
|
||||
dc.DrawLines(([coorc.x,coorc.y],[coory.x,coory.y])) #Y axis
|
||||
elif(gVIEW_POINT==2): #YZ
|
||||
p1x = pattern.points[0].y
|
||||
p1y = pattern.points[0].z
|
||||
p2x = pattern.points[1].y
|
||||
p2y = pattern.points[1].z
|
||||
dc.SetPen(wx.Pen('BLACK', 1, wx.SOLID))
|
||||
dc.DrawLines(([coorc.x,coorc.y],[coorx.x,coorx.y])) #X axis
|
||||
dc.DrawLines(([coorc.x,coorc.y],[coory.x,coory.y])) #Y axis
|
||||
else:
|
||||
p1,p2 = change_view(pattern.points[0],pattern.points[1],c)
|
||||
p1x = p1.x
|
||||
p1y = p1.y
|
||||
p2x = p2.x
|
||||
p2y = p2.y
|
||||
co1,co2 = change_view(POINT(0.0,0.0,0.0),POINT(20.0,0.0,0.0),c)
|
||||
dc.SetPen(wx.Pen('BLACK', 1, wx.SOLID))
|
||||
point1 = [co1.x+gDRAW_XSHIFT-veiw_start[0],co1.y+gDRAW_YSHIFT-veiw_start[1]]
|
||||
point2 = [co2.x+gDRAW_XSHIFT-veiw_start[0],-co2.y+gDRAW_YSHIFT-veiw_start[1]]
|
||||
dc.DrawLines((point1,point2)) #X axis
|
||||
co1,co2 = change_view(POINT(0.0,0.0,0.0),POINT(0.0,20.0,0.0),c)
|
||||
point1 = [co1.x+gDRAW_XSHIFT-veiw_start[0],co1.y+gDRAW_YSHIFT-veiw_start[1]]
|
||||
point2 = [co2.x+gDRAW_XSHIFT-veiw_start[0],-co2.y+gDRAW_YSHIFT-veiw_start[1]]
|
||||
dc.DrawLines((point1,point2)) #Y axis
|
||||
dc.DrawLines(([coorc.x,coorc.y],[coorc.x,coorc.y-20])) #Z axis
|
||||
x1 = p1x * gMAG + gDRAW_XSHIFT-veiw_start[0]
|
||||
y1 = -p1y * gMAG + gDRAW_YSHIFT-veiw_start[1]
|
||||
x2 = p2x * gMAG + gDRAW_XSHIFT-veiw_start[0]
|
||||
y2 = -p2y * gMAG + gDRAW_YSHIFT-veiw_start[1]
|
||||
if(pattern.style == 0): #move
|
||||
dc.SetPen(wx.Pen(gMOVE_COLOR, 1, wx.DOT_DASH))
|
||||
dc.DrawLines(([x1,y1],[x2,y2]))
|
||||
if(pattern.style == 1):
|
||||
dc.SetPen(wx.Pen(patterns.color, 1, wx.SOLID))
|
||||
dc.DrawLines([[x1,y1],[x2,y2]])
|
||||
if(pattern.style == 2 or pattern.style == 3):
|
||||
dc.SetPen(wx.Pen(color, 1, wx.SOLID))
|
||||
dc.DrawArcPoint(pattern.p1,pattern.p2,pattern.center)
|
||||
def OnMouseWheel(self, event):
|
||||
global gMAG, gMAG_MIN, gMAG_MAX, gDRAW_XSHIFT, gDRAW_YSHIFT, WINDOW_X, WINDOW_Y, CENTER_X, CENTER_Y, gPRE_X, gPRE_Y
|
||||
pos = event.GetPosition()
|
||||
w = event.GetWheelRotation()
|
||||
#mag_cont += copysign(1.0, w)
|
||||
pre_mag = gMAG
|
||||
gMAG += copysign(1.0, w)
|
||||
#gMAG += w/100.0
|
||||
#gMAG = 1
|
||||
gDRAW_XSHIFT = float(CENTER_X) - (gMAG*(float(pos.x)-gDRAW_XSHIFT))/pre_mag
|
||||
gDRAW_YSHIFT = float(CENTER_Y) - (gMAG*(float(pos.y)-gDRAW_YSHIFT))/pre_mag
|
||||
gPRE_X = float(pos.x)
|
||||
gPRE_Y = float(pos.y)
|
||||
if(gMAG < gMAG_MIN):
|
||||
gMAG = gMAG_MIN
|
||||
gDRAW_XSHIFT = CENTER_X
|
||||
gDRAW_YSHIFT = CENTER_Y
|
||||
if(gMAG > gMAG_MAX):
|
||||
gMAG = gMAG_MAX
|
||||
gDRAW_XSHIFT = float(CENTER_X) - (gMAG*(float(pos.x)-gDRAW_XSHIFT))/pre_mag
|
||||
gDRAW_YSHIFT = float(CENTER_Y) - (gMAG*(float(pos.y)-gDRAW_YSHIFT))/pre_mag
|
||||
#print 'Mag' + str(gMAG) + ", x shift=" + str(gDRAW_XSHIFT) + ", y shift=" + str(gDRAW_YSHIFT)
|
||||
#print 'OnMouseWheel' + str(pos) + ", w=" + str(gMAG)
|
||||
#self.OnPaint(event)
|
||||
self.Refresh(1)
|
||||
def OnDrag(self, event):
|
||||
pos = event.GetPosition()
|
||||
print "Drag: pos=" + str(pos)
|
||||
#self.Refresh(1)
|
||||
def OnScroll(self, event):
|
||||
global gDRAW_XSHIFT, gDRAW_YSHIFT
|
||||
pos = self.GetViewStart()
|
||||
print "pos=" + str(pos)
|
||||
gDRAW_XSHIFT -= pos[0]
|
||||
gDRAW_YSHIFT -= pos[1]
|
||||
print "X shif=" + str(gDRAW_XSHIFT) + ", Y shift=" + str(gDRAW_YSHIFT)
|
||||
#self.Refresh(1)
|
||||
def OnMouseLeftDown(self, event):
|
||||
global gMouseLeftDown
|
||||
pos = event.GetPosition()
|
||||
gMouseLeftDown[0] = 1
|
||||
gMouseLeftDown[1] = pos.x
|
||||
gMouseLeftDown[2] = pos.y
|
||||
#print "Left Down: pos=" + str(pos)
|
||||
def OnMouseRightDown(self, event):
|
||||
global gMouseRightDown
|
||||
pos = event.GetPosition()
|
||||
gMouseRightDown[0] = 1
|
||||
gMouseRightDown[1] = pos.x
|
||||
gMouseRightDown[2] = pos.y
|
||||
#print "Right Down: pos=" + str(pos)
|
||||
def OnMouseLeftUp(self, event):
|
||||
global gMouseLeftDown, gMAG, gDRAW_XSHIFT, gDRAW_YSHIFT, CENTER_X, CENTER_Y
|
||||
pos = event.GetPosition()
|
||||
size = self.GetSize()
|
||||
if gMouseLeftDown[0]:
|
||||
gMouseLeftDown[0] = 0
|
||||
pre_mag = gMAG
|
||||
dx = pos.x - gMouseLeftDown[1]
|
||||
dy = pos.y - gMouseLeftDown[2]
|
||||
cx = pos.x - dx/2
|
||||
cy = pos.y - dy/2
|
||||
if(dx > 0):
|
||||
gMAG = float(size.x)/float(dx/pre_mag)
|
||||
elif(dx < 0):
|
||||
gMAG = -float(pre_mag)/float(dx)
|
||||
#print "gmag=" + str(gMAG)
|
||||
if(dy > 0):
|
||||
if(gMAG > float(size.y)/float(dy/pre_mag)):
|
||||
gMAG = float(size.y)/float(dy/pre_mag)
|
||||
|
||||
gDRAW_XSHIFT = float(CENTER_X) - (gMAG*(float(cx)-gDRAW_XSHIFT))/pre_mag
|
||||
gDRAW_YSHIFT = float(CENTER_Y) - (gMAG*(float(cy)-gDRAW_YSHIFT))/pre_mag
|
||||
if(gMAG < gMAG_MIN):
|
||||
gMAG = gMAG_MIN
|
||||
gDRAW_XSHIFT = CENTER_X
|
||||
gDRAW_YSHIFT = CENTER_Y
|
||||
if(gMAG > gMAG_MAX):
|
||||
gMAG = gMAG_MAX
|
||||
gDRAW_XSHIFT = float(CENTER_X) - (gMAG*(float(cx)-gDRAW_XSHIFT))/pre_mag
|
||||
gDRAW_YSHIFT = float(CENTER_Y) - (gMAG*(float(cy)-gDRAW_YSHIFT))/pre_mag
|
||||
|
||||
self.Refresh(1)
|
||||
#print "X shif=" + str(gDRAW_XSHIFT) + ", Y shift=" + str(gDRAW_YSHIFT)
|
||||
#print "Left UP: pos=" + str(pos) + ", dx=" + str(dx) + ", dy=" + str(dy) + ", cx=" + str(cx) + ", cy=" + str(cy) + ", mag=" + str(gMAG)
|
||||
def OnMouseRightUp(self, event):
|
||||
global gMouseRightDown, gMAG
|
||||
pos = event.GetPosition()
|
||||
if gMouseRightDown[0]:
|
||||
gMouseRightDown[0] = 0
|
||||
dx = pos.x - gMouseRightDown[1]
|
||||
dy = pos.y - gMouseRightDown[2]
|
||||
dist = sqrt(dx*dx + dy*dy)/gMAG
|
||||
print dist
|
||||
def OnMouseLeftDClick(self, event):
|
||||
pos = event.GetPosition()
|
||||
def OnMouseRightDClick(self, event):
|
||||
pos = event.GetPosition()
|
||||
def OnMouseMove(self, event):
|
||||
pos = event.GetPosition()
|
||||
|
||||
class OpenFiles(wx.Dialog):
|
||||
def __init__(self, parent, id, title):
|
||||
global IN_INCH_FLAG, gGCODES, gCOLORS, GCODE_EXT, DEF_COLOR
|
||||
wx.Dialog.__init__(self, parent, id, title, size=(250, 210))
|
||||
self.dirname=''
|
||||
|
||||
panel = wx.Panel(self, -1)
|
||||
sizer = wx.GridBagSizer(0, 0)
|
||||
|
||||
text1 = wx.StaticText(panel, -1, 'G code file')
|
||||
sizer.Add(text1, (0, 0), flag= wx.LEFT | wx.TOP, border=10)
|
||||
|
||||
self.gcode = wx.TextCtrl(panel, -1)
|
||||
#self.gcode.SetValue(gGERBER_FILE)
|
||||
sizer.Add(self.gcode, (0, 1), (1, 3), wx.TOP | wx.EXPAND, 5)
|
||||
|
||||
button1 = wx.Button(panel, -1, 'Browse...', size=(-1, 30))
|
||||
sizer.Add(button1, (0, 4), (1, 1), wx.TOP | wx.LEFT | wx.RIGHT , 5)
|
||||
|
||||
text2 = wx.StaticText(panel, -1, 'G code color')
|
||||
sizer.Add(text2, (1, 0), flag= wx.LEFT | wx.TOP, border=10)
|
||||
self.gcode_color = wx.ComboBox(panel, -1, choices=gCOLORS, style=wx.CB_READONLY)
|
||||
self.gcode_color.SetValue(str(DEF_COLOR))
|
||||
sizer.Add(self.gcode_color, (1, 1), (1, 3), wx.TOP | wx.EXPAND, 5)
|
||||
|
||||
|
||||
radioList = ['mm', 'inch']
|
||||
rb1 = wx.RadioBox(panel, label="unit of Input file", choices=radioList, majorDimension=3, style=wx.RA_SPECIFY_COLS)
|
||||
rb1.SetSelection(int(IN_INCH_FLAG))
|
||||
sizer.Add(rb1, (2, 0), (1, 5), wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT , 10)
|
||||
|
||||
#sbox1 = wx.StaticBox(panel, -1, 'Read files')
|
||||
#vbox1 = wx.StaticBoxSizer(box1, orient=wx.VERTICAL)
|
||||
#sizer1.Add(grid1)
|
||||
|
||||
button4 = wx.Button(panel, -1, 'Append Open', size=(-1, 30))
|
||||
sizer.Add(button4, (4, 2), (1, 1), wx.LEFT, 10)
|
||||
|
||||
button5 = wx.Button(panel, -1, 'New Open', size=(-1, 30))
|
||||
sizer.Add(button5, (4, 3), (1, 1), wx.LEFT, 10)
|
||||
|
||||
button6 = wx.Button(panel, -1, 'Close', size=(-1, 30))
|
||||
sizer.Add(button6, (4, 4), (1, 1), wx.LEFT | wx.BOTTOM | wx.RIGHT, 10)
|
||||
|
||||
sizer.AddGrowableCol(2)
|
||||
|
||||
panel.SetSizer(sizer)
|
||||
sizer.Fit(self)
|
||||
# Events.
|
||||
self.Bind(wx.EVT_BUTTON, self.OnGcodeOpen, button1)
|
||||
self.Bind(wx.EVT_BUTTON, self.OnAppend, button4)
|
||||
self.Bind(wx.EVT_BUTTON, self.OnNEW, button5)
|
||||
self.Bind(wx.EVT_BUTTON, self.OnClose, button6)
|
||||
self.Bind(wx.EVT_RADIOBOX, self.EvtRadioBox1, rb1)
|
||||
|
||||
#self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
|
||||
#self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)
|
||||
|
||||
self.Centre()
|
||||
self.Show(True)
|
||||
|
||||
#Events
|
||||
def EvtRadioBox1(self, e):
|
||||
global IN_INCH_FLAG
|
||||
if(e.GetInt()==0): #milli
|
||||
IN_INCH_FLAG = 0
|
||||
elif(e.GetInt()==1): #Inch
|
||||
IN_INCH_FLAG = 1
|
||||
def OnGcodeOpen(self,e):
|
||||
global GCODE_EXT
|
||||
""" Open a file"""
|
||||
dlg = wx.FileDialog(self, "Choose a output G-code file", self.dirname, "", GCODE_EXT, wx.OPEN)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
self.filename = dlg.GetFilename()
|
||||
self.dirname = dlg.GetDirectory()
|
||||
self.gcode.SetValue(os.path.join(self.dirname, self.filename))
|
||||
dlg.Destroy()
|
||||
|
||||
def OnAppend(self,e):
|
||||
global IN_INCH_FLAG, gGCODES, gXMIN, gXMAX, gYMIN, gYMAX, gZMIN, gZMAX, gCENTER_X, gCENTER_Y, gCENTER_Z
|
||||
if(self.gcode.GetValue()):
|
||||
gGCODES.append(GCODE(self.gcode.GetValue(),self.gcode_color.GetValue()))
|
||||
set_unit()
|
||||
readGcodeFile()
|
||||
gCENTER_X = (gXMIN + gXMAX)/2
|
||||
gCENTER_Y = (gYMIN + gYMAX)/2
|
||||
gCENTER_Z = (gZMIN + gZMAX)/2
|
||||
#gerber2draw()
|
||||
self.Close(True) # Close the frame.
|
||||
def OnNEW(self,e):
|
||||
global IN_INCH_FLAG, gGCODES, gPATTERNS, gXMIN, gXMAX, gYMIN, gYMAX, gZMIN, gZMAX, gCENTER_X, gCENTER_Y, gCENTER_Z
|
||||
gGCODES = []
|
||||
gPATTERNS = []
|
||||
if(self.gcode.GetValue()):
|
||||
gGCODES.append(GCODE(self.gcode.GetValue(),self.gcode_color.GetValue()))
|
||||
set_unit()
|
||||
readGcodeFile()
|
||||
gCENTER_X = (gXMIN + gXMAX)/2
|
||||
gCENTER_Y = (gYMIN + gYMAX)/2
|
||||
gCENTER_Z = (gZMIN + gZMAX)/2
|
||||
#gerber2draw()
|
||||
self.Close(True) # Close the frame.
|
||||
def OnClose(self,e):
|
||||
self.Close(True) # Close the frame.
|
||||
|
||||
#Set Class
|
||||
class POINT:
|
||||
def __init__(self, x, y, z):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.z = z
|
||||
class LINE:
|
||||
def __init__(self, style, line, speed, points):
|
||||
self.style = style
|
||||
self.line = line
|
||||
self.speed = speed
|
||||
self.points = points
|
||||
|
||||
class ARC:
|
||||
def __init__(self,style, line, speed, plain, p1, p2, center):
|
||||
self.style = style
|
||||
self.line = line
|
||||
self.speed = speed
|
||||
self.plain = plain
|
||||
self.p1 = p1
|
||||
self.p2 = p2
|
||||
self.center = center
|
||||
|
||||
class GCODE:
|
||||
def __init__(self, name, color):
|
||||
self.name = name
|
||||
self.color = color
|
||||
|
||||
class PATTERN:
|
||||
def __init__(self, color,patterns):
|
||||
self.color = color
|
||||
self.patterns = patterns
|
||||
|
||||
#functions
|
||||
def main():
|
||||
app = wx.App()
|
||||
MainFrame(None, -1, 'pyGerber2Gcode')
|
||||
app.MainLoop()
|
||||
|
||||
def set_unit():
|
||||
global IN_INCH_FLAG, gUNIT, INCH
|
||||
if (IN_INCH_FLAG):
|
||||
gUNIT = INCH
|
||||
else:
|
||||
gUNIT = 1.0
|
||||
|
||||
def readGcodeFile():
|
||||
global gGCODES, gXMIN, gXMAX, gYMIN, gYMAX, gZMIN, gZMAX
|
||||
|
||||
for gcodes in gGCODES:
|
||||
try:
|
||||
f = open(gcodes.name,'r')
|
||||
except IOError, (errno, strerror):
|
||||
error_dialog("Unable to open the file" + gcodes.name + "\n",1)
|
||||
else:
|
||||
pre_x = 0.0
|
||||
pre_y = 0.0
|
||||
pre_z = 0.0
|
||||
x = pre_x
|
||||
y = pre_y
|
||||
z = pre_z
|
||||
s = 0
|
||||
l = 1
|
||||
style = 0
|
||||
patterns = []
|
||||
while 1:
|
||||
gcode = f.readline()
|
||||
if not gcode:
|
||||
break
|
||||
flag = 0
|
||||
#parse g code
|
||||
gg = re.search("[gG]([\d]+)\D",gcode)
|
||||
xx = re.search("[xX]([\d\.\-]+)\D",gcode)
|
||||
yy = re.search("[yY]([\d\.\-]+)\D",gcode)
|
||||
zz = re.search("[zZ]([\d\.\-]+)\D",gcode)
|
||||
ss = re.search("[fF]([\d\.\-]+)\D",gcode)
|
||||
if (gg):
|
||||
style = int(gg.group(1))
|
||||
if (xx):
|
||||
x = float(xx.group(1))
|
||||
flag = 1
|
||||
if (yy):
|
||||
y = float(yy.group(1))
|
||||
flag = 1
|
||||
if (zz):
|
||||
z = float(zz.group(1))
|
||||
flag = 1
|
||||
if (ss):
|
||||
s = float(ss.group(1))
|
||||
if(style == 1 or style == 0):
|
||||
if(flag):
|
||||
point1 = POINT(pre_x,pre_y,pre_z)
|
||||
point2 = POINT(x,y,z)
|
||||
patterns.append(LINE(style,l,s,[point1,point2]))
|
||||
|
||||
elif(style == 2 or style == 3):
|
||||
i=0
|
||||
j=0
|
||||
k=0
|
||||
ii = re.search("[iI]([\d\.\-]+)\D",gcode)
|
||||
jj = re.search("[jJ]([\d\.\-]+)\D",gcode)
|
||||
kk = re.search("[kK]([\d\.\-]+)\D",gcode)
|
||||
rr = re.search("[rR]([\d\.\-]+)\D",gcode)
|
||||
if(ii):
|
||||
i = float(rr.group(1))
|
||||
if(jj):
|
||||
j = float(rr.group(1))
|
||||
if(kk):
|
||||
k = float(rr.group(1))
|
||||
center = POINT(i,j,k)
|
||||
point1 = POINT(pre_x,pre_y,pre_z)
|
||||
point2 = POINT(x,y,z)
|
||||
if(style == 3):
|
||||
tmp_point = point2
|
||||
point2 = point1
|
||||
point1 = point2
|
||||
if(rr):
|
||||
r = float(rr.group(1))
|
||||
c1,c2 = calc_center(point1,point2,r,plain)
|
||||
center = c1
|
||||
if(r < 0):
|
||||
center = c2
|
||||
patterns.append(ARC(style,l,s,plain,point1,point2,center))
|
||||
elif(style == 17):
|
||||
plain = 0
|
||||
elif(style == 18):
|
||||
plain = 1
|
||||
elif(style == 19):
|
||||
plain = 2
|
||||
if(x > gXMAX):
|
||||
gXMAX = x
|
||||
if(x < gXMIN):
|
||||
gXMIN = x
|
||||
if(y > gYMAX):
|
||||
gYMAX = y
|
||||
if(y < gYMIN):
|
||||
gYMIN = y
|
||||
if(z > gZMAX):
|
||||
gZMAX = z
|
||||
if(z < gZMIN):
|
||||
gZMIN = z
|
||||
pre_x = x
|
||||
pre_y = y
|
||||
pre_z = z
|
||||
l += 1
|
||||
gPATTERNS.append(PATTERN(gcodes.color,patterns))
|
||||
f.close()
|
||||
|
||||
def calc_center(p1,p2,r,plain):
|
||||
r = copysign(1.0, r) * r
|
||||
if(plain == 0): #XY
|
||||
if(p1.x == p2.x):
|
||||
dx = (p2.x - p1.x)/2
|
||||
dy = sqrt(r*r-dx*dx)
|
||||
c1 = POINT(p1.x+dx,p1.y+dy,p1.z)
|
||||
c2 = POINT(p1.x+dx,p1.y-dy,p1.z)
|
||||
elif(p1.y == p2.y):
|
||||
dy = (p2.y - p1.y)/2
|
||||
dx = sqrt(r*r-dy*dy)
|
||||
c1 = POINT(p1.x+dx,p1.y+dy,p1.z)
|
||||
c2 = POINT(p1.x-dx,p1.y+dy,p1.z)
|
||||
else:
|
||||
a = (p2.y - p1.y)/(p2.x - p1.x)
|
||||
av = -1/a
|
||||
bv = (p2.y -+ p1.y)/2 - av * (p2.x + p1.x)/2
|
||||
dx = sqrt(r*r/(av*av+1))
|
||||
dy = av * dx
|
||||
cx = (p2.x + p1.x)/2
|
||||
cy = (p2.y + p1.y)/2
|
||||
c1 = POINT(p1.x+dx,p1.y-dy,p1.z)
|
||||
c2 = POINT(p1.x-dx,p1.y+dy,p1.z)
|
||||
# if(plain == 1): #ZX
|
||||
# if(plain == 2): #YZ
|
||||
return [c1,c2]
|
||||
|
||||
def rot_coor(p):
|
||||
global gTHETA, gPHI, gPSI
|
||||
dx = c.x-p.x
|
||||
dy = c.y-p.y
|
||||
ang = atan2(dy,dx) + gTHETA
|
||||
r = sqrt(dx*dx+dy*dy)
|
||||
|
||||
def change_view(p1,p2,c):
|
||||
global gTHETA, gPHI, gPSI
|
||||
pp1 = POINT(0.0,0.0,0.0)
|
||||
pp2 = POINT(0.0,0.0,0.0)
|
||||
# rot around z
|
||||
dx1 = p1.x-c.x
|
||||
dy1 = p1.y-c.y
|
||||
ang1 = atan2(dy1,dx1) + gTHETA
|
||||
dx2 = p2.x-c.x
|
||||
dy2 = p2.y-c.y
|
||||
ang2 = atan2(dy2,dx2) + gTHETA
|
||||
r1 = sqrt(dx1*dx1+dy1*dy1)
|
||||
r2 = sqrt(dx2*dx2+dy2*dy2)
|
||||
|
||||
pp1.x = c.x+r1*cos(ang1)
|
||||
pp1.y = c.y+r1*sin(ang1)
|
||||
pp2.x = c.x+r2*cos(ang2)
|
||||
pp2.y = c.y+r2*sin(ang2)
|
||||
|
||||
# rot around x
|
||||
dy1 = pp1.y-c.y
|
||||
dz1 = pp1.z-c.z
|
||||
ang1 = atan2(dy1,dz1) + gPHI
|
||||
dz2 = pp2.z-c.z
|
||||
dy2 = pp2.y-c.y
|
||||
ang2 = atan2(dy2,dz2) + gPHI
|
||||
r1 = sqrt(dz1*dz1+dy1*dy1)
|
||||
r2 = sqrt(dz2*dz2+dy2*dy2)
|
||||
|
||||
pp1.z = c.z+r1*cos(ang1)
|
||||
pp1.y = c.y+r1*sin(ang1)+p1.z
|
||||
pp2.z = c.z+r2*cos(ang2)
|
||||
pp2.y = c.y+r2*sin(ang2)+p2.z
|
||||
|
||||
# rot around y
|
||||
dx1 = pp1.x-c.x
|
||||
dz1 = pp1.z-c.z
|
||||
ang1 = atan2(dx1,dz1) + gPSI
|
||||
dz2 = pp2.z-c.z
|
||||
dx2 = pp2.x-c.x
|
||||
ang2 = atan2(dx2,dz2) + gPSI
|
||||
r1 = sqrt(dz1*dz1+dx1*dx1)
|
||||
r2 = sqrt(dz2*dz2+dx2*dx2)
|
||||
|
||||
pp1.z = c.z+r1*cos(ang1)
|
||||
pp1.x = c.y+r1*sin(ang1)
|
||||
pp2.z = c.z+r2*cos(ang2)
|
||||
pp2.x = c.y+r2*sin(ang2)
|
||||
|
||||
|
||||
return pp1,pp2
|
||||
|
||||
def circle_points(cx,cy,r,points_num):
|
||||
points=[]
|
||||
if(points_num <= 2):
|
||||
print "Too small angle at Circle"
|
||||
return
|
||||
i = points_num
|
||||
while i > 0:
|
||||
cir_x=cx+r*cos(2.0*pi*float(i)/float(points_num))
|
||||
cir_x=cx+r*cos(2.0*pi*float(i)/float(points_num))
|
||||
cir_y=cy+r*sin(2.0*pi*float(i)/float(points_num))
|
||||
points.extend([cir_x,cir_y])
|
||||
i -= 1
|
||||
cir_x=cx+r*cos(0.0)
|
||||
cir_y=cy+r*sin(0.0)
|
||||
points.extend([cir_x,cir_y])
|
||||
return points
|
||||
|
||||
def arc_points(cx,cy,r,s_angle,e_angle,kaku):
|
||||
points=[]
|
||||
if(s_angle == e_angle):
|
||||
print "Start and End angle are same"
|
||||
int(kaku)
|
||||
if(kaku <= 2):
|
||||
print "Too small angle"
|
||||
ang_step=(e_angle-s_angle)/(kaku-1)
|
||||
i = 0
|
||||
while i < kaku:
|
||||
arc_x=cx+r*cos(s_angle+ang_step*float(i))
|
||||
arc_y=cy+r*sin(s_angle+ang_step*float(i))
|
||||
points.extend([arc_x,arc_y])
|
||||
i += 1
|
||||
|
||||
return points
|
||||
|
||||
|
||||
|
||||
def error_dialog(error_mgs,sw):
|
||||
print error_mgs
|
||||
if(sw):
|
||||
#raw_input("\n\nPress the enter key to exit.")
|
||||
sys.exit()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,26 @@
|
|||
G04 (created by PCBNEW (2013-mar-13)-testing) date dom 26 may 2013 19:55:22 CEST*
|
||||
%MOIN*%
|
||||
G04 Gerber Fmt 3.4, Leading zero omitted, Abs format*
|
||||
%FSLAX34Y34*%
|
||||
G01*
|
||||
G70*
|
||||
G90*
|
||||
G04 APERTURE LIST*
|
||||
%ADD10C,0.039370*%
|
||||
%ADD11C,0.015000*%
|
||||
G04 APERTURE END LIST*
|
||||
G54D10*
|
||||
G54D11*
|
||||
X19600Y-6500D02*
|
||||
X20100Y-6500D01*
|
||||
X19600Y-27800D02*
|
||||
X19600Y-6500D01*
|
||||
X42200Y-27800D02*
|
||||
X19600Y-27800D01*
|
||||
X42200Y-27700D02*
|
||||
X42200Y-27800D01*
|
||||
X42200Y-6500D02*
|
||||
X42200Y-27700D01*
|
||||
X20100Y-6500D02*
|
||||
X42200Y-6500D01*
|
||||
M02*
|
|
@ -0,0 +1,120 @@
|
|||
M48
|
||||
;DRILL file {Pcbnew (2013-mar-13)-testing} date lun 27 may 2013 00:27:12 CEST
|
||||
;FORMAT={-:-/ absolute / inch / decimal}
|
||||
FMAT,2
|
||||
INCH,TZ
|
||||
T1C0.025
|
||||
T2C0.032
|
||||
T3C0.040
|
||||
T4C0.060
|
||||
T5C0.125
|
||||
%
|
||||
G90
|
||||
G05
|
||||
M72
|
||||
T1
|
||||
X2.77Y-1.93
|
||||
X3.24Y-2.34
|
||||
X4.1Y-2.07
|
||||
X4.1Y-2.2
|
||||
T2
|
||||
X2.305Y-0.91
|
||||
X2.46Y-0.77
|
||||
X2.46Y-1.08
|
||||
X2.56Y-0.77
|
||||
X2.56Y-1.08
|
||||
X2.655Y-0.91
|
||||
X2.66Y-0.77
|
||||
X2.76Y-0.77
|
||||
X2.82Y-2.67
|
||||
X2.86Y-0.77
|
||||
X2.92Y-2.67
|
||||
X2.96Y-0.77
|
||||
X2.97Y-1.94
|
||||
X2.97Y-2.06
|
||||
X3.01Y-1.47
|
||||
X3.02Y-2.67
|
||||
X3.06Y-0.77
|
||||
X3.12Y-2.67
|
||||
X3.16Y-0.77
|
||||
X3.22Y-2.67
|
||||
X3.27Y-1.94
|
||||
X3.27Y-2.06
|
||||
X3.31Y-1.47
|
||||
X3.32Y-0.77
|
||||
X3.32Y-2.67
|
||||
X3.41Y-0.9
|
||||
X3.41Y-1.
|
||||
X3.42Y-0.77
|
||||
X3.46Y-1.29
|
||||
X3.52Y-0.77
|
||||
X3.52Y-2.67
|
||||
X3.56Y-1.07
|
||||
X3.56Y-1.17
|
||||
X3.62Y-0.77
|
||||
X3.62Y-2.67
|
||||
X3.72Y-0.77
|
||||
X3.72Y-0.9
|
||||
X3.72Y-1.
|
||||
X3.72Y-2.67
|
||||
X3.76Y-1.29
|
||||
X3.82Y-0.77
|
||||
X3.82Y-2.67
|
||||
X3.86Y-1.14
|
||||
X3.86Y-1.44
|
||||
X3.92Y-0.77
|
||||
X3.92Y-2.67
|
||||
X4.02Y-0.77
|
||||
X4.02Y-2.67
|
||||
T3
|
||||
X2.33Y-2.455
|
||||
X2.33Y-2.63
|
||||
X2.4Y-1.245
|
||||
X2.4Y-1.42
|
||||
X2.58Y-2.455
|
||||
X2.58Y-2.63
|
||||
X2.65Y-1.245
|
||||
X2.65Y-1.42
|
||||
X2.78Y-1.03
|
||||
X2.78Y-1.13
|
||||
X2.96Y-0.91
|
||||
X2.96Y-1.11
|
||||
X2.96Y-1.21
|
||||
X2.96Y-1.31
|
||||
X3.02Y-2.2
|
||||
X3.02Y-2.3
|
||||
X3.02Y-2.4
|
||||
X3.02Y-2.5
|
||||
X3.06Y-0.91
|
||||
X3.06Y-1.11
|
||||
X3.06Y-1.21
|
||||
X3.06Y-1.31
|
||||
X3.12Y-2.2
|
||||
X3.12Y-2.3
|
||||
X3.12Y-2.4
|
||||
X3.12Y-2.5
|
||||
X3.16Y-1.11
|
||||
X3.16Y-1.21
|
||||
X3.16Y-1.31
|
||||
X3.26Y-1.11
|
||||
X3.26Y-1.21
|
||||
X3.26Y-1.31
|
||||
X3.52Y-2.53
|
||||
X3.62Y-2.53
|
||||
X3.72Y-2.53
|
||||
X3.82Y-2.53
|
||||
X3.86Y-1.55
|
||||
X3.86Y-1.65
|
||||
X3.86Y-1.75
|
||||
X3.86Y-1.85
|
||||
T4
|
||||
X3.5Y-1.5
|
||||
X3.5Y-1.7
|
||||
X3.5Y-1.9
|
||||
T5
|
||||
X2.07Y-2.67
|
||||
X2.12Y-0.77
|
||||
X4.12Y-1.37
|
||||
X4.12Y-2.47
|
||||
T0
|
||||
M30
|
|
@ -0,0 +1,26 @@
|
|||
M48
|
||||
;DRILL file {PCBnew (2010-00-09 BZR 23xx)-stable} date 2010年12月20日 17時22分05秒
|
||||
;FORMAT={-.-/ absolute / inch / decimal}
|
||||
R,T
|
||||
VER,1
|
||||
FMAT,2
|
||||
INCH,TZ
|
||||
TCST,OFF
|
||||
ICI,OFF
|
||||
ATC,ON
|
||||
T1C0.032
|
||||
%
|
||||
M47
|
||||
G05
|
||||
M72
|
||||
T1
|
||||
X8.600Y-5.675
|
||||
X8.600Y-5.775
|
||||
X8.600Y-6.025
|
||||
X8.600Y-6.125
|
||||
X8.825Y-6.150
|
||||
X8.925Y-6.150
|
||||
X9.100Y-6.050
|
||||
X9.100Y-6.150
|
||||
T0
|
||||
M30
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,41 @@
|
|||
(Generated by pygerber2gcode_cui_MOD.py )
|
||||
( 2013-05-27 01:17:55 )
|
||||
(Initialize)
|
||||
G92 X0.000000 Y0.000000 Z0.000000
|
||||
|
||||
(Start form here)
|
||||
G0 Z2.000000
|
||||
G0 X1.075569 Y57.951215
|
||||
G1 Z-0.475000 F30.000000
|
||||
G1 X57.209569 F50.000000
|
||||
G1 Y4.103215 F50.000000
|
||||
G1 Y3.849215 F50.000000
|
||||
G1 X-0.194431 F50.000000
|
||||
G1 Y57.951215 F50.000000
|
||||
G1 X1.075569 F50.000000
|
||||
G1 Z-0.950000 F30.000000
|
||||
G1 X57.209569 F50.000000
|
||||
G1 Y4.103215 F50.000000
|
||||
G1 Y3.849215 F50.000000
|
||||
G1 X-0.194431 F50.000000
|
||||
G1 Y57.951215 F50.000000
|
||||
G1 X1.075569 F50.000000
|
||||
G1 Z-1.425000 F30.000000
|
||||
G1 X57.209569 F50.000000
|
||||
G1 Y4.103215 F50.000000
|
||||
G1 Y3.849215 F50.000000
|
||||
G1 X-0.194431 F50.000000
|
||||
G1 Y57.951215 F50.000000
|
||||
G1 X1.075569 F50.000000
|
||||
G1 Z-1.900000 F30.000000
|
||||
G1 X57.209569 F50.000000
|
||||
G1 Y4.103215 F50.000000
|
||||
G1 Y3.849215 F50.000000
|
||||
G1 X-0.194431 F50.000000
|
||||
G1 Y57.951215 F50.000000
|
||||
G1 X1.075569 F50.000000
|
||||
|
||||
(Goto to Initial position)
|
||||
G0 Z2.000000
|
||||
G0 X0.000000 Y0.000000
|
||||
G0 Z0.000000
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,52 @@
|
|||
GERBER_DIR = "/home/carlosgs/GitRepos/Cyclone-PCB-Factory/Software/Send/pyGerber2Gcode_CUI/in"
|
||||
FRONT_FILE = ""
|
||||
BACK_FILE = "printshield-1.0-B_Cu.gtl"
|
||||
DRILL_FILE = "printshield-1.0.drl"
|
||||
EDGE_FILE = "printshield-1.0-Edge_Cuts.gbr"
|
||||
MIRROR_FRONT =0
|
||||
MIRROR_BACK = 0
|
||||
MIRROR_DRILL = 0
|
||||
MIRROR_EDGE = 0
|
||||
ROT_ANG = 0
|
||||
OUT_DIR = "/home/carlosgs/GitRepos/Cyclone-PCB-Factory/Software/Send/pyGerber2Gcode_CUI/out"
|
||||
OUT_FRONT_FILE = ""
|
||||
OUT_BACK_FILE = "printshield_pcb.gcode"
|
||||
OUT_DRILL_FILE = "printshield_drill.gcode"
|
||||
OUT_EDGE_FILE = "printshield_edge.gcode"
|
||||
|
||||
INI_X=0.0
|
||||
INI_Y=0.0
|
||||
INI_Z=0.0
|
||||
MOVE_HEIGHT=2.0
|
||||
IN_INCH_FLAG=1
|
||||
OUT_INCH_FLAG=0
|
||||
MCODE_FLAG=0
|
||||
XY_SPEED=100
|
||||
Z_SPEED=60
|
||||
LEFT_X=5.0
|
||||
LOWER_Y=5.0
|
||||
DRILL_SPEED=30
|
||||
DRILL_DEPTH=-1.7
|
||||
CUT_DEPTH=-0.04
|
||||
TOOL_D=0.1
|
||||
DRILL_D=0.4
|
||||
CAD_UNIT=0.00254
|
||||
DRILL_UNIT=0.00254
|
||||
EDGE_UNIT=0.00254
|
||||
EDGE_TOOL_D=2.4
|
||||
EDGE_DEPTH=-1.9
|
||||
EDGE_SPEED=50
|
||||
EDGE_Z_SPEED=30
|
||||
MERGE_DRILL_DATA=0
|
||||
Z_STEP=-0.5
|
||||
GERBER_COLOR=BLACK
|
||||
DRILL_COLOR=BLUE
|
||||
EDGE_COLOR=GREEN YELLOW
|
||||
CONTOUR_COLOR=MAGENTA
|
||||
GERBER_EXT=*.gtl
|
||||
DRILL_EXT=*.drl
|
||||
EDGE_EXT=*.gbr
|
||||
GCODE_EXT=*.gcode
|
||||
GDRILL_EXT=*.gcode
|
||||
GEDGE_EXT=*.gcode
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue