Created class ObjectCollection to manage the list of objects in the program. Converted the program to use it. Not fully functional yet.
This commit is contained in:
parent
69fbe7a9a3
commit
609561f7a3
562
FlatCAM.py
562
FlatCAM.py
|
@ -23,14 +23,17 @@ from numpy import arange, sin, pi
|
|||
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
|
||||
#from mpl_toolkits.axes_grid.anchored_artists import AnchoredText
|
||||
|
||||
from camlib import *
|
||||
|
||||
import sys
|
||||
import urllib
|
||||
import copy
|
||||
import random
|
||||
|
||||
########################################
|
||||
## Imports part of FlatCAM ##
|
||||
########################################
|
||||
from camlib import *
|
||||
from FlatCAMObj import *
|
||||
|
||||
from FlatCAMWorker import Worker
|
||||
|
||||
########################################
|
||||
|
@ -41,6 +44,8 @@ class App:
|
|||
The main application class. The constructor starts the GUI.
|
||||
"""
|
||||
|
||||
version_url = "http://caram.cl/flatcam/VERSION"
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Starts the application. Takes no parameters.
|
||||
|
@ -78,7 +83,7 @@ class App:
|
|||
self.combo_options = self.builder.get_object("combo_options")
|
||||
self.combo_options.set_active(1)
|
||||
|
||||
self.setup_project_list() # The "Project" tab
|
||||
#self.setup_project_list() # The "Project" tab
|
||||
self.setup_component_editor() # The "Selected" tab
|
||||
|
||||
## Setup the toolbar. Adds buttons.
|
||||
|
@ -95,16 +100,20 @@ class App:
|
|||
|
||||
self.setup_tooltips()
|
||||
|
||||
# TODO: Hardcoded list
|
||||
for kind in ['gerber', 'excellon', 'geometry', 'cncjob']:
|
||||
entry_name = self.builder.get_object("entry_text_" + kind + "_name")
|
||||
entry_name.connect("activate", self.on_activate_name)
|
||||
|
||||
#### DATA ####
|
||||
self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
|
||||
self.setup_obj_classes()
|
||||
self.stuff = {} # FlatCAMObj's by name
|
||||
self.mouse = None # Mouse coordinates over plot
|
||||
self.recent = []
|
||||
|
||||
# What is selected by the user. It is
|
||||
# a key if self.stuff
|
||||
self.selected_item_name = None
|
||||
self.collection = ObjectCollection()
|
||||
self.builder.get_object("box_project").pack_start(self.collection.view, False, False, 1)
|
||||
# TODO: Do this different
|
||||
self.collection.view.connect("row_activated", self.on_row_activated)
|
||||
|
||||
# Used to inhibit the on_options_update callback when
|
||||
# the options are being changed by the program and not the user.
|
||||
|
@ -140,6 +149,7 @@ class App:
|
|||
# self.radios_inv.update({obj.kind + "_" + option: obj.radios_inv[option]})
|
||||
|
||||
## Event subscriptions ##
|
||||
# TODO: Move to plotcanvas
|
||||
self.plot_click_subscribers = {}
|
||||
self.plot_mousemove_subscribers = {}
|
||||
|
||||
|
@ -168,11 +178,11 @@ class App:
|
|||
self.worker.start()
|
||||
|
||||
#### Check for updates ####
|
||||
# Separate thread (Not worker)
|
||||
self.version = 4
|
||||
t1 = threading.Thread(target=self.versionCheck)
|
||||
t1.daemon = True
|
||||
t1.start()
|
||||
# self.worker.add_task(self.versionCheck)
|
||||
|
||||
#### For debugging only ###
|
||||
def somethreadfunc(app_obj):
|
||||
|
@ -245,27 +255,47 @@ class App:
|
|||
"""
|
||||
FlatCAMObj.app = self
|
||||
|
||||
def setup_project_list(self):
|
||||
"""
|
||||
Sets up list or Tree where whatever has been loaded or created is
|
||||
displayed.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
self.store = Gtk.ListStore(str)
|
||||
self.tree = Gtk.TreeView(self.store)
|
||||
self.tree_select = self.tree.get_selection()
|
||||
renderer = Gtk.CellRendererText()
|
||||
column = Gtk.TreeViewColumn("Objects", renderer, text=0)
|
||||
self.tree.append_column(column)
|
||||
self.builder.get_object("box_project").pack_start(self.tree, False, False, 1)
|
||||
|
||||
# Double-click or Enter takes you to the object's options
|
||||
self.tree.connect("row_activated", self.on_row_activated)
|
||||
|
||||
# Changes the selected item and populates the object options form
|
||||
self.signal_id = self.tree_select.connect("changed", self.on_tree_selection_changed)
|
||||
# def setup_project_list(self):
|
||||
# """
|
||||
# Sets up list or Tree where whatever has been loaded or created is
|
||||
# displayed.
|
||||
#
|
||||
# :return: None
|
||||
# """
|
||||
#
|
||||
# # Model
|
||||
# self.store = Gtk.ListStore(GdkPixbuf.Pixbuf, str)
|
||||
# #self.store = Gtk.ListStore(str, str)
|
||||
#
|
||||
# # View
|
||||
# self.tree = Gtk.TreeView(model=self.store)
|
||||
#
|
||||
# # Renderers
|
||||
# renderer_pixbuf = Gtk.CellRendererPixbuf()
|
||||
# column_pixbuf = Gtk.TreeViewColumn("Type", renderer_pixbuf, pixbuf=0)
|
||||
# # column_pixbuf = Gtk.TreeViewColumn("Type")
|
||||
# # column_pixbuf.pack_start(renderer_pixbuf, False)
|
||||
# # column_pixbuf.add_attribute(renderer_pixbuf, "pixbuf", 1)
|
||||
# self.tree.append_column(column_pixbuf)
|
||||
#
|
||||
# # renderer1 = Gtk.CellRendererText()
|
||||
# # column1 = Gtk.TreeViewColumn("Type", renderer1, text=0)
|
||||
# # self.tree.append_column(column1)
|
||||
#
|
||||
# renderer = Gtk.CellRendererText()
|
||||
# column = Gtk.TreeViewColumn("Object name", renderer, text=1)
|
||||
# self.tree.append_column(column)
|
||||
#
|
||||
# self.tree_select = self.tree.get_selection()
|
||||
#
|
||||
#
|
||||
# self.builder.get_object("box_project").pack_start(self.tree, False, False, 1)
|
||||
#
|
||||
# # Double-click or Enter takes you to the object's options
|
||||
# self.tree.connect("row_activated", self.on_row_activated)
|
||||
#
|
||||
# # Changes the selected item and populates the object options form
|
||||
# self.signal_id = self.tree_select.connect("changed", self.on_tree_selection_changed)
|
||||
|
||||
def setup_component_editor(self):
|
||||
"""
|
||||
|
@ -293,6 +323,7 @@ class App:
|
|||
|
||||
def setup_recent_items(self):
|
||||
|
||||
# TODO: Move this to constructor
|
||||
icons = {
|
||||
"gerber": "share/flatcam_icon16.png",
|
||||
"excellon": "share/drill16.png",
|
||||
|
@ -309,13 +340,6 @@ class App:
|
|||
|
||||
# Closure needed to create callbacks in a loop.
|
||||
# Otherwise late binding occurs.
|
||||
# def make_callback(func, fname):
|
||||
# def opener(*args):
|
||||
# t = threading.Thread(target=lambda: func(fname))
|
||||
# t.daemon = True
|
||||
# t.start()
|
||||
# return opener
|
||||
|
||||
def make_callback(func, fname):
|
||||
def opener(*args):
|
||||
self.worker.add_task(func, [fname])
|
||||
|
@ -362,21 +386,31 @@ class App:
|
|||
"""
|
||||
self.info_label.set_text(text)
|
||||
|
||||
def build_list(self):
|
||||
"""
|
||||
Clears and re-populates the list of objects in currently
|
||||
in the project.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
print "build_list(): clearing"
|
||||
self.tree_select.unselect_all()
|
||||
self.store.clear()
|
||||
print "repopulating...",
|
||||
for key in self.stuff:
|
||||
print key,
|
||||
self.store.append([key])
|
||||
print
|
||||
# def build_list(self):
|
||||
# """
|
||||
# Clears and re-populates the list of objects in currently
|
||||
# in the project.
|
||||
#
|
||||
# :return: None
|
||||
# """
|
||||
# icons = {
|
||||
# "gerber": "share/flatcam_icon16.png",
|
||||
# "excellon": "share/drill16.png",
|
||||
# "cncjob": "share/cnc16.png",
|
||||
# "geometry": "share/geometry16.png"
|
||||
# }
|
||||
#
|
||||
#
|
||||
# print "build_list(): clearing"
|
||||
# self.tree_select.unselect_all()
|
||||
# self.store.clear()
|
||||
# print "repopulating...",
|
||||
# for key in self.stuff:
|
||||
# print key,
|
||||
# obj = self.stuff[key]
|
||||
# icon = GdkPixbuf.Pixbuf.new_from_file(icons[obj.kind])
|
||||
# self.store.append([icon, key])
|
||||
# print
|
||||
|
||||
def get_radio_value(self, radio_set):
|
||||
"""
|
||||
|
@ -401,26 +435,24 @@ class App:
|
|||
self.plotcanvas.clear()
|
||||
self.set_progress_bar(0.1, "Re-plotting...")
|
||||
|
||||
def thread_func(app_obj):
|
||||
def worker_task(app_obj):
|
||||
percentage = 0.1
|
||||
try:
|
||||
delta = 0.9 / len(self.stuff)
|
||||
delta = 0.9 / len(self.collection.get_list())
|
||||
except ZeroDivisionError:
|
||||
GLib.timeout_add(300, lambda: app_obj.set_progress_bar(0.0, ""))
|
||||
return
|
||||
for i in self.stuff:
|
||||
self.stuff[i].plot()
|
||||
for obj in self.collection.get_list():
|
||||
obj.plot()
|
||||
percentage += delta
|
||||
GLib.idle_add(lambda: app_obj.set_progress_bar(percentage, "Re-plotting..."))
|
||||
|
||||
GLib.idle_add(app_obj.plotcanvas.auto_adjust_axes)
|
||||
GLib.idle_add(lambda: self.on_zoom_fit(None))
|
||||
GLib.timeout_add(300, lambda: app_obj.set_progress_bar(0.0, ""))
|
||||
GLib.timeout_add(300, lambda: app_obj.set_progress_bar(0.0, "Idle"))
|
||||
|
||||
# t = threading.Thread(target=thread_func, args=(self,))
|
||||
# t.daemon = True
|
||||
# t.start()
|
||||
self.worker.add_task(thread_func, [self])
|
||||
# Send to worker
|
||||
self.worker.add_task(worker_task, [self])
|
||||
|
||||
def get_eval(self, widget_name):
|
||||
"""
|
||||
|
@ -442,26 +474,26 @@ class App:
|
|||
self.info("Could not evaluate: " + value)
|
||||
return None
|
||||
|
||||
def set_list_selection(self, name):
|
||||
"""
|
||||
Marks a given object as selected in the list ob objects
|
||||
in the GUI. This selection will in turn trigger
|
||||
``self.on_tree_selection_changed()``.
|
||||
|
||||
:param name: Name of the object.
|
||||
:type name: str
|
||||
:return: None
|
||||
"""
|
||||
|
||||
iter = self.store.get_iter_first()
|
||||
while iter is not None and self.store[iter][0] != name:
|
||||
iter = self.store.iter_next(iter)
|
||||
self.tree_select.unselect_all()
|
||||
self.tree_select.select_iter(iter)
|
||||
|
||||
# Need to return False such that GLib.idle_add
|
||||
# or .timeout_add do not repeat.
|
||||
return False
|
||||
# def set_list_selection(self, name):
|
||||
# """
|
||||
# Marks a given object as selected in the list ob objects
|
||||
# in the GUI. This selection will in turn trigger
|
||||
# ``self.on_tree_selection_changed()``.
|
||||
#
|
||||
# :param name: Name of the object.
|
||||
# :type name: str
|
||||
# :return: None
|
||||
# """
|
||||
#
|
||||
# iter = self.store.get_iter_first()
|
||||
# while iter is not None and self.store[iter][1] != name:
|
||||
# iter = self.store.iter_next(iter)
|
||||
# self.tree_select.unselect_all()
|
||||
# self.tree_select.select_iter(iter)
|
||||
#
|
||||
# # Need to return False such that GLib.idle_add
|
||||
# # or .timeout_add do not repeat.
|
||||
# return False
|
||||
|
||||
def new_object(self, kind, name, initialize):
|
||||
"""
|
||||
|
@ -482,7 +514,7 @@ class App:
|
|||
"""
|
||||
|
||||
### Check for existing name
|
||||
if name in self.stuff:
|
||||
if name in self.collection.get_names():
|
||||
## Create a new name
|
||||
# Ends with number?
|
||||
match = re.search(r'(.*[^\d])?(\d+)$', name)
|
||||
|
@ -503,12 +535,6 @@ class App:
|
|||
obj = classdict[kind](name)
|
||||
obj.units = self.options["units"] # TODO: The constructor should look at defaults.
|
||||
|
||||
# Initialize as per user request
|
||||
# User must take care to implement initialize
|
||||
# in a thread-safe way as is is likely that we
|
||||
# have been invoked in a separate thread.
|
||||
#initialize(obj, self)
|
||||
|
||||
# Set default options from self.options
|
||||
for option in self.options:
|
||||
if option.find(kind + "_") == 0:
|
||||
|
@ -527,14 +553,10 @@ class App:
|
|||
obj.convert_units(self.options["units"])
|
||||
|
||||
# Add to our records
|
||||
self.stuff[name] = obj
|
||||
# TODO: Perhaps make collection thread safe instead?
|
||||
GLib.idle_add(lambda: self.collection.append(obj, active=True))
|
||||
|
||||
# Update GUI list and select it (Thread-safe?)
|
||||
self.store.append([name])
|
||||
#self.build_list()
|
||||
GLib.idle_add(lambda: self.set_list_selection(name))
|
||||
# TODO: Gtk.notebook.set_current_page is not known to
|
||||
# TODO: return False. Fix this??
|
||||
# Show object details now.
|
||||
GLib.timeout_add(100, lambda: self.notebook.set_current_page(1))
|
||||
|
||||
# Plot
|
||||
|
@ -560,22 +582,22 @@ class App:
|
|||
self.progress_bar.set_fraction(percentage)
|
||||
return False
|
||||
|
||||
def get_current(self):
|
||||
"""
|
||||
Returns the currently selected FlatCAMObj in the application.
|
||||
|
||||
:return: Currently selected FlatCAMObj in the application.
|
||||
:rtype: FlatCAMObj or None
|
||||
"""
|
||||
|
||||
# TODO: Could possibly read the form into the object here.
|
||||
# But there are some cases when the form for the object
|
||||
# is not up yet. See on_tree_selection_changed.
|
||||
|
||||
try:
|
||||
return self.stuff[self.selected_item_name]
|
||||
except:
|
||||
return None
|
||||
# def get_current(self):
|
||||
# """
|
||||
# Returns the currently selected FlatCAMObj in the application.
|
||||
#
|
||||
# :return: Currently selected FlatCAMObj in the application.
|
||||
# :rtype: FlatCAMObj or None
|
||||
# """
|
||||
#
|
||||
# # TODO: Could possibly read the form into the object here.
|
||||
# # But there are some cases when the form for the object
|
||||
# # is not up yet. See on_tree_selection_changed.
|
||||
#
|
||||
# try:
|
||||
# return self.stuff[self.selected_item_name]
|
||||
# except:
|
||||
# return None
|
||||
|
||||
def load_defaults(self):
|
||||
"""
|
||||
|
@ -712,11 +734,11 @@ class App:
|
|||
|
||||
# Capture the latest changes
|
||||
try:
|
||||
self.get_current().read_form()
|
||||
self.collection.get_active().read_form()
|
||||
except:
|
||||
pass
|
||||
|
||||
d = {"objs": [self.stuff[o].to_dict() for o in self.stuff],
|
||||
d = {"objs": [obj.to_dict() for obj in self.collection.get_list()],
|
||||
"options": self.options}
|
||||
|
||||
try:
|
||||
|
@ -746,15 +768,12 @@ class App:
|
|||
try:
|
||||
f = open(filename, 'r')
|
||||
except:
|
||||
#print "WARNING: Failed to open project file:", filename
|
||||
self.info("ERROR: Failed to open project file: %s" % filename)
|
||||
return
|
||||
|
||||
try:
|
||||
d = json.load(f, object_hook=dict2obj)
|
||||
except:
|
||||
#print sys.exc_info()
|
||||
#print "WARNING: Failed to parse project file:", filename
|
||||
self.info("ERROR: Failed to parse project file: %s" % filename)
|
||||
f.close()
|
||||
return
|
||||
|
@ -790,8 +809,8 @@ class App:
|
|||
combo = self.builder.get_object(combo)
|
||||
|
||||
combo.remove_all()
|
||||
for obj in self.stuff:
|
||||
combo.append_text(obj)
|
||||
for name in self.collection.get_names():
|
||||
combo.append_text(name)
|
||||
|
||||
def versionCheck(self, *args):
|
||||
"""
|
||||
|
@ -803,7 +822,7 @@ class App:
|
|||
"""
|
||||
|
||||
try:
|
||||
f = urllib.urlopen("http://caram.cl/flatcam/VERSION") # TODO: Hardcoded.
|
||||
f = urllib.urlopen(App.version_url)
|
||||
except:
|
||||
GLib.idle_add(lambda: self.info("ERROR trying to check for latest version."))
|
||||
return
|
||||
|
@ -868,52 +887,49 @@ class App:
|
|||
|
||||
self.set_progress_bar(0.1, "Re-plotting...")
|
||||
|
||||
def thread_func(app_obj):
|
||||
def worker_task(app_obj):
|
||||
percentage = 0.1
|
||||
try:
|
||||
delta = 0.9 / len(self.stuff)
|
||||
delta = 0.9 / len(self.collection.get_list())
|
||||
except ZeroDivisionError:
|
||||
GLib.timeout_add(300, lambda: app_obj.set_progress_bar(0.0, ""))
|
||||
return
|
||||
for i in self.stuff:
|
||||
if i != app_obj.selected_item_name or not except_current:
|
||||
self.stuff[i].options['plot'] = False
|
||||
self.stuff[i].plot()
|
||||
for obj in self.collection.get_list():
|
||||
#if i != app_obj.selected_item_name or not except_current:
|
||||
if obj != self.collection.get_active() or not except_current:
|
||||
obj.options['plot'] = False
|
||||
obj.plot()
|
||||
percentage += delta
|
||||
GLib.idle_add(lambda: app_obj.set_progress_bar(percentage, "Re-plotting..."))
|
||||
|
||||
GLib.idle_add(app_obj.plotcanvas.auto_adjust_axes)
|
||||
GLib.timeout_add(300, lambda: app_obj.set_progress_bar(0.0, ""))
|
||||
|
||||
# t = threading.Thread(target=thread_func, args=(self,))
|
||||
# t.daemon = True
|
||||
# t.start()
|
||||
self.worker.add_task(thread_func, [self])
|
||||
# Send to worker
|
||||
self.worker.add_task(worker_task, [self])
|
||||
|
||||
def enable_all_plots(self, *args):
|
||||
self.plotcanvas.clear()
|
||||
self.set_progress_bar(0.1, "Re-plotting...")
|
||||
|
||||
def thread_func(app_obj):
|
||||
def worker_task(app_obj):
|
||||
percentage = 0.1
|
||||
try:
|
||||
delta = 0.9 / len(self.stuff)
|
||||
delta = 0.9 / len(self.collection.get_list())
|
||||
except ZeroDivisionError:
|
||||
GLib.timeout_add(300, lambda: app_obj.set_progress_bar(0.0, ""))
|
||||
return
|
||||
for i in self.stuff:
|
||||
self.stuff[i].options['plot'] = True
|
||||
self.stuff[i].plot()
|
||||
for obj in self.collection.get_list():
|
||||
obj.options['plot'] = True
|
||||
obj.plot()
|
||||
percentage += delta
|
||||
GLib.idle_add(lambda: app_obj.set_progress_bar(percentage, "Re-plotting..."))
|
||||
|
||||
GLib.idle_add(app_obj.plotcanvas.auto_adjust_axes)
|
||||
GLib.timeout_add(300, lambda: app_obj.set_progress_bar(0.0, ""))
|
||||
|
||||
# t = threading.Thread(target=thread_func, args=(self,))
|
||||
# t.daemon = True
|
||||
# t.start()
|
||||
self.worker.add_task(thread_func, [self])
|
||||
# Send to worker
|
||||
self.worker.add_task(worker_task, [self])
|
||||
|
||||
def register_recent(self, kind, filename):
|
||||
record = {'kind': kind, 'filename': filename}
|
||||
|
@ -960,7 +976,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
obj = self.get_current()
|
||||
obj = self.collection.get_active()
|
||||
obj.read_form()
|
||||
assert isinstance(obj, FlatCAMObj)
|
||||
try:
|
||||
|
@ -981,8 +997,10 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
self.get_current().read_form()
|
||||
self.get_current().plot()
|
||||
# self.get_current().read_form()
|
||||
# self.get_current().plot()
|
||||
self.collection.get_active().read_form()
|
||||
self.collection.get_active().plot()
|
||||
|
||||
def on_about(self, widget):
|
||||
"""
|
||||
|
@ -1007,12 +1025,8 @@ class App:
|
|||
# TODO: Move (some of) this to camlib!
|
||||
|
||||
# Object to mirror
|
||||
try:
|
||||
obj_name = self.builder.get_object("comboboxtext_bottomlayer").get_active_text()
|
||||
fcobj = self.stuff[obj_name]
|
||||
except KeyError:
|
||||
self.info("WARNING: Cannot mirror that object.")
|
||||
return
|
||||
obj_name = self.builder.get_object("comboboxtext_bottomlayer").get_active_text()
|
||||
fcobj = self.collection.get_by_name(obj_name)
|
||||
|
||||
# For now, lets limit to Gerbers and Excellons.
|
||||
# assert isinstance(gerb, FlatCAMGerber)
|
||||
|
@ -1030,23 +1044,13 @@ class App:
|
|||
px, py = eval(self.point_entry.get_text())
|
||||
else: # The axis is the line dividing the box in the middle
|
||||
name = self.box_combo.get_active_text()
|
||||
bb_obj = self.stuff[name]
|
||||
bb_obj = self.collection.get_by_name(name)
|
||||
xmin, ymin, xmax, ymax = bb_obj.bounds()
|
||||
px = 0.5*(xmin+xmax)
|
||||
py = 0.5*(ymin+ymax)
|
||||
|
||||
# Do the mirroring
|
||||
# xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
|
||||
# mirrored = affinity.scale(fcobj.solid_geometry, xscale, yscale, origin=(px, py))
|
||||
#
|
||||
# def obj_init(obj_inst, app_inst):
|
||||
# obj_inst.solid_geometry = mirrored
|
||||
#
|
||||
# self.new_object("gerber", fcobj.options["name"] + "_mirror", obj_init)
|
||||
|
||||
fcobj.mirror(axis, [px, py])
|
||||
fcobj.plot()
|
||||
#self.on_update_plot(None)
|
||||
|
||||
def on_create_aligndrill(self, widget):
|
||||
"""
|
||||
|
@ -1067,7 +1071,7 @@ class App:
|
|||
px, py = eval(self.point_entry.get_text())
|
||||
else:
|
||||
name = self.box_combo.get_active_text()
|
||||
bb_obj = self.stuff[name]
|
||||
bb_obj = self.collection.get_by_name(name)
|
||||
xmin, ymin, xmax, ymax = bb_obj.bounds()
|
||||
px = 0.5*(xmin+xmax)
|
||||
py = 0.5*(ymin+ymax)
|
||||
|
@ -1232,11 +1236,10 @@ class App:
|
|||
self.read_form()
|
||||
scale_options(factor)
|
||||
self.options2form()
|
||||
for obj in self.stuff:
|
||||
for obj in self.collection.get_list():
|
||||
units = self.get_radio_value({"rb_mm": "MM", "rb_inch": "IN"})
|
||||
#print "Converting ", obj, " to ", units
|
||||
self.stuff[obj].convert_units(units)
|
||||
current = self.get_current()
|
||||
obj.convert_units(units)
|
||||
current = self.collection.get_active()
|
||||
if current is not None:
|
||||
current.to_form()
|
||||
self.plot_all()
|
||||
|
@ -1355,7 +1358,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
obj = self.get_current()
|
||||
obj = self.collection.get_active()
|
||||
if obj is None:
|
||||
self.info("WARNING: No object selected.")
|
||||
return
|
||||
|
@ -1374,7 +1377,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
obj = self.get_current()
|
||||
obj = self.collection.get_active()
|
||||
if obj is None:
|
||||
self.info("WARNING: No object selected.")
|
||||
return
|
||||
|
@ -1393,7 +1396,7 @@ class App:
|
|||
:param param: Ignored.
|
||||
:return: None
|
||||
"""
|
||||
obj = self.get_current()
|
||||
obj = self.collection.get_active()
|
||||
if obj is None:
|
||||
self.info("WARNING: No object selected.")
|
||||
return
|
||||
|
@ -1413,7 +1416,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
obj = self.get_current()
|
||||
obj = self.collection.get_active()
|
||||
if obj is None:
|
||||
self.info("WARNING: No object selected.")
|
||||
return
|
||||
|
@ -1501,7 +1504,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
obj = self.get_current()
|
||||
obj = self.collection.get_active()
|
||||
factor = self.get_eval("entry_eval_" + obj.kind + "_scalefactor")
|
||||
obj.scale(factor)
|
||||
obj.to_form()
|
||||
|
@ -1542,7 +1545,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
# TODO: Use Gerber.get_bounding_box(...)
|
||||
gerber = self.get_current()
|
||||
gerber = self.collection.get_active()
|
||||
gerber.read_form()
|
||||
name = gerber.options["name"] + "_bbox"
|
||||
|
||||
|
@ -1565,7 +1568,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
obj = self.get_current()
|
||||
obj = self.collection.get_active()
|
||||
obj.read_form()
|
||||
|
||||
self.set_progress_bar(0.5, "Plotting...")
|
||||
|
@ -1589,7 +1592,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
excellon = self.get_current()
|
||||
excellon = self.collection.get_active()
|
||||
excellon.read_form()
|
||||
job_name = excellon.options["name"] + "_cnc"
|
||||
|
||||
|
@ -1636,7 +1639,7 @@ class App:
|
|||
:param widget: The widget from which this was called.
|
||||
:return: None
|
||||
"""
|
||||
excellon = self.get_current()
|
||||
excellon = self.collection.get_active()
|
||||
assert isinstance(excellon, FlatCAMExcellon)
|
||||
excellon.show_tool_chooser()
|
||||
|
||||
|
@ -1650,7 +1653,7 @@ class App:
|
|||
:return:
|
||||
"""
|
||||
self.on_eval_update(widget)
|
||||
obj = self.get_current()
|
||||
obj = self.collection.get_active()
|
||||
assert isinstance(obj, FlatCAMObj)
|
||||
obj.read_form()
|
||||
|
||||
|
@ -1664,7 +1667,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
gerb = self.get_current()
|
||||
gerb = self.collection.get_active()
|
||||
gerb.read_form()
|
||||
name = gerb.options["name"] + "_noncopper"
|
||||
|
||||
|
@ -1688,7 +1691,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
gerb = self.get_current()
|
||||
gerb = self.collection.get_active()
|
||||
gerb.read_form()
|
||||
name = gerb.options["name"] + "_cutout"
|
||||
|
||||
|
@ -1749,7 +1752,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
gerb = self.get_current()
|
||||
gerb = self.collection.get_active()
|
||||
gerb.read_form()
|
||||
dia = gerb.options["isotooldia"]
|
||||
passes = int(gerb.options["isopasses"])
|
||||
|
@ -1779,7 +1782,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
source_geo = self.get_current()
|
||||
source_geo = self.collection.get_active()
|
||||
source_geo.read_form()
|
||||
job_name = source_geo.options["name"] + "_cnc"
|
||||
|
||||
|
@ -1834,7 +1837,7 @@ class App:
|
|||
"""
|
||||
|
||||
self.info("Click inside the desired polygon.")
|
||||
geo = self.get_current()
|
||||
geo = self.collection.get_active()
|
||||
geo.read_form()
|
||||
assert isinstance(geo, FlatCAMGeometry)
|
||||
tooldia = geo.options["painttooldia"]
|
||||
|
@ -1868,7 +1871,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
def on_success(app_obj, filename):
|
||||
cncjob = app_obj.get_current()
|
||||
cncjob = app_obj.collection.get_active()
|
||||
f = open(filename, 'w')
|
||||
f.write(cncjob.gcode)
|
||||
f.close()
|
||||
|
@ -1885,17 +1888,17 @@ class App:
|
|||
"""
|
||||
|
||||
# Keep this for later
|
||||
name = copy.copy(self.selected_item_name)
|
||||
name = copy.copy(self.collection.get_active().options["name"])
|
||||
|
||||
# Remove plot
|
||||
self.plotcanvas.figure.delaxes(self.get_current().axes)
|
||||
self.plotcanvas.figure.delaxes(self.collection.get_active().axes)
|
||||
self.plotcanvas.auto_adjust_axes()
|
||||
|
||||
# Remove from dictionary
|
||||
self.stuff.pop(self.selected_item_name)
|
||||
# Clear form
|
||||
self.setup_component_editor()
|
||||
|
||||
# Update UI
|
||||
self.build_list() # Update the items list
|
||||
# Remove from dictionary
|
||||
self.collection.delete_active()
|
||||
|
||||
self.info("Object deleted: %s" % name)
|
||||
|
||||
|
@ -1907,7 +1910,7 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
self.get_current().read_form()
|
||||
self.collection.get_active().read_form()
|
||||
|
||||
self.plot_all()
|
||||
|
||||
|
@ -1929,49 +1932,10 @@ class App:
|
|||
:return: None
|
||||
"""
|
||||
|
||||
# Disconnect event listener
|
||||
self.tree.get_selection().disconnect(self.signal_id)
|
||||
|
||||
new_name = entry.get_text() # Get from form
|
||||
self.stuff[new_name] = self.stuff.pop(self.selected_item_name) # Update dictionary
|
||||
self.stuff[new_name].options["name"] = new_name # update object
|
||||
self.info('Name change: ' + self.selected_item_name + " to " + new_name)
|
||||
|
||||
self.selected_item_name = new_name # Update selection name
|
||||
|
||||
self.build_list() # Update the items list
|
||||
|
||||
# Reconnect event listener
|
||||
self.signal_id = self.tree.get_selection().connect(
|
||||
"changed", self.on_tree_selection_changed)
|
||||
|
||||
def on_tree_selection_changed(self, selection):
|
||||
"""
|
||||
Callback for selection change in the project list. This changes
|
||||
the currently selected FlatCAMObj.
|
||||
|
||||
:param selection: Selection associated to the project tree or list
|
||||
:type selection: Gtk.TreeSelection
|
||||
:return: None
|
||||
"""
|
||||
print "DEBUG: on_tree_selection_change(): ",
|
||||
model, treeiter = selection.get_selected()
|
||||
|
||||
if treeiter is not None:
|
||||
# Save data for previous selection
|
||||
obj = self.get_current()
|
||||
if obj is not None:
|
||||
obj.read_form()
|
||||
|
||||
print "DEBUG: You selected", model[treeiter][0]
|
||||
self.selected_item_name = model[treeiter][0]
|
||||
obj_new = self.get_current()
|
||||
if obj_new is not None:
|
||||
GLib.idle_add(lambda: obj_new.build_ui())
|
||||
else:
|
||||
print "DEBUG: Nothing selected"
|
||||
self.selected_item_name = None
|
||||
self.setup_component_editor()
|
||||
old_name = copy.copy(self.collection.get_active().options["name"])
|
||||
new_name = entry.get_text()
|
||||
self.collection.change_name(old_name, new_name)
|
||||
self.info("Name changed from %s to %s" % (old_name, new_name))
|
||||
|
||||
def on_file_new(self, param):
|
||||
"""
|
||||
|
@ -1981,19 +1945,18 @@ class App:
|
|||
:param param: Whatever is passed by the event. Ignore.
|
||||
:return: None
|
||||
"""
|
||||
# Remove everythong from memory
|
||||
# Remove everything from memory
|
||||
# Clear plot
|
||||
self.plotcanvas.clear()
|
||||
|
||||
# Clear object editor
|
||||
#self.setup_component_editor()
|
||||
# Delete data
|
||||
self.collection.delete_all()
|
||||
|
||||
# Clear data
|
||||
self.stuff = {}
|
||||
# Clear object editor
|
||||
self.setup_component_editor()
|
||||
|
||||
# Clear list
|
||||
#self.tree_select.unselect_all()
|
||||
self.build_list()
|
||||
self.collection.build_list()
|
||||
|
||||
# Clear project filename
|
||||
self.project_filename = None
|
||||
|
@ -2339,7 +2302,7 @@ class App:
|
|||
:param event: Ignored.
|
||||
:return: None
|
||||
"""
|
||||
xmin, ymin, xmax, ymax = get_bounds(self.stuff)
|
||||
xmin, ymin, xmax, ymax = self.collection.get_bounds()
|
||||
width = xmax - xmin
|
||||
height = ymax - ymin
|
||||
xmin -= 0.05 * width
|
||||
|
@ -2804,11 +2767,79 @@ class PlotCanvas:
|
|||
|
||||
|
||||
class ObjectCollection:
|
||||
|
||||
classdict = {
|
||||
"gerber": FlatCAMGerber,
|
||||
"excellon": FlatCAMExcellon,
|
||||
"cncjob": FlatCAMCNCjob,
|
||||
"geometry": FlatCAMGeometry
|
||||
}
|
||||
|
||||
icons = {
|
||||
"gerber": "share/flatcam_icon16.png",
|
||||
"excellon": "share/drill16.png",
|
||||
"cncjob": "share/cnc16.png",
|
||||
"geometry": "share/geometry16.png"
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
|
||||
### Data
|
||||
# List of FLatCAMObject's
|
||||
self.collection = []
|
||||
self.active = None
|
||||
|
||||
### GUI List components
|
||||
## Model
|
||||
self.store = Gtk.ListStore(GdkPixbuf.Pixbuf, str)
|
||||
|
||||
## View
|
||||
self.view = Gtk.TreeView(model=self.store)
|
||||
self.view.connect("row_activated", self.on_row_activated)
|
||||
self.tree_selection = self.view.get_selection()
|
||||
self.change_subscription = self.tree_selection.connect("changed", self.on_list_selection_change)
|
||||
|
||||
# Renderers
|
||||
renderer_pixbuf = Gtk.CellRendererPixbuf()
|
||||
column_pixbuf = Gtk.TreeViewColumn("Type", renderer_pixbuf, pixbuf=0)
|
||||
self.view.append_column(column_pixbuf)
|
||||
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
column_text = Gtk.TreeViewColumn("Name", renderer_text, text=1)
|
||||
self.view.append_column(column_text)
|
||||
|
||||
def delete_all(self):
|
||||
print "OC.delete_all()"
|
||||
self.collection = []
|
||||
self.active = None
|
||||
|
||||
def delete_active(self):
|
||||
print "OC.delete_active()"
|
||||
self.collection.remove(self.active)
|
||||
self.active = None
|
||||
self.build_list()
|
||||
|
||||
def on_row_activated(self, *args):
|
||||
print "OC.on_row_activated()"
|
||||
return
|
||||
|
||||
def on_list_selection_change(self, selection):
|
||||
print "OC.on_list_selection_change()"
|
||||
model, treeiter = selection.get_selected()
|
||||
|
||||
try:
|
||||
self.get_active().read_form()
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.set_active(model[treeiter][1])
|
||||
self.get_active().build_ui()
|
||||
except:
|
||||
pass
|
||||
|
||||
def set_active(self, name):
|
||||
print "OC.set_active()"
|
||||
for obj in self.collection:
|
||||
if obj.options['name'] == name:
|
||||
self.active = obj
|
||||
|
@ -2816,10 +2847,63 @@ class ObjectCollection:
|
|||
return None
|
||||
|
||||
def get_active(self):
|
||||
print "OC.get_active()"
|
||||
return self.active
|
||||
|
||||
def append(self, obj):
|
||||
self.collection.append(obj)
|
||||
def set_list_selection(self, name):
|
||||
print "OC.set_list_selection()"
|
||||
iterat = self.store.get_iter_first()
|
||||
while iterat is not None and self.store[iterat][1] != name:
|
||||
iterat = self.store.iter_next(iterat)
|
||||
self.tree_selection.unselect_all()
|
||||
self.tree_selection.select_iter(iterat)
|
||||
|
||||
def append(self, obj, active=False):
|
||||
print "OC.append()"
|
||||
if obj not in self.collection:
|
||||
self.collection.append(obj)
|
||||
self.build_list()
|
||||
|
||||
if active:
|
||||
self.set_list_selection(obj.options["name"])
|
||||
|
||||
def get_names(self):
|
||||
print "OC.get_names()"
|
||||
return [o.options["name"] for o in self.collection]
|
||||
|
||||
def build_list(self):
|
||||
print "OC.build_list()"
|
||||
self.store.clear()
|
||||
for obj in self.collection:
|
||||
icon = GdkPixbuf.Pixbuf.new_from_file(ObjectCollection.icons[obj.kind])
|
||||
self.store.append([icon, obj.options["name"]])
|
||||
|
||||
def get_bounds(self):
|
||||
print "OC.get_bounds()"
|
||||
return get_bounds(self.collection)
|
||||
|
||||
def get_list(self):
|
||||
return self.collection
|
||||
|
||||
def get_by_name(self, name):
|
||||
for obj in self.collection:
|
||||
if obj.options["name"] == name:
|
||||
return obj
|
||||
return None
|
||||
|
||||
def change_name(self, old_name, new_name):
|
||||
self.tree_selection.disconnect(self.change_subscription)
|
||||
|
||||
for obj in self.collection:
|
||||
if obj.options["name"] == old_name:
|
||||
obj.options["name"] = new_name
|
||||
self.build_list()
|
||||
self.tree_selection.connect("changed", self.on_list_selection_change)
|
||||
if obj == self.get_active():
|
||||
self.set_active(new_name)
|
||||
self.set_list_selection(new_name)
|
||||
break
|
||||
|
||||
|
||||
app = App()
|
||||
Gtk.main()
|
||||
|
|
797
FlatCAM.ui
797
FlatCAM.ui
|
@ -132,6 +132,404 @@ THE SOFTWARE.</property>
|
|||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-open</property>
|
||||
</object>
|
||||
<object class="GtkOffscreenWindow" id="offscreenwindow_dblsided">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="sw_dblsided">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkViewport" id="vp_dblsided">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box_dblsided">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label53">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_bottom">6</property>
|
||||
<property name="ypad">3</property>
|
||||
<property name="label" translatable="yes">Double-Sided PCB Tool</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="semibold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid7">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="row_spacing">3</property>
|
||||
<property name="column_spacing">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label84">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_markup" translatable="yes">The object that you want to flip around,
|
||||
usually the Gerber object defining the
|
||||
bottom copper layer. You can also flip
|
||||
an Excellon object in case you want to drill
|
||||
from the bottom side.</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="xpad">3</property>
|
||||
<property name="label" translatable="yes">Bottom Layer:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="comboboxtext_bottomlayer">
|
||||
<property name="width_request">200</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="entry_text_column">0</property>
|
||||
<property name="id_column">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label85">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_markup" translatable="yes"><b>X</b> flips from top to bottom,
|
||||
<b>Y</b> flips from left to right.</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="xpad">3</property>
|
||||
<property name="label" translatable="yes">Mirror Axis:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box24">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="rb_mirror_x">
|
||||
<property name="label" translatable="yes">X</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="rb_mirror_y">
|
||||
<property name="label" translatable="yes">Y</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">rb_mirror_x</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label86">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_markup" translatable="yes">How the location of the axis
|
||||
is specified.</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="xpad">3</property>
|
||||
<property name="label" translatable="yes">Axis location:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box25">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="rb_mirror_point">
|
||||
<property name="label" translatable="yes">Point</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_markup" translatable="yes">The axis must pass through the
|
||||
specified point.</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_toggle_pointbox" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="rb_mirror_box">
|
||||
<property name="label" translatable="yes">Box</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_markup" translatable="yes">The axis cuts a box (some Geometry object
|
||||
in the project) exactly in the middle.</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">rb_mirror_point</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label87">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_markup" translatable="yes"><b>Point:</b> Click on the desired point on the plot.
|
||||
This copies the point to the clipboard. Then paste it
|
||||
in the box by right-clicking and choosing paste, or
|
||||
hitting Control-v.
|
||||
|
||||
<b>Box:</b> Choose an object in the project
|
||||
that you want to use as a box for specifying
|
||||
the flipping axis. If the object is not a rectangle,
|
||||
a bounding box arounf the object is calculated.</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="xpad">3</property>
|
||||
<property name="label" translatable="yes">Point/Box:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box_pointbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label89">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_markup" translatable="yes">List of coordinates where to drill alignment
|
||||
holes, in the format <b>(x1, y1), (x2, y2)</b>, etc.
|
||||
You can click on the plot and paste each
|
||||
coordinate here.
|
||||
|
||||
All <b>coordinates are duplicated</b> and mirrored
|
||||
automatically around the axis so drill pattens are
|
||||
identical when flipping your board around.</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="xpad">3</property>
|
||||
<property name="label" translatable="yes">Algnmt holes:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry_dblsided_alignholes">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label90">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_markup" translatable="yes">Diameter of the drill for
|
||||
the aligment holes.</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="xpad">3</property>
|
||||
<property name="label" translatable="yes">Drill diam.:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry_dblsided_alignholediam">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="invisible_char_set">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box27">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="margin_top">6</property>
|
||||
<property name="margin_bottom">3</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button19">
|
||||
<property name="label" translatable="yes">Create Alignment Drill</property>
|
||||
<property name="width_request">120</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_markup" translatable="yes">Creates an Excellon object with
|
||||
the specified holes and their
|
||||
mirror pairs.</property>
|
||||
<property name="halign">end</property>
|
||||
<signal name="activate" handler="on_create_aligndrill" swapped="no"/>
|
||||
<signal name="clicked" handler="on_create_aligndrill" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">4</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button18">
|
||||
<property name="label" translatable="yes">Mirror Object</property>
|
||||
<property name="width_request">120</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_markup" translatable="yes">Mirrors the object specified in
|
||||
<b>Bottom Layer</b> around the
|
||||
specified axis.</property>
|
||||
<property name="halign">end</property>
|
||||
<signal name="activate" handler="on_create_mirror" swapped="no"/>
|
||||
<signal name="clicked" handler="on_create_mirror" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">4</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkOffscreenWindow" id="offscrwindow_cncjob">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
|
@ -1145,7 +1543,6 @@ after hitting Enter in the text box.</property>
|
|||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="invisible_char_set">True</property>
|
||||
<signal name="activate" handler="on_activate_name" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -2721,404 +3118,6 @@ this object.</property>
|
|||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkOffscreenWindow" id="offscreenwindow_dblsided">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="sw_dblsided">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkViewport" id="vp_dblsided">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box_dblsided">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label53">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_bottom">6</property>
|
||||
<property name="ypad">3</property>
|
||||
<property name="label" translatable="yes">Double-Sided PCB Tool</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="semibold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid7">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="row_spacing">3</property>
|
||||
<property name="column_spacing">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label84">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_markup" translatable="yes">The object that you want to flip around,
|
||||
usually the Gerber object defining the
|
||||
bottom copper layer. You can also flip
|
||||
an Excellon object in case you want to drill
|
||||
from the bottom side.</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="xpad">3</property>
|
||||
<property name="label" translatable="yes">Bottom Layer:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="comboboxtext_bottomlayer">
|
||||
<property name="width_request">200</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="entry_text_column">0</property>
|
||||
<property name="id_column">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label85">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_markup" translatable="yes"><b>X</b> flips from top to bottom,
|
||||
<b>Y</b> flips from left to right.</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="xpad">3</property>
|
||||
<property name="label" translatable="yes">Mirror Axis:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box24">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="rb_mirror_x">
|
||||
<property name="label" translatable="yes">X</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="rb_mirror_y">
|
||||
<property name="label" translatable="yes">Y</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">rb_mirror_x</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label86">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_markup" translatable="yes">How the location of the axis
|
||||
is specified.</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="xpad">3</property>
|
||||
<property name="label" translatable="yes">Axis location:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box25">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="rb_mirror_point">
|
||||
<property name="label" translatable="yes">Point</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_markup" translatable="yes">The axis must pass through the
|
||||
specified point.</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_toggle_pointbox" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="rb_mirror_box">
|
||||
<property name="label" translatable="yes">Box</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_markup" translatable="yes">The axis cuts a box (some Geometry object
|
||||
in the project) exactly in the middle.</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">rb_mirror_point</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label87">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_markup" translatable="yes"><b>Point:</b> Click on the desired point on the plot.
|
||||
This copies the point to the clipboard. Then paste it
|
||||
in the box by right-clicking and choosing paste, or
|
||||
hitting Control-v.
|
||||
|
||||
<b>Box:</b> Choose an object in the project
|
||||
that you want to use as a box for specifying
|
||||
the flipping axis. If the object is not a rectangle,
|
||||
a bounding box arounf the object is calculated.</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="xpad">3</property>
|
||||
<property name="label" translatable="yes">Point/Box:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box_pointbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label89">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_markup" translatable="yes">List of coordinates where to drill alignment
|
||||
holes, in the format <b>(x1, y1), (x2, y2)</b>, etc.
|
||||
You can click on the plot and paste each
|
||||
coordinate here.
|
||||
|
||||
All <b>coordinates are duplicated</b> and mirrored
|
||||
automatically around the axis so drill pattens are
|
||||
identical when flipping your board around.</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="xpad">3</property>
|
||||
<property name="label" translatable="yes">Algnmt holes:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry_dblsided_alignholes">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label90">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_markup" translatable="yes">Diameter of the drill for
|
||||
the aligment holes.</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="xpad">3</property>
|
||||
<property name="label" translatable="yes">Drill diam.:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry_dblsided_alignholediam">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="invisible_char_set">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box27">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="margin_top">6</property>
|
||||
<property name="margin_bottom">3</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button19">
|
||||
<property name="label" translatable="yes">Create Alignment Drill</property>
|
||||
<property name="width_request">120</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_markup" translatable="yes">Creates an Excellon object with
|
||||
the specified holes and their
|
||||
mirror pairs.</property>
|
||||
<property name="halign">end</property>
|
||||
<signal name="activate" handler="on_create_aligndrill" swapped="no"/>
|
||||
<signal name="clicked" handler="on_create_aligndrill" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">4</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button18">
|
||||
<property name="label" translatable="yes">Mirror Object</property>
|
||||
<property name="width_request">120</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_markup" translatable="yes">Mirrors the object specified in
|
||||
<b>Bottom Layer</b> around the
|
||||
specified axis.</property>
|
||||
<property name="halign">end</property>
|
||||
<signal name="activate" handler="on_create_mirror" swapped="no"/>
|
||||
<signal name="clicked" handler="on_create_mirror" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">4</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="width_request">600</property>
|
||||
<property name="height_request">400</property>
|
||||
|
|
|
@ -111,8 +111,8 @@ class FlatCAMObj:
|
|||
# Put in the UI
|
||||
box_selected.pack_start(sw, True, True, 0)
|
||||
|
||||
entry_name = self.app.builder.get_object("entry_text_" + self.kind + "_name")
|
||||
entry_name.connect("activate", self.app.on_activate_name)
|
||||
# entry_name = self.app.builder.get_object("entry_text_" + self.kind + "_name")
|
||||
# entry_name.connect("activate", self.app.on_activate_name)
|
||||
self.to_form()
|
||||
sw.show()
|
||||
|
||||
|
|
26
camlib.py
26
camlib.py
|
@ -2251,16 +2251,35 @@ class CNCjob(Geometry):
|
|||
self.create_geometry()
|
||||
|
||||
|
||||
def get_bounds(geometry_set):
|
||||
# def get_bounds(geometry_set):
|
||||
# xmin = Inf
|
||||
# ymin = Inf
|
||||
# xmax = -Inf
|
||||
# ymax = -Inf
|
||||
#
|
||||
# #print "Getting bounds of:", str(geometry_set)
|
||||
# for gs in geometry_set:
|
||||
# try:
|
||||
# gxmin, gymin, gxmax, gymax = geometry_set[gs].bounds()
|
||||
# xmin = min([xmin, gxmin])
|
||||
# ymin = min([ymin, gymin])
|
||||
# xmax = max([xmax, gxmax])
|
||||
# ymax = max([ymax, gymax])
|
||||
# except:
|
||||
# print "DEV WARNING: Tried to get bounds of empty geometry."
|
||||
#
|
||||
# return [xmin, ymin, xmax, ymax]
|
||||
|
||||
def get_bounds(geometry_list):
|
||||
xmin = Inf
|
||||
ymin = Inf
|
||||
xmax = -Inf
|
||||
ymax = -Inf
|
||||
|
||||
#print "Getting bounds of:", str(geometry_set)
|
||||
for gs in geometry_set:
|
||||
for gs in geometry_list:
|
||||
try:
|
||||
gxmin, gymin, gxmax, gymax = geometry_set[gs].bounds()
|
||||
gxmin, gymin, gxmax, gymax = gs.bounds()
|
||||
xmin = min([xmin, gxmin])
|
||||
ymin = min([ymin, gymin])
|
||||
xmax = max([xmax, gxmax])
|
||||
|
@ -2270,7 +2289,6 @@ def get_bounds(geometry_set):
|
|||
|
||||
return [xmin, ymin, xmax, ymax]
|
||||
|
||||
|
||||
def arc(center, radius, start, stop, direction, steps_per_circ):
|
||||
"""
|
||||
Creates a list of point along the specified arc.
|
||||
|
|
|
@ -1 +1 @@
|
|||
[{"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\BLDC2003Through.drl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\Project Outputs for RTWO1\\PCB1.GTL"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\BLDC_1303_Bottom.gbr"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\PlacaReles.drl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\PlacaReles-F_Cu.gtl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\Example1_copper_bottom.gbr"}, {"kind": "cncjob", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\RTWO1_CNC\\cutout1.gcode"}, {"kind": "project", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\RTWO1.fcproj"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\Project Outputs for RTWO1\\PCB1.TXT"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\Project Outputs for RTWO1\\PCB1.DRL"}]
|
||||
[{"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\Project Outputs for RTWO1\\PCB1.GBL"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\BLDC2003Through.drl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\Project Outputs for RTWO1\\PCB1.GTL"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\BLDC_1303_Bottom.gbr"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\PlacaReles.drl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\PlacaReles-F_Cu.gtl"}, {"kind": "gerber", "filename": "C:\\Users\\jpcaram\\Dropbox\\CNC\\pcbcam\\test_files\\Example1_copper_bottom.gbr"}, {"kind": "cncjob", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\RTWO1_CNC\\cutout1.gcode"}, {"kind": "project", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\RTWO1.fcproj"}, {"kind": "excellon", "filename": "C:\\Users\\jpcaram\\Dropbox\\PhD\\PLLs\\RTWO\\Project Outputs for RTWO1\\PCB1.TXT"}]
|
Loading…
Reference in New Issue