Use of logging instead of print statements.
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<property name="border_width">5</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="program_name">FlatCAM</property>
|
||||
<property name="version">Version Alpha 3 (2014/03) - UNSTABLE</property>
|
||||
<property name="version">Version Alpha 5 (2014/05)</property>
|
||||
<property name="copyright" translatable="yes">(c) 2014 Juan Pablo Caram</property>
|
||||
<property name="comments" translatable="yes">2D Post-processing for Manufacturing specialized in
|
||||
Printed Circuit Boards</property>
|
||||
|
||||
1074
FlatCAMApp.py
1074
FlatCAMApp.py
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,7 @@ from gi.repository import GObject
|
||||
|
||||
import inspect # TODO: Remove
|
||||
|
||||
from FlatCAMApp import *
|
||||
import FlatCAMApp
|
||||
from camlib import *
|
||||
from ObjectUI import *
|
||||
|
||||
@@ -123,15 +123,15 @@ class FlatCAMObj(GObject.GObject, object):
|
||||
"""
|
||||
|
||||
if self.axes is None:
|
||||
print "New axes"
|
||||
FlatCAMApp.App.log.debug("setup_axes(): New axes")
|
||||
self.axes = figure.add_axes([0.05, 0.05, 0.9, 0.9],
|
||||
label=self.options["name"])
|
||||
elif self.axes not in figure.axes:
|
||||
print "Clearing and attaching axes"
|
||||
FlatCAMApp.App.log.debug("setup_axes(): Clearing and attaching axes")
|
||||
self.axes.cla()
|
||||
figure.add_axes(self.axes)
|
||||
else:
|
||||
print "Clearing Axes"
|
||||
FlatCAMApp.App.log.debug("setup_axes(): Clearing Axes")
|
||||
self.axes.cla()
|
||||
|
||||
# Remove all decoration. The app's axes will have
|
||||
@@ -158,7 +158,7 @@ class FlatCAMObj(GObject.GObject, object):
|
||||
:return: None
|
||||
:rtype: None
|
||||
"""
|
||||
print inspect.stack()[1][3], "--> FlatCAMObj.read_form()"
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> FlatCAMObj.read_form()")
|
||||
for option in self.options:
|
||||
self.read_form_item(option)
|
||||
|
||||
@@ -171,7 +171,7 @@ class FlatCAMObj(GObject.GObject, object):
|
||||
"""
|
||||
|
||||
self.muted_ui = True
|
||||
print inspect.stack()[1][3], "--> FlatCAMObj.build_ui()"
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> FlatCAMObj.build_ui()")
|
||||
|
||||
# Where the UI for this object is drawn
|
||||
# box_selected = self.app.builder.get_object("box_selected")
|
||||
@@ -186,8 +186,8 @@ class FlatCAMObj(GObject.GObject, object):
|
||||
# box_selected.pack_start(sw, True, True, 0)
|
||||
box_selected.add(self.ui)
|
||||
self.to_form()
|
||||
box_selected.show_all()
|
||||
self.ui.show()
|
||||
GLib.idle_add(box_selected.show_all)
|
||||
GLib.idle_add(self.ui.show_all)
|
||||
self.muted_ui = False
|
||||
|
||||
def set_form_item(self, option):
|
||||
@@ -202,7 +202,7 @@ class FlatCAMObj(GObject.GObject, object):
|
||||
try:
|
||||
self.form_fields[option].set_value(self.options[option])
|
||||
except KeyError:
|
||||
App.log.warn("Tried to set an option or field that does not exist: %s" % option)
|
||||
self.app.log.warn("Tried to set an option or field that does not exist: %s" % option)
|
||||
|
||||
def read_form_item(self, option):
|
||||
"""
|
||||
@@ -216,7 +216,7 @@ class FlatCAMObj(GObject.GObject, object):
|
||||
try:
|
||||
self.options[option] = self.form_fields[option].get_value()
|
||||
except KeyError:
|
||||
App.log.warning("Failed to read option from field: %s" % option)
|
||||
self.app.log.warning("Failed to read option from field: %s" % option)
|
||||
|
||||
def plot(self):
|
||||
"""
|
||||
@@ -497,8 +497,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
||||
zorder=2)
|
||||
self.axes.add_patch(patch)
|
||||
except AssertionError:
|
||||
print "WARNING: A geometry component was not a polygon:"
|
||||
print poly
|
||||
FlatCAMApp.App.log.warning("A geometry component was not a polygon:")
|
||||
FlatCAMApp.App.log.warning(str(poly))
|
||||
else:
|
||||
for poly in geometry:
|
||||
x, y = poly.exterior.xy
|
||||
@@ -547,15 +547,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
||||
"toolselection": ""
|
||||
})
|
||||
|
||||
# self.form_kinds.update({
|
||||
# "plot": "cb",
|
||||
# "solid": "cb",
|
||||
# "drillz": "entry_eval",
|
||||
# "travelz": "entry_eval",
|
||||
# "feedrate": "entry_eval",
|
||||
# "toolselection": "entry_text"
|
||||
# })
|
||||
|
||||
# TODO: Document this.
|
||||
self.tool_cbs = {}
|
||||
|
||||
@@ -564,10 +555,49 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
||||
# from predecessors.
|
||||
self.ser_attrs += ['options', 'kind']
|
||||
|
||||
assert isinstance(self.ui, ExcellonObjectUI)
|
||||
self.ui.plot_cb.connect('clicked', self.on_plot_cb_click)
|
||||
self.ui.plot_cb.connect('activate', self.on_plot_cb_click)
|
||||
self.ui.solid_cb.connect('clicked', self.on_solid_cb_click)
|
||||
self.ui.solid_cb.connect('activate', self.on_solid_cb_click)
|
||||
self.ui.choose_tools_button.connect('clicked', lambda args: self.show_tool_chooser())
|
||||
self.ui.choose_tools_button.connect('activate', lambda args: self.show_tool_chooser())
|
||||
self.ui.generate_cnc_button.connect('clicked', self.on_create_cncjob_button_click)
|
||||
self.ui.generate_cnc_button.connect('activate', self.on_create_cncjob_button_click)
|
||||
|
||||
def on_create_cncjob_button_click(self, *args):
|
||||
self.read_form()
|
||||
job_name = self.options["name"] + "_cnc"
|
||||
|
||||
# Object initialization function for app.new_object()
|
||||
def job_init(job_obj, app_obj):
|
||||
assert isinstance(job_obj, FlatCAMCNCjob)
|
||||
|
||||
GLib.idle_add(lambda: app_obj.set_progress_bar(0.2, "Creating CNC Job..."))
|
||||
job_obj.z_cut = self.options["drillz"]
|
||||
job_obj.z_move = self.options["travelz"]
|
||||
job_obj.feedrate = self.options["feedrate"]
|
||||
# There could be more than one drill size...
|
||||
# job_obj.tooldia = # TODO: duplicate variable!
|
||||
# job_obj.options["tooldia"] =
|
||||
job_obj.generate_from_excellon_by_tool(self, self.options["toolselection"])
|
||||
|
||||
GLib.idle_add(lambda: app_obj.set_progress_bar(0.5, "Parsing G-Code..."))
|
||||
job_obj.gcode_parse()
|
||||
|
||||
GLib.idle_add(lambda: app_obj.set_progress_bar(0.6, "Creating New Geometry..."))
|
||||
job_obj.create_geometry()
|
||||
|
||||
GLib.idle_add(lambda: app_obj.set_progress_bar(0.8, "Plotting..."))
|
||||
|
||||
# To be run in separate thread
|
||||
def job_thread(app_obj):
|
||||
app_obj.new_object("cncjob", job_name, job_init)
|
||||
GLib.idle_add(lambda: app_obj.set_progress_bar(1.0, "Done!"))
|
||||
GLib.timeout_add_seconds(1, lambda: app_obj.set_progress_bar(0.0, ""))
|
||||
|
||||
# Send to worker
|
||||
self.app.worker.add_task(job_thread, [self.app])
|
||||
|
||||
def on_plot_cb_click(self, *args):
|
||||
if self.muted_ui:
|
||||
@@ -669,11 +699,6 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
||||
"tooldia": self.ui.tooldia_entry
|
||||
})
|
||||
|
||||
# self.form_kinds.update({
|
||||
# "plot": "cb",
|
||||
# "tooldia": "entry_eval"
|
||||
# })
|
||||
|
||||
# Attributes to be included in serialization
|
||||
# Always append to it because it carries contents
|
||||
# from predecessors.
|
||||
@@ -682,6 +707,18 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
||||
self.ui.plot_cb.connect('clicked', self.on_plot_cb_click)
|
||||
self.ui.plot_cb.connect('activate', self.on_plot_cb_click)
|
||||
|
||||
self.ui.export_gcode_button.connect('clicked', self.on_exportgcode_button_click)
|
||||
self.ui.export_gcode_button.connect('activate', self.on_exportgcode_button_click)
|
||||
|
||||
def on_exportgcode_button_click(self, *args):
|
||||
def on_success(app_obj, filename):
|
||||
f = open(filename, 'w')
|
||||
f.write(self.gcode)
|
||||
f.close()
|
||||
app_obj.info("Saved to: " + filename)
|
||||
|
||||
self.app.file_chooser_save_action(on_success)
|
||||
|
||||
def on_plot_cb_click(self, *args):
|
||||
if self.muted_ui:
|
||||
return
|
||||
@@ -702,7 +739,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
||||
|
||||
def convert_units(self, units):
|
||||
factor = CNCjob.convert_units(self, units)
|
||||
print "FlatCAMCNCjob.convert_units()"
|
||||
FlatCAMApp.App.log.debug("FlatCAMCNCjob.convert_units()")
|
||||
self.options["tooldia"] *= factor
|
||||
|
||||
|
||||
@@ -795,7 +832,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
||||
geo_obj.options["cnctooldia"] = tooldia
|
||||
|
||||
name = self.options["name"] + "_paint"
|
||||
self.new_object("geometry", name, gen_paintarea)
|
||||
self.app.new_object("geometry", name, gen_paintarea)
|
||||
|
||||
subscription = self.app.plotcanvas.mpl_connect('button_press_event', doit)
|
||||
|
||||
@@ -934,7 +971,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
||||
self.axes.plot(x, y, 'r-')
|
||||
continue
|
||||
|
||||
print "WARNING: Did not plot:", str(type(geo))
|
||||
FlatCAMApp.App.log.warning("Did not plot:", str(type(geo)))
|
||||
|
||||
#self.app.plotcanvas.auto_adjust_axes()
|
||||
GLib.idle_add(self.app.plotcanvas.auto_adjust_axes)
|
||||
@@ -1,6 +1,15 @@
|
||||
############################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://caram.cl/software/flatcam #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
|
||||
from gi.repository import Gtk
|
||||
import re
|
||||
from copy import copy
|
||||
import FlatCAMApp
|
||||
|
||||
|
||||
class RadioSet(Gtk.Box):
|
||||
@@ -24,16 +33,20 @@ class RadioSet(Gtk.Box):
|
||||
else:
|
||||
choice['radio'] = Gtk.RadioButton.new_with_label_from_widget(self.group, choice['label'])
|
||||
self.pack_start(choice['radio'], expand=True, fill=False, padding=2)
|
||||
# choice['radio'].connect('toggled', self.on_toggle)
|
||||
choice['radio'].connect('toggled', self.on_toggle)
|
||||
|
||||
# def on_toggle(self, *args):
|
||||
# return
|
||||
self.group_toggle_fn = lambda x, y: None
|
||||
|
||||
def on_toggle(self, btn):
|
||||
if btn.get_active():
|
||||
self.group_toggle_fn(btn, self.get_value)
|
||||
return
|
||||
|
||||
def get_value(self):
|
||||
for choice in self.choices:
|
||||
if choice['radio'].get_active():
|
||||
return choice['value']
|
||||
print "ERROR: No button was toggled in RadioSet."
|
||||
FlatCAMApp.App.log.error("No button was toggled in RadioSet.")
|
||||
return None
|
||||
|
||||
def set_value(self, val):
|
||||
@@ -41,7 +54,7 @@ class RadioSet(Gtk.Box):
|
||||
if choice['value'] == val:
|
||||
choice['radio'].set_active(True)
|
||||
return
|
||||
print "ERROR: Value given is not part of this RadioSet:", val
|
||||
FlatCAMApp.App.log.error("Value given is not part of this RadioSet: %s" % str(val))
|
||||
|
||||
|
||||
class LengthEntry(Gtk.Entry):
|
||||
@@ -63,7 +76,7 @@ class LengthEntry(Gtk.Entry):
|
||||
if val is not None:
|
||||
self.set_text(str(val))
|
||||
else:
|
||||
print "WARNING: Could not interpret entry:", self.get_text()
|
||||
FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
|
||||
|
||||
def get_value(self):
|
||||
raw = self.get_text().strip(' ')
|
||||
@@ -76,7 +89,7 @@ class LengthEntry(Gtk.Entry):
|
||||
else:
|
||||
return float(match.group(1))
|
||||
except:
|
||||
print "ERROR: Could not parse value in entry:", raw
|
||||
FlatCAMApp.App.log.error("Could not parse value in entry: %s" % str(raw))
|
||||
return None
|
||||
|
||||
def set_value(self, val):
|
||||
@@ -94,14 +107,14 @@ class FloatEntry(Gtk.Entry):
|
||||
if val is not None:
|
||||
self.set_text(str(val))
|
||||
else:
|
||||
print "WARNING: Could not interpret entry:", self.get_text()
|
||||
FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
|
||||
|
||||
def get_value(self):
|
||||
raw = self.get_text().strip(' ')
|
||||
try:
|
||||
evaled = eval(raw)
|
||||
except:
|
||||
print "ERROR: Could not evaluate:", raw
|
||||
FlatCAMApp.App.log.error("Could not evaluate: %s" % str(raw))
|
||||
return None
|
||||
|
||||
return float(evaled)
|
||||
@@ -132,6 +145,29 @@ class FCEntry(Gtk.Entry):
|
||||
self.set_text(str(val))
|
||||
|
||||
|
||||
class EvalEntry(Gtk.Entry):
|
||||
def __init__(self):
|
||||
Gtk.Entry.__init__(self)
|
||||
|
||||
def on_activate(self, *args):
|
||||
val = self.get_value()
|
||||
if val is not None:
|
||||
self.set_text(str(val))
|
||||
else:
|
||||
FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
|
||||
|
||||
def get_value(self):
|
||||
raw = self.get_text().strip(' ')
|
||||
try:
|
||||
return eval(raw)
|
||||
except:
|
||||
FlatCAMApp.App.log.error("Could not evaluate: %s" % str(raw))
|
||||
return None
|
||||
|
||||
def set_value(self, val):
|
||||
self.set_text(str(val))
|
||||
|
||||
|
||||
class FCCheckBox(Gtk.CheckButton):
|
||||
def __init__(self, label=''):
|
||||
Gtk.CheckButton.__init__(self, label=label)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
from FlatCAMObj import *
|
||||
from gi.repository import Gtk, GdkPixbuf
|
||||
import inspect # TODO: Remove
|
||||
import FlatCAMApp
|
||||
|
||||
|
||||
class ObjectCollection:
|
||||
@@ -75,11 +76,11 @@ class ObjectCollection:
|
||||
iterat = self.store.iter_next(iterat)
|
||||
|
||||
def delete_all(self):
|
||||
print "OC.delete_all()"
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.delete_all()")
|
||||
self.store.clear()
|
||||
|
||||
def delete_active(self):
|
||||
print "OC.delete_active()"
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.delete_active()")
|
||||
try:
|
||||
model, treeiter = self.tree_selection.get_selected()
|
||||
self.store.remove(treeiter)
|
||||
@@ -94,7 +95,7 @@ class ObjectCollection:
|
||||
:param selection: Ignored.
|
||||
:return: None
|
||||
"""
|
||||
print inspect.stack()[1][3], "--> OC.on_list_selection_change()"
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.on_list_selection_change()")
|
||||
try:
|
||||
self.get_active().build_ui()
|
||||
except AttributeError: # For None being active
|
||||
@@ -109,11 +110,11 @@ class ObjectCollection:
|
||||
:type name: str
|
||||
:return: None
|
||||
"""
|
||||
print "OC.set_active()"
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.set_active()")
|
||||
self.set_list_selection(name)
|
||||
|
||||
def get_active(self):
|
||||
print inspect.stack()[1][3], "--> OC.get_active()"
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.get_active()")
|
||||
try:
|
||||
model, treeiter = self.tree_selection.get_selected()
|
||||
return model[treeiter][0]
|
||||
@@ -128,7 +129,7 @@ class ObjectCollection:
|
||||
:rtype name: str
|
||||
:return: None
|
||||
"""
|
||||
print inspect.stack()[1][3], "--> OC.set_list_selection()"
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.set_list_selection()")
|
||||
iterat = self.store.get_iter_first()
|
||||
while iterat is not None and self.store[iterat][0].options["name"] != name:
|
||||
iterat = self.store.iter_next(iterat)
|
||||
@@ -144,7 +145,7 @@ class ObjectCollection:
|
||||
:type active: bool
|
||||
:return: None
|
||||
"""
|
||||
print inspect.stack()[1][3], "--> OC.append()"
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.append()")
|
||||
|
||||
def guitask():
|
||||
self.store.append([obj])
|
||||
@@ -159,7 +160,7 @@ class ObjectCollection:
|
||||
:return: List of names.
|
||||
:rtype: list
|
||||
"""
|
||||
print "OC.get_names()"
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.get_names()")
|
||||
names = []
|
||||
iterat = self.store.get_iter_first()
|
||||
while iterat is not None:
|
||||
@@ -175,7 +176,7 @@ class ObjectCollection:
|
||||
:return: [xmin, ymin, xmax, ymax]
|
||||
:rtype: list
|
||||
"""
|
||||
print "OC.get_bounds()"
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.get_bounds()")
|
||||
|
||||
# TODO: Move the operation out of here.
|
||||
|
||||
@@ -194,7 +195,7 @@ class ObjectCollection:
|
||||
xmax = max([xmax, gxmax])
|
||||
ymax = max([ymax, gymax])
|
||||
except:
|
||||
print "DEV WARNING: Tried to get bounds of empty geometry."
|
||||
FlatCAMApp.App.log.waring("DEV WARNING: Tried to get bounds of empty geometry.")
|
||||
iterat = self.store.iter_next(iterat)
|
||||
return [xmin, ymin, xmax, ymax]
|
||||
|
||||
@@ -205,6 +206,7 @@ class ObjectCollection:
|
||||
:return: List with all FlatCAMObj.
|
||||
:rtype: list
|
||||
"""
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.get_list()")
|
||||
collection_list = []
|
||||
iterat = self.store.get_iter_first()
|
||||
while iterat is not None:
|
||||
@@ -222,6 +224,8 @@ class ObjectCollection:
|
||||
:return: The requested object or None if no such object.
|
||||
:rtype: FlatCAMObj or None
|
||||
"""
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> OC.get_by_name()")
|
||||
|
||||
iterat = self.store.get_iter_first()
|
||||
while iterat is not None:
|
||||
obj = self.store[iterat][0]
|
||||
|
||||
55
ObjectUI.py
55
ObjectUI.py
@@ -1,12 +1,20 @@
|
||||
############################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://caram.cl/software/flatcam #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
|
||||
from gi.repository import Gtk
|
||||
import re
|
||||
from copy import copy
|
||||
|
||||
from GUIElements import *
|
||||
|
||||
|
||||
class ObjectUI(Gtk.VBox):
|
||||
"""
|
||||
Base class for the UI of FlatCAM objects.
|
||||
"""
|
||||
|
||||
def __init__(self, icon_file='share/flatcam_icon32.png', title='FlatCAM Object'):
|
||||
Gtk.VBox.__init__(self, spacing=3, margin=5, vexpand=False)
|
||||
|
||||
@@ -26,7 +34,7 @@ class ObjectUI(Gtk.VBox):
|
||||
|
||||
## Object name
|
||||
self.name_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 2)
|
||||
self.pack_start(self.name_box, expand=True, fill=False, padding=2)
|
||||
self.pack_start(self.name_box, expand=False, fill=False, padding=2)
|
||||
name_label = Gtk.Label('Name:')
|
||||
name_label.set_justify(Gtk.Justification.RIGHT)
|
||||
self.name_box.pack_start(name_label,
|
||||
@@ -42,10 +50,10 @@ class ObjectUI(Gtk.VBox):
|
||||
## Scale
|
||||
self.scale_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
|
||||
self.scale_label.set_markup('<b>Scale:</b>')
|
||||
self.pack_start(self.scale_label, expand=True, fill=False, padding=2)
|
||||
self.pack_start(self.scale_label, expand=False, fill=False, padding=2)
|
||||
|
||||
grid5 = Gtk.Grid(column_spacing=3, row_spacing=2)
|
||||
self.pack_start(grid5, expand=True, fill=False, padding=2)
|
||||
self.pack_start(grid5, expand=False, fill=False, padding=2)
|
||||
|
||||
# Factor
|
||||
l10 = Gtk.Label('Factor:', xalign=1)
|
||||
@@ -56,25 +64,25 @@ class ObjectUI(Gtk.VBox):
|
||||
|
||||
# GO Button
|
||||
self.scale_button = Gtk.Button(label='Scale')
|
||||
self.pack_start(self.scale_button, expand=True, fill=False, padding=2)
|
||||
self.pack_start(self.scale_button, expand=False, fill=False, padding=2)
|
||||
|
||||
## Offset
|
||||
self.offset_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
|
||||
self.offset_label.set_markup('<b>Offset:</b>')
|
||||
self.pack_start(self.offset_label, expand=True, fill=False, padding=2)
|
||||
self.pack_start(self.offset_label, expand=False, fill=False, padding=2)
|
||||
|
||||
grid6 = Gtk.Grid(column_spacing=3, row_spacing=2)
|
||||
self.pack_start(grid6, expand=True, fill=False, padding=2)
|
||||
self.pack_start(grid6, expand=False, fill=False, padding=2)
|
||||
|
||||
# Vector
|
||||
l11 = Gtk.Label('Offset Vector:', xalign=1)
|
||||
grid6.attach(l11, 0, 0, 1, 1)
|
||||
self.offsetvector_entry = FCEntry()
|
||||
self.offsetvector_entry = EvalEntry()
|
||||
self.offsetvector_entry.set_text("(0.0, 0.0)")
|
||||
grid6.attach(self.offsetvector_entry, 1, 0, 1, 1)
|
||||
|
||||
self.offset_button = Gtk.Button(label='Scale')
|
||||
self.pack_start(self.offset_button, expand=True, fill=False, padding=2)
|
||||
self.pack_start(self.offset_button, expand=False, fill=False, padding=2)
|
||||
|
||||
def set_field(self, name, value):
|
||||
getattr(self, name).set_value(value)
|
||||
@@ -84,16 +92,20 @@ class ObjectUI(Gtk.VBox):
|
||||
|
||||
|
||||
class CNCObjectUI(ObjectUI):
|
||||
"""
|
||||
User interface for CNCJob objects.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
ObjectUI.__init__(self, title='CNC Job Object', icon_file='share/cnc32.png')
|
||||
|
||||
## Plot options
|
||||
self.plot_options_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
|
||||
self.plot_options_label.set_markup("<b>Plot Options:</b>")
|
||||
self.pack_start(self.plot_options_label, expand=False, fill=True, padding=2)
|
||||
self.custom_box.pack_start(self.plot_options_label, expand=False, fill=True, padding=2)
|
||||
|
||||
grid0 = Gtk.Grid(column_spacing=3, row_spacing=2)
|
||||
self.pack_start(grid0, expand=True, fill=False, padding=2)
|
||||
self.custom_box.pack_start(grid0, expand=False, fill=False, padding=2)
|
||||
|
||||
# Plot CB
|
||||
self.plot_cb = FCCheckBox(label='Plot')
|
||||
@@ -107,19 +119,23 @@ class CNCObjectUI(ObjectUI):
|
||||
|
||||
# Update plot button
|
||||
self.updateplot_button = Gtk.Button(label='Update Plot')
|
||||
self.pack_start(self.updateplot_button, expand=True, fill=False, padding=2)
|
||||
self.custom_box.pack_start(self.updateplot_button, expand=False, fill=False, padding=2)
|
||||
|
||||
## Export G-Code
|
||||
self.export_gcode_label = Gtk.Label(justify=Gtk.Justification.LEFT, xalign=0, margin_top=5)
|
||||
self.export_gcode_label.set_markup("<b>Export G-Code:</b>")
|
||||
self.pack_start(self.export_gcode_label, expand=True, fill=False, padding=2)
|
||||
self.custom_box.pack_start(self.export_gcode_label, expand=False, fill=False, padding=2)
|
||||
|
||||
# GO Button
|
||||
self.export_gcode_button = Gtk.Button(label='Export G-Code')
|
||||
self.pack_start(self.export_gcode_button, expand=True, fill=False, padding=2)
|
||||
self.custom_box.pack_start(self.export_gcode_button, expand=False, fill=False, padding=2)
|
||||
|
||||
|
||||
class GeometryObjectUI(ObjectUI):
|
||||
"""
|
||||
User interface for Geometry objects.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
ObjectUI.__init__(self, title='Geometry Object', icon_file='share/geometry32.png')
|
||||
|
||||
@@ -200,6 +216,10 @@ class GeometryObjectUI(ObjectUI):
|
||||
|
||||
|
||||
class ExcellonObjectUI(ObjectUI):
|
||||
"""
|
||||
User interface for Excellon objects.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
ObjectUI.__init__(self, title='Excellon Object', icon_file='share/drill32.png')
|
||||
|
||||
@@ -254,6 +274,9 @@ class ExcellonObjectUI(ObjectUI):
|
||||
|
||||
|
||||
class GerberObjectUI(ObjectUI):
|
||||
"""
|
||||
User interface for Gerber objects.
|
||||
"""
|
||||
def __init__(self):
|
||||
ObjectUI.__init__(self, title='Gerber Object')
|
||||
|
||||
|
||||
310
PlotCanvas.py
Normal file
310
PlotCanvas.py
Normal file
@@ -0,0 +1,310 @@
|
||||
from gi.repository import Gdk
|
||||
from matplotlib.figure import Figure
|
||||
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
|
||||
#from FlatCAMApp import *
|
||||
import FlatCAMApp
|
||||
|
||||
|
||||
class PlotCanvas:
|
||||
"""
|
||||
Class handling the plotting area in the application.
|
||||
"""
|
||||
|
||||
def __init__(self, container):
|
||||
"""
|
||||
The constructor configures the Matplotlib figure that
|
||||
will contain all plots, creates the base axes and connects
|
||||
events to the plotting area.
|
||||
|
||||
:param container: The parent container in which to draw plots.
|
||||
:rtype: PlotCanvas
|
||||
"""
|
||||
# Options
|
||||
self.x_margin = 15 # pixels
|
||||
self.y_margin = 25 # Pixels
|
||||
|
||||
# Parent container
|
||||
self.container = container
|
||||
|
||||
# Plots go onto a single matplotlib.figure
|
||||
self.figure = Figure(dpi=50) # TODO: dpi needed?
|
||||
self.figure.patch.set_visible(False)
|
||||
|
||||
# These axes show the ticks and grid. No plotting done here.
|
||||
# New axes must have a label, otherwise mpl returns an existing one.
|
||||
self.axes = self.figure.add_axes([0.05, 0.05, 0.9, 0.9], label="base", alpha=0.0)
|
||||
self.axes.set_aspect(1)
|
||||
self.axes.grid(True)
|
||||
|
||||
# The canvas is the top level container (Gtk.DrawingArea)
|
||||
self.canvas = FigureCanvas(self.figure)
|
||||
self.canvas.set_hexpand(1)
|
||||
self.canvas.set_vexpand(1)
|
||||
self.canvas.set_can_focus(True) # For key press
|
||||
|
||||
# Attach to parent
|
||||
self.container.attach(self.canvas, 0, 0, 600, 400) # TODO: Height and width are num. columns??
|
||||
|
||||
# Events
|
||||
self.canvas.mpl_connect('motion_notify_event', self.on_mouse_move)
|
||||
self.canvas.connect('configure-event', self.auto_adjust_axes)
|
||||
self.canvas.add_events(Gdk.EventMask.SMOOTH_SCROLL_MASK)
|
||||
self.canvas.connect("scroll-event", self.on_scroll)
|
||||
self.canvas.mpl_connect('key_press_event', self.on_key_down)
|
||||
self.canvas.mpl_connect('key_release_event', self.on_key_up)
|
||||
|
||||
self.mouse = [0, 0]
|
||||
self.key = None
|
||||
|
||||
def on_key_down(self, event):
|
||||
"""
|
||||
|
||||
:param event:
|
||||
:return:
|
||||
"""
|
||||
self.key = event.key
|
||||
|
||||
def on_key_up(self, event):
|
||||
"""
|
||||
|
||||
:param event:
|
||||
:return:
|
||||
"""
|
||||
self.key = None
|
||||
|
||||
def mpl_connect(self, event_name, callback):
|
||||
"""
|
||||
Attach an event handler to the canvas through the Matplotlib interface.
|
||||
|
||||
:param event_name: Name of the event
|
||||
:type event_name: str
|
||||
:param callback: Function to call
|
||||
:type callback: func
|
||||
:return: Connection id
|
||||
:rtype: int
|
||||
"""
|
||||
return self.canvas.mpl_connect(event_name, callback)
|
||||
|
||||
def mpl_disconnect(self, cid):
|
||||
"""
|
||||
Disconnect callback with the give id.
|
||||
:param cid: Callback id.
|
||||
:return: None
|
||||
"""
|
||||
self.canvas.mpl_disconnect(cid)
|
||||
|
||||
def connect(self, event_name, callback):
|
||||
"""
|
||||
Attach an event handler to the canvas through the native GTK interface.
|
||||
|
||||
:param event_name: Name of the event
|
||||
:type event_name: str
|
||||
:param callback: Function to call
|
||||
:type callback: function
|
||||
:return: Nothing
|
||||
"""
|
||||
self.canvas.connect(event_name, callback)
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
Clears axes and figure.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
# Clear
|
||||
self.axes.cla()
|
||||
try:
|
||||
self.figure.clf()
|
||||
except KeyError:
|
||||
FlatCAMApp.App.log.warning("KeyError in MPL figure.clf()")
|
||||
|
||||
# Re-build
|
||||
self.figure.add_axes(self.axes)
|
||||
self.axes.set_aspect(1)
|
||||
self.axes.grid(True)
|
||||
|
||||
# Re-draw
|
||||
self.canvas.queue_draw()
|
||||
|
||||
def adjust_axes(self, xmin, ymin, xmax, ymax):
|
||||
"""
|
||||
Adjusts all axes while maintaining the use of the whole canvas
|
||||
and an aspect ratio to 1:1 between x and y axes. The parameters are an original
|
||||
request that will be modified to fit these restrictions.
|
||||
|
||||
:param xmin: Requested minimum value for the X axis.
|
||||
:type xmin: float
|
||||
:param ymin: Requested minimum value for the Y axis.
|
||||
:type ymin: float
|
||||
:param xmax: Requested maximum value for the X axis.
|
||||
:type xmax: float
|
||||
:param ymax: Requested maximum value for the Y axis.
|
||||
:type ymax: float
|
||||
:return: None
|
||||
"""
|
||||
|
||||
FlatCAMApp.App.log.debug("PC.adjust_axes()")
|
||||
|
||||
width = xmax - xmin
|
||||
height = ymax - ymin
|
||||
try:
|
||||
r = width / height
|
||||
except ZeroDivisionError:
|
||||
FlatCAMApp.App.log.error("Height is %f" % height)
|
||||
return
|
||||
canvas_w, canvas_h = self.canvas.get_width_height()
|
||||
canvas_r = float(canvas_w) / canvas_h
|
||||
x_ratio = float(self.x_margin) / canvas_w
|
||||
y_ratio = float(self.y_margin) / canvas_h
|
||||
|
||||
if r > canvas_r:
|
||||
ycenter = (ymin + ymax) / 2.0
|
||||
newheight = height * r / canvas_r
|
||||
ymin = ycenter - newheight / 2.0
|
||||
ymax = ycenter + newheight / 2.0
|
||||
else:
|
||||
xcenter = (xmax + xmin) / 2.0
|
||||
newwidth = width * canvas_r / r
|
||||
xmin = xcenter - newwidth / 2.0
|
||||
xmax = xcenter + newwidth / 2.0
|
||||
|
||||
# Adjust axes
|
||||
for ax in self.figure.get_axes():
|
||||
if ax._label != 'base':
|
||||
ax.set_frame_on(False) # No frame
|
||||
ax.set_xticks([]) # No tick
|
||||
ax.set_yticks([]) # No ticks
|
||||
ax.patch.set_visible(False) # No background
|
||||
ax.set_aspect(1)
|
||||
ax.set_xlim((xmin, xmax))
|
||||
ax.set_ylim((ymin, ymax))
|
||||
ax.set_position([x_ratio, y_ratio, 1 - 2 * x_ratio, 1 - 2 * y_ratio])
|
||||
|
||||
# Re-draw
|
||||
self.canvas.queue_draw()
|
||||
|
||||
def auto_adjust_axes(self, *args):
|
||||
"""
|
||||
Calls ``adjust_axes()`` using the extents of the base axes.
|
||||
|
||||
:rtype : None
|
||||
:return: None
|
||||
"""
|
||||
|
||||
xmin, xmax = self.axes.get_xlim()
|
||||
ymin, ymax = self.axes.get_ylim()
|
||||
self.adjust_axes(xmin, ymin, xmax, ymax)
|
||||
|
||||
def zoom(self, factor, center=None):
|
||||
"""
|
||||
Zooms the plot by factor around a given
|
||||
center point. Takes care of re-drawing.
|
||||
|
||||
:param factor: Number by which to scale the plot.
|
||||
:type factor: float
|
||||
:param center: Coordinates [x, y] of the point around which to scale the plot.
|
||||
:type center: list
|
||||
:return: None
|
||||
"""
|
||||
|
||||
xmin, xmax = self.axes.get_xlim()
|
||||
ymin, ymax = self.axes.get_ylim()
|
||||
width = xmax - xmin
|
||||
height = ymax - ymin
|
||||
|
||||
if center is None or center == [None, None]:
|
||||
center = [(xmin + xmax) / 2.0, (ymin + ymax) / 2.0]
|
||||
|
||||
# For keeping the point at the pointer location
|
||||
relx = (xmax - center[0]) / width
|
||||
rely = (ymax - center[1]) / height
|
||||
|
||||
new_width = width / factor
|
||||
new_height = height / factor
|
||||
|
||||
xmin = center[0] - new_width * (1 - relx)
|
||||
xmax = center[0] + new_width * relx
|
||||
ymin = center[1] - new_height * (1 - rely)
|
||||
ymax = center[1] + new_height * rely
|
||||
|
||||
# Adjust axes
|
||||
for ax in self.figure.get_axes():
|
||||
ax.set_xlim((xmin, xmax))
|
||||
ax.set_ylim((ymin, ymax))
|
||||
|
||||
# Re-draw
|
||||
self.canvas.queue_draw()
|
||||
|
||||
def pan(self, x, y):
|
||||
xmin, xmax = self.axes.get_xlim()
|
||||
ymin, ymax = self.axes.get_ylim()
|
||||
width = xmax - xmin
|
||||
height = ymax - ymin
|
||||
|
||||
# Adjust axes
|
||||
for ax in self.figure.get_axes():
|
||||
ax.set_xlim((xmin + x*width, xmax + x*width))
|
||||
ax.set_ylim((ymin + y*height, ymax + y*height))
|
||||
|
||||
# Re-draw
|
||||
self.canvas.queue_draw()
|
||||
|
||||
def new_axes(self, name):
|
||||
"""
|
||||
Creates and returns an Axes object attached to this object's Figure.
|
||||
|
||||
:param name: Unique label for the axes.
|
||||
:return: Axes attached to the figure.
|
||||
:rtype: Axes
|
||||
"""
|
||||
|
||||
return self.figure.add_axes([0.05, 0.05, 0.9, 0.9], label=name)
|
||||
|
||||
def on_scroll(self, canvas, event):
|
||||
"""
|
||||
Scroll event handler.
|
||||
|
||||
:param canvas: The widget generating the event. Ignored.
|
||||
:param event: Event object containing the event information.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
# So it can receive key presses
|
||||
self.canvas.grab_focus()
|
||||
|
||||
# Event info
|
||||
z, direction = event.get_scroll_direction()
|
||||
|
||||
if self.key is None:
|
||||
|
||||
if direction is Gdk.ScrollDirection.UP:
|
||||
self.zoom(1.5, self.mouse)
|
||||
else:
|
||||
self.zoom(1/1.5, self.mouse)
|
||||
return
|
||||
|
||||
if self.key == 'shift':
|
||||
|
||||
if direction is Gdk.ScrollDirection.UP:
|
||||
self.pan(0.3, 0)
|
||||
else:
|
||||
self.pan(-0.3, 0)
|
||||
return
|
||||
|
||||
if self.key == 'ctrl+control':
|
||||
|
||||
if direction is Gdk.ScrollDirection.UP:
|
||||
self.pan(0, 0.3)
|
||||
else:
|
||||
self.pan(0, -0.3)
|
||||
return
|
||||
|
||||
def on_mouse_move(self, event):
|
||||
"""
|
||||
Mouse movement event hadler. Stores the coordinates.
|
||||
|
||||
:param event: Contains information about the event.
|
||||
:return: None
|
||||
"""
|
||||
self.mouse = [event.xdata, event.ydata]
|
||||
67
camlib.py
67
camlib.py
@@ -27,6 +27,15 @@ import simplejson as json
|
||||
# TODO: Commented for FlatCAM packaging with cx_freeze
|
||||
#from matplotlib.pyplot import plot
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger('base2')
|
||||
log.setLevel(logging.DEBUG)
|
||||
formatter = logging.Formatter('[%(levelname)s] %(message)s')
|
||||
handler = logging.StreamHandler()
|
||||
handler.setFormatter(formatter)
|
||||
log.addHandler(handler)
|
||||
|
||||
|
||||
class Geometry(object):
|
||||
def __init__(self):
|
||||
@@ -57,7 +66,7 @@ class Geometry(object):
|
||||
of geometry: (xmin, ymin, xmax, ymax).
|
||||
"""
|
||||
if self.solid_geometry is None:
|
||||
print "Warning: solid_geometry not computed yet."
|
||||
log.warning("solid_geometry not computed yet.")
|
||||
return (0, 0, 0, 0)
|
||||
|
||||
if type(self.solid_geometry) == list:
|
||||
@@ -72,7 +81,7 @@ class Geometry(object):
|
||||
bounds of geometry.
|
||||
"""
|
||||
if self.solid_geometry is None:
|
||||
print "Warning: solid_geometry not computed yet."
|
||||
log.warning("Solid_geometry not computed yet.")
|
||||
return 0
|
||||
bounds = self.bounds()
|
||||
return (bounds[2]-bounds[0], bounds[3]-bounds[1])
|
||||
@@ -133,7 +142,7 @@ class Geometry(object):
|
||||
:return: Scaling factor resulting from unit change.
|
||||
:rtype: float
|
||||
"""
|
||||
print "Geometry.convert_units()"
|
||||
log.debug("Geometry.convert_units()")
|
||||
|
||||
if units.upper() == self.units.upper():
|
||||
return 1.0
|
||||
@@ -143,7 +152,7 @@ class Geometry(object):
|
||||
elif units.upper() == "IN":
|
||||
factor = 1/25.4
|
||||
else:
|
||||
print "Unsupported units:", units
|
||||
log.error("Unsupported units: %s" % str(units))
|
||||
return 1.0
|
||||
|
||||
self.units = units
|
||||
@@ -293,7 +302,7 @@ class ApertureMacro:
|
||||
self.primitives.append([eval(x) for x in elements])
|
||||
continue
|
||||
|
||||
print "WARNING: Unknown syntax of aperture macro part:", part
|
||||
log.warning("Unknown syntax of aperture macro part: %s" % str(part))
|
||||
|
||||
def append(self, data):
|
||||
"""
|
||||
@@ -834,7 +843,7 @@ class Gerber (Geometry):
|
||||
"modifiers": paramList}
|
||||
return apid
|
||||
|
||||
print "WARNING: Aperture not implemented:", apertureType
|
||||
log.warning("Aperture not implemented: %s" % str(apertureType))
|
||||
return None
|
||||
|
||||
def parse_file(self, filename):
|
||||
@@ -975,7 +984,7 @@ class Gerber (Geometry):
|
||||
geo = Polygon(path)
|
||||
else:
|
||||
if last_path_aperture is None:
|
||||
print "Warning: No aperture defined for curent path. (%d)" % line_num
|
||||
log.warning("No aperture defined for curent path. (%d)" % line_num)
|
||||
width = self.apertures[last_path_aperture]["size"]
|
||||
geo = LineString(path).buffer(width/2)
|
||||
poly_buffer.append(geo)
|
||||
@@ -1016,13 +1025,13 @@ class Gerber (Geometry):
|
||||
j = 0
|
||||
|
||||
if quadrant_mode is None:
|
||||
print "ERROR: Found arc without preceding quadrant specification G74 or G75. (%d)" % line_num
|
||||
print gline
|
||||
log.error("Found arc without preceding quadrant specification G74 or G75. (%d)" % line_num)
|
||||
log.error(gline)
|
||||
continue
|
||||
|
||||
if mode is None and current_interpolation_mode not in [2, 3]:
|
||||
print "ERROR: Found arc without circular interpolation mode defined. (%d)" % line_num
|
||||
print gline
|
||||
log.error("Found arc without circular interpolation mode defined. (%d)" % line_num)
|
||||
log.error(gline)
|
||||
continue
|
||||
elif mode is not None:
|
||||
current_interpolation_mode = int(mode)
|
||||
@@ -1033,10 +1042,10 @@ class Gerber (Geometry):
|
||||
|
||||
# Nothing created! Pen Up.
|
||||
if current_operation_code == 2:
|
||||
print "Warning: Arc with D2. (%d)" % line_num
|
||||
log.warning("Arc with D2. (%d)" % line_num)
|
||||
if len(path) > 1:
|
||||
if last_path_aperture is None:
|
||||
print "Warning: No aperture defined for curent path. (%d)" % line_num
|
||||
log.warning("No aperture defined for curent path. (%d)" % line_num)
|
||||
|
||||
# --- BUFFERED ---
|
||||
width = self.apertures[last_path_aperture]["size"]
|
||||
@@ -1050,7 +1059,7 @@ class Gerber (Geometry):
|
||||
|
||||
# Flash should not happen here
|
||||
if current_operation_code == 3:
|
||||
print "ERROR: Trying to flash within arc. (%d)" % line_num
|
||||
log.error("Trying to flash within arc. (%d)" % line_num)
|
||||
continue
|
||||
|
||||
if quadrant_mode == 'MULTI':
|
||||
@@ -1075,7 +1084,7 @@ class Gerber (Geometry):
|
||||
continue
|
||||
|
||||
if quadrant_mode == 'SINGLE':
|
||||
print "Warning: Single quadrant arc are not implemented yet. (%d)" % line_num
|
||||
log.warning("Single quadrant arc are not implemented yet. (%d)" % line_num)
|
||||
|
||||
### Operation code alone
|
||||
match = self.opcode_re.search(gline)
|
||||
@@ -1228,7 +1237,7 @@ class Gerber (Geometry):
|
||||
continue
|
||||
|
||||
### Line did not match any pattern. Warn user.
|
||||
print "WARNING: Line ignored (%d):" % line_num, gline
|
||||
log.warning("Line ignored (%d): %s" % (line_num, gline))
|
||||
|
||||
if len(path) > 1:
|
||||
# EOF, create shapely LineString if something still in path
|
||||
@@ -1528,7 +1537,7 @@ class Excellon(Geometry):
|
||||
y = current_y
|
||||
|
||||
if x is None or y is None:
|
||||
print "ERROR: Missing coordinates"
|
||||
log.error("Missing coordinates")
|
||||
continue
|
||||
|
||||
self.drills.append({'point': Point((x, y)), 'tool': current_tool})
|
||||
@@ -1550,7 +1559,7 @@ class Excellon(Geometry):
|
||||
y = current_y
|
||||
|
||||
if x is None or y is None:
|
||||
print "ERROR: Missing coordinates"
|
||||
log.error("Missing coordinates")
|
||||
continue
|
||||
|
||||
self.drills.append({'point': Point((x, y)), 'tool': current_tool})
|
||||
@@ -1581,7 +1590,7 @@ class Excellon(Geometry):
|
||||
self.units = {"INCH": "IN", "METRIC": "MM"}[match.group(1)]
|
||||
continue
|
||||
|
||||
print "WARNING: Line ignored:", eline
|
||||
log.warning("Line ignored: %s" % eline)
|
||||
|
||||
def parse_number(self, number_str):
|
||||
"""
|
||||
@@ -1724,7 +1733,7 @@ class CNCjob(Geometry):
|
||||
|
||||
def convert_units(self, units):
|
||||
factor = Geometry.convert_units(self, units)
|
||||
print "CNCjob.convert_units()"
|
||||
log.debug("CNCjob.convert_units()")
|
||||
|
||||
self.z_cut *= factor
|
||||
self.z_move *= factor
|
||||
@@ -1783,20 +1792,20 @@ class CNCjob(Geometry):
|
||||
:return: None
|
||||
:rtype: None
|
||||
"""
|
||||
print "Creating CNC Job from Excellon..."
|
||||
log.debug("Creating CNC Job from Excellon...")
|
||||
if tools == "all":
|
||||
tools = [tool for tool in exobj.tools]
|
||||
else:
|
||||
tools = [x.strip() for x in tools.split(",")]
|
||||
tools = filter(lambda i: i in exobj.tools, tools)
|
||||
print "Tools are:", tools
|
||||
log.debug("Tools are: %s" % str(tools))
|
||||
|
||||
points = []
|
||||
for drill in exobj.drills:
|
||||
if drill['tool'] in tools:
|
||||
points.append(drill['point'])
|
||||
|
||||
print "Found %d drills." % len(points)
|
||||
log.debug("Found %d drills." % len(points))
|
||||
#self.kind = "drill"
|
||||
self.gcode = []
|
||||
|
||||
@@ -1873,8 +1882,8 @@ class CNCjob(Geometry):
|
||||
self.gcode += self.polygon2gcode(poly, tolerance=tolerance)
|
||||
continue
|
||||
|
||||
print "WARNING: G-code generation not implemented for %s" % (str(type(geo)))
|
||||
|
||||
log.warning("G-code generation not implemented for %s" % (str(type(geo))))
|
||||
|
||||
self.gcode += "G00 Z%.4f\n" % self.z_move # Stop cutting
|
||||
self.gcode += "G00 X0Y0\n"
|
||||
self.gcode += "M05\n" # Spindle stop
|
||||
@@ -1967,8 +1976,8 @@ class CNCjob(Geometry):
|
||||
## Changing height
|
||||
if 'Z' in gobj:
|
||||
if ('X' in gobj or 'Y' in gobj) and gobj['Z'] != current['Z']:
|
||||
print "WARNING: Non-orthogonal motion: From", current
|
||||
print " To:", gobj
|
||||
log.warning("Non-orthogonal motion: From %s" % str(current))
|
||||
log.warning(" To: %s" % str(gobj))
|
||||
current['Z'] = gobj['Z']
|
||||
# Store the path into geometry and reset path
|
||||
if len(path) > 1:
|
||||
@@ -2239,7 +2248,7 @@ def get_bounds(geometry_list):
|
||||
xmax = max([xmax, gxmax])
|
||||
ymax = max([ymax, gymax])
|
||||
except:
|
||||
print "DEV WARNING: Tried to get bounds of empty geometry."
|
||||
log.warning("DEVELOPMENT: Tried to get bounds of empty geometry.")
|
||||
|
||||
return [xmin, ymin, xmax, ymax]
|
||||
|
||||
@@ -2392,7 +2401,7 @@ def plotg(geo):
|
||||
_ = iter(g)
|
||||
plotg(g)
|
||||
except:
|
||||
print "Cannot plot:", str(type(g))
|
||||
log.error("Cannot plot: " + str(type(g)))
|
||||
continue
|
||||
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"gerber_noncopperrounded": false, "geometry_paintoverlap": 0.15, "geometry_plot": true, "excellon_feedrate": 5.0, "gerber_plot": true, "excellon_drillz": -0.1, "geometry_feedrate": 3.0, "units": "IN", "excellon_travelz": 0.1, "gerber_multicolored": false, "gerber_solid": true, "gerber_isopasses": 1, "excellon_plot": true, "gerber_isotooldia": 0.016, "cncjob_tooldia": 0.016, "geometry_travelz": 0.1, "gerber_cutoutmargin": 0.2, "excellon_solid": false, "geometry_paintmargin": 0.01, "geometry_cutz": -0.002, "geometry_cnctooldia": 0.016, "gerber_cutouttooldia": 0.07, "geometry_painttooldia": 0.0625, "gerber_gaps": "4", "gerber_bboxmargin": 0.0, "cncjob_plot": true, "gerber_cutoutgapsize": 0.15, "gerber_isooverlap": 0.15, "gerber_bboxrounded": false, "geometry_multicolored": false, "gerber_noncoppermargin": 0.0, "geometry_solid": false}
|
||||
{"gerber_noncopperrounded": false, "geometry_paintoverlap": 0.15, "geometry_plot": true, "excellon_feedrate": 5.0, "gerber_plot": true, "excellon_drillz": -0.1, "geometry_feedrate": 3.0, "units": "IN", "excellon_travelz": 0.1, "gerber_multicolored": false, "gerber_solid": true, "gerber_isopasses": 1, "excellon_plot": true, "gerber_isotooldia": 0.016, "gerber_bboxmargin": 0.0, "cncjob_tooldia": 0.016, "geometry_travelz": 0.1, "gerber_cutoutmargin": 0.2, "excellon_solid": false, "geometry_paintmargin": 0.01, "geometry_cutz": -0.002, "geometry_cnctooldia": 0.016, "gerber_cutouttooldia": 0.07, "gerber_gaps": "4", "geometry_painttooldia": 0.0625, "cncjob_plot": true, "gerber_cutoutgapsize": 0.15, "gerber_isooverlap": 0.15, "gerber_bboxrounded": false, "gerber_noncoppermargin": 0.0}
|
||||
@@ -1 +1 @@
|
||||
[{"kind": "project", "filename": "C:\\Users\\jpcaram\\Dropbox\\VNA\\KiCad_Bridge2\\Bridge2.fcproj"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\Kenney\\Project Outputs for AnalogPredistortion1\\apd.TXT"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\Kenney\\Project Outputs for AnalogPredistortion1\\apd.GTL"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\VNA\\KiCad_Bridge2\\KiCad_Bridge2.drl"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\LockController_v1.0_pcb-RoundHoles.TXT\\LockController_v1.0_pcb-RoundHoles.TXT"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\VNA\\KiCad_Bridge2\\KiCad_Bridge2-F_Cu.gtl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\WindMills - Bottom Copper 2.gbr"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\Example1_copper_bottom_Gndplane_modified.gbr"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\Example1_copper_bottom_Gndplane.gbr"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\CC_LOAD_7000164-00_REV_A_copper_top.gbr"}]
|
||||
[{"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\bedini 7 coils capacitor discharge.gbr"}, {"kind": "cncjob", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\test.cnc"}, {"kind": "project", "filename": "C:\\Users\\jpcaram\\Dropbox\\VNA\\KiCad_Bridge2\\Bridge2_test.fcproj"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\Controller_Board_Shield\\CBS-B_Cu.gbl"}, {"kind": "cncjob", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\squarerpcb\\KiCad_Squarer.gcode"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\VNA\\KiCad_Squarer\\KiCad_Squarer.drl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\VNA\\KiCad_Squarer\\KiCad_Squarer-F_Cu.gtl"}, {"kind": "project", "filename": "C:\\Users\\jpcaram\\Dropbox\\VNA\\KiCad_Bridge2\\Bridge2.fcproj"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\Kenney\\Project Outputs for AnalogPredistortion1\\apd.TXT"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\Kenney\\Project Outputs for AnalogPredistortion1\\apd.GTL"}]
|
||||
Reference in New Issue
Block a user