Merge remote-tracking branch 'remotes/jpcgt/flatcam/Beta' into Beta
This commit is contained in:
commit
70e939ca36
486
FlatCAMApp.py
486
FlatCAMApp.py
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,11 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
|
||||
class LoudDict(dict):
|
||||
"""
|
||||
|
|
102
FlatCAMObj.py
102
FlatCAMObj.py
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
import copy
|
||||
import inspect # TODO: For debugging only.
|
||||
|
@ -36,7 +36,7 @@ class ValidationError(Exception):
|
|||
self.errors = errors
|
||||
|
||||
# ##################################### ##
|
||||
# # FlatCAMObj ##
|
||||
# # FlatCAMObj # ##
|
||||
# ##################################### ##
|
||||
|
||||
|
||||
|
@ -90,6 +90,8 @@ class FlatCAMObj(QtCore.QObject):
|
|||
self.isHovering = False
|
||||
self.notHovering = True
|
||||
|
||||
self.units = 'IN'
|
||||
|
||||
# assert isinstance(self.ui, ObjectUI)
|
||||
# self.ui.name_entry.returnPressed.connect(self.on_name_activate)
|
||||
# self.ui.offset_button.clicked.connect(self.on_offset_button_click)
|
||||
|
@ -135,8 +137,7 @@ class FlatCAMObj(QtCore.QObject):
|
|||
if key == 'plot':
|
||||
self.visible = self.options['plot']
|
||||
|
||||
# self.emit(QtCore.SIGNAL("optionChanged"), key)
|
||||
self.optionChanged.emit(key)
|
||||
# self.optionChanged.emit(key)
|
||||
|
||||
def set_ui(self, ui):
|
||||
self.ui = ui
|
||||
|
@ -296,8 +297,6 @@ class FlatCAMObj(QtCore.QObject):
|
|||
return False
|
||||
|
||||
self.clear()
|
||||
|
||||
|
||||
return True
|
||||
|
||||
def serialize(self):
|
||||
|
@ -340,14 +339,19 @@ class FlatCAMObj(QtCore.QObject):
|
|||
|
||||
@visible.setter
|
||||
def visible(self, value):
|
||||
self.shapes.visible = value
|
||||
log.debug("FlatCAMObj.visible()")
|
||||
|
||||
def worker_task(app_obj):
|
||||
app_obj.shapes.visible = value
|
||||
|
||||
# Not all object types has annotations
|
||||
try:
|
||||
self.annotation.visible = value
|
||||
except AttributeError:
|
||||
app_obj.annotation.visible = value
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
self.app.worker_task.emit({'fcn': worker_task, 'params': [self]})
|
||||
|
||||
@property
|
||||
def drawing_tolerance(self):
|
||||
return self._drawing_tolerance if self.units == 'MM' or not self.units else self._drawing_tolerance / 25.4
|
||||
|
@ -365,12 +369,6 @@ class FlatCAMObj(QtCore.QObject):
|
|||
except AttributeError:
|
||||
pass
|
||||
|
||||
# Not all object types have mark_shapes
|
||||
# try:
|
||||
# self.mark_shapes.clear(update)
|
||||
# except AttributeError:
|
||||
# pass
|
||||
|
||||
def delete(self):
|
||||
# Free resources
|
||||
del self.ui
|
||||
|
@ -1053,7 +1051,6 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
:param kwargs: color and face_color
|
||||
:return:
|
||||
"""
|
||||
|
||||
FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + " --> FlatCAMGerber.plot()")
|
||||
|
||||
# Does all the required setup and returns False
|
||||
|
@ -1065,6 +1062,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
color = kwargs['color']
|
||||
else:
|
||||
color = self.app.defaults['global_plot_line']
|
||||
|
||||
if 'face_color' in kwargs:
|
||||
face_color = kwargs['face_color']
|
||||
else:
|
||||
|
@ -1078,7 +1076,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
|
||||
# Make sure geometry is iterable.
|
||||
try:
|
||||
_ = iter(geometry)
|
||||
__ = iter(geometry)
|
||||
except TypeError:
|
||||
geometry = [geometry]
|
||||
|
||||
|
@ -2795,7 +2793,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
|
||||
# this stays for compatibility reasons, in case we try to open old projects
|
||||
try:
|
||||
_ = iter(self.solid_geometry)
|
||||
__ = iter(self.solid_geometry)
|
||||
except TypeError:
|
||||
self.solid_geometry = [self.solid_geometry]
|
||||
|
||||
|
@ -2932,18 +2930,18 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
"""
|
||||
pts = []
|
||||
|
||||
## Iterable: descend into each item.
|
||||
# Iterable: descend into each item.
|
||||
try:
|
||||
for subo in o:
|
||||
pts += FlatCAMGeometry.get_pts(subo)
|
||||
|
||||
## Non-iterable
|
||||
# Non-iterable
|
||||
except TypeError:
|
||||
if o is not None:
|
||||
if type(o) == MultiPolygon:
|
||||
for poly in o:
|
||||
pts += FlatCAMGeometry.get_pts(poly)
|
||||
## Descend into .exerior and .interiors
|
||||
# ## Descend into .exerior and .interiors
|
||||
elif type(o) == Polygon:
|
||||
pts += FlatCAMGeometry.get_pts(o.exterior)
|
||||
for i in o.interiors:
|
||||
|
@ -2951,7 +2949,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
elif type(o) == MultiLineString:
|
||||
for line in o:
|
||||
pts += FlatCAMGeometry.get_pts(line)
|
||||
## Has .coords: list them.
|
||||
# ## Has .coords: list them.
|
||||
else:
|
||||
pts += list(o.coords)
|
||||
else:
|
||||
|
@ -3033,6 +3031,12 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
# engine of FlatCAM. Most likely are generated by some of tools and are special cases of geometries.
|
||||
self. special_group = None
|
||||
|
||||
self.old_pp_state = ''
|
||||
self.old_toolchangeg_state = ''
|
||||
|
||||
# store here the default data for Geometry Data
|
||||
self.default_data = {}
|
||||
|
||||
# Attributes to be included in serialization
|
||||
# Always append to it because it carries contents
|
||||
# from predecessors.
|
||||
|
@ -3391,11 +3395,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
try:
|
||||
# works for CheckBoxes
|
||||
self.ui.grid3.itemAt(i).widget().stateChanged.connect(self.gui_form_to_storage)
|
||||
except:
|
||||
except Exception as e:
|
||||
# works for ComboBoxes
|
||||
try:
|
||||
self.ui.grid3.itemAt(i).widget().currentIndexChanged.connect(self.gui_form_to_storage)
|
||||
except:
|
||||
except Exception as e2:
|
||||
# works for Entry
|
||||
try:
|
||||
self.ui.grid3.itemAt(i).widget().editingFinished.connect(self.gui_form_to_storage)
|
||||
|
@ -3492,13 +3496,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
def on_tool_add(self, dia=None):
|
||||
self.ui_disconnect()
|
||||
|
||||
last_offset = None
|
||||
last_offset_value = None
|
||||
last_type = None
|
||||
last_tool_type = None
|
||||
last_data = None
|
||||
last_solid_geometry = []
|
||||
|
||||
# if a Tool diameter entered is a char instead a number the final message of Tool adding is changed
|
||||
# because the Default value for Tool is used.
|
||||
change_message = False
|
||||
|
@ -3547,7 +3544,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.tools.update({
|
||||
self.tooluid: {
|
||||
'tooldia': tooldia,
|
||||
'offset': ('Path'),
|
||||
'offset': 'Path',
|
||||
'offset_value': 0.0,
|
||||
'type': _('Rough'),
|
||||
'tool_type': 'C1',
|
||||
|
@ -3556,7 +3553,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
}
|
||||
})
|
||||
else:
|
||||
# print("LAST", self.tools[maxuid])
|
||||
last_data = self.tools[max_uid]['data']
|
||||
last_offset = self.tools[max_uid]['offset']
|
||||
last_offset_value = self.tools[max_uid]['offset_value']
|
||||
|
@ -3580,7 +3576,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
'solid_geometry': deepcopy(last_solid_geometry)
|
||||
}
|
||||
})
|
||||
# print("CURRENT", self.tools[-1])
|
||||
|
||||
self.ui.tool_offset_entry.hide()
|
||||
self.ui.tool_offset_lbl.hide()
|
||||
|
@ -4277,6 +4272,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
# Object initialization function for app.new_object()
|
||||
# RUNNING ON SEPARATE THREAD!
|
||||
def job_init_single_geometry(job_obj, app_obj):
|
||||
log.debug("Creating a CNCJob out of a single-geometry")
|
||||
|
||||
assert isinstance(job_obj, FlatCAMCNCjob), \
|
||||
"Initializer expected a FlatCAMCNCjob, got %s" % type(job_obj)
|
||||
|
||||
|
@ -4451,8 +4448,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
|
||||
app_obj.progress.emit(40)
|
||||
|
||||
tol = float(self.app.defaults['global_tolerance'])
|
||||
res = job_obj.generate_from_geometry_2(
|
||||
self, tooldia=tooldia_val, offset=tool_offset, tolerance=0.0005,
|
||||
self, tooldia=tooldia_val, offset=tool_offset, tolerance=tol,
|
||||
z_cut=z_cut, z_move=z_move,
|
||||
feedrate=feedrate, feedrate_z=feedrate_z, feedrate_rapid=feedrate_rapid,
|
||||
spindlespeed=spindlespeed, spindledir=spindledir, dwell=dwell, dwelltime=dwelltime,
|
||||
|
@ -4488,6 +4486,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
# Object initialization function for app.new_object()
|
||||
# RUNNING ON SEPARATE THREAD!
|
||||
def job_init_multi_geometry(job_obj, app_obj):
|
||||
log.debug("Creating a CNCJob out of a multi-geometry")
|
||||
|
||||
assert isinstance(job_obj, FlatCAMCNCjob), \
|
||||
"Initializer expected a FlatCAMCNCjob, got %s" % type(job_obj)
|
||||
|
||||
|
@ -4682,9 +4682,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
spindledir = self.app.defaults['geometry_spindledir']
|
||||
|
||||
tool_solid_geometry = self.tools[current_uid]['solid_geometry']
|
||||
tol = float(self.app.defaults['global_tolerance'])
|
||||
res = job_obj.generate_from_multitool_geometry(
|
||||
tool_solid_geometry, tooldia=tooldia_val, offset=tool_offset,
|
||||
tolerance=0.0005, z_cut=z_cut, z_move=z_move,
|
||||
tolerance=tol, z_cut=z_cut, z_move=z_move,
|
||||
feedrate=feedrate, feedrate_z=feedrate_z, feedrate_rapid=feedrate_rapid,
|
||||
spindlespeed=spindlespeed, spindledir=spindledir, dwell=dwell, dwelltime=dwelltime,
|
||||
multidepth=multidepth, depthpercut=depthpercut,
|
||||
|
@ -4741,7 +4742,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
else:
|
||||
self.app.new_object("cncjob", outname, job_init_multi_geometry)
|
||||
|
||||
|
||||
def generatecncjob(self, outname=None,
|
||||
tooldia=None, offset=None,
|
||||
z_cut=None, z_move=None,
|
||||
|
@ -4850,8 +4850,13 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
'or self.options["feedrate_probe"]'
|
||||
))
|
||||
|
||||
# TODO: The tolerance should not be hard coded. Just for testing.
|
||||
job_obj.generate_from_geometry_2(self, tooldia=tooldia, offset=offset, tolerance=0.0005,
|
||||
job_obj.options['xmin'] = self.options['xmin']
|
||||
job_obj.options['ymin'] = self.options['ymin']
|
||||
job_obj.options['xmax'] = self.options['xmax']
|
||||
job_obj.options['ymax'] = self.options['ymax']
|
||||
|
||||
tol = float(self.app.defaults['global_tolerance'])
|
||||
job_obj.generate_from_geometry_2(self, tooldia=tooldia, offset=offset, tolerance=tol,
|
||||
z_cut=z_cut, z_move=z_move,
|
||||
feedrate=feedrate, feedrate_z=feedrate_z, feedrate_rapid=feedrate_rapid,
|
||||
spindlespeed=spindlespeed, dwell=dwell, dwelltime=dwelltime,
|
||||
|
@ -5464,6 +5469,15 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
# set the kind of geometries are plotted by default with plot2() from camlib.CNCJob
|
||||
self.ui.cncplot_method_combo.set_value(self.app.defaults["cncjob_plot_kind"])
|
||||
|
||||
try:
|
||||
self.ui.annotation_cb.stateChanged.disconnect(self.on_annotation_change)
|
||||
except:
|
||||
pass
|
||||
self.ui.annotation_cb.stateChanged.connect(self.on_annotation_change)
|
||||
|
||||
# set if to display text annotations
|
||||
self.ui.annotation_cb.set_value(self.app.defaults["cncjob_annotation"])
|
||||
|
||||
# Show/Hide Advanced Options
|
||||
if self.app.defaults["global_app_level"] == 'b':
|
||||
self.ui.level.setText(_(
|
||||
|
@ -5913,6 +5927,14 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
self.shapes.clear(update=True)
|
||||
self.annotation.clear(update=True)
|
||||
|
||||
def on_annotation_change(self):
|
||||
if self.ui.annotation_cb.get_value():
|
||||
self.app.plotcanvas.text_collection.enabled = True
|
||||
else:
|
||||
self.app.plotcanvas.text_collection.enabled = False
|
||||
kind = self.ui.cncplot_method_combo.get_value()
|
||||
self.plot(kind=kind)
|
||||
|
||||
def convert_units(self, units):
|
||||
factor = CNCjob.convert_units(self, units)
|
||||
FlatCAMApp.App.log.debug("FlatCAMCNCjob.convert_units()")
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Matthieu Berthomé #
|
||||
# Date: 5/26/2017 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from importlib.machinery import SourceFileLoader
|
||||
import os
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from flatcamGUI.FlatCAMGUI import FlatCAMActivityView
|
||||
from PyQt5 import QtCore
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from PyQt5 import QtGui, QtCore, QtWidgets, QtWidgets
|
||||
from PyQt5.QtCore import Qt
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
# File modified by: Dennis Hayrullin #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
# from PyQt5.QtCore import QModelIndex
|
||||
from FlatCAMObj import *
|
||||
|
@ -20,9 +20,9 @@ from PyQt5.QtCore import Qt
|
|||
|
||||
import gettext
|
||||
import FlatCAMTranslation as fcTranslate
|
||||
import builtins
|
||||
|
||||
fcTranslate.apply_language('strings')
|
||||
import builtins
|
||||
if '_' not in builtins.__dict__:
|
||||
_ = gettext.gettext
|
||||
|
||||
|
@ -261,7 +261,7 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
font.setFamily("Seagoe UI")
|
||||
self.view.setFont(font)
|
||||
|
||||
## GUI Events
|
||||
# ## GUI Events
|
||||
self.view.selectionModel().selectionChanged.connect(self.on_list_selection_change)
|
||||
self.view.activated.connect(self.on_item_activated)
|
||||
# self.view.keyPressed.connect(self.on_key)
|
||||
|
@ -399,11 +399,11 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
if index.isValid():
|
||||
obj = index.internalPointer().obj
|
||||
if obj:
|
||||
old_name = str(obj.options['name'])
|
||||
old_name = obj.options['name']
|
||||
new_name = str(data)
|
||||
if old_name != new_name and new_name != '':
|
||||
# rename the object
|
||||
obj.options["name"] = str(data)
|
||||
obj.options["name"] = deepcopy(data)
|
||||
|
||||
# update the SHELL auto-completer model data
|
||||
try:
|
||||
|
@ -411,11 +411,12 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
self.app.myKeywords.append(new_name)
|
||||
self.app.shell._edit.set_model_data(self.app.myKeywords)
|
||||
self.app.ui.code_editor.set_model_data(self.app.myKeywords)
|
||||
except:
|
||||
except Exception as e:
|
||||
log.debug(
|
||||
"setData() --> Could not remove the old object name from auto-completer model list")
|
||||
"setData() --> Could not remove the old object name from auto-completer model list. %s" %
|
||||
str(e))
|
||||
|
||||
obj.build_ui()
|
||||
# obj.build_ui()
|
||||
self.app.inform.emit(_("Object renamed from <b>{old}</b> to <b>{new}</b>").format(old=old_name,
|
||||
new=new_name))
|
||||
|
||||
|
@ -452,7 +453,7 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
|
||||
# Prevent same name
|
||||
while name in self.get_names():
|
||||
## Create a new name
|
||||
# ## Create a new name
|
||||
# Ends with number?
|
||||
FlatCAMApp.App.log.debug("new_object(): Object name (%s) exists, changing." % name)
|
||||
match = re.search(r'(.*[^\d])?(\d+)$', name)
|
||||
|
@ -525,8 +526,8 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
ymin = min([ymin, gymin])
|
||||
xmax = max([xmax, gxmax])
|
||||
ymax = max([ymax, gymax])
|
||||
except:
|
||||
FlatCAMApp.App.log.warning("DEV WARNING: Tried to get bounds of empty geometry.")
|
||||
except Exception as e:
|
||||
FlatCAMApp.App.log.warning("DEV WARNING: Tried to get bounds of empty geometry. %s" % str(e))
|
||||
|
||||
return [xmin, ymin, xmax, ymax]
|
||||
|
||||
|
@ -536,12 +537,12 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
|
||||
:param name: The name of the object.
|
||||
:type name: str
|
||||
:param isCaseSensitive: whether searching of the object is done by name where the name is case sensitive
|
||||
: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()")
|
||||
|
||||
|
||||
if isCaseSensitive is None or isCaseSensitive is True:
|
||||
for obj in self.get_list():
|
||||
if obj.options['name'] == name:
|
||||
|
@ -569,10 +570,9 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
self.app.myKeywords.remove(name)
|
||||
self.app.shell._edit.set_model_data(self.app.myKeywords)
|
||||
self.app.ui.code_editor.set_model_data(self.app.myKeywords)
|
||||
except:
|
||||
except Exception as e:
|
||||
log.debug(
|
||||
"delete_active() --> Could not remove the old object name from auto-completer model list")
|
||||
|
||||
"delete_active() --> Could not remove the old object name from auto-completer model list. %s" % str(e))
|
||||
|
||||
self.beginRemoveRows(self.index(group.row(), 0, QtCore.QModelIndex()), active.row(), active.row())
|
||||
|
||||
|
@ -649,12 +649,12 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
:return: List of objects
|
||||
"""
|
||||
|
||||
l = self.get_list()
|
||||
obj_list = self.get_list()
|
||||
|
||||
for sel in self.get_selected():
|
||||
l.remove(sel)
|
||||
obj_list.remove(sel)
|
||||
|
||||
return l
|
||||
return obj_list
|
||||
|
||||
def set_active(self, name):
|
||||
"""
|
||||
|
@ -731,8 +731,8 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
self.app.inform.emit('')
|
||||
try:
|
||||
self.app.ui.selected_scroll_area.takeWidget()
|
||||
except:
|
||||
FlatCAMApp.App.log.debug("Nothing to remove")
|
||||
except Exception as e:
|
||||
FlatCAMApp.App.log.debug("Nothing to remove. %s" % str(e))
|
||||
|
||||
self.app.setup_component_editor()
|
||||
return
|
||||
|
|
65
README.md
65
README.md
|
@ -9,12 +9,77 @@ CAD program, and create G-Code for Isolation routing.
|
|||
|
||||
=================================================
|
||||
|
||||
7.06.2019
|
||||
|
||||
- fixed bug in ToolCutout where creating a cutout object geometry from another external isolation geometry failed
|
||||
- fixed bug in cncjob TclCommand where the gcode could not be correctly generated due of missing bounds params in obj.options dict
|
||||
- fixed a hardcoded tolerance in FlatCAMGeometry.generatecncjob() and in FlatCAMGeometry.mtool_gen_cncjob() to use the parameter from Preferences
|
||||
- updated translations
|
||||
- RELEASE 8.918
|
||||
|
||||
5.06.2019
|
||||
|
||||
- updated translations
|
||||
- some layout changes in Edit -> Preferences such that the German translation (longer words than English) to fit correctly
|
||||
- after editing an parameter the focus is lost so the user knows that something happened
|
||||
|
||||
4.06.2019
|
||||
|
||||
- PEP8 updates in FlatCAMExcEditor.py
|
||||
- added the Excellon Editor parameters to the Edit -> Preferences -> Excellon GUI
|
||||
- fixed a small bug in Excellon Editor
|
||||
- PEP8 cleanup in FlatCAMGui
|
||||
- finished adding the Excellon Editor parameters into the app logic and added a selection limit within Excellon Editor just like in the other editors
|
||||
|
||||
3.06.2019
|
||||
|
||||
- TclCommand Geocutout is now creating a new geometry object when working on a geometry, preserving also the origin object
|
||||
- added a new parameter in Edit -> Preferences -> CNCJob named Annotation Color; it controls the color of the font used for annotations
|
||||
- added a new parameter in Edit -> Preferences -> CNCJob named Annotation Size; it controls the size of the font used for annotations
|
||||
- made visibility change threaded in FlatCAMObj()
|
||||
|
||||
2.06.2019
|
||||
|
||||
- fixed issue with geometry name not being updated immediately after change while doing geocutout TclCommand
|
||||
- some changes to enable/disable project context menu entry handlers
|
||||
|
||||
1.06.2019
|
||||
|
||||
- fixed text annotation for CNC job so there are no overlapping numbers when 2 lines meet on the same point
|
||||
- fixed issue in CNC job plotting where some of the isolation polygons are painted incorrectly
|
||||
- fixed issue in CNCJob where the set circle steps is not used
|
||||
|
||||
31.05.2019
|
||||
|
||||
- added the possibility to display text annotation for the CNC travel lines. The setting is both in Preferences and in the CNC object properties
|
||||
|
||||
30.05.2019
|
||||
|
||||
- editing a multi geometry will no longer pop-up a Tcl window
|
||||
- solved issue #292 where a new geometry renamed with many underscores failed to store the name in a saved project
|
||||
- the name for the saved projects are updated to the current time and not to the time of the app startup
|
||||
- some PEP8 changes related to comments starting with only one '#' symbol
|
||||
- more PEP8 cleanup
|
||||
- solved issue where after the opening of an object the file path is not saved for further open operations
|
||||
|
||||
24.05.2019
|
||||
|
||||
- added a toggle Grid button to the canvas context menu in the Grids submenu
|
||||
- added a toggle left panel button to the canvas context menu
|
||||
|
||||
23.05.2019
|
||||
|
||||
- fixed bug in Gerber editor FCDisk and FCSemiDisc that the resulting geometry was not stored into the '0' aperture where all the solids are stored
|
||||
- fixed minor issue in Gerber Editor where apertures were included in the saved object even if there was no geometric data for that aperture
|
||||
- some PEP8 cleanup in FlatCAMApp.py
|
||||
|
||||
22.05.2019
|
||||
|
||||
- Geo Editor - added a new editor tool, Eraser
|
||||
- some PEP8 cleanup of the Geo Editor
|
||||
- fixed some selection issues in the new tool Eraser in Geometry Editor
|
||||
- updated the translation files
|
||||
- RELEASE 8.917
|
||||
|
||||
21.05.2019
|
||||
|
||||
|
|
218
camlib.py
218
camlib.py
|
@ -1,12 +1,11 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
#import traceback
|
||||
|
||||
from io import StringIO
|
||||
|
||||
|
@ -58,6 +57,12 @@ if platform.architecture()[0] == '64bit':
|
|||
from ortools.constraint_solver import pywrapcp
|
||||
from ortools.constraint_solver import routing_enums_pb2
|
||||
|
||||
import gettext
|
||||
import FlatCAMTranslation as fcTranslate
|
||||
|
||||
fcTranslate.apply_language('strings')
|
||||
import builtins
|
||||
|
||||
log = logging.getLogger('base2')
|
||||
log.setLevel(logging.DEBUG)
|
||||
|
||||
|
@ -66,11 +71,6 @@ handler = logging.StreamHandler()
|
|||
handler.setFormatter(formatter)
|
||||
log.addHandler(handler)
|
||||
|
||||
import gettext
|
||||
import FlatCAMTranslation as fcTranslate
|
||||
|
||||
fcTranslate.apply_language('strings')
|
||||
import builtins
|
||||
if '_' not in builtins.__dict__:
|
||||
_ = gettext.gettext
|
||||
|
||||
|
@ -132,21 +132,20 @@ class Geometry(object):
|
|||
:param radius: Radius of the circle.
|
||||
:return: None
|
||||
"""
|
||||
# TODO: Decide what solid_geometry is supposed to be and how we append to it.
|
||||
|
||||
if self.solid_geometry is None:
|
||||
self.solid_geometry = []
|
||||
|
||||
if type(self.solid_geometry) is list:
|
||||
self.solid_geometry.append(Point(origin).buffer(radius, int(int(self.geo_steps_per_circle) / 4)))
|
||||
self.solid_geometry.append(Point(origin).buffer(
|
||||
radius, int(int(self.geo_steps_per_circle) / 4)))
|
||||
return
|
||||
|
||||
try:
|
||||
self.solid_geometry = self.solid_geometry.union(Point(origin).buffer(radius,
|
||||
int(int(self.geo_steps_per_circle) / 4)))
|
||||
except:
|
||||
#print "Failed to run union on polygons."
|
||||
log.error("Failed to run union on polygons.")
|
||||
self.solid_geometry = self.solid_geometry.union(Point(origin).buffer(
|
||||
radius, int(int(self.geo_steps_per_circle) / 4)))
|
||||
except Exception as e:
|
||||
log.error("Failed to run union on polygons. %s" % str(e))
|
||||
return
|
||||
|
||||
def add_polygon(self, points):
|
||||
|
@ -165,9 +164,8 @@ class Geometry(object):
|
|||
|
||||
try:
|
||||
self.solid_geometry = self.solid_geometry.union(Polygon(points))
|
||||
except:
|
||||
#print "Failed to run union on polygons."
|
||||
log.error("Failed to run union on polygons.")
|
||||
except Exception as e:
|
||||
log.error("Failed to run union on polygons. %s" % str(e))
|
||||
return
|
||||
|
||||
def add_polyline(self, points):
|
||||
|
@ -186,13 +184,11 @@ class Geometry(object):
|
|||
|
||||
try:
|
||||
self.solid_geometry = self.solid_geometry.union(LineString(points))
|
||||
except:
|
||||
#print "Failed to run union on polygons."
|
||||
log.error("Failed to run union on polylines.")
|
||||
except Exception as e:
|
||||
log.error("Failed to run union on polylines. %s" % str(e))
|
||||
return
|
||||
|
||||
def is_empty(self):
|
||||
|
||||
if isinstance(self.solid_geometry, BaseGeometry):
|
||||
return self.solid_geometry.is_empty
|
||||
|
||||
|
@ -336,7 +332,8 @@ class Geometry(object):
|
|||
poly, which can can be iterable, contain iterable of, or
|
||||
be itself an implementer of .contains().
|
||||
|
||||
:param poly: See description
|
||||
:param point: See description
|
||||
:param geoset: a polygon or list of polygons where to find if the param point is contained
|
||||
:return: Polygon containing point or None.
|
||||
"""
|
||||
|
||||
|
@ -366,12 +363,12 @@ class Geometry(object):
|
|||
if geometry is None:
|
||||
geometry = self.solid_geometry
|
||||
|
||||
## If iterable, expand recursively.
|
||||
# ## If iterable, expand recursively.
|
||||
try:
|
||||
for geo in geometry:
|
||||
interiors.extend(self.get_interiors(geometry=geo))
|
||||
|
||||
## Not iterable, get the interiors if polygon.
|
||||
# ## Not iterable, get the interiors if polygon.
|
||||
except TypeError:
|
||||
if type(geometry) == Polygon:
|
||||
interiors.extend(geometry.interiors)
|
||||
|
@ -393,12 +390,12 @@ class Geometry(object):
|
|||
if geometry is None:
|
||||
geometry = self.solid_geometry
|
||||
|
||||
## If iterable, expand recursively.
|
||||
# ## If iterable, expand recursively.
|
||||
try:
|
||||
for geo in geometry:
|
||||
exteriors.extend(self.get_exteriors(geometry=geo))
|
||||
|
||||
## Not iterable, get the exterior if polygon.
|
||||
# ## Not iterable, get the exterior if polygon.
|
||||
except TypeError:
|
||||
if type(geometry) == Polygon:
|
||||
exteriors.append(geometry.exterior)
|
||||
|
@ -423,7 +420,7 @@ class Geometry(object):
|
|||
if reset:
|
||||
self.flat_geometry = []
|
||||
|
||||
## If iterable, expand recursively.
|
||||
# ## If iterable, expand recursively.
|
||||
try:
|
||||
for geo in geometry:
|
||||
if geo is not None:
|
||||
|
@ -431,7 +428,7 @@ class Geometry(object):
|
|||
reset=False,
|
||||
pathonly=pathonly)
|
||||
|
||||
## Not iterable, do the actual indexing and add.
|
||||
# ## Not iterable, do the actual indexing and add.
|
||||
except TypeError:
|
||||
if pathonly and type(geometry) == Polygon:
|
||||
self.flat_geometry.append(geometry.exterior)
|
||||
|
@ -480,18 +477,18 @@ class Geometry(object):
|
|||
# if reset:
|
||||
# self.flat_geometry = []
|
||||
#
|
||||
# ## If iterable, expand recursively.
|
||||
# # ## If iterable, expand recursively.
|
||||
# try:
|
||||
# for geo in geometry:
|
||||
# self.flatten_to_paths(geometry=geo, reset=False)
|
||||
#
|
||||
# ## Not iterable, do the actual indexing and add.
|
||||
# # ## Not iterable, do the actual indexing and add.
|
||||
# except TypeError:
|
||||
# if type(geometry) == Polygon:
|
||||
# g = geometry.exterior
|
||||
# self.flat_geometry.append(g)
|
||||
#
|
||||
# ## Add first and last points of the path to the index.
|
||||
# # ## Add first and last points of the path to the index.
|
||||
# self.flat_geometry_rtree.insert(len(self.flat_geometry) - 1, g.coords[0])
|
||||
# self.flat_geometry_rtree.insert(len(self.flat_geometry) - 1, g.coords[-1])
|
||||
#
|
||||
|
@ -694,7 +691,6 @@ class Geometry(object):
|
|||
else:
|
||||
scale_factor = 1 / dpi
|
||||
|
||||
|
||||
geos = []
|
||||
unscaled_geos = []
|
||||
|
||||
|
@ -807,7 +803,7 @@ class Geometry(object):
|
|||
assert type(polygon) == Polygon or type(polygon) == MultiPolygon, \
|
||||
"Expected a Polygon or MultiPolygon, got %s" % type(polygon)
|
||||
|
||||
## The toolpaths
|
||||
# ## The toolpaths
|
||||
# Index first and last points in paths
|
||||
def get_pts(o):
|
||||
return [o.coords[0], o.coords[-1]]
|
||||
|
@ -893,7 +889,7 @@ class Geometry(object):
|
|||
# Current buffer radius
|
||||
radius = tooldia / 2 * (1 - overlap)
|
||||
|
||||
## The toolpaths
|
||||
# ## The toolpaths
|
||||
# Index first and last points in paths
|
||||
def get_pts(o):
|
||||
return [o.coords[0], o.coords[-1]]
|
||||
|
@ -973,7 +969,7 @@ class Geometry(object):
|
|||
|
||||
# log.debug("camlib.clear_polygon3()")
|
||||
|
||||
## The toolpaths
|
||||
# ## The toolpaths
|
||||
# Index first and last points in paths
|
||||
def get_pts(o):
|
||||
return [o.coords[0], o.coords[-1]]
|
||||
|
@ -1071,7 +1067,7 @@ class Geometry(object):
|
|||
|
||||
# Assuming geolist is a flat list of flat elements
|
||||
|
||||
## Index first and last points in paths
|
||||
# ## Index first and last points in paths
|
||||
def get_pts(o):
|
||||
return [o.coords[0], o.coords[-1]]
|
||||
|
||||
|
@ -1085,7 +1081,7 @@ class Geometry(object):
|
|||
# storage.insert(LineString(shape))
|
||||
# #storage.insert(shape)
|
||||
|
||||
## Iterate over geometry paths getting the nearest each time.
|
||||
# ## Iterate over geometry paths getting the nearest each time.
|
||||
#optimized_paths = []
|
||||
optimized_paths = FlatCAMRTreeStorage()
|
||||
optimized_paths.get_points = get_pts
|
||||
|
@ -1159,7 +1155,7 @@ class Geometry(object):
|
|||
|
||||
log.debug("path_connect()")
|
||||
|
||||
## Index first and last points in paths
|
||||
# ## Index first and last points in paths
|
||||
def get_pts(o):
|
||||
return [o.coords[0], o.coords[-1]]
|
||||
#
|
||||
|
@ -1180,11 +1176,7 @@ class Geometry(object):
|
|||
try:
|
||||
while True:
|
||||
path_count += 1
|
||||
|
||||
#print "geo is", geo
|
||||
|
||||
_, left = storage.nearest(geo.coords[0])
|
||||
#print "left is", left
|
||||
|
||||
# If left touches geo, remove left from original
|
||||
# storage and append to geo.
|
||||
|
@ -1210,7 +1202,6 @@ class Geometry(object):
|
|||
continue
|
||||
|
||||
_, right = storage.nearest(geo.coords[-1])
|
||||
#print "right is", right
|
||||
|
||||
# If right touches geo, remove left from original
|
||||
# storage and append to geo.
|
||||
|
@ -1243,7 +1234,7 @@ class Geometry(object):
|
|||
if type(right) == LinearRing:
|
||||
optimized_geometry.insert(right)
|
||||
else:
|
||||
# Cannot exteng geo any further. Put it away.
|
||||
# Cannot extend geo any further. Put it away.
|
||||
optimized_geometry.insert(geo)
|
||||
|
||||
# Continue with right.
|
||||
|
@ -1288,7 +1279,7 @@ class Geometry(object):
|
|||
|
||||
def to_dict(self):
|
||||
"""
|
||||
Returns a respresentation of the object as a dictionary.
|
||||
Returns a representation of the object as a dictionary.
|
||||
Attributes to include are listed in ``self.ser_attrs``.
|
||||
|
||||
:return: A dictionary-encoded copy of the object.
|
||||
|
@ -1485,7 +1476,7 @@ class ApertureMacro:
|
|||
<Comment>: 0 <Text>
|
||||
"""
|
||||
|
||||
## Regular expressions
|
||||
# ## Regular expressions
|
||||
am1_re = re.compile(r'^%AM([^\*]+)\*(.+)?(%)?$')
|
||||
am2_re = re.compile(r'(.*)%$')
|
||||
amcomm_re = re.compile(r'^0(.*)')
|
||||
|
@ -1496,8 +1487,8 @@ class ApertureMacro:
|
|||
self.name = name
|
||||
self.raw = ""
|
||||
|
||||
## These below are recomputed for every aperture
|
||||
## definition, in other words, are temporary variables.
|
||||
# ## These below are recomputed for every aperture
|
||||
# ## definition, in other words, are temporary variables.
|
||||
self.primitives = []
|
||||
self.locvars = {}
|
||||
self.geometry = None
|
||||
|
@ -1582,7 +1573,7 @@ class ApertureMacro:
|
|||
# variables are defined in an aperture definition.
|
||||
match = ApertureMacro.amprim_re.search(part)
|
||||
if match:
|
||||
## Replace all variables
|
||||
# ## Replace all variables
|
||||
for v in self.locvars:
|
||||
# replaced the following line with the next to fix Mentor custom apertures not parsed OK
|
||||
# part = re.sub(r'\$' + str(v) + r'(?![0-9a-zA-Z])', str(self.locvars[v]), part)
|
||||
|
@ -1594,7 +1585,7 @@ class ApertureMacro:
|
|||
# Change x with *
|
||||
part = re.sub(r'[xX]', "*", part)
|
||||
|
||||
## Store
|
||||
# ## Store
|
||||
elements = part.split(",")
|
||||
self.primitives.append([eval(x) for x in elements])
|
||||
continue
|
||||
|
@ -1754,8 +1745,8 @@ class ApertureMacro:
|
|||
|
||||
i = 1 # Number of rings created so far
|
||||
|
||||
## If the ring does not have an interior it means that it is
|
||||
## a disk. Then stop.
|
||||
# ## If the ring does not have an interior it means that it is
|
||||
# ## a disk. Then stop.
|
||||
while len(ring.interiors) > 0 and i < nrings:
|
||||
r -= thickness + gap
|
||||
if r <= 0:
|
||||
|
@ -1764,7 +1755,7 @@ class ApertureMacro:
|
|||
result = cascaded_union([result, ring])
|
||||
i += 1
|
||||
|
||||
## Crosshair
|
||||
# ## Crosshair
|
||||
hor = LineString([(x - cross_len, y), (x + cross_len, y)]).buffer(cross_th/2.0, cap_style=2)
|
||||
ver = LineString([(x, y-cross_len), (x, y + cross_len)]).buffer(cross_th/2.0, cap_style=2)
|
||||
result = cascaded_union([result, hor, ver])
|
||||
|
@ -1802,7 +1793,7 @@ class ApertureMacro:
|
|||
:rtype: shapely.geometry.polygon
|
||||
"""
|
||||
|
||||
## Primitive makers
|
||||
# ## Primitive makers
|
||||
makers = {
|
||||
"1": ApertureMacro.make_circle,
|
||||
"2": ApertureMacro.make_vectorline,
|
||||
|
@ -1815,19 +1806,19 @@ class ApertureMacro:
|
|||
"7": ApertureMacro.make_thermal
|
||||
}
|
||||
|
||||
## Store modifiers as local variables
|
||||
# ## Store modifiers as local variables
|
||||
modifiers = modifiers or []
|
||||
modifiers = [float(m) for m in modifiers]
|
||||
self.locvars = {}
|
||||
for i in range(0, len(modifiers)):
|
||||
self.locvars[str(i + 1)] = modifiers[i]
|
||||
|
||||
## Parse
|
||||
# ## Parse
|
||||
self.primitives = [] # Cleanup
|
||||
self.geometry = Polygon()
|
||||
self.parse_content()
|
||||
|
||||
## Make the geometry
|
||||
# ## Make the geometry
|
||||
for primitive in self.primitives:
|
||||
# Make the primitive
|
||||
prim_geo = makers[str(int(primitive[0]))](primitive[1:])
|
||||
|
@ -1898,9 +1889,7 @@ class Gerber (Geometry):
|
|||
:rtype: Gerber
|
||||
"""
|
||||
|
||||
# How to discretize a circle.
|
||||
# if steps_per_circle is None:
|
||||
# steps_per_circle = int(Gerber.defaults['steps_per_circle'])
|
||||
# How to approximate a circle with lines.
|
||||
self.steps_per_circle = int(self.app.defaults["gerber_circle_steps"])
|
||||
|
||||
# Initialize parent
|
||||
|
@ -1917,7 +1906,7 @@ class Gerber (Geometry):
|
|||
"""Zeros in Gerber numbers. If 'L' then remove leading zeros, if 'T' remove trailing zeros. Used during parsing.
|
||||
"""
|
||||
|
||||
## Gerber elements ##
|
||||
# ## Gerber elements # ##
|
||||
'''
|
||||
apertures = {
|
||||
'id':{
|
||||
|
@ -2304,7 +2293,7 @@ class Gerber (Geometry):
|
|||
continue
|
||||
|
||||
# ############################################################# ##
|
||||
# Number format ##################
|
||||
# Number format ############################################### ##
|
||||
# Example: %FSLAX24Y24*%
|
||||
# ############################################################# ##
|
||||
# TODO: This is ignoring most of the format. Implement the rest.
|
||||
|
@ -3084,7 +3073,7 @@ class Gerber (Geometry):
|
|||
else:
|
||||
log.warning("Invalid arc in line %d." % line_num)
|
||||
|
||||
## EOF
|
||||
# ## EOF
|
||||
match = self.eof_re.search(gline)
|
||||
if match:
|
||||
continue
|
||||
|
@ -3100,7 +3089,7 @@ class Gerber (Geometry):
|
|||
pass
|
||||
else:
|
||||
# EOF, create shapely LineString if something still in path
|
||||
## --- Buffered ---
|
||||
# ## --- Buffered ---
|
||||
|
||||
geo_dict = dict()
|
||||
# this treats the case when we are storing geometry as paths
|
||||
|
@ -3392,7 +3381,7 @@ class Gerber (Geometry):
|
|||
self.app.inform.emit(_("[success] Gerber Scale done."))
|
||||
|
||||
|
||||
## solid_geometry ???
|
||||
# ## solid_geometry ???
|
||||
# It's a cascaded union of objects.
|
||||
# self.solid_geometry = affinity.scale(self.solid_geometry, factor,
|
||||
# factor, origin=(0, 0))
|
||||
|
@ -3435,7 +3424,7 @@ class Gerber (Geometry):
|
|||
else:
|
||||
return affinity.translate(obj, xoff=dx, yoff=dy)
|
||||
|
||||
## Solid geometry
|
||||
# ## Solid geometry
|
||||
self.solid_geometry = offset_geom(self.solid_geometry)
|
||||
self.follow_geometry = offset_geom(self.follow_geometry)
|
||||
|
||||
|
@ -3677,7 +3666,7 @@ class Excellon(Geometry):
|
|||
self.num_tools = [] # List for keeping the tools sorted
|
||||
self.index_per_tool = {} # Dictionary to store the indexed points for each tool
|
||||
|
||||
## IN|MM -> Units are inherited from Geometry
|
||||
# ## IN|MM -> Units are inherited from Geometry
|
||||
#self.units = units
|
||||
|
||||
# Trailing "T" or leading "L" (default)
|
||||
|
@ -3946,7 +3935,7 @@ class Excellon(Geometry):
|
|||
log.warning("Found end of the header: %s" % eline)
|
||||
continue
|
||||
|
||||
## Alternative units format M71/M72
|
||||
# ## Alternative units format M71/M72
|
||||
# Supposed to be just in the body (yes, the body)
|
||||
# but some put it in the header (PADS for example).
|
||||
# Will detect anywhere. Occurrence will change the
|
||||
|
@ -3969,7 +3958,7 @@ class Excellon(Geometry):
|
|||
#### Body ## ##
|
||||
if not in_header:
|
||||
|
||||
## Tool change ##
|
||||
# ## Tool change # ##
|
||||
match = self.toolsel_re.search(eline)
|
||||
if match:
|
||||
current_tool = str(int(match.group(1)))
|
||||
|
@ -4009,7 +3998,7 @@ class Excellon(Geometry):
|
|||
|
||||
continue
|
||||
|
||||
## Allegro Type Tool change ##
|
||||
# ## Allegro Type Tool change # ##
|
||||
if allegro_warning is True:
|
||||
match = self.absinc_re.search(eline)
|
||||
match1 = self.stop_re.search(eline)
|
||||
|
@ -4019,7 +4008,7 @@ class Excellon(Geometry):
|
|||
log.debug(" Tool change for Allegro type of Excellon: %s" % current_tool)
|
||||
continue
|
||||
|
||||
## Slots parsing for drilled slots (contain G85)
|
||||
# ## Slots parsing for drilled slots (contain G85)
|
||||
# a Excellon drilled slot line may look like this:
|
||||
# X01125Y0022244G85Y0027756
|
||||
match = self.slots_re.search(eline)
|
||||
|
@ -4032,7 +4021,7 @@ class Excellon(Geometry):
|
|||
start_coords_match = match.group(1)
|
||||
stop_coords_match = match.group(2)
|
||||
|
||||
# Slot coordinates without period ##
|
||||
# Slot coordinates without period # ##
|
||||
# get the coordinates for slot start and for slot stop into variables
|
||||
start_coords_noperiod = self.coordsnoperiod_re.search(start_coords_match)
|
||||
stop_coords_noperiod = self.coordsnoperiod_re.search(stop_coords_match)
|
||||
|
@ -4101,7 +4090,7 @@ class Excellon(Geometry):
|
|||
)
|
||||
continue
|
||||
|
||||
# Slot coordinates with period: Use literally. ##
|
||||
# Slot coordinates with period: Use literally. # ##
|
||||
# get the coordinates for slot start and for slot stop into variables
|
||||
start_coords_period = self.coordsperiod_re.search(start_coords_match)
|
||||
stop_coords_period = self.coordsperiod_re.search(stop_coords_match)
|
||||
|
@ -4170,7 +4159,7 @@ class Excellon(Geometry):
|
|||
)
|
||||
continue
|
||||
|
||||
## Coordinates without period ##
|
||||
# ## Coordinates without period # ##
|
||||
match = self.coordsnoperiod_re.search(eline)
|
||||
if match:
|
||||
matchr = self.repeat_re.search(eline)
|
||||
|
@ -4201,7 +4190,7 @@ class Excellon(Geometry):
|
|||
log.error("Missing coordinates")
|
||||
continue
|
||||
|
||||
## Excellon Routing parse
|
||||
# ## Excellon Routing parse
|
||||
if len(re.findall("G00", eline)) > 0:
|
||||
self.match_routing_start = 'G00'
|
||||
|
||||
|
@ -4251,7 +4240,7 @@ class Excellon(Geometry):
|
|||
# log.debug("{:15} {:8} {:8}".format(eline, x, y))
|
||||
continue
|
||||
|
||||
## Coordinates with period: Use literally. ##
|
||||
# ## Coordinates with period: Use literally. # ##
|
||||
match = self.coordsperiod_re.search(eline)
|
||||
if match:
|
||||
matchr = self.repeat_re.search(eline)
|
||||
|
@ -4282,7 +4271,7 @@ class Excellon(Geometry):
|
|||
log.error("Missing coordinates")
|
||||
continue
|
||||
|
||||
## Excellon Routing parse
|
||||
# ## Excellon Routing parse
|
||||
if len(re.findall("G00", eline)) > 0:
|
||||
self.match_routing_start = 'G00'
|
||||
|
||||
|
@ -4336,7 +4325,7 @@ class Excellon(Geometry):
|
|||
#### Header ## ##
|
||||
if in_header:
|
||||
|
||||
## Tool definitions ##
|
||||
# ## Tool definitions # ##
|
||||
match = self.toolset_re.search(eline)
|
||||
if match:
|
||||
|
||||
|
@ -4354,7 +4343,7 @@ class Excellon(Geometry):
|
|||
log.debug(" Tool definition: %s %s" % (name, spec))
|
||||
continue
|
||||
|
||||
## Units and number format ##
|
||||
# ## Units and number format # ##
|
||||
match = self.units_re.match(eline)
|
||||
if match:
|
||||
self.units_found = match.group(1)
|
||||
|
@ -4412,7 +4401,7 @@ class Excellon(Geometry):
|
|||
log.warning("Type of zeros found: %s" % self.zeros)
|
||||
continue
|
||||
|
||||
## Units and number format outside header##
|
||||
# ## Units and number format outside header# ##
|
||||
match = self.units_re.match(eline)
|
||||
if match:
|
||||
self.units_found = match.group(1)
|
||||
|
@ -4489,7 +4478,7 @@ class Excellon(Geometry):
|
|||
# You must show all zeros to the right of the number and can omit
|
||||
# all zeros to the left of the number. The CNC-7 will count the number
|
||||
# of digits you typed and automatically fill in the missing zeros.
|
||||
## flatCAM expects 6digits
|
||||
# ## flatCAM expects 6digits
|
||||
# flatCAM expects the number of digits entered into the defaults
|
||||
|
||||
if self.units.lower() == "in": # Inches is 00.0000
|
||||
|
@ -4920,7 +4909,6 @@ class CNCjob(Geometry):
|
|||
"pp_geometry_name":'default',
|
||||
"pp_excellon_name":'default',
|
||||
"excellon_optimization_type": "B",
|
||||
"steps_per_circle": 64
|
||||
}
|
||||
|
||||
def __init__(self,
|
||||
|
@ -4937,11 +4925,9 @@ class CNCjob(Geometry):
|
|||
steps_per_circle=None):
|
||||
|
||||
# Used when parsing G-code arcs
|
||||
if steps_per_circle is None:
|
||||
steps_per_circle = int(CNCjob.defaults["steps_per_circle"])
|
||||
self.steps_per_circle = int(steps_per_circle)
|
||||
self.steps_per_circle = int(self.app.defaults['cncjob_steps_per_circle'])
|
||||
|
||||
Geometry.__init__(self, geo_steps_per_circle=int(steps_per_circle))
|
||||
Geometry.__init__(self, geo_steps_per_circle=self.steps_per_circle)
|
||||
|
||||
self.kind = kind
|
||||
self.origin_kind = None
|
||||
|
@ -4983,7 +4969,6 @@ class CNCjob(Geometry):
|
|||
|
||||
self.pp_solderpaste_name = None
|
||||
|
||||
|
||||
# Controls if the move from Z_Toolchange to Z_Move is done fast with G0 or normally with G1
|
||||
self.f_plunge = None
|
||||
|
||||
|
@ -5588,7 +5573,7 @@ class CNCjob(Geometry):
|
|||
else:
|
||||
temp_solid_geometry = geometry
|
||||
|
||||
## Flatten the geometry. Only linear elements (no polygons) remain.
|
||||
# ## Flatten the geometry. Only linear elements (no polygons) remain.
|
||||
flat_geometry = self.flatten(temp_solid_geometry, pathonly=True)
|
||||
log.debug("%d paths" % len(flat_geometry))
|
||||
|
||||
|
@ -5665,7 +5650,7 @@ class CNCjob(Geometry):
|
|||
"This is dangerous, skipping %s file") % self.options['name'])
|
||||
return 'fail'
|
||||
|
||||
## Index first and last points in paths
|
||||
# ## Index first and last points in paths
|
||||
# What points to index.
|
||||
def get_pts(o):
|
||||
return [o.coords[0], o.coords[-1]]
|
||||
|
@ -5719,7 +5704,7 @@ class CNCjob(Geometry):
|
|||
if self.dwell is True:
|
||||
self.gcode += self.doformat(p.dwell_code) # Dwell time
|
||||
|
||||
## Iterate over geometry paths getting the nearest each time.
|
||||
# ## Iterate over geometry paths getting the nearest each time.
|
||||
log.debug("Starting G-Code...")
|
||||
path_count = 0
|
||||
current_pt = (0, 0)
|
||||
|
@ -5855,7 +5840,7 @@ class CNCjob(Geometry):
|
|||
else:
|
||||
temp_solid_geometry = geometry.solid_geometry
|
||||
|
||||
## Flatten the geometry. Only linear elements (no polygons) remain.
|
||||
# ## Flatten the geometry. Only linear elements (no polygons) remain.
|
||||
flat_geometry = self.flatten(temp_solid_geometry, pathonly=True)
|
||||
log.debug("%d paths" % len(flat_geometry))
|
||||
|
||||
|
@ -5928,7 +5913,7 @@ class CNCjob(Geometry):
|
|||
"This is dangerous, skipping %s file") % self.options['name'])
|
||||
return 'fail'
|
||||
|
||||
## Index first and last points in paths
|
||||
# ## Index first and last points in paths
|
||||
# What points to index.
|
||||
def get_pts(o):
|
||||
return [o.coords[0], o.coords[-1]]
|
||||
|
@ -5943,8 +5928,6 @@ class CNCjob(Geometry):
|
|||
if shape is not None: # TODO: This shouldn't have happened.
|
||||
storage.insert(shape)
|
||||
|
||||
# self.input_geometry_bounds = geometry.bounds()
|
||||
|
||||
if not append:
|
||||
self.gcode = ""
|
||||
|
||||
|
@ -6041,7 +6024,7 @@ class CNCjob(Geometry):
|
|||
|
||||
log.debug("Generate_from_solderpaste_geometry()")
|
||||
|
||||
## Index first and last points in paths
|
||||
# ## Index first and last points in paths
|
||||
# What points to index.
|
||||
def get_pts(o):
|
||||
return [o.coords[0], o.coords[-1]]
|
||||
|
@ -6077,7 +6060,7 @@ class CNCjob(Geometry):
|
|||
else self.app.defaults['tools_solderpaste_pp']
|
||||
p = self.app.postprocessors[self.pp_solderpaste_name]
|
||||
|
||||
## Flatten the geometry. Only linear elements (no polygons) remain.
|
||||
# ## Flatten the geometry. Only linear elements (no polygons) remain.
|
||||
flat_geometry = self.flatten(kwargs['solid_geometry'], pathonly=True)
|
||||
log.debug("%d paths" % len(flat_geometry))
|
||||
|
||||
|
@ -6096,7 +6079,7 @@ class CNCjob(Geometry):
|
|||
self.gcode += self.doformat(p.spindle_off_code)
|
||||
self.gcode += self.doformat(p.toolchange_code)
|
||||
|
||||
## Iterate over geometry paths getting the nearest each time.
|
||||
# ## Iterate over geometry paths getting the nearest each time.
|
||||
log.debug("Starting SolderPaste G-Code...")
|
||||
path_count = 0
|
||||
current_pt = (0, 0)
|
||||
|
@ -6355,12 +6338,12 @@ class CNCjob(Geometry):
|
|||
|
||||
gobj = self.codes_split(line)
|
||||
|
||||
## Units
|
||||
# ## Units
|
||||
if 'G' in gobj and (gobj['G'] == 20.0 or gobj['G'] == 21.0):
|
||||
self.units = {20.0: "IN", 21.0: "MM"}[gobj['G']]
|
||||
continue
|
||||
|
||||
## Changing height
|
||||
# ## Changing height
|
||||
if 'Z' in gobj:
|
||||
if 'Roland' in self.pp_excellon_name or 'Roland' in self.pp_geometry_name:
|
||||
pass
|
||||
|
@ -6431,9 +6414,7 @@ class CNCjob(Geometry):
|
|||
radius = sqrt(gobj['I']**2 + gobj['J']**2)
|
||||
start = arctan2(-gobj['J'], -gobj['I'])
|
||||
stop = arctan2(-center[1] + y, -center[0] + x)
|
||||
path += arc(center, radius, start, stop,
|
||||
arcdir[current['G']],
|
||||
int(self.steps_per_circle / 4))
|
||||
path += arc(center, radius, start, stop, arcdir[current['G']], int(self.steps_per_circle / 4))
|
||||
|
||||
# Update current instruction
|
||||
for code in gobj:
|
||||
|
@ -6498,6 +6479,7 @@ class CNCjob(Geometry):
|
|||
:param tool_tolerance: Tolerance when drawing the toolshape.
|
||||
:return: None
|
||||
"""
|
||||
# units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
||||
|
||||
gcode_parsed = gcode_parsed if gcode_parsed else self.gcode_parsed
|
||||
path_num = 0
|
||||
|
@ -6515,15 +6497,21 @@ class CNCjob(Geometry):
|
|||
elif kind == 'cut':
|
||||
if geo['kind'][0] == 'C':
|
||||
obj.add_shape(shape=geo['geom'], color=color['C'][1], visible=visible)
|
||||
|
||||
else:
|
||||
text = []
|
||||
pos = []
|
||||
for geo in gcode_parsed:
|
||||
if geo['kind'][0] == 'T':
|
||||
current_position = geo['geom'].coords[0]
|
||||
if current_position not in pos:
|
||||
pos.append(current_position)
|
||||
path_num += 1
|
||||
text.append(str(path_num))
|
||||
current_position = geo['geom'].coords[-1]
|
||||
if current_position not in pos:
|
||||
pos.append(current_position)
|
||||
path_num += 1
|
||||
|
||||
text.append(str(path_num))
|
||||
pos.append(geo['geom'].coords[0])
|
||||
|
||||
# plot the geometry of Excellon objects
|
||||
if self.origin_kind == 'excellon':
|
||||
|
@ -6531,10 +6519,12 @@ class CNCjob(Geometry):
|
|||
poly = Polygon(geo['geom'])
|
||||
except ValueError:
|
||||
# if the geos are travel lines it will enter into Exception
|
||||
poly = geo['geom'].buffer(tooldia / 2.0).simplify(tool_tolerance)
|
||||
poly = geo['geom'].buffer(distance=(tooldia / 1.99999999), resolution=self.steps_per_circle)
|
||||
poly = poly.simplify(tool_tolerance)
|
||||
else:
|
||||
# plot the geometry of any objects other than Excellon
|
||||
poly = geo['geom'].buffer(tooldia / 2.0).simplify(tool_tolerance)
|
||||
poly = geo['geom'].buffer(distance=(tooldia / 1.99999999), resolution=self.steps_per_circle)
|
||||
poly = poly.simplify(tool_tolerance)
|
||||
|
||||
if kind == 'all':
|
||||
obj.add_shape(shape=poly, color=color[geo['kind'][0]][1], face_color=color[geo['kind'][0]][0],
|
||||
|
@ -6548,7 +6538,9 @@ class CNCjob(Geometry):
|
|||
obj.add_shape(shape=poly, color=color['C'][1], face_color=color['C'][0],
|
||||
visible=visible, layer=1)
|
||||
|
||||
obj.annotation.set(text=text, pos=pos, visible=obj.options['plot'])
|
||||
obj.annotation.set(text=text, pos=pos, visible=obj.options['plot'],
|
||||
font_size=self.app.defaults["cncjob_annotation_fontsize"],
|
||||
color=self.app.defaults["cncjob_annotation_fontcolor"])
|
||||
|
||||
def create_geometry(self):
|
||||
# TODO: This takes forever. Too much data?
|
||||
|
@ -7301,7 +7293,7 @@ def dict2obj(d):
|
|||
|
||||
# def plotg(geo, solid_poly=False, color="black"):
|
||||
# try:
|
||||
# _ = iter(geo)
|
||||
# __ = iter(geo)
|
||||
# except:
|
||||
# geo = [geo]
|
||||
#
|
||||
|
@ -7334,7 +7326,7 @@ def dict2obj(d):
|
|||
# continue
|
||||
#
|
||||
# try:
|
||||
# _ = iter(g)
|
||||
# __ = iter(g)
|
||||
# plotg(g, color=color)
|
||||
# except:
|
||||
# log.error("Cannot plot: " + str(type(g)))
|
||||
|
@ -7640,7 +7632,7 @@ def parse_gerber_number(strnumber, int_digits, frac_digits, zeros):
|
|||
|
||||
def autolist(obj):
|
||||
try:
|
||||
_ = iter(obj)
|
||||
__ = iter(obj)
|
||||
return obj
|
||||
except TypeError:
|
||||
return [obj]
|
||||
|
@ -7699,7 +7691,7 @@ class FlatCAMRTree(object):
|
|||
# Python RTree Index
|
||||
self.rti = rtindex.Index()
|
||||
|
||||
## Track object-point relationship
|
||||
# ## Track object-point relationship
|
||||
# Each is list of points in object.
|
||||
self.obj2points = []
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@ from copy import copy, deepcopy
|
|||
|
||||
import gettext
|
||||
import FlatCAMTranslation as fcTranslate
|
||||
import builtins
|
||||
|
||||
fcTranslate.apply_language('strings')
|
||||
import builtins
|
||||
if '_' not in builtins.__dict__:
|
||||
_ = gettext.gettext
|
||||
|
||||
|
@ -34,9 +34,9 @@ class FCDrillAdd(FCShapeTool):
|
|||
|
||||
self.selected_dia = None
|
||||
try:
|
||||
self.draw_app.app.inform.emit(self.start_msg)
|
||||
# self.selected_dia = self.draw_app.tool2tooldia[self.draw_app.tools_table_exc.currentRow() + 1]
|
||||
self.draw_app.app.inform.emit(_("Click to place ..."))
|
||||
self.selected_dia = self.draw_app.tool2tooldia[self.draw_app.last_tool_selected]
|
||||
|
||||
# as a visual marker, select again in tooltable the actual tool that we are using
|
||||
# remember that it was deselected when clicking on canvas
|
||||
item = self.draw_app.tools_table_exc.item((self.draw_app.last_tool_selected - 1), 1)
|
||||
|
@ -140,7 +140,7 @@ class FCDrillArray(FCShapeTool):
|
|||
self.pt = []
|
||||
|
||||
try:
|
||||
self.draw_app.app.inform.emit(self.start_msg)
|
||||
self.draw_app.app.inform.emit(_("Click to place ..."))
|
||||
self.selected_dia = self.draw_app.tool2tooldia[self.draw_app.last_tool_selected]
|
||||
# as a visual marker, select again in tooltable the actual tool that we are using
|
||||
# remember that it was deselected when clicking on canvas
|
||||
|
@ -204,7 +204,7 @@ class FCDrillArray(FCShapeTool):
|
|||
_("[ERROR_NOTCL] The value is not Float. Check for comma instead of dot separator."))
|
||||
return
|
||||
except Exception as e:
|
||||
self.draw_app.app.inform.emit(_("[ERROR_NOTCL] The value is mistyped. Check the value."))
|
||||
self.draw_app.app.inform.emit(_("[ERROR_NOTCL] The value is mistyped. Check the value. %s") % str(e))
|
||||
return
|
||||
|
||||
if self.drill_array == 'Linear':
|
||||
|
@ -350,7 +350,9 @@ class FCDrillResize(FCShapeTool):
|
|||
try:
|
||||
new_dia = self.draw_app.resdrill_entry.get_value()
|
||||
except:
|
||||
self.draw_app.app.inform.emit(_("[ERROR_NOTCL] Resize drill(s) failed. Please enter a diameter for resize."))
|
||||
self.draw_app.app.inform.emit(
|
||||
_("[ERROR_NOTCL] Resize drill(s) failed. Please enter a diameter for resize.")
|
||||
)
|
||||
return
|
||||
|
||||
if new_dia not in self.draw_app.olddia_newdia:
|
||||
|
@ -416,7 +418,6 @@ class FCDrillResize(FCShapeTool):
|
|||
|
||||
for shp in sel_shapes_to_be_deleted:
|
||||
self.draw_app.selected.remove(shp)
|
||||
sel_shapes_to_be_deleted = []
|
||||
|
||||
self.draw_app.build_ui()
|
||||
self.draw_app.replot()
|
||||
|
@ -440,6 +441,8 @@ class FCDrillMove(FCShapeTool):
|
|||
# self.shape_buffer = self.draw_app.shape_buffer
|
||||
self.origin = None
|
||||
self.destination = None
|
||||
self.sel_limit = self.draw_app.app.defaults["excellon_editor_sel_limit"]
|
||||
self.selection_shape = self.selection_bbox()
|
||||
self.selected_dia_list = []
|
||||
|
||||
if self.draw_app.launched_from_shortcuts is True:
|
||||
|
@ -503,6 +506,25 @@ class FCDrillMove(FCShapeTool):
|
|||
self.draw_app.build_ui()
|
||||
self.draw_app.app.inform.emit(_("[success] Done. Drill(s) Move completed."))
|
||||
|
||||
def selection_bbox(self):
|
||||
geo_list = []
|
||||
for select_shape in self.draw_app.get_selected():
|
||||
geometric_data = select_shape.geo
|
||||
try:
|
||||
for g in geometric_data:
|
||||
geo_list.append(g)
|
||||
except TypeError:
|
||||
geo_list.append(geometric_data)
|
||||
|
||||
xmin, ymin, xmax, ymax = get_shapely_list_bounds(geo_list)
|
||||
|
||||
pt1 = (xmin, ymin)
|
||||
pt2 = (xmax, ymin)
|
||||
pt3 = (xmax, ymax)
|
||||
pt4 = (xmin, ymax)
|
||||
|
||||
return Polygon([pt1, pt2, pt3, pt4])
|
||||
|
||||
def utility_geometry(self, data=None):
|
||||
"""
|
||||
Temporary geometry on screen while using this tool.
|
||||
|
@ -520,9 +542,22 @@ class FCDrillMove(FCShapeTool):
|
|||
|
||||
dx = data[0] - self.origin[0]
|
||||
dy = data[1] - self.origin[1]
|
||||
|
||||
if len(self.draw_app.get_selected()) <= self.sel_limit:
|
||||
try:
|
||||
for geom in self.draw_app.get_selected():
|
||||
geo_list.append(affinity.translate(geom.geo, xoff=dx, yoff=dy))
|
||||
except AttributeError:
|
||||
self.draw_app.select_tool('drill_select')
|
||||
self.draw_app.selected = []
|
||||
return
|
||||
return DrawToolUtilityShape(geo_list)
|
||||
else:
|
||||
try:
|
||||
ss_el = affinity.translate(self.selection_shape, xoff=dx, yoff=dy)
|
||||
except ValueError:
|
||||
ss_el = None
|
||||
return DrawToolUtilityShape(ss_el)
|
||||
|
||||
|
||||
class FCDrillCopy(FCDrillMove):
|
||||
|
@ -595,8 +630,8 @@ class FCDrillSelect(DrawTool):
|
|||
|
||||
try:
|
||||
for storage in self.exc_editor_app.storage_dict:
|
||||
for shape in self.exc_editor_app.storage_dict[storage].get_objects():
|
||||
self.sel_storage.insert(shape)
|
||||
for sh in self.exc_editor_app.storage_dict[storage].get_objects():
|
||||
self.sel_storage.insert(sh)
|
||||
|
||||
_, closest_shape = self.sel_storage.nearest(pos)
|
||||
|
||||
|
@ -718,19 +753,18 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
draw_shape_idx = -1
|
||||
|
||||
def __init__(self, app):
|
||||
assert isinstance(app, FlatCAMApp.App), \
|
||||
"Expected the app to be a FlatCAMApp.App, got %s" % type(app)
|
||||
assert isinstance(app, FlatCAMApp.App), "Expected the app to be a FlatCAMApp.App, got %s" % type(app)
|
||||
|
||||
super(FlatCAMExcEditor, self).__init__()
|
||||
|
||||
self.app = app
|
||||
self.canvas = self.app.plotcanvas
|
||||
|
||||
## Current application units in Upper Case
|
||||
# ## Current application units in Upper Case
|
||||
self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
||||
|
||||
self.exc_edit_widget = QtWidgets.QWidget()
|
||||
## Box for custom widgets
|
||||
# ## Box for custom widgets
|
||||
# This gets populated in offspring implementations.
|
||||
layout = QtWidgets.QVBoxLayout()
|
||||
self.exc_edit_widget.setLayout(layout)
|
||||
|
@ -744,22 +778,22 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.tools_box.setContentsMargins(0, 0, 0, 0)
|
||||
self.drills_frame.setLayout(self.tools_box)
|
||||
|
||||
## Page Title box (spacing between children)
|
||||
# ## Page Title box (spacing between children)
|
||||
self.title_box = QtWidgets.QHBoxLayout()
|
||||
self.tools_box.addLayout(self.title_box)
|
||||
|
||||
## Page Title icon
|
||||
# ## Page Title icon
|
||||
pixmap = QtGui.QPixmap('share/flatcam_icon32.png')
|
||||
self.icon = QtWidgets.QLabel()
|
||||
self.icon.setPixmap(pixmap)
|
||||
self.title_box.addWidget(self.icon, stretch=0)
|
||||
|
||||
## Title label
|
||||
# ## Title label
|
||||
self.title_label = QtWidgets.QLabel("<font size=5><b>%s</b></font>" % _('Excellon Editor'))
|
||||
self.title_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
||||
self.title_box.addWidget(self.title_label, stretch=1)
|
||||
|
||||
## Object name
|
||||
# ## Object name
|
||||
self.name_box = QtWidgets.QHBoxLayout()
|
||||
self.tools_box.addLayout(self.name_box)
|
||||
name_label = QtWidgets.QLabel(_("Name:"))
|
||||
|
@ -804,7 +838,6 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
addtool_entry_lbl.setToolTip(
|
||||
_("Diameter for the new tool")
|
||||
)
|
||||
grid1.addWidget(addtool_entry_lbl, 0, 0)
|
||||
|
||||
hlay = QtWidgets.QHBoxLayout()
|
||||
self.addtool_entry = FCEntry()
|
||||
|
@ -818,6 +851,8 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
)
|
||||
self.addtool_btn.setFixedWidth(80)
|
||||
hlay.addWidget(self.addtool_btn)
|
||||
|
||||
grid1.addWidget(addtool_entry_lbl, 0, 0)
|
||||
grid1.addLayout(hlay, 0, 1)
|
||||
|
||||
grid2 = QtWidgets.QGridLayout()
|
||||
|
@ -905,6 +940,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.array_form = QtWidgets.QFormLayout()
|
||||
self.array_box.addLayout(self.array_form)
|
||||
|
||||
# Set the number of drill holes in the drill array
|
||||
self.drill_array_size_label = QtWidgets.QLabel(_('Nr of drills:'))
|
||||
self.drill_array_size_label.setToolTip(
|
||||
_("Specify how many drills to be in the array.")
|
||||
|
@ -924,6 +960,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.linear_form = QtWidgets.QFormLayout()
|
||||
self.linear_box.addLayout(self.linear_form)
|
||||
|
||||
# Linear Drill Array direction
|
||||
self.drill_axis_label = QtWidgets.QLabel(_('Direction:'))
|
||||
self.drill_axis_label.setToolTip(
|
||||
_("Direction on which the linear array is oriented:\n"
|
||||
|
@ -936,9 +973,9 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.drill_axis_radio = RadioSet([{'label': 'X', 'value': 'X'},
|
||||
{'label': 'Y', 'value': 'Y'},
|
||||
{'label': 'Angle', 'value': 'A'}])
|
||||
self.drill_axis_radio.set_value('X')
|
||||
self.linear_form.addRow(self.drill_axis_label, self.drill_axis_radio)
|
||||
|
||||
# Linear Drill Array pitch distance
|
||||
self.drill_pitch_label = QtWidgets.QLabel(_('Pitch:'))
|
||||
self.drill_pitch_label.setToolTip(
|
||||
_("Pitch = Distance between elements of the array.")
|
||||
|
@ -948,6 +985,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.drill_pitch_entry = LengthEntry()
|
||||
self.linear_form.addRow(self.drill_pitch_label, self.drill_pitch_entry)
|
||||
|
||||
# Linear Drill Array angle
|
||||
self.linear_angle_label = QtWidgets.QLabel(_('Angle:'))
|
||||
self.linear_angle_label.setToolTip(
|
||||
_( "Angle at which the linear array is placed.\n"
|
||||
|
@ -981,7 +1019,6 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
|
||||
self.drill_direction_radio = RadioSet([{'label': 'CW', 'value': 'CW'},
|
||||
{'label': 'CCW.', 'value': 'CCW'}])
|
||||
self.drill_direction_radio.set_value('CW')
|
||||
self.circular_form.addRow(self.drill_direction_label, self.drill_direction_radio)
|
||||
|
||||
self.drill_angle_label = QtWidgets.QLabel(_('Angle:'))
|
||||
|
@ -1001,7 +1038,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.array_frame.hide()
|
||||
self.tools_box.addStretch()
|
||||
|
||||
## Toolbar events and properties
|
||||
# ## Toolbar events and properties
|
||||
self.tools_exc = {
|
||||
"drill_select": {"button": self.app.ui.select_drill_btn,
|
||||
"constructor": FCDrillSelect},
|
||||
|
@ -1073,12 +1110,6 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
|
||||
self.app.ui.exc_move_drill_menuitem.triggered.connect(self.exc_move_drills)
|
||||
|
||||
# Init GUI
|
||||
self.drill_array_size_entry.set_value(5)
|
||||
self.drill_pitch_entry.set_value(2.54)
|
||||
self.drill_angle_entry.set_value(12)
|
||||
self.drill_direction_radio.set_value('CW')
|
||||
self.drill_axis_radio.set_value('X')
|
||||
self.exc_obj = None
|
||||
|
||||
# VisPy Visuals
|
||||
|
@ -1090,7 +1121,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.shapes.enabled = False
|
||||
self.tool_shape.enabled = False
|
||||
|
||||
## List of selected shapes.
|
||||
# ## List of selected shapes.
|
||||
self.selected = []
|
||||
|
||||
self.move_timer = QtCore.QTimer()
|
||||
|
@ -1105,6 +1136,8 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.snap_y = None
|
||||
self.pos = None
|
||||
|
||||
self.complete = False
|
||||
|
||||
def make_callback(thetool):
|
||||
def f():
|
||||
self.on_tool_select(thetool)
|
||||
|
@ -1159,15 +1192,13 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
|
||||
@staticmethod
|
||||
def make_storage():
|
||||
|
||||
## Shape storage.
|
||||
# ## Shape storage.
|
||||
storage = FlatCAMRTreeStorage()
|
||||
storage.get_points = DrawToolShape.get_pts
|
||||
|
||||
return storage
|
||||
|
||||
def set_ui(self):
|
||||
|
||||
# updated units
|
||||
self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
||||
|
||||
|
@ -1186,6 +1217,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.points_edit[tool_dia].append(drill['point'])
|
||||
except KeyError:
|
||||
self.points_edit[tool_dia] = [drill['point']]
|
||||
|
||||
# update the olddia_newdia dict to make sure we have an updated state of the tool_table
|
||||
for key in self.points_edit:
|
||||
self.olddia_newdia[key] = key
|
||||
|
@ -1211,6 +1243,15 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
tool_dia = float('%.2f' % v['C'])
|
||||
self.tool2tooldia[int(k)] = tool_dia
|
||||
|
||||
# Init GUI
|
||||
self.addtool_entry.set_value(float(self.app.defaults['excellon_editor_newdia']))
|
||||
self.drill_array_size_entry.set_value(int(self.app.defaults['excellon_editor_array_size']))
|
||||
self.drill_axis_radio.set_value(self.app.defaults['excellon_editor_lin_dir'])
|
||||
self.drill_pitch_entry.set_value(float(self.app.defaults['excellon_editor_lin_pitch']))
|
||||
self.linear_angle_spinner.set_value(float(self.app.defaults['excellon_editor_lin_angle']))
|
||||
self.drill_direction_radio.set_value(self.app.defaults['excellon_editor_circ_dir'])
|
||||
self.drill_angle_entry.set_value(float(self.app.defaults['excellon_editor_circ_angle']))
|
||||
|
||||
def build_ui(self, first_run=None):
|
||||
|
||||
try:
|
||||
|
@ -1231,11 +1272,6 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.edited_obj_name = self.exc_obj.options['name']
|
||||
self.name_entry.set_value(self.edited_obj_name)
|
||||
|
||||
if self.units == "IN":
|
||||
self.addtool_entry.set_value(0.039)
|
||||
else:
|
||||
self.addtool_entry.set_value(1.00)
|
||||
|
||||
sort_temp = []
|
||||
|
||||
for diam in self.olddia_newdia:
|
||||
|
@ -1278,9 +1314,9 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
# slot editing not implemented
|
||||
pass
|
||||
|
||||
id = QtWidgets.QTableWidgetItem('%d' % int(tool_id))
|
||||
id.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
|
||||
self.tools_table_exc.setItem(self.tool_row, 0, id) # Tool name/id
|
||||
idd = QtWidgets.QTableWidgetItem('%d' % int(tool_id))
|
||||
idd.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
|
||||
self.tools_table_exc.setItem(self.tool_row, 0, idd) # Tool name/id
|
||||
|
||||
# Make sure that the drill diameter when in MM is with no more than 2 decimals
|
||||
# There are no drill bits in MM with more than 3 decimals diameter
|
||||
|
@ -1375,7 +1411,6 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.tools_table_exc.item(self.tool_row, kl).setFont(font)
|
||||
self.tools_table_exc.item(self.tool_row, kl).setForeground(QtGui.QColor(0, 70, 255))
|
||||
|
||||
|
||||
# all the tools are selected by default
|
||||
self.tools_table_exc.selectColumn(0)
|
||||
#
|
||||
|
@ -1458,7 +1493,8 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
# we add a new entry in the tool2tooldia dict
|
||||
self.tool2tooldia[len(self.olddia_newdia)] = tool_dia
|
||||
|
||||
self.app.inform.emit(_("[success] Added new tool with dia: {dia} {units}").format(dia=str(tool_dia), units=str(self.units)))
|
||||
self.app.inform.emit(_("[success] Added new tool with dia: {dia} {units}").format(dia=str(tool_dia),
|
||||
units=str(self.units)))
|
||||
|
||||
self.build_ui()
|
||||
|
||||
|
@ -1475,7 +1511,6 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
def on_tool_delete(self, dia=None):
|
||||
self.is_modified = True
|
||||
deleted_tool_dia_list = []
|
||||
deleted_tool_offset_list = []
|
||||
|
||||
try:
|
||||
if dia is None or dia is False:
|
||||
|
@ -1516,14 +1551,15 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
# delete the tool
|
||||
self.tool2tooldia.pop(tool_to_be_deleted, None)
|
||||
|
||||
# delete also the drills from points_edit dict just in case we add the tool again, we don't want to show the
|
||||
# number of drills from before was deleter
|
||||
# delete also the drills from points_edit dict just in case we add the tool again,
|
||||
# we don't want to show the number of drills from before was deleter
|
||||
self.points_edit[deleted_tool_dia] = []
|
||||
flag_del = []
|
||||
|
||||
self.olddia_newdia.pop(deleted_tool_dia, None)
|
||||
|
||||
self.app.inform.emit(_("[success] Deleted tool with dia: {del_dia} {units}").format(del_dia=str(deleted_tool_dia), units=str(self.units)))
|
||||
self.app.inform.emit(_("[success] Deleted tool with dia: {del_dia} {units}").format(
|
||||
del_dia=str(deleted_tool_dia),
|
||||
units=str(self.units)))
|
||||
|
||||
self.replot()
|
||||
# self.app.inform.emit("Could not delete selected tool")
|
||||
|
@ -1539,7 +1575,6 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
# self.tools_table_exc.selectionModel().currentChanged.disconnect()
|
||||
|
||||
self.is_modified = True
|
||||
geometry = []
|
||||
current_table_dia_edited = None
|
||||
|
||||
if self.tools_table_exc.currentItem() is not None:
|
||||
|
@ -1575,10 +1610,11 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
factor = current_table_dia_edited / dia_changed
|
||||
geometry = []
|
||||
|
||||
for shape in self.storage_dict[dia_changed].get_objects():
|
||||
geometry.append(DrawToolShape(
|
||||
MultiLineString([affinity.scale(subgeo, xfact=factor, yfact=factor, origin='center')
|
||||
for subgeo in shape.geo])))
|
||||
for shape_exc in self.storage_dict[dia_changed].get_objects():
|
||||
scaled_geo = MultiLineString(
|
||||
[affinity.scale(subgeo, xfact=factor, yfact=factor, origin='center') for subgeo in shape_exc.geo]
|
||||
)
|
||||
geometry.append(DrawToolShape(scaled_geo))
|
||||
|
||||
# add bogus drill points (for total count of drills)
|
||||
for k, v in self.olddia_newdia.items():
|
||||
|
@ -1586,8 +1622,8 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.points_edit[k].append((0, 0))
|
||||
break
|
||||
|
||||
# search for the oldia that correspond to the newdia and add the drills in it's storage
|
||||
# everything will be sort out later, when the edited excellon is updated
|
||||
# search for the old dia that correspond to the new dia and add the drills in it's storage
|
||||
# everything will be sort out later, when the edited Excellon is updated
|
||||
for k, v in self.olddia_newdia.items():
|
||||
if v == current_table_dia_edited:
|
||||
self.add_exc_shape(geometry, self.storage_dict[k])
|
||||
|
@ -1739,7 +1775,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.drills_frame.hide()
|
||||
|
||||
def connect_canvas_event_handlers(self):
|
||||
## Canvas events
|
||||
# ## Canvas events
|
||||
|
||||
# first connect to new, then disconnect the old handlers
|
||||
# don't ask why but if there is nothing connected I've seen issues
|
||||
|
@ -1833,7 +1869,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
Imports the geometry from the given FlatCAM Excellon object
|
||||
into the editor.
|
||||
|
||||
:param fcgeometry: FlatCAMExcellon
|
||||
:param exc_obj: FlatCAMExcellon object
|
||||
:return: None
|
||||
"""
|
||||
|
||||
|
@ -1870,16 +1906,16 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
stop_hor_line = ((point.x + (tool_dia / 2)), point.y)
|
||||
start_vert_line = (point.x, (point.y - (tool_dia / 2)))
|
||||
stop_vert_line = (point.x, (point.y + (tool_dia / 2)))
|
||||
shape = MultiLineString([(start_hor_line, stop_hor_line),(start_vert_line, stop_vert_line)])
|
||||
if shape is not None:
|
||||
self.add_exc_shape(DrawToolShape(shape), storage_elem)
|
||||
shape_geo = MultiLineString([(start_hor_line, stop_hor_line), (start_vert_line, stop_vert_line)])
|
||||
if shape_geo is not None:
|
||||
self.add_exc_shape(DrawToolShape(shape_geo), storage_elem)
|
||||
self.storage_dict[tool_dia] = storage_elem
|
||||
|
||||
self.replot()
|
||||
|
||||
# add a first tool in the Tool Table but only if the Excellon Object is empty
|
||||
if not self.tool2tooldia:
|
||||
self.on_tool_add(tooldia=1.00)
|
||||
self.on_tool_add(tooldia=float(self.app.defaults['excellon_editor_newdia']))
|
||||
|
||||
def update_fcexcellon(self, exc_obj):
|
||||
"""
|
||||
|
@ -1907,7 +1943,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
# create a tuple with the coordinates (x, y) and add it to the list that is the value of the
|
||||
# edited_points dictionary
|
||||
point = (x_coord, y_coord)
|
||||
if not storage_tooldia in edited_points:
|
||||
if storage_tooldia not in edited_points:
|
||||
edited_points[storage_tooldia] = [point]
|
||||
else:
|
||||
edited_points[storage_tooldia].append(point)
|
||||
|
@ -1964,8 +2000,8 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
if self.is_modified is True:
|
||||
if "_edit" in self.edited_obj_name:
|
||||
try:
|
||||
id = int(self.edited_obj_name[-1]) + 1
|
||||
self.edited_obj_name = self.edited_obj_name[:-1] + str(id)
|
||||
idd = int(self.edited_obj_name[-1]) + 1
|
||||
self.edited_obj_name = self.edited_obj_name[:-1] + str(idd)
|
||||
except ValueError:
|
||||
self.edited_obj_name += "_1"
|
||||
else:
|
||||
|
@ -2116,7 +2152,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
|
||||
def toolbar_tool_toggle(self, key):
|
||||
self.options[key] = self.sender().isChecked()
|
||||
if self.options[key] == True:
|
||||
if self.options[key] is True:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
@ -2151,7 +2187,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
if self.active_tool is not None and event.button is 1:
|
||||
# Dispatch event to active_tool
|
||||
# msg = self.active_tool.click(self.app.geo_editor.snap(event.xdata, event.ydata))
|
||||
msg = self.active_tool.click(self.app.geo_editor.snap(self.pos[0], self.pos[1]))
|
||||
self.active_tool.click(self.app.geo_editor.snap(self.pos[0], self.pos[1]))
|
||||
|
||||
# If it is a shape generating tool
|
||||
if isinstance(self.active_tool, FCShapeTool) and self.active_tool.complete:
|
||||
|
@ -2207,6 +2243,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
|
||||
:param shape: Shape to be added.
|
||||
:type shape: DrawToolShape
|
||||
:param storage: object where to store the shapes
|
||||
:return: None
|
||||
"""
|
||||
# List of DrawToolShape?
|
||||
|
@ -2221,8 +2258,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
assert shape.geo is not None, \
|
||||
"Shape object has empty geometry (None)"
|
||||
|
||||
assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or \
|
||||
not isinstance(shape.geo, list), \
|
||||
assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or not isinstance(shape.geo, list), \
|
||||
"Shape objects has empty geometry ([])"
|
||||
|
||||
if isinstance(shape, DrawToolUtilityShape):
|
||||
|
@ -2251,8 +2287,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
assert shape.geo is not None, \
|
||||
"Shape object has empty geometry (None)"
|
||||
|
||||
assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or \
|
||||
not isinstance(shape.geo, list), \
|
||||
assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or not isinstance(shape.geo, list), \
|
||||
"Shape objects has empty geometry ([])"
|
||||
|
||||
if isinstance(shape, DrawToolUtilityShape):
|
||||
|
@ -2318,14 +2353,15 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
log.warning("Error: %s" % str(e))
|
||||
raise
|
||||
|
||||
def draw_selection_area_handler(self, start_pos, end_pos, sel_type):
|
||||
def draw_selection_area_handler(self, start, end, sel_type):
|
||||
"""
|
||||
:param start_pos: mouse position when the selection LMB click was done
|
||||
:param end_pos: mouse position when the left mouse button is released
|
||||
:param sel_type: if True it's a left to right selection (enclosure), if False it's a 'touch' selection
|
||||
:type Bool
|
||||
:return:
|
||||
"""
|
||||
start_pos = (start[0], start[1])
|
||||
end_pos = (end[0], end[1])
|
||||
poly_selection = Polygon([start_pos, (end_pos[0], start_pos[1]), end_pos, (start_pos[0], end_pos[1])])
|
||||
|
||||
self.app.delete_selection_shape()
|
||||
|
@ -2488,10 +2524,8 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.tool_shape.add(
|
||||
shape=geo.geo, color=(self.app.defaults["global_draw_color"] + '80'),
|
||||
update=False, layer=0, tolerance=None)
|
||||
|
||||
self.tool_shape.redraw()
|
||||
|
||||
|
||||
def replot(self):
|
||||
self.plot_all()
|
||||
|
||||
|
@ -2526,10 +2560,8 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
#
|
||||
# self.plot_shape(geometry=shape.geo, color=self.app.defaults['global_draw_color'])
|
||||
|
||||
|
||||
|
||||
for shape in self.utility:
|
||||
self.plot_shape(geometry=shape.geo, linewidth=1)
|
||||
for shape_form in self.utility:
|
||||
self.plot_shape(geometry=shape_form.geo, linewidth=1)
|
||||
continue
|
||||
|
||||
self.shapes.redraw()
|
||||
|
@ -2553,13 +2585,13 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
for geo in geometry:
|
||||
plot_elements += self.plot_shape(geometry=geo, color=color, linewidth=linewidth)
|
||||
|
||||
## Non-iterable
|
||||
# ## Non-iterable
|
||||
except TypeError:
|
||||
## DrawToolShape
|
||||
# ## DrawToolShape
|
||||
if isinstance(geometry, DrawToolShape):
|
||||
plot_elements += self.plot_shape(geometry=geometry.geo, color=color, linewidth=linewidth)
|
||||
|
||||
## Polygon: Descend into exterior and each interior.
|
||||
# ## Polygon: Descend into exterior and each interior.
|
||||
if type(geometry) == Polygon:
|
||||
plot_elements += self.plot_shape(geometry=geometry.exterior, color=color, linewidth=linewidth)
|
||||
plot_elements += self.plot_shape(geometry=geometry.interiors, color=color, linewidth=linewidth)
|
||||
|
@ -2604,11 +2636,11 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.build_ui()
|
||||
self.app.inform.emit(_("[success] Done. Drill(s) deleted."))
|
||||
|
||||
def delete_shape(self, shape):
|
||||
def delete_shape(self, del_shape):
|
||||
self.is_modified = True
|
||||
|
||||
if shape in self.utility:
|
||||
self.utility.remove(shape)
|
||||
if del_shape in self.utility:
|
||||
self.utility.remove(del_shape)
|
||||
return
|
||||
|
||||
for storage in self.storage_dict:
|
||||
|
@ -2616,8 +2648,8 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
# self.storage_dict[storage].remove(shape)
|
||||
# except:
|
||||
# pass
|
||||
if shape in self.storage_dict[storage].get_objects():
|
||||
self.storage_dict[storage].remove(shape)
|
||||
if del_shape in self.storage_dict[storage].get_objects():
|
||||
self.storage_dict[storage].remove(del_shape)
|
||||
# a hack to make the tool_table display less drills per diameter
|
||||
# self.points_edit it's only useful first time when we load the data into the storage
|
||||
# but is still used as referecen when building tool_table in self.build_ui()
|
||||
|
@ -2625,15 +2657,13 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
# deleting self.points_edit elements (doesn't matter who but just the number) solved the display issue.
|
||||
del self.points_edit[storage][0]
|
||||
|
||||
if shape in self.selected:
|
||||
self.selected.remove(shape) # TODO: Check performance
|
||||
if del_shape in self.selected:
|
||||
self.selected.remove(del_shape) # TODO: Check performance
|
||||
|
||||
def delete_utility_geometry(self):
|
||||
# for_deletion = [shape for shape in self.shape_buffer if shape.utility]
|
||||
# for_deletion = [shape for shape in self.storage.get_objects() if shape.utility]
|
||||
for_deletion = [shape for shape in self.utility]
|
||||
for shape in for_deletion:
|
||||
self.delete_shape(shape)
|
||||
for_deletion = [util_shape for util_shape in self.utility]
|
||||
for util_shape in for_deletion:
|
||||
self.delete_shape(util_shape)
|
||||
|
||||
self.tool_shape.clear(update=True)
|
||||
self.tool_shape.redraw()
|
||||
|
@ -2652,17 +2682,17 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.tools_exc[toolname]["button"].setChecked(True)
|
||||
self.on_tool_select(toolname)
|
||||
|
||||
def set_selected(self, shape):
|
||||
def set_selected(self, sel_shape):
|
||||
|
||||
# Remove and add to the end.
|
||||
if shape in self.selected:
|
||||
self.selected.remove(shape)
|
||||
if sel_shape in self.selected:
|
||||
self.selected.remove(sel_shape)
|
||||
|
||||
self.selected.append(shape)
|
||||
self.selected.append(sel_shape)
|
||||
|
||||
def set_unselected(self, shape):
|
||||
if shape in self.selected:
|
||||
self.selected.remove(shape)
|
||||
def set_unselected(self, unsel_shape):
|
||||
if unsel_shape in self.selected:
|
||||
self.selected.remove(unsel_shape)
|
||||
|
||||
def on_array_type_combo(self):
|
||||
if self.array_type_combo.currentIndex() == 0:
|
||||
|
@ -2702,3 +2732,24 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
def exc_move_drills(self):
|
||||
self.select_tool('drill_move')
|
||||
return
|
||||
|
||||
|
||||
def get_shapely_list_bounds(geometry_list):
|
||||
xmin = Inf
|
||||
ymin = Inf
|
||||
xmax = -Inf
|
||||
ymax = -Inf
|
||||
|
||||
for gs in geometry_list:
|
||||
try:
|
||||
gxmin, gymin, gxmax, gymax = gs.bounds
|
||||
xmin = min([xmin, gxmin])
|
||||
ymin = min([ymin, gymin])
|
||||
xmax = max([xmax, gxmax])
|
||||
ymax = max([ymax, gymax])
|
||||
except Exception as e:
|
||||
log.warning("DEVELOPMENT: Tried to get bounds of empty geometry. --> %s" % str(e))
|
||||
|
||||
return [xmin, ymin, xmax, ymax]
|
||||
|
||||
# EOF
|
||||
|
|
|
@ -629,7 +629,7 @@ class TransformEditorTool(FlatCAMTool):
|
|||
|
||||
self.transform_lay = QtWidgets.QVBoxLayout()
|
||||
self.layout.addLayout(self.transform_lay)
|
||||
## Title
|
||||
# ## Title
|
||||
title_label = QtWidgets.QLabel("%s" % (_('Editor %s') % self.toolName))
|
||||
title_label.setStyleSheet("""
|
||||
QLabel
|
||||
|
@ -2918,7 +2918,7 @@ class FCTransform(FCShapeTool):
|
|||
|
||||
|
||||
# ##################### ##
|
||||
# ## Main Application ###
|
||||
# # ## Main Application # ##
|
||||
# ##################### ##
|
||||
class FlatCAMGeoEditor(QtCore.QObject):
|
||||
|
||||
|
@ -2935,7 +2935,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
self.app = app
|
||||
self.canvas = app.plotcanvas
|
||||
|
||||
## Toolbar events and properties
|
||||
# ## Toolbar events and properties
|
||||
self.tools = {
|
||||
"select": {"button": self.app.ui.geo_select_btn,
|
||||
"constructor": FCSelect},
|
||||
|
@ -2965,7 +2965,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
"constructor": FCCopy}
|
||||
}
|
||||
|
||||
# ## Data
|
||||
# # ## Data
|
||||
self.active_tool = None
|
||||
|
||||
self.storage = FlatCAMGeoEditor.make_storage()
|
||||
|
@ -3373,10 +3373,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
|
||||
def toolbar_tool_toggle(self, key):
|
||||
self.options[key] = self.sender().isChecked()
|
||||
if self.options[key] == True:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
return 1 if self.options[key] == True else 0
|
||||
|
||||
def clear(self):
|
||||
self.active_tool = None
|
||||
|
@ -3416,7 +3413,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
if multigeo_tool:
|
||||
self.multigeo_tool = multigeo_tool
|
||||
geo_to_edit = fcgeometry.flatten(geometry=fcgeometry.tools[self.multigeo_tool]['solid_geometry'])
|
||||
self.app.inform.emit(_("[WARNING] Editing MultiGeo Geometry, tool: {tool} with diameter: {dia}").
|
||||
self.app.inform.emit(_("[WARNING_NOTCL] Editing MultiGeo Geometry, tool: {tool} with diameter: {dia}").
|
||||
format(tool=self.multigeo_tool, dia=fcgeometry.tools[self.multigeo_tool]['tooldia']))
|
||||
else:
|
||||
geo_to_edit = fcgeometry.flatten()
|
||||
|
@ -3572,7 +3569,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
if self.active_tool is None:
|
||||
return
|
||||
|
||||
# ## Snap coordinates
|
||||
# # ## Snap coordinates
|
||||
if self.app.grid_status():
|
||||
x, y = self.snap(x, y)
|
||||
self.app.app_cursor.enabled = True
|
||||
|
@ -3600,14 +3597,14 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
if event.button == 1 and event.is_dragging == 1 and isinstance(self.active_tool, FCEraser):
|
||||
pass
|
||||
else:
|
||||
# ## Utility geometry (animated)
|
||||
# # ## Utility geometry (animated)
|
||||
geo = self.active_tool.utility_geometry(data=(x, y))
|
||||
if isinstance(geo, DrawToolShape) and geo.geo is not None:
|
||||
# Remove any previous utility shape
|
||||
self.tool_shape.clear(update=True)
|
||||
self.draw_utility_geometry(geo=geo)
|
||||
|
||||
# ## Selection area on canvas section ###
|
||||
# # ## Selection area on canvas section # ##
|
||||
dx = pos[0] - self.pos[0]
|
||||
if event.is_dragging == 1 and event.button == 1:
|
||||
self.app.delete_selection_shape()
|
||||
|
@ -3941,9 +3938,9 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
snap_x, snap_y = (x, y)
|
||||
snap_distance = Inf
|
||||
|
||||
# ## Object (corner?) snap
|
||||
# ## No need for the objects, just the coordinates
|
||||
# ## in the index.
|
||||
# # ## Object (corner?) snap
|
||||
# # ## No need for the objects, just the coordinates
|
||||
# # ## in the index.
|
||||
if self.options["corner_snap"]:
|
||||
try:
|
||||
nearest_pt, shape = self.storage.nearest((x, y))
|
||||
|
@ -3955,7 +3952,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
except (StopIteration, AssertionError):
|
||||
pass
|
||||
|
||||
# ## Grid snap
|
||||
# # ## Grid snap
|
||||
if self.options["grid_snap"]:
|
||||
if self.options["global_gridx"] != 0:
|
||||
snap_x_ = round(x / self.options["global_gridx"]) * self.options['global_gridx']
|
||||
|
|
|
@ -52,7 +52,7 @@ class DrawToolShape(object):
|
|||
"""
|
||||
pts = []
|
||||
|
||||
## Iterable: descend into each item.
|
||||
# ## Iterable: descend into each item.
|
||||
try:
|
||||
for sub_o in o:
|
||||
pts += DrawToolShape.get_pts(sub_o)
|
||||
|
@ -64,7 +64,7 @@ class DrawToolShape(object):
|
|||
if isinstance(o, DrawToolShape):
|
||||
pts += DrawToolShape.get_pts(o.geo)
|
||||
|
||||
## Descend into .exerior and .interiors
|
||||
# ## Descend into .exerior and .interiors
|
||||
elif type(o) == Polygon:
|
||||
pts += DrawToolShape.get_pts(o.exterior)
|
||||
for i in o.interiors:
|
||||
|
@ -72,7 +72,7 @@ class DrawToolShape(object):
|
|||
elif type(o) == MultiLineString:
|
||||
for line in o:
|
||||
pts += DrawToolShape.get_pts(line)
|
||||
## Has .coords: list them.
|
||||
# ## Has .coords: list them.
|
||||
else:
|
||||
if DrawToolShape.tolerance is not None:
|
||||
pts += list(o.simplify(DrawToolShape.tolerance).coords)
|
||||
|
@ -1349,7 +1349,14 @@ class FCDisc(FCShapeTool):
|
|||
size_ap = float(self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['size'])
|
||||
self.buf_val = (size_ap / 2) if size_ap > 0 else 0.0000001
|
||||
|
||||
self.storage_obj = self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['geometry']
|
||||
if '0' in self.draw_app.storage_dict:
|
||||
self.storage_obj = self.draw_app.storage_dict['0']['geometry']
|
||||
else:
|
||||
self.draw_app.storage_dict['0'] = dict()
|
||||
self.draw_app.storage_dict['0']['type'] = 'C'
|
||||
self.draw_app.storage_dict['0']['size'] = 0.0
|
||||
self.draw_app.storage_dict['0']['geometry'] = list()
|
||||
self.storage_obj = self.draw_app.storage_dict['0']['geometry']
|
||||
|
||||
self.draw_app.app.inform.emit(_("Click on Center point ..."))
|
||||
|
||||
|
@ -1436,7 +1443,14 @@ class FCSemiDisc(FCShapeTool):
|
|||
size_ap = float(self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['size'])
|
||||
self.buf_val = (size_ap / 2) if size_ap > 0 else 0.0000001
|
||||
|
||||
self.storage_obj = self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['geometry']
|
||||
if '0' in self.draw_app.storage_dict:
|
||||
self.storage_obj = self.draw_app.storage_dict['0']['geometry']
|
||||
else:
|
||||
self.draw_app.storage_dict['0'] = dict()
|
||||
self.draw_app.storage_dict['0']['type'] = 'C'
|
||||
self.draw_app.storage_dict['0']['size'] = 0.0
|
||||
self.draw_app.storage_dict['0']['geometry'] = list()
|
||||
self.storage_obj = self.draw_app.storage_dict['0']['geometry']
|
||||
|
||||
self.steps_per_circ = self.draw_app.app.defaults["gerber_circle_steps"]
|
||||
|
||||
|
@ -2050,7 +2064,9 @@ class FCEraser(FCShapeTool):
|
|||
if 'solid' in geo_el.geo:
|
||||
geometric_data = geo_el.geo['solid']
|
||||
if eraser_sel_shapes.within(geometric_data) or eraser_sel_shapes.intersects(geometric_data):
|
||||
geo_el.geo['solid'] = geometric_data.difference(eraser_sel_shapes)
|
||||
geos = geometric_data.difference(eraser_sel_shapes)
|
||||
geos = geos.buffer(0)
|
||||
geo_el.geo['solid'] = deepcopy(geos)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
@ -2374,7 +2390,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
hlay_ad.addWidget(self.addaperture_btn)
|
||||
hlay_ad.addWidget(self.delaperture_btn)
|
||||
|
||||
# ## BUFFER TOOL ###
|
||||
# # ## BUFFER TOOL # ##
|
||||
|
||||
self.buffer_tool_frame = QtWidgets.QFrame()
|
||||
self.buffer_tool_frame.setContentsMargins(0, 0, 0, 0)
|
||||
|
@ -2418,7 +2434,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
self.buffer_button = QtWidgets.QPushButton(_("Buffer"))
|
||||
hlay_buf.addWidget(self.buffer_button)
|
||||
|
||||
# ## SCALE TOOL ###
|
||||
# # ## SCALE TOOL # ##
|
||||
|
||||
self.scale_tool_frame = QtWidgets.QFrame()
|
||||
self.scale_tool_frame.setContentsMargins(0, 0, 0, 0)
|
||||
|
@ -2617,7 +2633,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
"constructor": FCApertureMove},
|
||||
}
|
||||
|
||||
# ## Data
|
||||
# # ## Data
|
||||
self.active_tool = None
|
||||
|
||||
self.storage_dict = {}
|
||||
|
@ -3621,7 +3637,13 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
self.gerber_obj.options['name'].upper())
|
||||
|
||||
out_name = outname
|
||||
local_storage_dict = deepcopy(self.storage_dict)
|
||||
|
||||
local_storage_dict = dict()
|
||||
for aperture in self.storage_dict:
|
||||
if 'geometry' in self.storage_dict[aperture]:
|
||||
# add aperture only if it has geometry
|
||||
if len(self.storage_dict[aperture]['geometry']) > 0:
|
||||
local_storage_dict[aperture] = deepcopy(self.storage_dict[aperture])
|
||||
|
||||
# How the object should be initialized
|
||||
def obj_init(grb_obj, app_obj):
|
||||
|
@ -4057,7 +4079,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
if self.active_tool is None:
|
||||
return
|
||||
|
||||
# ## Snap coordinates
|
||||
# # ## Snap coordinates
|
||||
if self.app.grid_status():
|
||||
x, y = self.app.geo_editor.snap(x, y)
|
||||
self.app.app_cursor.enabled = True
|
||||
|
@ -4082,7 +4104,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (dx, dy))
|
||||
|
||||
# ## Utility geometry (animated)
|
||||
# # ## Utility geometry (animated)
|
||||
geo = self.active_tool.utility_geometry(data=(x, y))
|
||||
|
||||
if isinstance(geo, DrawToolShape) and geo.geo is not None:
|
||||
|
@ -4090,7 +4112,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
self.tool_shape.clear(update=True)
|
||||
self.draw_utility_geometry(geo=geo)
|
||||
|
||||
# ## Selection area on canvas section ###
|
||||
# # ## Selection area on canvas section # ##
|
||||
if event.is_dragging == 1 and event.button == 1:
|
||||
# I make an exception for FCRegion and FCTrack because clicking and dragging while making regions can
|
||||
# create strange issues like missing a point in a track/region
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
# File Modified (major mod): Marius Adrian Stanciu #
|
||||
# Date: 3/10/2019 #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from PyQt5.QtCore import QSettings
|
||||
from flatcamGUI.GUIElements import *
|
||||
|
@ -203,6 +203,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
self.menufile.addSeparator()
|
||||
|
||||
self.menufile_save = self.menufile.addMenu(QtGui.QIcon('share/save_as.png'), _('Save'))
|
||||
|
||||
# Save Project
|
||||
self.menufilesaveproject = QtWidgets.QAction(QtGui.QIcon('share/floppy16.png'), _('&Save Project ...'), self)
|
||||
self.menufile_save.addAction(self.menufilesaveproject)
|
||||
|
@ -377,7 +378,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
_("Toggle Workspace\tSHIFT+W"))
|
||||
|
||||
# ## Tool ###
|
||||
# self.menutool = self.menu.addMenu('&Tool')
|
||||
self.menutool = QtWidgets.QMenu(_('&Tool'))
|
||||
self.menutoolaction = self.menu.addMenu(self.menutool)
|
||||
self.menutoolshell = self.menutool.addAction(QtGui.QIcon('share/shell16.png'), _('&Command Line\tS'))
|
||||
|
@ -393,14 +393,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
)
|
||||
self.menuhelp_about = self.menuhelp.addAction(QtGui.QIcon('share/about32.png'), _('About'))
|
||||
|
||||
|
||||
# ## FlatCAM Editor menu ###
|
||||
# self.editor_menu = QtWidgets.QMenu("Editor")
|
||||
# self.menu.addMenu(self.editor_menu)
|
||||
self.geo_editor_menu = QtWidgets.QMenu(">Geo Editor<")
|
||||
self.menu.addMenu(self.geo_editor_menu)
|
||||
|
||||
# self.select_menuitem = self.menu.addAction(QtGui.QIcon('share/pointer16.png'), "Select 'Esc'")
|
||||
self.geo_add_circle_menuitem = self.geo_editor_menu.addAction(
|
||||
QtGui.QIcon('share/circle32.png'), _('Add Circle\tO')
|
||||
)
|
||||
|
@ -469,7 +465,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
QtGui.QIcon('share/move32.png'),_( 'Move Drill(s)\tM'))
|
||||
|
||||
# ## APPLICATION GERBER EDITOR MENU ###
|
||||
|
||||
self.grb_editor_menu = QtWidgets.QMenu(_(">Gerber Editor<"))
|
||||
self.menu.addMenu(self.grb_editor_menu)
|
||||
|
||||
|
@ -516,9 +511,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
self.exc_editor_menu.menuAction().setVisible(False)
|
||||
self.exc_editor_menu.setDisabled(True)
|
||||
|
||||
################################
|
||||
### Project Tab Context menu ###
|
||||
################################
|
||||
# ################################
|
||||
# ### Project Tab Context menu ###
|
||||
# ################################
|
||||
|
||||
self.menuproject = QtWidgets.QMenu()
|
||||
self.menuprojectenable = self.menuproject.addAction(QtGui.QIcon('share/replot32.png'), _('Enable Plot'))
|
||||
|
@ -535,9 +530,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
|
||||
self.menuprojectproperties = self.menuproject.addAction(QtGui.QIcon('share/properties32.png'), _('Properties'))
|
||||
|
||||
################
|
||||
### Splitter ###
|
||||
################
|
||||
# ################
|
||||
# ### Splitter ###
|
||||
# ################
|
||||
|
||||
# IMPORTANT #
|
||||
# The order: SPITTER -> NOTEBOOK -> SNAP TOOLBAR is important and without it the GUI will not be initialized as
|
||||
|
@ -638,10 +633,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
|
||||
# self.toolbarview.setVisible(False)
|
||||
|
||||
### Shell Toolbar ###
|
||||
# ## Shell Toolbar ##
|
||||
self.shell_btn = self.toolbarshell.addAction(QtGui.QIcon('share/shell32.png'), _("&Command Line"))
|
||||
|
||||
### Tools Toolbar ###
|
||||
# ## Tools Toolbar ##
|
||||
self.dblsided_btn = self.toolbartools.addAction(QtGui.QIcon('share/doubleside32.png'), _("2Sided Tool"))
|
||||
self.cutout_btn = self.toolbartools.addAction(QtGui.QIcon('share/cut16_bis.png'), _("&Cutout Tool"))
|
||||
self.ncc_btn = self.toolbartools.addAction(QtGui.QIcon('share/ncc16.png'), _("NCC Tool"))
|
||||
|
@ -732,7 +727,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
self.grb_edit_toolbar.addSeparator()
|
||||
self.aperture_move_btn = self.grb_edit_toolbar.addAction(QtGui.QIcon('share/move32.png'), _("Move"))
|
||||
|
||||
### Snap Toolbar ###
|
||||
# # ## Snap Toolbar # ##
|
||||
# Snap GRID toolbar is always active to facilitate usage of measurements done on GRID
|
||||
# self.addToolBar(self.snap_toolbar)
|
||||
|
||||
|
@ -960,9 +955,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
"which is the file storing the working default preferences."))
|
||||
self.pref_tab_bottom_layout_2.addWidget(self.pref_save_button)
|
||||
|
||||
########################################
|
||||
# #################################################
|
||||
# ## HERE WE BUILD THE SHORTCUTS LIST. TAB AREA ###
|
||||
########################################
|
||||
# #################################################
|
||||
self.shortcuts_tab = QtWidgets.QWidget()
|
||||
self.sh_tab_layout = QtWidgets.QVBoxLayout()
|
||||
self.sh_tab_layout.setContentsMargins(2, 2, 2, 2)
|
||||
|
@ -1575,11 +1570,13 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
|
||||
|
||||
# ########################################################### ##
|
||||
### HERE WE BUILD THE CONTEXT MENU FOR RMB CLICK ON CANVAS ###
|
||||
# # ## HERE WE BUILD THE CONTEXT MENU FOR RMB CLICK ON CANVAS # ##
|
||||
# ########################################################### ##
|
||||
self.popMenu = FCMenu()
|
||||
|
||||
self.popmenu_disable = self.popMenu.addAction(QtGui.QIcon('share/clear_plot32.png'), _("Disable"))
|
||||
self.popmenu_disable = self.popMenu.addAction(QtGui.QIcon('share/disable32.png'), _("Disable Plot"))
|
||||
self.popmenu_panel_toggle = self.popMenu.addAction(QtGui.QIcon('share/notebook16.png'), _("Toggle Panel"))
|
||||
|
||||
self.popMenu.addSeparator()
|
||||
self.cmenu_newmenu = self.popMenu.addMenu(QtGui.QIcon('share/file32.png'), _("New"))
|
||||
self.popmenu_new_geo = self.cmenu_newmenu.addAction(QtGui.QIcon('share/new_geo32_bis.png'), _("Geometry"))
|
||||
|
@ -1731,6 +1728,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
self.show()
|
||||
|
||||
self.filename = ""
|
||||
self.units = ""
|
||||
self.setAcceptDrops(True)
|
||||
|
||||
# # restore the Toolbar State from file
|
||||
|
@ -2036,9 +2034,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
else:
|
||||
key = event.key
|
||||
|
||||
# Propagate to tool
|
||||
response = None
|
||||
|
||||
if self.app.call_source == 'app':
|
||||
if modifiers == QtCore.Qt.ControlModifier:
|
||||
if key == QtCore.Qt.Key_A:
|
||||
|
@ -2702,7 +2697,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
|
||||
# we do this so we can reuse the following keys while inside a Tool
|
||||
# the above keys are general enough so were left outside
|
||||
if self.app.grb_editor.active_tool is not None and self.grb_select_btn.isChecked() == False:
|
||||
if self.app.grb_editor.active_tool is not None and self.grb_select_btn.isChecked() is False:
|
||||
response = self.app.grb_editor.active_tool.on_key(key=key)
|
||||
if response is not None:
|
||||
self.app.inform.emit(response)
|
||||
|
@ -2811,7 +2806,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
# Add Track
|
||||
if key == QtCore.Qt.Key_T or key == 'T':
|
||||
self.app.grb_editor.launched_from_shortcuts = True
|
||||
## Current application units in Upper Case
|
||||
# ## Current application units in Upper Case
|
||||
self.app.grb_editor.select_tool('track')
|
||||
return
|
||||
|
||||
|
@ -2988,7 +2983,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
# Add Tool
|
||||
if key == QtCore.Qt.Key_T or key == 'T':
|
||||
self.app.exc_editor.launched_from_shortcuts = True
|
||||
## Current application units in Upper Case
|
||||
# ## Current application units in Upper Case
|
||||
self.units = self.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
||||
tool_add_popup = FCInputDialog(title=_("New Tool ..."),
|
||||
text=_('Enter a Tool Diameter:'),
|
||||
|
@ -2999,7 +2994,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
if ok:
|
||||
self.app.exc_editor.on_tool_add(tooldia=val)
|
||||
self.app.inform.emit(
|
||||
_("[success] Added new tool with dia: {dia} {units}").format(dia='%.4f' % float(val), units=str(self.units)))
|
||||
_("[success] Added new tool with dia: {dia} {units}").format(dia='%.4f' % float(val),
|
||||
units=str(self.units)))
|
||||
else:
|
||||
self.app.inform.emit(
|
||||
_("[WARNING_NOTCL] Adding Tool cancelled ..."))
|
||||
|
@ -3126,7 +3122,7 @@ class GeneralPreferencesUI(QtWidgets.QWidget):
|
|||
self.setLayout(self.layout)
|
||||
|
||||
self.general_app_group = GeneralAppPrefGroupUI()
|
||||
self.general_app_group.setFixedWidth(250)
|
||||
self.general_app_group.setFixedWidth(280)
|
||||
|
||||
self.general_gui_group = GeneralGUIPrefGroupUI()
|
||||
self.general_gui_group.setFixedWidth(250)
|
||||
|
@ -3159,7 +3155,6 @@ class GerberPreferencesUI(QtWidgets.QWidget):
|
|||
self.gerber_editor_group = GerberEditorPrefGroupUI()
|
||||
self.gerber_editor_group.setFixedWidth(200)
|
||||
|
||||
|
||||
self.vlay = QtWidgets.QVBoxLayout()
|
||||
self.vlay.addWidget(self.gerber_opt_group)
|
||||
self.vlay.addWidget(self.gerber_exp_group)
|
||||
|
@ -3182,11 +3177,13 @@ class ExcellonPreferencesUI(QtWidgets.QWidget):
|
|||
self.excellon_gen_group = ExcellonGenPrefGroupUI()
|
||||
self.excellon_gen_group.setFixedWidth(220)
|
||||
self.excellon_opt_group = ExcellonOptPrefGroupUI()
|
||||
self.excellon_opt_group.setFixedWidth(250)
|
||||
self.excellon_opt_group.setFixedWidth(290)
|
||||
self.excellon_exp_group = ExcellonExpPrefGroupUI()
|
||||
self.excellon_exp_group.setFixedWidth(250)
|
||||
self.excellon_adv_opt_group = ExcellonAdvOptPrefGroupUI()
|
||||
self.excellon_adv_opt_group.setFixedWidth(250)
|
||||
self.excellon_editor_group = ExcellonEditorPrefGroupUI()
|
||||
self.excellon_editor_group.setFixedWidth(260)
|
||||
|
||||
self.vlay = QtWidgets.QVBoxLayout()
|
||||
self.vlay.addWidget(self.excellon_opt_group)
|
||||
|
@ -3195,6 +3192,7 @@ class ExcellonPreferencesUI(QtWidgets.QWidget):
|
|||
self.layout.addWidget(self.excellon_gen_group)
|
||||
self.layout.addLayout(self.vlay)
|
||||
self.layout.addWidget(self.excellon_adv_opt_group)
|
||||
self.layout.addWidget(self.excellon_editor_group)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
|
@ -3209,9 +3207,9 @@ class GeometryPreferencesUI(QtWidgets.QWidget):
|
|||
self.geometry_gen_group = GeometryGenPrefGroupUI()
|
||||
self.geometry_gen_group.setFixedWidth(220)
|
||||
self.geometry_opt_group = GeometryOptPrefGroupUI()
|
||||
self.geometry_opt_group.setFixedWidth(250)
|
||||
self.geometry_opt_group.setFixedWidth(300)
|
||||
self.geometry_adv_opt_group = GeometryAdvOptPrefGroupUI()
|
||||
self.geometry_adv_opt_group.setFixedWidth(250)
|
||||
self.geometry_adv_opt_group.setFixedWidth(270)
|
||||
self.geometry_editor_group = GeometryEditorPrefGroupUI()
|
||||
self.geometry_editor_group.setFixedWidth(250)
|
||||
|
||||
|
@ -3289,7 +3287,7 @@ class CNCJobPreferencesUI(QtWidgets.QWidget):
|
|||
self.setLayout(self.layout)
|
||||
|
||||
self.cncjob_gen_group = CNCJobGenPrefGroupUI()
|
||||
self.cncjob_gen_group.setFixedWidth(270)
|
||||
self.cncjob_gen_group.setFixedWidth(320)
|
||||
self.cncjob_opt_group = CNCJobOptPrefGroupUI()
|
||||
self.cncjob_opt_group.setFixedWidth(260)
|
||||
self.cncjob_adv_opt_group = CNCJobAdvOptPrefGroupUI()
|
||||
|
@ -3615,7 +3613,6 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
|
|||
# Create a form layout for the Application general settings
|
||||
self.form_box = QtWidgets.QFormLayout()
|
||||
|
||||
|
||||
# Layout selection
|
||||
self.layout_label = QtWidgets.QLabel(_('Layout:'))
|
||||
self.layout_label.setToolTip(
|
||||
|
@ -3994,7 +3991,7 @@ class GerberGenPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str("Gerber General"))
|
||||
|
||||
## Plot options
|
||||
# ## Plot options
|
||||
self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
|
||||
self.layout.addWidget(self.plot_options_label)
|
||||
|
||||
|
@ -4042,8 +4039,7 @@ class GerberOptPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("Gerber Options")))
|
||||
|
||||
|
||||
## Isolation Routing
|
||||
# ## Isolation Routing
|
||||
self.isolation_routing_label = QtWidgets.QLabel(_("<b>Isolation Routing:</b>"))
|
||||
self.isolation_routing_label.setToolTip(
|
||||
_("Create a Geometry object with\n"
|
||||
|
@ -4077,8 +4073,13 @@ class GerberOptPrefGroupUI(OptionsGroupUI):
|
|||
overlabel = QtWidgets.QLabel(_('Pass overlap:'))
|
||||
overlabel.setToolTip(
|
||||
_("How much (fraction) of the tool width to overlap each tool pass.\n"
|
||||
<<<<<<< HEAD
|
||||
"Example:\n"
|
||||
"A value here of 0.25 means an overlap of 25% from the tool diameter found above.")
|
||||
=======
|
||||
"Example:\n"
|
||||
"A value here of 0.25 means an overlap of 25%% from the tool diameter found above.")
|
||||
>>>>>>> remotes/jpcgt/flatcam/Beta
|
||||
)
|
||||
grid0.addWidget(overlabel, 2, 0)
|
||||
self.iso_overlap_entry = FloatEntry()
|
||||
|
@ -4102,7 +4103,7 @@ class GerberOptPrefGroupUI(OptionsGroupUI):
|
|||
)
|
||||
grid0.addWidget(self.combine_passes_cb, 4, 0)
|
||||
|
||||
## Clear non-copper regions
|
||||
# ## Clear non-copper regions
|
||||
self.clearcopper_label = QtWidgets.QLabel(_("<b>Clear non-copper:</b>"))
|
||||
self.clearcopper_label.setToolTip(
|
||||
_("Create a Geometry object with\n"
|
||||
|
@ -4133,7 +4134,7 @@ class GerberOptPrefGroupUI(OptionsGroupUI):
|
|||
)
|
||||
grid1.addWidget(self.noncopper_rounded_cb, 1, 0, 1, 2)
|
||||
|
||||
## Bounding box
|
||||
# ## Bounding box
|
||||
self.boundingbox_label = QtWidgets.QLabel(_('<b>Bounding Box:</b>'))
|
||||
self.layout.addWidget(self.boundingbox_label)
|
||||
|
||||
|
@ -4167,8 +4168,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("Gerber Adv. Options")))
|
||||
|
||||
|
||||
## Advanced Gerber Parameters
|
||||
# ## Advanced Gerber Parameters
|
||||
self.adv_param_label = QtWidgets.QLabel(_("<b>Advanced Param.:</b>"))
|
||||
self.adv_param_label.setToolTip(
|
||||
_("A list of Gerber advanced parameters.\n"
|
||||
|
@ -4186,7 +4186,6 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
_("Generate a 'Follow' geometry.\n"
|
||||
"This means that it will cut through\n"
|
||||
"the middle of the trace.")
|
||||
|
||||
)
|
||||
grid0.addWidget(self.follow_cb, 0, 0)
|
||||
|
||||
|
@ -4617,7 +4616,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("Excellon Options")))
|
||||
|
||||
## Create CNC Job
|
||||
# ## Create CNC Job
|
||||
self.cncjob_label = QtWidgets.QLabel(_('<b>Create CNC Job</b>'))
|
||||
self.cncjob_label.setToolTip(
|
||||
_("Parameters used to create a CNC Job object\n"
|
||||
|
@ -4727,7 +4726,6 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
|
|||
self.pp_excellon_name_cb.setFocusPolicy(Qt.StrongFocus)
|
||||
grid2.addWidget(self.pp_excellon_name_cb, 9, 1)
|
||||
|
||||
|
||||
# ### Choose what to use for Gcode creation: Drills, Slots or Both
|
||||
excellon_gcode_type_label = QtWidgets.QLabel(_('<b>Gcode: </b>'))
|
||||
excellon_gcode_type_label.setToolTip(
|
||||
|
@ -4791,9 +4789,9 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("Excellon Adv. Options")))
|
||||
|
||||
######################
|
||||
## ADVANCED OPTIONS ##
|
||||
######################
|
||||
# #######################
|
||||
# ## ADVANCED OPTIONS ###
|
||||
# #######################
|
||||
|
||||
self.cncjob_label = QtWidgets.QLabel(_('<b>Advanced Options:</b>'))
|
||||
self.cncjob_label.setToolTip(
|
||||
|
@ -5026,6 +5024,129 @@ class ExcellonExpPrefGroupUI(OptionsGroupUI):
|
|||
self.zeros_radio.setDisabled(False)
|
||||
|
||||
|
||||
class ExcellonEditorPrefGroupUI(OptionsGroupUI):
|
||||
def __init__(self, parent=None):
|
||||
super(ExcellonEditorPrefGroupUI, self).__init__(self)
|
||||
|
||||
self.setTitle(str(_("Excellon Editor")))
|
||||
|
||||
# Excellon Editor Parameters
|
||||
self.param_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
|
||||
self.param_label.setToolTip(
|
||||
_("A list of Excellon Editor parameters.")
|
||||
)
|
||||
self.layout.addWidget(self.param_label)
|
||||
|
||||
grid0 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid0)
|
||||
|
||||
# Selection Limit
|
||||
self.sel_limit_label = QtWidgets.QLabel(_("Selection limit:"))
|
||||
self.sel_limit_label.setToolTip(
|
||||
_("Set the number of selected Excellon geometry\n"
|
||||
"items above which the utility geometry\n"
|
||||
"becomes just a selection rectangle.\n"
|
||||
"Increases the performance when moving a\n"
|
||||
"large number of geometric elements.")
|
||||
)
|
||||
self.sel_limit_entry = IntEntry()
|
||||
|
||||
grid0.addWidget(self.sel_limit_label, 0, 0)
|
||||
grid0.addWidget(self.sel_limit_entry, 0, 1)
|
||||
|
||||
# New tool diameter
|
||||
self.addtool_entry_lbl = QtWidgets.QLabel(_('New Tool Dia:'))
|
||||
self.addtool_entry_lbl.setToolTip(
|
||||
_("Diameter for the new tool")
|
||||
)
|
||||
|
||||
self.addtool_entry = FCEntry()
|
||||
self.addtool_entry.setValidator(QtGui.QDoubleValidator(0.0001, 99.9999, 4))
|
||||
|
||||
grid0.addWidget(self.addtool_entry_lbl, 1, 0)
|
||||
grid0.addWidget(self.addtool_entry, 1, 1)
|
||||
|
||||
# Number of drill holes in a drill array
|
||||
self.drill_array_size_label = QtWidgets.QLabel(_('Nr of drills:'))
|
||||
self.drill_array_size_label.setToolTip(
|
||||
_("Specify how many drills to be in the array.")
|
||||
)
|
||||
# self.drill_array_size_label.setFixedWidth(100)
|
||||
|
||||
self.drill_array_size_entry = LengthEntry()
|
||||
|
||||
grid0.addWidget(self.drill_array_size_label, 2, 0)
|
||||
grid0.addWidget(self.drill_array_size_entry, 2, 1)
|
||||
|
||||
self.drill_array_linear_label = QtWidgets.QLabel(_('<b>Linear Drill Array:</b>'))
|
||||
grid0.addWidget(self.drill_array_linear_label, 3, 0, 1, 2)
|
||||
|
||||
# Linear Drill Array direction
|
||||
self.drill_axis_label = QtWidgets.QLabel(_('Linear Dir.:'))
|
||||
self.drill_axis_label.setToolTip(
|
||||
_("Direction on which the linear array is oriented:\n"
|
||||
"- 'X' - horizontal axis \n"
|
||||
"- 'Y' - vertical axis or \n"
|
||||
"- 'Angle' - a custom angle for the array inclination")
|
||||
)
|
||||
# self.drill_axis_label.setFixedWidth(100)
|
||||
self.drill_axis_radio = RadioSet([{'label': 'X', 'value': 'X'},
|
||||
{'label': 'Y', 'value': 'Y'},
|
||||
{'label': 'Angle', 'value': 'A'}])
|
||||
|
||||
grid0.addWidget(self.drill_axis_label, 4, 0)
|
||||
grid0.addWidget(self.drill_axis_radio, 4, 1)
|
||||
|
||||
# Linear Drill Array pitch distance
|
||||
self.drill_pitch_label = QtWidgets.QLabel(_('Pitch:'))
|
||||
self.drill_pitch_label.setToolTip(
|
||||
_("Pitch = Distance between elements of the array.")
|
||||
)
|
||||
# self.drill_pitch_label.setFixedWidth(100)
|
||||
self.drill_pitch_entry = LengthEntry()
|
||||
|
||||
grid0.addWidget(self.drill_pitch_label, 5, 0)
|
||||
grid0.addWidget(self.drill_pitch_entry, 5, 1)
|
||||
|
||||
# Linear Drill Array custom angle
|
||||
self.drill_angle_label = QtWidgets.QLabel(_('Angle:'))
|
||||
self.drill_angle_label.setToolTip(
|
||||
_("Angle at which each element in circular array is placed.")
|
||||
)
|
||||
self.drill_angle_entry = LengthEntry()
|
||||
|
||||
grid0.addWidget(self.drill_angle_label, 6, 0)
|
||||
grid0.addWidget(self.drill_angle_entry, 6, 1)
|
||||
|
||||
self.drill_array_circ_label = QtWidgets.QLabel(_('<b>Circular Drill Array:</b>'))
|
||||
grid0.addWidget(self.drill_array_circ_label, 7, 0, 1, 2)
|
||||
|
||||
# Circular Drill Array direction
|
||||
self.drill_circular_direction_label = QtWidgets.QLabel(_('Circular Dir.:'))
|
||||
self.drill_circular_direction_label.setToolTip(
|
||||
_("Direction for circular array.\n"
|
||||
"Can be CW = clockwise or CCW = counter clockwise.")
|
||||
)
|
||||
|
||||
self.drill_circular_dir_radio = RadioSet([{'label': 'CW', 'value': 'CW'},
|
||||
{'label': 'CCW.', 'value': 'CCW'}])
|
||||
|
||||
grid0.addWidget(self.drill_circular_direction_label, 8, 0)
|
||||
grid0.addWidget(self.drill_circular_dir_radio, 8, 1)
|
||||
|
||||
# Circular Drill Array Angle
|
||||
self.drill_circular_angle_label = QtWidgets.QLabel(_('Circ. Angle:'))
|
||||
self.drill_circular_angle_label.setToolTip(
|
||||
_("Angle at which each element in circular array is placed.")
|
||||
)
|
||||
self.drill_circular_angle_entry = LengthEntry()
|
||||
|
||||
grid0.addWidget(self.drill_circular_angle_label, 9, 0)
|
||||
grid0.addWidget(self.drill_circular_angle_entry, 9, 1)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
|
||||
class GeometryGenPrefGroupUI(OptionsGroupUI):
|
||||
def __init__(self, parent=None):
|
||||
# OptionsGroupUI.__init__(self, "Geometry General Preferences", parent=parent)
|
||||
|
@ -5033,7 +5154,7 @@ class GeometryGenPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("Geometry General")))
|
||||
|
||||
## Plot options
|
||||
# ## Plot options
|
||||
self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
|
||||
self.layout.addWidget(self.plot_options_label)
|
||||
|
||||
|
@ -5084,7 +5205,7 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
|
|||
self.setTitle(str(_("Geometry Options")))
|
||||
|
||||
# ------------------------------
|
||||
## Create CNC Job
|
||||
# ## Create CNC Job
|
||||
# ------------------------------
|
||||
self.cncjob_label = QtWidgets.QLabel(_('<b>Create CNC Job:</b>'))
|
||||
self.cncjob_label.setToolTip(
|
||||
|
@ -5243,7 +5364,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
self.setTitle(str(_("Geometry Adv. Options")))
|
||||
|
||||
# ------------------------------
|
||||
## Advanced Options
|
||||
# ## Advanced Options
|
||||
# ------------------------------
|
||||
self.cncjob_label = QtWidgets.QLabel(_('<b>Advanced Options:</b>'))
|
||||
self.cncjob_label.setToolTip(
|
||||
|
@ -5405,7 +5526,7 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("CNC Job General")))
|
||||
|
||||
## Plot options
|
||||
# ## Plot options
|
||||
self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
|
||||
self.layout.addWidget(self.plot_options_label)
|
||||
|
||||
|
@ -5441,15 +5562,62 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.cncplot_method_radio, 1, 1)
|
||||
grid0.addWidget(QtWidgets.QLabel(''), 1, 2)
|
||||
|
||||
# Number of circle steps for circular aperture linear approximation
|
||||
# Display Annotation
|
||||
self.annotation_label = QtWidgets.QLabel(_("Display Annotation:"))
|
||||
self.annotation_label.setToolTip(
|
||||
_("This selects if to display text annotation on the plot.\n"
|
||||
"When checked it will display numbers in order for each end\n"
|
||||
"of a travel line."
|
||||
)
|
||||
)
|
||||
self.annotation_cb = FCCheckBox()
|
||||
|
||||
grid0.addWidget(self.annotation_label, 2, 0)
|
||||
grid0.addWidget(self.annotation_cb, 2, 1)
|
||||
grid0.addWidget(QtWidgets.QLabel(''), 2, 2)
|
||||
|
||||
# Annotation Font Size
|
||||
self.annotation_fontsize_label = QtWidgets.QLabel(_("Annotation Size:"))
|
||||
self.annotation_fontsize_label.setToolTip(
|
||||
_("The font size of the annotation text. In pixels.")
|
||||
)
|
||||
grid0.addWidget(self.annotation_fontsize_label, 3, 0)
|
||||
self.annotation_fontsize_sp = FCSpinner()
|
||||
grid0.addWidget(self.annotation_fontsize_sp, 3, 1)
|
||||
grid0.addWidget(QtWidgets.QLabel(''), 3, 2)
|
||||
|
||||
# Annotation Font Color
|
||||
self.annotation_color_label = QtWidgets.QLabel(_('Annotation Color:'))
|
||||
self.annotation_color_label.setToolTip(
|
||||
_("Set the font color for the annotation texts.")
|
||||
)
|
||||
self.annotation_fontcolor_entry = FCEntry()
|
||||
self.annotation_fontcolor_button = QtWidgets.QPushButton()
|
||||
self.annotation_fontcolor_button.setFixedSize(15, 15)
|
||||
|
||||
self.form_box_child = QtWidgets.QHBoxLayout()
|
||||
self.form_box_child.setContentsMargins(0, 0, 0, 0)
|
||||
self.form_box_child.addWidget(self.annotation_fontcolor_entry)
|
||||
self.form_box_child.addWidget(self.annotation_fontcolor_button, alignment=Qt.AlignRight)
|
||||
self.form_box_child.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
||||
|
||||
color_widget = QtWidgets.QWidget()
|
||||
color_widget.setLayout(self.form_box_child)
|
||||
grid0.addWidget(self.annotation_color_label, 4, 0)
|
||||
grid0.addWidget(color_widget, 4, 1)
|
||||
grid0.addWidget(QtWidgets.QLabel(''), 4, 2)
|
||||
|
||||
# ###################################################################
|
||||
# Number of circle steps for circular aperture linear approximation #
|
||||
# ###################################################################
|
||||
self.steps_per_circle_label = QtWidgets.QLabel(_("Circle Steps:"))
|
||||
self.steps_per_circle_label.setToolTip(
|
||||
_("The number of circle steps for <b>GCode</b> \n"
|
||||
"circle and arc shapes linear approximation.")
|
||||
)
|
||||
grid0.addWidget(self.steps_per_circle_label, 2, 0)
|
||||
grid0.addWidget(self.steps_per_circle_label, 5, 0)
|
||||
self.steps_per_circle_entry = IntEntry()
|
||||
grid0.addWidget(self.steps_per_circle_entry, 2, 1)
|
||||
grid0.addWidget(self.steps_per_circle_entry, 5, 1)
|
||||
|
||||
# Tool dia for plot
|
||||
tdlabel = QtWidgets.QLabel(_('Tool dia:'))
|
||||
|
@ -5457,9 +5625,9 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
|
|||
_("Diameter of the tool to be\n"
|
||||
"rendered in the plot.")
|
||||
)
|
||||
grid0.addWidget(tdlabel, 3, 0)
|
||||
grid0.addWidget(tdlabel, 6, 0)
|
||||
self.tooldia_entry = LengthEntry()
|
||||
grid0.addWidget(self.tooldia_entry, 3, 1)
|
||||
grid0.addWidget(self.tooldia_entry,6, 1)
|
||||
|
||||
# Number of decimals to use in GCODE coordinates
|
||||
cdeclabel = QtWidgets.QLabel(_('Coords dec.:'))
|
||||
|
@ -5467,9 +5635,9 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
|
|||
_("The number of decimals to be used for \n"
|
||||
"the X, Y, Z coordinates in CNC code (GCODE, etc.)")
|
||||
)
|
||||
grid0.addWidget(cdeclabel, 4, 0)
|
||||
grid0.addWidget(cdeclabel, 7, 0)
|
||||
self.coords_dec_entry = IntEntry()
|
||||
grid0.addWidget(self.coords_dec_entry, 4, 1)
|
||||
grid0.addWidget(self.coords_dec_entry, 7, 1)
|
||||
|
||||
# Number of decimals to use in GCODE feedrate
|
||||
frdeclabel = QtWidgets.QLabel(_('Feedrate dec.:'))
|
||||
|
@ -5477,9 +5645,9 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
|
|||
_("The number of decimals to be used for \n"
|
||||
"the Feedrate parameter in CNC code (GCODE, etc.)")
|
||||
)
|
||||
grid0.addWidget(frdeclabel, 5, 0)
|
||||
grid0.addWidget(frdeclabel, 8, 0)
|
||||
self.fr_dec_entry = IntEntry()
|
||||
grid0.addWidget(self.fr_dec_entry, 5, 1)
|
||||
grid0.addWidget(self.fr_dec_entry, 8, 1)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
|
@ -5491,7 +5659,7 @@ class CNCJobOptPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("CNC Job Options")))
|
||||
|
||||
## Export G-Code
|
||||
# ## Export G-Code
|
||||
self.export_gcode_label = QtWidgets.QLabel(_("<b>Export G-Code:</b>"))
|
||||
self.export_gcode_label.setToolTip(
|
||||
_("Export and save G-Code to\n"
|
||||
|
@ -5532,7 +5700,7 @@ class CNCJobAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("CNC Job Adv. Options")))
|
||||
|
||||
## Export G-Code
|
||||
# ## Export G-Code
|
||||
self.export_gcode_label = QtWidgets.QLabel(_("<b>Export G-Code:</b>"))
|
||||
self.export_gcode_label.setToolTip(
|
||||
_("Export and save G-Code to\n"
|
||||
|
@ -5592,7 +5760,8 @@ class CNCJobAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
self.tc_variable_combo.setItemData(8, _("z_move = Z height for travel"), Qt.ToolTipRole)
|
||||
self.tc_variable_combo.setItemData(9, _("z_depthpercut = the step value for multidepth cut"), Qt.ToolTipRole)
|
||||
self.tc_variable_combo.setItemData(10, _("spindlesspeed = the value for the spindle speed"), Qt.ToolTipRole)
|
||||
self.tc_variable_combo.setItemData(11, _("dwelltime = time to dwell to allow the spindle to reach it's set RPM"),
|
||||
self.tc_variable_combo.setItemData(11,
|
||||
_("dwelltime = time to dwell to allow the spindle to reach it's set RPM"),
|
||||
Qt.ToolTipRole)
|
||||
|
||||
hlay1.addStretch()
|
||||
|
@ -5615,7 +5784,7 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("NCC Tool Options")))
|
||||
|
||||
## Clear non-copper regions
|
||||
# ## Clear non-copper regions
|
||||
self.clearcopper_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
|
||||
self.clearcopper_label.setToolTip(
|
||||
_("Create a Geometry object with\n"
|
||||
|
@ -5716,7 +5885,7 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("Cutout Tool Options")))
|
||||
|
||||
## Board cuttout
|
||||
# ## Board cuttout
|
||||
self.board_cutout_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
|
||||
self.board_cutout_label.setToolTip(
|
||||
_("Create toolpaths to cut around\n"
|
||||
|
@ -5795,7 +5964,7 @@ class Tools2sidedPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("2Sided Tool Options")))
|
||||
|
||||
## Board cuttout
|
||||
# ## Board cuttout
|
||||
self.dblsided_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
|
||||
self.dblsided_label.setToolTip(
|
||||
_("A tool to help in creating a double sided\n"
|
||||
|
@ -5806,7 +5975,7 @@ class Tools2sidedPrefGroupUI(OptionsGroupUI):
|
|||
grid0 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid0)
|
||||
|
||||
## Drill diameter for alignment holes
|
||||
# ## Drill diameter for alignment holes
|
||||
self.drill_dia_entry = LengthEntry()
|
||||
self.dd_label = QtWidgets.QLabel(_("Drill diam.:"))
|
||||
self.dd_label.setToolTip(
|
||||
|
@ -5816,7 +5985,7 @@ class Tools2sidedPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.dd_label, 0, 0)
|
||||
grid0.addWidget(self.drill_dia_entry, 0, 1)
|
||||
|
||||
## Axis
|
||||
# ## Axis
|
||||
self.mirror_axis_radio = RadioSet([{'label': 'X', 'value': 'X'},
|
||||
{'label': 'Y', 'value': 'Y'}])
|
||||
self.mirax_label = QtWidgets.QLabel(_("Mirror Axis:"))
|
||||
|
@ -5829,7 +5998,7 @@ class Tools2sidedPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.mirax_label, 2, 0)
|
||||
grid0.addWidget(self.mirror_axis_radio, 2, 1)
|
||||
|
||||
## Axis Location
|
||||
# ## Axis Location
|
||||
self.axis_location_radio = RadioSet([{'label': 'Point', 'value': 'point'},
|
||||
{'label': 'Box', 'value': 'box'}])
|
||||
self.axloc_label = QtWidgets.QLabel(_("Axis Ref:"))
|
||||
|
@ -5853,7 +6022,7 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI):
|
|||
self.setTitle(str(_("Paint Tool Options")))
|
||||
|
||||
# ------------------------------
|
||||
## Paint area
|
||||
# ## Paint area
|
||||
# ------------------------------
|
||||
self.paint_label = QtWidgets.QLabel(_('<b>Parameters:</b>'))
|
||||
self.paint_label.setToolTip(
|
||||
|
@ -5957,7 +6126,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("Film Tool Options")))
|
||||
|
||||
## Board cuttout
|
||||
# ## Board cuttout
|
||||
self.film_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
|
||||
self.film_label.setToolTip(
|
||||
_("Create a PCB film from a Gerber or Geometry\n"
|
||||
|
@ -6018,7 +6187,7 @@ class ToolsPanelizePrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("Panelize Tool Options")))
|
||||
|
||||
## Board cuttout
|
||||
# ## Board cuttout
|
||||
self.panelize_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
|
||||
self.panelize_label.setToolTip(
|
||||
_("Create an object that contains an array of (x, y) elements,\n"
|
||||
|
@ -6030,7 +6199,7 @@ class ToolsPanelizePrefGroupUI(OptionsGroupUI):
|
|||
grid0 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid0)
|
||||
|
||||
## Spacing Columns
|
||||
# ## Spacing Columns
|
||||
self.pspacing_columns = FCEntry()
|
||||
self.spacing_columns_label = QtWidgets.QLabel(_("Spacing cols:"))
|
||||
self.spacing_columns_label.setToolTip(
|
||||
|
@ -6040,7 +6209,7 @@ class ToolsPanelizePrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.spacing_columns_label, 0, 0)
|
||||
grid0.addWidget(self.pspacing_columns, 0, 1)
|
||||
|
||||
## Spacing Rows
|
||||
# ## Spacing Rows
|
||||
self.pspacing_rows = FCEntry()
|
||||
self.spacing_rows_label = QtWidgets.QLabel(_("Spacing rows:"))
|
||||
self.spacing_rows_label.setToolTip(
|
||||
|
@ -6050,7 +6219,7 @@ class ToolsPanelizePrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.spacing_rows_label, 1, 0)
|
||||
grid0.addWidget(self.pspacing_rows, 1, 1)
|
||||
|
||||
## Columns
|
||||
# ## Columns
|
||||
self.pcolumns = FCEntry()
|
||||
self.columns_label = QtWidgets.QLabel(_("Columns:"))
|
||||
self.columns_label.setToolTip(
|
||||
|
@ -6059,7 +6228,7 @@ class ToolsPanelizePrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.columns_label, 2, 0)
|
||||
grid0.addWidget(self.pcolumns, 2, 1)
|
||||
|
||||
## Rows
|
||||
# ## Rows
|
||||
self.prows = FCEntry()
|
||||
self.rows_label = QtWidgets.QLabel(_("Rows:"))
|
||||
self.rows_label.setToolTip(
|
||||
|
@ -6068,7 +6237,7 @@ class ToolsPanelizePrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.rows_label, 3, 0)
|
||||
grid0.addWidget(self.prows, 3, 1)
|
||||
|
||||
## Type of resulting Panel object
|
||||
# ## Type of resulting Panel object
|
||||
self.panel_type_radio = RadioSet([{'label': 'Gerber', 'value': 'gerber'},
|
||||
{'label': 'Geo', 'value': 'geometry'}])
|
||||
self.panel_type_label = QtWidgets.QLabel(_("Panel Type:"))
|
||||
|
@ -6081,7 +6250,7 @@ class ToolsPanelizePrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.panel_type_label, 4, 0)
|
||||
grid0.addWidget(self.panel_type_radio, 4, 1)
|
||||
|
||||
## Constrains
|
||||
# ## Constrains
|
||||
self.pconstrain_cb = FCCheckBox(_("Constrain within:"))
|
||||
self.pconstrain_cb.setToolTip(
|
||||
_("Area define by DX and DY within to constrain the panel.\n"
|
||||
|
@ -6120,7 +6289,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("Calculators Tool Options")))
|
||||
|
||||
## V-shape Calculator Tool
|
||||
# ## V-shape Calculator Tool
|
||||
self.vshape_tool_label = QtWidgets.QLabel(_("<b>V-Shape Tool Calculator:</b>"))
|
||||
self.vshape_tool_label.setToolTip(
|
||||
_("Calculate the tool diameter for a given V-shape tool,\n"
|
||||
|
@ -6132,7 +6301,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
|
|||
grid0 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid0)
|
||||
|
||||
## Tip Diameter
|
||||
# ## Tip Diameter
|
||||
self.tip_dia_entry = FCEntry()
|
||||
self.tip_dia_label = QtWidgets.QLabel(_("Tip Diameter:"))
|
||||
self.tip_dia_label.setToolTip(
|
||||
|
@ -6142,7 +6311,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.tip_dia_label, 0, 0)
|
||||
grid0.addWidget(self.tip_dia_entry, 0, 1)
|
||||
|
||||
## Tip angle
|
||||
# ## Tip angle
|
||||
self.tip_angle_entry = FCEntry()
|
||||
self.tip_angle_label = QtWidgets.QLabel(_("Tip angle:"))
|
||||
self.tip_angle_label.setToolTip(
|
||||
|
@ -6152,7 +6321,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.tip_angle_label, 1, 0)
|
||||
grid0.addWidget(self.tip_angle_entry, 1, 1)
|
||||
|
||||
## Depth-of-cut Cut Z
|
||||
# ## Depth-of-cut Cut Z
|
||||
self.cut_z_entry = FCEntry()
|
||||
self.cut_z_label = QtWidgets.QLabel(_("Cut Z:"))
|
||||
self.cut_z_label.setToolTip(
|
||||
|
@ -6162,7 +6331,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.cut_z_label, 2, 0)
|
||||
grid0.addWidget(self.cut_z_entry, 2, 1)
|
||||
|
||||
## Electroplating Calculator Tool
|
||||
# ## Electroplating Calculator Tool
|
||||
self.plate_title_label = QtWidgets.QLabel(_("<b>ElectroPlating Calculator:</b>"))
|
||||
self.plate_title_label.setToolTip(
|
||||
_("This calculator is useful for those who plate the via/pad/drill holes,\n"
|
||||
|
@ -6173,7 +6342,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
|
|||
grid1 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid1)
|
||||
|
||||
## PCB Length
|
||||
# ## PCB Length
|
||||
self.pcblength_entry = FCEntry()
|
||||
self.pcblengthlabel = QtWidgets.QLabel(_("Board Length:"))
|
||||
|
||||
|
@ -6181,7 +6350,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
|
|||
grid1.addWidget(self.pcblengthlabel, 0, 0)
|
||||
grid1.addWidget(self.pcblength_entry, 0, 1)
|
||||
|
||||
## PCB Width
|
||||
# ## PCB Width
|
||||
self.pcbwidth_entry = FCEntry()
|
||||
self.pcbwidthlabel = QtWidgets.QLabel(_("Board Width:"))
|
||||
|
||||
|
@ -6189,7 +6358,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
|
|||
grid1.addWidget(self.pcbwidthlabel, 1, 0)
|
||||
grid1.addWidget(self.pcbwidth_entry, 1, 1)
|
||||
|
||||
## Current Density
|
||||
# ## Current Density
|
||||
self.cdensity_label = QtWidgets.QLabel(_("Current Density:"))
|
||||
self.cdensity_entry = FCEntry()
|
||||
|
||||
|
@ -6198,7 +6367,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
|
|||
grid1.addWidget(self.cdensity_label, 2, 0)
|
||||
grid1.addWidget(self.cdensity_entry, 2, 1)
|
||||
|
||||
## PCB Copper Growth
|
||||
# ## PCB Copper Growth
|
||||
self.growth_label = QtWidgets.QLabel(_("Copper Growth:"))
|
||||
self.growth_entry = FCEntry()
|
||||
|
||||
|
@ -6217,7 +6386,7 @@ class ToolsTransformPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("Transform Tool Options")))
|
||||
|
||||
## Transformations
|
||||
# ## Transformations
|
||||
self.transform_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
|
||||
self.transform_label.setToolTip(
|
||||
_("Various transformations that can be applied\n"
|
||||
|
@ -6228,7 +6397,7 @@ class ToolsTransformPrefGroupUI(OptionsGroupUI):
|
|||
grid0 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid0)
|
||||
|
||||
## Rotate Angle
|
||||
# ## Rotate Angle
|
||||
self.rotate_entry = FCEntry()
|
||||
self.rotate_label = QtWidgets.QLabel(_("Rotate Angle:"))
|
||||
self.rotate_label.setToolTip(
|
||||
|
@ -6237,7 +6406,7 @@ class ToolsTransformPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.rotate_label, 0, 0)
|
||||
grid0.addWidget(self.rotate_entry, 0, 1)
|
||||
|
||||
## Skew/Shear Angle on X axis
|
||||
# ## Skew/Shear Angle on X axis
|
||||
self.skewx_entry = FCEntry()
|
||||
self.skewx_label = QtWidgets.QLabel(_("Skew_X angle:"))
|
||||
self.skewx_label.setToolTip(
|
||||
|
@ -6246,7 +6415,7 @@ class ToolsTransformPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.skewx_label, 1, 0)
|
||||
grid0.addWidget(self.skewx_entry, 1, 1)
|
||||
|
||||
## Skew/Shear Angle on Y axis
|
||||
# ## Skew/Shear Angle on Y axis
|
||||
self.skewy_entry = FCEntry()
|
||||
self.skewy_label = QtWidgets.QLabel(_("Skew_Y angle:"))
|
||||
self.skewy_label.setToolTip(
|
||||
|
@ -6255,7 +6424,7 @@ class ToolsTransformPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.skewy_label, 2, 0)
|
||||
grid0.addWidget(self.skewy_entry, 2, 1)
|
||||
|
||||
## Scale factor on X axis
|
||||
# ## Scale factor on X axis
|
||||
self.scalex_entry = FCEntry()
|
||||
self.scalex_label = QtWidgets.QLabel(_("Scale_X factor:"))
|
||||
self.scalex_label.setToolTip(
|
||||
|
@ -6264,7 +6433,7 @@ class ToolsTransformPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.scalex_label, 3, 0)
|
||||
grid0.addWidget(self.scalex_entry, 3, 1)
|
||||
|
||||
## Scale factor on X axis
|
||||
# ## Scale factor on X axis
|
||||
self.scaley_entry = FCEntry()
|
||||
self.scaley_label = QtWidgets.QLabel(_("Scale_Y factor:"))
|
||||
self.scaley_label.setToolTip(
|
||||
|
@ -6273,7 +6442,7 @@ class ToolsTransformPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.scaley_label, 4, 0)
|
||||
grid0.addWidget(self.scaley_entry, 4, 1)
|
||||
|
||||
## Link Scale factors
|
||||
# ## Link Scale factors
|
||||
self.link_cb = FCCheckBox(_("Link"))
|
||||
self.link_cb.setToolTip(
|
||||
_("Scale the selected object(s)\n"
|
||||
|
@ -6281,7 +6450,7 @@ class ToolsTransformPrefGroupUI(OptionsGroupUI):
|
|||
)
|
||||
grid0.addWidget(self.link_cb, 5, 0)
|
||||
|
||||
## Scale Reference
|
||||
# ## Scale Reference
|
||||
self.reference_cb = FCCheckBox(_("Scale Reference"))
|
||||
self.reference_cb.setToolTip(
|
||||
_("Scale the selected object(s)\n"
|
||||
|
@ -6291,7 +6460,7 @@ class ToolsTransformPrefGroupUI(OptionsGroupUI):
|
|||
)
|
||||
grid0.addWidget(self.reference_cb, 5, 1)
|
||||
|
||||
## Offset distance on X axis
|
||||
# ## Offset distance on X axis
|
||||
self.offx_entry = FCEntry()
|
||||
self.offx_label = QtWidgets.QLabel(_("Offset_X val:"))
|
||||
self.offx_label.setToolTip(
|
||||
|
@ -6300,7 +6469,7 @@ class ToolsTransformPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.offx_label, 6, 0)
|
||||
grid0.addWidget(self.offx_entry, 6, 1)
|
||||
|
||||
## Offset distance on Y axis
|
||||
# ## Offset distance on Y axis
|
||||
self.offy_entry = FCEntry()
|
||||
self.offy_label = QtWidgets.QLabel(_("Offset_Y val:"))
|
||||
self.offy_label.setToolTip(
|
||||
|
@ -6309,7 +6478,7 @@ class ToolsTransformPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.offy_label, 7, 0)
|
||||
grid0.addWidget(self.offy_entry, 7, 1)
|
||||
|
||||
## Mirror (Flip) Reference Point
|
||||
# ## Mirror (Flip) Reference Point
|
||||
self.mirror_reference_cb = FCCheckBox(_("Mirror Reference"))
|
||||
self.mirror_reference_cb.setToolTip(
|
||||
_("Flip the selected object(s)\n"
|
||||
|
@ -6344,7 +6513,7 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
|||
|
||||
self.setTitle(str(_("SolderPaste Tool Options")))
|
||||
|
||||
## Solder Paste Dispensing
|
||||
# ## Solder Paste Dispensing
|
||||
self.solderpastelabel = QtWidgets.QLabel(_("<b>Parameters:</b>"))
|
||||
self.solderpastelabel.setToolTip(
|
||||
_("A tool to create GCode for dispensing\n"
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
# File Modified (major mod): Marius Adrian Stanciu #
|
||||
# Date: 3/10/2019 #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from PyQt5 import QtGui, QtCore, QtWidgets
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
|
||||
|
@ -159,6 +159,10 @@ class LengthEntry(QtWidgets.QLineEdit):
|
|||
'MM': 1.0}
|
||||
}
|
||||
self.readyToEdit = True
|
||||
self.editingFinished.connect(self.on_edit_finished)
|
||||
|
||||
def on_edit_finished(self):
|
||||
self.clearFocus()
|
||||
|
||||
def mousePressEvent(self, e, Parent=None):
|
||||
super(LengthEntry, self).mousePressEvent(e) # required to deselect on 2e click
|
||||
|
@ -209,6 +213,10 @@ class FloatEntry(QtWidgets.QLineEdit):
|
|||
def __init__(self, parent=None):
|
||||
super(FloatEntry, self).__init__(parent)
|
||||
self.readyToEdit = True
|
||||
self.editingFinished.connect(self.on_edit_finished)
|
||||
|
||||
def on_edit_finished(self):
|
||||
self.clearFocus()
|
||||
|
||||
def mousePressEvent(self, e, Parent=None):
|
||||
super(FloatEntry, self).mousePressEvent(e) # required to deselect on 2e click
|
||||
|
@ -256,6 +264,10 @@ class FloatEntry2(QtWidgets.QLineEdit):
|
|||
def __init__(self, parent=None):
|
||||
super(FloatEntry2, self).__init__(parent)
|
||||
self.readyToEdit = True
|
||||
self.editingFinished.connect(self.on_edit_finished)
|
||||
|
||||
def on_edit_finished(self):
|
||||
self.clearFocus()
|
||||
|
||||
def mousePressEvent(self, e, Parent=None):
|
||||
super(FloatEntry2, self).mousePressEvent(e) # required to deselect on 2e click
|
||||
|
@ -295,6 +307,10 @@ class IntEntry(QtWidgets.QLineEdit):
|
|||
self.allow_empty = allow_empty
|
||||
self.empty_val = empty_val
|
||||
self.readyToEdit = True
|
||||
self.editingFinished.connect(self.on_edit_finished)
|
||||
|
||||
def on_edit_finished(self):
|
||||
self.clearFocus()
|
||||
|
||||
def mousePressEvent(self, e, Parent=None):
|
||||
super(IntEntry, self).mousePressEvent(e) # required to deselect on 2e click
|
||||
|
@ -335,6 +351,10 @@ class FCEntry(QtWidgets.QLineEdit):
|
|||
def __init__(self, parent=None):
|
||||
super(FCEntry, self).__init__(parent)
|
||||
self.readyToEdit = True
|
||||
self.editingFinished.connect(self.on_edit_finished)
|
||||
|
||||
def on_edit_finished(self):
|
||||
self.clearFocus()
|
||||
|
||||
def mousePressEvent(self, e, Parent=None):
|
||||
super(FCEntry, self).mousePressEvent(e) # required to deselect on 2e click
|
||||
|
@ -365,6 +385,10 @@ class FCEntry2(FCEntry):
|
|||
def __init__(self, parent=None):
|
||||
super(FCEntry2, self).__init__(parent)
|
||||
self.readyToEdit = True
|
||||
self.editingFinished.connect(self.on_edit_finished)
|
||||
|
||||
def on_edit_finished(self):
|
||||
self.clearFocus()
|
||||
|
||||
def set_value(self, val):
|
||||
try:
|
||||
|
@ -378,6 +402,10 @@ class EvalEntry(QtWidgets.QLineEdit):
|
|||
def __init__(self, parent=None):
|
||||
super(EvalEntry, self).__init__(parent)
|
||||
self.readyToEdit = True
|
||||
self.editingFinished.connect(self.on_edit_finished)
|
||||
|
||||
def on_edit_finished(self):
|
||||
self.clearFocus()
|
||||
|
||||
def mousePressEvent(self, e, Parent=None):
|
||||
super(EvalEntry, self).mousePressEvent(e) # required to deselect on 2e click
|
||||
|
@ -420,6 +448,10 @@ class EvalEntry2(QtWidgets.QLineEdit):
|
|||
def __init__(self, parent=None):
|
||||
super(EvalEntry2, self).__init__(parent)
|
||||
self.readyToEdit = True
|
||||
self.editingFinished.connect(self.on_edit_finished)
|
||||
|
||||
def on_edit_finished(self):
|
||||
self.clearFocus()
|
||||
|
||||
def mousePressEvent(self, e, Parent=None):
|
||||
super(EvalEntry2, self).mousePressEvent(e) # required to deselect on 2e click
|
||||
|
@ -1462,6 +1494,10 @@ class FCSpinner(QtWidgets.QSpinBox):
|
|||
def __init__(self, parent=None):
|
||||
super(FCSpinner, self).__init__(parent)
|
||||
self.readyToEdit = True
|
||||
self.editingFinished.connect(self.on_edit_finished)
|
||||
|
||||
def on_edit_finished(self):
|
||||
self.clearFocus()
|
||||
|
||||
def mousePressEvent(self, e, parent=None):
|
||||
super(FCSpinner, self).mousePressEvent(e) # required to deselect on 2e click
|
||||
|
@ -1497,6 +1533,10 @@ class FCDoubleSpinner(QtWidgets.QDoubleSpinBox):
|
|||
def __init__(self, parent=None):
|
||||
super(FCDoubleSpinner, self).__init__(parent)
|
||||
self.readyToEdit = True
|
||||
self.editingFinished.connect(self.on_edit_finished)
|
||||
|
||||
def on_edit_finished(self):
|
||||
self.clearFocus()
|
||||
|
||||
def mousePressEvent(self, e, parent=None):
|
||||
super(FCDoubleSpinner, self).mousePressEvent(e) # required to deselect on 2e click
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
# File Modified (major mod): Marius Adrian Stanciu #
|
||||
# Date: 3/10/2019 #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from PyQt5 import QtGui, QtCore, QtWidgets
|
||||
from PyQt5.QtCore import Qt
|
||||
|
@ -36,22 +36,22 @@ class ObjectUI(QtWidgets.QWidget):
|
|||
layout = QtWidgets.QVBoxLayout()
|
||||
self.setLayout(layout)
|
||||
|
||||
## Page Title box (spacing between children)
|
||||
# ## Page Title box (spacing between children)
|
||||
self.title_box = QtWidgets.QHBoxLayout()
|
||||
layout.addLayout(self.title_box)
|
||||
|
||||
## Page Title icon
|
||||
# ## Page Title icon
|
||||
pixmap = QtGui.QPixmap(icon_file)
|
||||
self.icon = QtWidgets.QLabel()
|
||||
self.icon.setPixmap(pixmap)
|
||||
self.title_box.addWidget(self.icon, stretch=0)
|
||||
|
||||
## Title label
|
||||
# ## Title label
|
||||
self.title_label = QtWidgets.QLabel("<font size=5><b>%s</b></font>" % title)
|
||||
self.title_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
||||
self.title_box.addWidget(self.title_label, stretch=1)
|
||||
|
||||
## App Level label
|
||||
# ## App Level label
|
||||
self.level = QtWidgets.QLabel("")
|
||||
self.level.setToolTip(
|
||||
_(
|
||||
|
@ -66,13 +66,13 @@ class ObjectUI(QtWidgets.QWidget):
|
|||
self.level.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||
self.title_box.addWidget(self.level)
|
||||
|
||||
## Box box for custom widgets
|
||||
# ## Box box for custom widgets
|
||||
# This gets populated in offspring implementations.
|
||||
self.custom_box = QtWidgets.QVBoxLayout()
|
||||
layout.addLayout(self.custom_box)
|
||||
|
||||
######################### ##
|
||||
## Common to all objects ##
|
||||
# ## Common to all objects # ##
|
||||
######################### ##
|
||||
|
||||
#### Scale ## ##
|
||||
|
@ -176,7 +176,7 @@ class GerberObjectUI(ObjectUI):
|
|||
self.plot_cb.setFixedWidth(59)
|
||||
grid0.addWidget(self.plot_cb, 0, 3)
|
||||
|
||||
## Object name
|
||||
# ## Object name
|
||||
self.name_hlay = QtWidgets.QHBoxLayout()
|
||||
self.custom_box.addLayout(self.name_hlay)
|
||||
name_label = QtWidgets.QLabel(_("<b>Name:</b>"))
|
||||
|
@ -380,7 +380,7 @@ class GerberObjectUI(ObjectUI):
|
|||
grid2 = QtWidgets.QGridLayout()
|
||||
self.custom_box.addLayout(grid2)
|
||||
|
||||
## Clear non-copper regions
|
||||
# ## Clear non-copper regions
|
||||
self.clearcopper_label = QtWidgets.QLabel(_("<b>Clear N-copper:</b>"))
|
||||
self.clearcopper_label.setToolTip(
|
||||
_("Create a Geometry object with\n"
|
||||
|
@ -396,7 +396,7 @@ class GerberObjectUI(ObjectUI):
|
|||
)
|
||||
grid2.addWidget(self.generate_ncc_button, 0, 1)
|
||||
|
||||
## Board cutout
|
||||
# ## Board cutout
|
||||
self.board_cutout_label = QtWidgets.QLabel(_("<b>Board cutout:</b>"))
|
||||
self.board_cutout_label.setToolTip(
|
||||
_("Create toolpaths to cut around\n"
|
||||
|
@ -412,7 +412,7 @@ class GerberObjectUI(ObjectUI):
|
|||
)
|
||||
grid2.addWidget(self.generate_cutout_button, 1, 1)
|
||||
|
||||
## Non-copper regions
|
||||
# ## Non-copper regions
|
||||
self.noncopper_label = QtWidgets.QLabel(_("<b>Non-copper regions:</b>"))
|
||||
self.noncopper_label.setToolTip(
|
||||
_("Create polygons covering the\n"
|
||||
|
@ -450,7 +450,7 @@ class GerberObjectUI(ObjectUI):
|
|||
self.generate_noncopper_button = QtWidgets.QPushButton(_('Generate Geo'))
|
||||
grid4.addWidget(self.generate_noncopper_button, 1, 1)
|
||||
|
||||
## Bounding box
|
||||
# ## Bounding box
|
||||
self.boundingbox_label = QtWidgets.QLabel(_('<b>Bounding Box:</b>'))
|
||||
self.boundingbox_label.setToolTip(
|
||||
_("Create a geometry surrounding the Gerber object.\n"
|
||||
|
@ -511,7 +511,7 @@ class ExcellonObjectUI(ObjectUI):
|
|||
hlay_plot.addStretch()
|
||||
hlay_plot.addWidget(self.solid_cb)
|
||||
|
||||
## Object name
|
||||
# ## Object name
|
||||
self.name_hlay = QtWidgets.QHBoxLayout()
|
||||
self.custom_box.addLayout(self.name_hlay)
|
||||
name_label = QtWidgets.QLabel(_("<b>Name:</b>"))
|
||||
|
@ -833,7 +833,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
|
||||
self.custom_box.addWidget(self.plot_options_label)
|
||||
|
||||
## Object name
|
||||
# ## Object name
|
||||
self.name_hlay = QtWidgets.QHBoxLayout()
|
||||
self.custom_box.addLayout(self.name_hlay)
|
||||
name_label = QtWidgets.QLabel(_("<b>Name:</b>"))
|
||||
|
@ -1346,7 +1346,7 @@ class CNCObjectUI(ObjectUI):
|
|||
self.offset_label.hide()
|
||||
self.offset_button.hide()
|
||||
|
||||
## Plot options
|
||||
# ## Plot options
|
||||
self.plot_options_label = QtWidgets.QLabel(_("<b>Plot Options:</b>"))
|
||||
self.custom_box.addWidget(self.plot_options_label)
|
||||
|
||||
|
@ -1366,7 +1366,17 @@ class CNCObjectUI(ObjectUI):
|
|||
{"label": "Cut", "value": "cut"}
|
||||
], stretch=False)
|
||||
|
||||
## Object name
|
||||
self.annotation_label = QtWidgets.QLabel(_("<b>Display Annotation:</b>"))
|
||||
self.annotation_label.setToolTip(
|
||||
_(
|
||||
"This selects if to display text annotation on the plot.\n"
|
||||
"When checked it will display numbers in order for each end\n"
|
||||
"of a travel line."
|
||||
)
|
||||
)
|
||||
self.annotation_cb = FCCheckBox()
|
||||
|
||||
# ## Object name
|
||||
self.name_hlay = QtWidgets.QHBoxLayout()
|
||||
self.custom_box.addLayout(self.name_hlay)
|
||||
name_label = QtWidgets.QLabel(_("<b>Name:</b>"))
|
||||
|
@ -1399,9 +1409,12 @@ class CNCObjectUI(ObjectUI):
|
|||
f_lay.addWidget(self.cncplot_method_label, 0, 0)
|
||||
f_lay.addWidget(self.cncplot_method_combo, 0, 1)
|
||||
f_lay.addWidget(QtWidgets.QLabel(''), 0, 2)
|
||||
f_lay.addWidget(self.t_distance_label, 1, 0)
|
||||
f_lay.addWidget(self.t_distance_entry, 1, 1)
|
||||
f_lay.addWidget(self.units_label, 1, 2)
|
||||
f_lay.addWidget(self.annotation_label, 1, 0)
|
||||
f_lay.addWidget(self.annotation_cb, 1, 1)
|
||||
f_lay.addWidget(QtWidgets.QLabel(''), 1, 2)
|
||||
f_lay.addWidget(self.t_distance_label, 2, 0)
|
||||
f_lay.addWidget(self.t_distance_entry, 2, 1)
|
||||
f_lay.addWidget(self.units_label, 2, 2)
|
||||
|
||||
self.t_distance_label.hide()
|
||||
self.t_distance_entry.setVisible(False)
|
||||
|
@ -1463,7 +1476,7 @@ class CNCObjectUI(ObjectUI):
|
|||
self.custom_box.addWidget(self.updateplot_button)
|
||||
|
||||
################ ##
|
||||
## Export G-Code
|
||||
# ## Export G-Code
|
||||
################ ##
|
||||
self.export_gcode_label = QtWidgets.QLabel(_("<b>Export CNC Code:</b>"))
|
||||
self.export_gcode_label.setToolTip(
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://caram.cl/software/flatcam #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
|
@ -74,7 +74,7 @@ class PlotCanvas(QtCore.QObject):
|
|||
self.text_collection = self.new_text_collection()
|
||||
|
||||
# TODO: Should be setting to show/hide CNC job annotations (global or per object)
|
||||
self.text_collection.enabled = False
|
||||
self.text_collection.enabled = True
|
||||
|
||||
# draw a rectangle made out of 4 lines on the canvas to serve as a hint for the work area
|
||||
# all CNC have a limited workspace
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Dennis Hayrullin #
|
||||
# Date: 2/5/2016 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
import numpy as np
|
||||
from PyQt5.QtGui import QPalette
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Dennis Hayrullin #
|
||||
# Date: 2/5/2016 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from vispy.visuals import markers, LineVisual, InfiniteLineVisual
|
||||
from vispy.visuals.axis import Ticker, _get_ticks_talbot
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Dennis Hayrullin #
|
||||
# Date: 2/5/2016 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from OpenGL import GLU
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Dennis Hayrullin #
|
||||
# Date: 2/5/2016 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from vispy.visuals import CompoundVisual, LineVisual, MeshVisual, TextVisual, MarkersVisual
|
||||
from vispy.scene.visuals import VisualNode, generate_docstring, visuals
|
||||
|
@ -456,20 +456,26 @@ class TextCollectionVisual(TextVisual):
|
|||
self.data = {}
|
||||
self.last_key = -1
|
||||
self.lock = threading.Lock()
|
||||
|
||||
self.method = 'gpu'
|
||||
super(TextCollectionVisual, self).__init__(**kwargs)
|
||||
|
||||
self.freeze()
|
||||
|
||||
def add(self, text, pos, visible=True, update=True):
|
||||
def add(self, text, pos, visible=True, update=True, font_size=9, color='black'):
|
||||
"""
|
||||
Adds array of text to collection
|
||||
:param text: list
|
||||
Array of strings ['str1', 'str2', ... ]
|
||||
:param pos: list
|
||||
Array of string positions [(0, 0), (10, 10), ... ]
|
||||
:param visible: bool
|
||||
| Set True to make it visible
|
||||
:param update: bool
|
||||
Set True to redraw collection
|
||||
:param font_size: int
|
||||
Set font size to redraw collection
|
||||
:param color: string
|
||||
Set font color to redraw collection
|
||||
:return: int
|
||||
Index of array
|
||||
"""
|
||||
|
@ -480,7 +486,7 @@ class TextCollectionVisual(TextVisual):
|
|||
self.lock.release()
|
||||
|
||||
# Prepare data for translation
|
||||
self.data[key] = {'text': text, 'pos': pos, 'visible': visible}
|
||||
self.data[key] = {'text': text, 'pos': pos, 'visible': visible,'font_size': font_size, 'color': color}
|
||||
|
||||
if update:
|
||||
self.redraw()
|
||||
|
@ -516,6 +522,8 @@ class TextCollectionVisual(TextVisual):
|
|||
"""
|
||||
labels = []
|
||||
pos = []
|
||||
font_s = 9
|
||||
color = 'black'
|
||||
|
||||
# Merge buffers
|
||||
for data in list(self.data.values()):
|
||||
|
@ -523,6 +531,8 @@ class TextCollectionVisual(TextVisual):
|
|||
try:
|
||||
labels += data['text']
|
||||
pos += data['pos']
|
||||
font_s = data['font_size']
|
||||
color = data['color']
|
||||
except Exception as e:
|
||||
print("Data error", e)
|
||||
|
||||
|
@ -530,6 +540,8 @@ class TextCollectionVisual(TextVisual):
|
|||
if len(labels) > 0:
|
||||
self.text = labels
|
||||
self.pos = pos
|
||||
self.font_size = font_s
|
||||
self.color = color
|
||||
else:
|
||||
self.text = None
|
||||
self.pos = (0, 0)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from shapely.geometry import LineString
|
||||
import logging
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
# Vasilis Vlachoudis
|
||||
# Date: 20-Oct-2015
|
||||
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File modified: Marius Adrian Stanciu #
|
||||
# Date: 3/10/2019 #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
import math
|
||||
import sys
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
#########################################################################
|
||||
# ####################################################################### ##
|
||||
# ## Borrowed code from 'https://github.com/gddc/ttfquery/blob/master/ # ##
|
||||
# ## and made it work with Python 3 ########### ##
|
||||
#########################################################################
|
||||
# ####################################################################### ##
|
||||
|
||||
import re, os, sys, glob
|
||||
import itertools
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
|
@ -17,7 +17,7 @@
|
|||
# * All transformations #
|
||||
# #
|
||||
# Reference: www.w3.org/TR/SVG/Overview.html #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
# import xml.etree.ElementTree as ET
|
||||
from svg.path import Line, Arc, CubicBezier, QuadraticBezier, parse_path
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
from FlatCAMObj import *
|
||||
|
@ -31,7 +31,7 @@ class ToolCalculator(FlatCAMTool):
|
|||
|
||||
self.app = app
|
||||
|
||||
## Title
|
||||
# ## Title
|
||||
title_label = QtWidgets.QLabel("%s" % self.toolName)
|
||||
title_label.setStyleSheet("""
|
||||
QLabel
|
||||
|
@ -43,13 +43,13 @@ class ToolCalculator(FlatCAMTool):
|
|||
self.layout.addWidget(title_label)
|
||||
|
||||
#################### ##
|
||||
## Units Calculator ##
|
||||
# ## Units Calculator # ##
|
||||
#################### ##
|
||||
|
||||
self.unists_spacer_label = QtWidgets.QLabel(" ")
|
||||
self.layout.addWidget(self.unists_spacer_label)
|
||||
|
||||
## Title of the Units Calculator
|
||||
# ## Title of the Units Calculator
|
||||
units_label = QtWidgets.QLabel("<font size=3><b>%s</b></font>" % self.unitsName)
|
||||
self.layout.addWidget(units_label)
|
||||
|
||||
|
@ -77,17 +77,17 @@ class ToolCalculator(FlatCAMTool):
|
|||
|
||||
|
||||
########################## ##
|
||||
## V-shape Tool Calculator ##
|
||||
# ## V-shape Tool Calculator # ##
|
||||
########################## ##
|
||||
|
||||
self.v_shape_spacer_label = QtWidgets.QLabel(" ")
|
||||
self.layout.addWidget(self.v_shape_spacer_label)
|
||||
|
||||
## Title of the V-shape Tools Calculator
|
||||
# ## Title of the V-shape Tools Calculator
|
||||
v_shape_title_label = QtWidgets.QLabel("<font size=3><b>%s</b></font>" % self.v_shapeName)
|
||||
self.layout.addWidget(v_shape_title_label)
|
||||
|
||||
## Form Layout
|
||||
# ## Form Layout
|
||||
form_layout = QtWidgets.QFormLayout()
|
||||
self.layout.addLayout(form_layout)
|
||||
|
||||
|
@ -127,7 +127,7 @@ class ToolCalculator(FlatCAMTool):
|
|||
form_layout.addRow(self.cutDepth_label, self.cutDepth_entry)
|
||||
form_layout.addRow(self.effectiveToolDia_label, self.effectiveToolDia_entry)
|
||||
|
||||
## Buttons
|
||||
# ## Buttons
|
||||
self.calculate_vshape_button = QtWidgets.QPushButton(_("Calculate"))
|
||||
# self.calculate_button.setFixedWidth(70)
|
||||
self.calculate_vshape_button.setToolTip(
|
||||
|
@ -140,13 +140,13 @@ class ToolCalculator(FlatCAMTool):
|
|||
|
||||
|
||||
################################## ##
|
||||
## ElectroPlating Tool Calculator ##
|
||||
# ## ElectroPlating Tool Calculator # ##
|
||||
################################## ##
|
||||
|
||||
self.plate_spacer_label = QtWidgets.QLabel(" ")
|
||||
self.layout.addWidget(self.plate_spacer_label)
|
||||
|
||||
## Title of the ElectroPlating Tools Calculator
|
||||
# ## Title of the ElectroPlating Tools Calculator
|
||||
plate_title_label = QtWidgets.QLabel("<font size=3><b>%s</b></font>" % self.eplateName)
|
||||
plate_title_label.setToolTip(
|
||||
_("This calculator is useful for those who plate the via/pad/drill holes,\n"
|
||||
|
@ -154,7 +154,7 @@ class ToolCalculator(FlatCAMTool):
|
|||
)
|
||||
self.layout.addWidget(plate_title_label)
|
||||
|
||||
## Plate Form Layout
|
||||
# ## Plate Form Layout
|
||||
plate_form_layout = QtWidgets.QFormLayout()
|
||||
self.layout.addLayout(plate_form_layout)
|
||||
|
||||
|
@ -210,7 +210,7 @@ class ToolCalculator(FlatCAMTool):
|
|||
plate_form_layout.addRow(self.cvaluelabel, self.cvalue_entry)
|
||||
plate_form_layout.addRow(self.timelabel, self.time_entry)
|
||||
|
||||
## Buttons
|
||||
# ## Buttons
|
||||
self.calculate_plate_button = QtWidgets.QPushButton(_("Calculate"))
|
||||
# self.calculate_button.setFixedWidth(70)
|
||||
self.calculate_plate_button.setToolTip(
|
||||
|
@ -223,7 +223,7 @@ class ToolCalculator(FlatCAMTool):
|
|||
|
||||
self.layout.addStretch()
|
||||
|
||||
## Signals
|
||||
# ## Signals
|
||||
self.cutDepth_entry.textChanged.connect(self.on_calculate_tool_dia)
|
||||
self.cutDepth_entry.editingFinished.connect(self.on_calculate_tool_dia)
|
||||
self.tipDia_entry.editingFinished.connect(self.on_calculate_tool_dia)
|
||||
|
@ -264,7 +264,7 @@ class ToolCalculator(FlatCAMTool):
|
|||
def set_tool_ui(self):
|
||||
self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
||||
|
||||
## Initialize form
|
||||
# ## Initialize form
|
||||
self.mm_entry.set_value('0')
|
||||
self.inch_entry.set_value('0')
|
||||
|
||||
|
|
|
@ -415,7 +415,7 @@ class CutOut(FlatCAMTool):
|
|||
object_geo = cutout_obj.solid_geometry
|
||||
|
||||
try:
|
||||
_ = iter(object_geo)
|
||||
__ = iter(object_geo)
|
||||
except TypeError:
|
||||
object_geo = [object_geo]
|
||||
|
||||
|
@ -424,7 +424,8 @@ class CutOut(FlatCAMTool):
|
|||
geo = (geo.buffer(margin + abs(dia / 2))).exterior
|
||||
|
||||
# Get min and max data for each object as we just cut rectangles across X or Y
|
||||
xmin, ymin, xmax, ymax = geo.bounds
|
||||
xmin, ymin, xmax, ymax = recursive_bounds(geo)
|
||||
|
||||
px = 0.5 * (xmin + xmax) + margin
|
||||
py = 0.5 * (ymin + ymax) + margin
|
||||
lenx = (xmax - xmin) + (margin * 2)
|
||||
|
@ -475,6 +476,11 @@ class CutOut(FlatCAMTool):
|
|||
solid_geo.append(geo)
|
||||
|
||||
geo_obj.solid_geometry = deepcopy(solid_geo)
|
||||
xmin, ymin, xmax, ymax = recursive_bounds(geo_obj.solid_geometry)
|
||||
geo_obj.options['xmin'] = xmin
|
||||
geo_obj.options['ymin'] = ymin
|
||||
geo_obj.options['xmax'] = xmax
|
||||
geo_obj.options['ymax'] = ymax
|
||||
|
||||
outname = cutout_obj.options["name"] + "_cutout"
|
||||
self.app.new_object('geometry', outname, geo_init)
|
||||
|
@ -565,7 +571,7 @@ class CutOut(FlatCAMTool):
|
|||
object_geo = cutout_obj.solid_geometry
|
||||
|
||||
try:
|
||||
_ = iter(object_geo)
|
||||
__ = iter(object_geo)
|
||||
except TypeError:
|
||||
object_geo = [object_geo]
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class DblSidedTool(FlatCAMTool):
|
|||
def __init__(self, app):
|
||||
FlatCAMTool.__init__(self, app)
|
||||
|
||||
## Title
|
||||
# ## Title
|
||||
title_label = QtWidgets.QLabel("%s" % self.toolName)
|
||||
title_label.setStyleSheet("""
|
||||
QLabel
|
||||
|
@ -34,11 +34,11 @@ class DblSidedTool(FlatCAMTool):
|
|||
self.empty_lb = QtWidgets.QLabel("")
|
||||
self.layout.addWidget(self.empty_lb)
|
||||
|
||||
## Grid Layout
|
||||
# ## Grid Layout
|
||||
grid_lay = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid_lay)
|
||||
|
||||
## Gerber Object to mirror
|
||||
# ## Gerber Object to mirror
|
||||
self.gerber_object_combo = QtWidgets.QComboBox()
|
||||
self.gerber_object_combo.setModel(self.app.collection)
|
||||
self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
|
@ -62,7 +62,7 @@ class DblSidedTool(FlatCAMTool):
|
|||
grid_lay.addWidget(self.gerber_object_combo, 1, 0)
|
||||
grid_lay.addWidget(self.mirror_gerber_button, 1, 1)
|
||||
|
||||
## Excellon Object to mirror
|
||||
# ## Excellon Object to mirror
|
||||
self.exc_object_combo = QtWidgets.QComboBox()
|
||||
self.exc_object_combo.setModel(self.app.collection)
|
||||
self.exc_object_combo.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex()))
|
||||
|
@ -86,7 +86,7 @@ class DblSidedTool(FlatCAMTool):
|
|||
grid_lay.addWidget(self.exc_object_combo, 3, 0)
|
||||
grid_lay.addWidget(self.mirror_exc_button, 3, 1)
|
||||
|
||||
## Geometry Object to mirror
|
||||
# ## Geometry Object to mirror
|
||||
self.geo_object_combo = QtWidgets.QComboBox()
|
||||
self.geo_object_combo.setModel(self.app.collection)
|
||||
self.geo_object_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex()))
|
||||
|
@ -110,11 +110,11 @@ class DblSidedTool(FlatCAMTool):
|
|||
grid_lay.addWidget(self.geo_object_combo, 5, 0)
|
||||
grid_lay.addWidget(self.mirror_geo_button, 5, 1)
|
||||
|
||||
## Grid Layout
|
||||
# ## Grid Layout
|
||||
grid_lay1 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid_lay1)
|
||||
|
||||
## Axis
|
||||
# ## Axis
|
||||
self.mirror_axis = RadioSet([{'label': 'X', 'value': 'X'},
|
||||
{'label': 'Y', 'value': 'Y'}])
|
||||
self.mirax_label = QtWidgets.QLabel(_("Mirror Axis:"))
|
||||
|
@ -127,7 +127,7 @@ class DblSidedTool(FlatCAMTool):
|
|||
grid_lay1.addWidget(self.mirax_label, 7, 0)
|
||||
grid_lay1.addWidget(self.mirror_axis, 7, 1)
|
||||
|
||||
## Axis Location
|
||||
# ## Axis Location
|
||||
self.axis_location = RadioSet([{'label': 'Point', 'value': 'point'},
|
||||
{'label': 'Box', 'value': 'box'}])
|
||||
self.axloc_label = QtWidgets.QLabel(_("Axis Ref:"))
|
||||
|
@ -143,11 +143,11 @@ class DblSidedTool(FlatCAMTool):
|
|||
self.empty_lb2 = QtWidgets.QLabel("")
|
||||
grid_lay1.addWidget(self.empty_lb2, 9, 0)
|
||||
|
||||
## Grid Layout
|
||||
# ## Grid Layout
|
||||
grid_lay2 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid_lay2)
|
||||
|
||||
## Point/Box
|
||||
# ## Point/Box
|
||||
self.point_box_container = QtWidgets.QVBoxLayout()
|
||||
self.pb_label = QtWidgets.QLabel("<b>%s</b>" % _('Point/Box Reference:'))
|
||||
self.pb_label.setToolTip(
|
||||
|
@ -189,7 +189,7 @@ class DblSidedTool(FlatCAMTool):
|
|||
self.box_combo_type.hide()
|
||||
|
||||
|
||||
## Alignment holes
|
||||
# ## Alignment holes
|
||||
self.ah_label = QtWidgets.QLabel("<b>%s</b>" % _('Alignment Drill Coordinates:'))
|
||||
self.ah_label.setToolTip(
|
||||
_( "Alignment holes (x1, y1), (x2, y2), ... "
|
||||
|
@ -220,7 +220,7 @@ class DblSidedTool(FlatCAMTool):
|
|||
grid_lay3.addWidget(self.alignment_holes, 0, 0)
|
||||
grid_lay3.addWidget(self.add_drill_point_button, 0, 1)
|
||||
|
||||
## Drill diameter for alignment holes
|
||||
# ## Drill diameter for alignment holes
|
||||
self.dt_label = QtWidgets.QLabel("<b>%s</b>:" % _('Alignment Drill Diameter'))
|
||||
self.dt_label.setToolTip(
|
||||
_("Diameter of the drill for the "
|
||||
|
@ -243,7 +243,7 @@ class DblSidedTool(FlatCAMTool):
|
|||
hlay2 = QtWidgets.QHBoxLayout()
|
||||
self.layout.addLayout(hlay2)
|
||||
|
||||
## Buttons
|
||||
# ## Buttons
|
||||
self.create_alignment_hole_button = QtWidgets.QPushButton(_("Create Excellon Object"))
|
||||
self.create_alignment_hole_button.setToolTip(
|
||||
_("Creates an Excellon Object containing the\n"
|
||||
|
@ -261,7 +261,7 @@ class DblSidedTool(FlatCAMTool):
|
|||
|
||||
self.layout.addStretch()
|
||||
|
||||
## Signals
|
||||
# ## Signals
|
||||
self.create_alignment_hole_button.clicked.connect(self.on_create_alignment_holes)
|
||||
self.mirror_gerber_button.clicked.connect(self.on_mirror_gerber)
|
||||
self.mirror_exc_button.clicked.connect(self.on_mirror_exc)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
|
||||
|
@ -165,7 +165,7 @@ class Film(FlatCAMTool):
|
|||
|
||||
self.layout.addStretch()
|
||||
|
||||
## Signals
|
||||
# ## Signals
|
||||
self.film_object_button.clicked.connect(self.on_film_creation)
|
||||
self.tf_type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed)
|
||||
self.tf_type_box_combo.currentIndexChanged.connect(self.on_type_box_index_changed)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
|
||||
|
@ -144,7 +144,7 @@ class ToolImage(FlatCAMTool):
|
|||
|
||||
self.layout.addStretch()
|
||||
|
||||
## Signals
|
||||
# ## Signals
|
||||
self.import_button.clicked.connect(self.on_file_importimage)
|
||||
|
||||
def run(self, toggle=True):
|
||||
|
@ -173,7 +173,7 @@ class ToolImage(FlatCAMTool):
|
|||
FlatCAMTool.install(self, icon, separator, **kwargs)
|
||||
|
||||
def set_tool_ui(self):
|
||||
## Initialize form
|
||||
# ## Initialize form
|
||||
self.dpi_entry.set_value(96)
|
||||
self.image_type.set_value('black')
|
||||
self.mask_bw_entry.set_value(250)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
from FlatCAMObj import *
|
||||
|
@ -32,11 +32,11 @@ class Measurement(FlatCAMTool):
|
|||
self.canvas = self.app.plotcanvas
|
||||
self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower()
|
||||
|
||||
## Title
|
||||
# ## Title
|
||||
title_label = QtWidgets.QLabel("<font size=4><b>%s</b></font><br>" % self.toolName)
|
||||
self.layout.addWidget(title_label)
|
||||
|
||||
## Form Layout
|
||||
# ## Form Layout
|
||||
form_layout = QtWidgets.QFormLayout()
|
||||
self.layout.addLayout(form_layout)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
from FlatCAMObj import *
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Modified by: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
from copy import copy,deepcopy
|
||||
|
@ -38,7 +38,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
self.tools_box.setContentsMargins(0, 0, 0, 0)
|
||||
self.tools_frame.setLayout(self.tools_box)
|
||||
|
||||
## Title
|
||||
# ## Title
|
||||
title_label = QtWidgets.QLabel("%s" % self.toolName)
|
||||
title_label.setStyleSheet("""
|
||||
QLabel
|
||||
|
@ -49,11 +49,11 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
""")
|
||||
self.tools_box.addWidget(title_label)
|
||||
|
||||
## Form Layout
|
||||
# ## Form Layout
|
||||
form_layout = QtWidgets.QFormLayout()
|
||||
self.tools_box.addLayout(form_layout)
|
||||
|
||||
## Object
|
||||
# ## Object
|
||||
self.object_combo = QtWidgets.QComboBox()
|
||||
self.object_combo.setModel(self.app.collection)
|
||||
self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 4/23/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
from shapely.geometry import Point, Polygon, LineString
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Modified: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
from copy import copy,deepcopy
|
||||
|
@ -29,7 +29,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
FlatCAMTool.__init__(self, app)
|
||||
Geometry.__init__(self, geo_steps_per_circle=self.app.defaults["geometry_circle_steps"])
|
||||
|
||||
## Title
|
||||
# ## Title
|
||||
title_label = QtWidgets.QLabel("%s" % self.toolName)
|
||||
title_label.setStyleSheet("""
|
||||
QLabel
|
||||
|
@ -47,11 +47,11 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
self.tools_box.setContentsMargins(0, 0, 0, 0)
|
||||
self.tools_frame.setLayout(self.tools_box)
|
||||
|
||||
## Form Layout
|
||||
# ## Form Layout
|
||||
form_layout = QtWidgets.QFormLayout()
|
||||
self.tools_box.addLayout(form_layout)
|
||||
|
||||
## Object
|
||||
# ## Object
|
||||
self.object_combo = QtWidgets.QComboBox()
|
||||
self.object_combo.setModel(self.app.collection)
|
||||
self.object_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex()))
|
||||
|
@ -305,7 +305,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
|
||||
self.tool_type_item_options = ["C1", "C2", "C3", "C4", "B", "V"]
|
||||
|
||||
## Signals
|
||||
# ## Signals
|
||||
self.addtool_btn.clicked.connect(self.on_tool_add)
|
||||
self.addtool_entry.returnPressed.connect(self.on_tool_add)
|
||||
# self.copytool_btn.clicked.connect(lambda: self.on_tool_copy())
|
||||
|
@ -365,7 +365,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
self.tools_frame.show()
|
||||
self.reset_fields()
|
||||
|
||||
## Init the GUI interface
|
||||
# ## Init the GUI interface
|
||||
self.paintmargin_entry.set_value(self.default_data["paintmargin"])
|
||||
self.paintmethod_combo.set_value(self.default_data["paintmethod"])
|
||||
self.selectmethod_combo.set_value(self.default_data["selectmethod"])
|
||||
|
@ -1035,13 +1035,13 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
if reset:
|
||||
self.flat_geometry = []
|
||||
|
||||
## If iterable, expand recursively.
|
||||
# ## If iterable, expand recursively.
|
||||
try:
|
||||
for geo in geometry:
|
||||
if geo is not None:
|
||||
recurse(geometry=geo, reset=False)
|
||||
|
||||
## Not iterable, do the actual indexing and add.
|
||||
# ## Not iterable, do the actual indexing and add.
|
||||
except TypeError:
|
||||
self.flat_geometry.append(geometry)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
from copy import copy, deepcopy
|
||||
|
@ -28,7 +28,7 @@ class Panelize(FlatCAMTool):
|
|||
super(Panelize, self).__init__(self)
|
||||
self.app = app
|
||||
|
||||
## Title
|
||||
# ## Title
|
||||
title_label = QtWidgets.QLabel("%s" % self.toolName)
|
||||
title_label.setStyleSheet("""
|
||||
QLabel
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 4/15/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
|
||||
|
@ -152,7 +152,7 @@ class PcbWizard(FlatCAMTool):
|
|||
|
||||
self.modified_excellon_file = ''
|
||||
|
||||
## Signals
|
||||
# ## Signals
|
||||
self.excellon_brn.clicked.connect(self.on_load_excellon_click)
|
||||
self.inf_btn.clicked.connect(self.on_load_inf_click)
|
||||
self.import_button.clicked.connect(lambda: self.on_import_excellon(
|
||||
|
@ -207,7 +207,7 @@ class PcbWizard(FlatCAMTool):
|
|||
self.exc_file_content = None
|
||||
self.tools_from_inf = {}
|
||||
|
||||
## Initialize form
|
||||
# ## Initialize form
|
||||
self.int_entry.set_value(self.integral)
|
||||
self.frac_entry.set_value(self.fractional)
|
||||
self.zeros_radio.set_value(self.zeros)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from PyQt5 import QtGui, QtCore, QtWidgets
|
||||
from PyQt5.QtCore import Qt
|
||||
|
@ -37,7 +37,7 @@ class Properties(FlatCAMTool):
|
|||
self.properties_box.setContentsMargins(0, 0, 0, 0)
|
||||
self.properties_frame.setLayout(self.properties_box)
|
||||
|
||||
## Title
|
||||
# ## Title
|
||||
title_label = QtWidgets.QLabel("%s" % self.toolName)
|
||||
title_label.setStyleSheet("""
|
||||
QLabel
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
# Date: 2/5/2014 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
# from PyQt5.QtCore import pyqtSignal
|
||||
from PyQt5.QtCore import Qt
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
from FlatCAMCommon import LoudDict
|
||||
|
@ -39,7 +39,7 @@ class SolderPaste(FlatCAMTool):
|
|||
def __init__(self, app):
|
||||
FlatCAMTool.__init__(self, app)
|
||||
|
||||
## Title
|
||||
# ## Title
|
||||
title_label = QtWidgets.QLabel("%s" % self.toolName)
|
||||
title_label.setStyleSheet("""
|
||||
QLabel
|
||||
|
@ -50,11 +50,11 @@ class SolderPaste(FlatCAMTool):
|
|||
""")
|
||||
self.layout.addWidget(title_label)
|
||||
|
||||
## Form Layout
|
||||
# ## Form Layout
|
||||
obj_form_layout = QtWidgets.QFormLayout()
|
||||
self.layout.addLayout(obj_form_layout)
|
||||
|
||||
## Gerber Object to be used for solderpaste dispensing
|
||||
# ## Gerber Object to be used for solderpaste dispensing
|
||||
self.obj_combo = FCComboBox(callback=self.on_rmb_combo)
|
||||
self.obj_combo.setModel(self.app.collection)
|
||||
self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
|
@ -135,7 +135,7 @@ class SolderPaste(FlatCAMTool):
|
|||
|
||||
self.layout.addSpacing(10)
|
||||
|
||||
## Buttons
|
||||
# ## Buttons
|
||||
grid0_1 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid0_1)
|
||||
|
||||
|
@ -157,7 +157,7 @@ class SolderPaste(FlatCAMTool):
|
|||
self.gcode_box.setContentsMargins(0, 0, 0, 0)
|
||||
self.gcode_frame.setLayout(self.gcode_box)
|
||||
|
||||
## Form Layout
|
||||
# ## Form Layout
|
||||
self.gcode_form_layout = QtWidgets.QFormLayout()
|
||||
self.gcode_box.addLayout(self.gcode_form_layout)
|
||||
|
||||
|
@ -283,7 +283,7 @@ class SolderPaste(FlatCAMTool):
|
|||
self.pp_combo.setStyleSheet('background-color: rgb(255,255,255)')
|
||||
self.gcode_form_layout.addRow(pp_label, self.pp_combo)
|
||||
|
||||
## Buttons
|
||||
# ## Buttons
|
||||
grid1 = QtWidgets.QGridLayout()
|
||||
self.gcode_box.addLayout(grid1)
|
||||
|
||||
|
@ -301,7 +301,7 @@ class SolderPaste(FlatCAMTool):
|
|||
self.generation_frame.setLayout(self.generation_box)
|
||||
|
||||
|
||||
## Buttons
|
||||
# ## Buttons
|
||||
grid2 = QtWidgets.QGridLayout()
|
||||
self.generation_box.addLayout(grid2)
|
||||
|
||||
|
@ -313,11 +313,11 @@ class SolderPaste(FlatCAMTool):
|
|||
grid2.addWidget(step2_lbl, 0, 0)
|
||||
grid2.addWidget(self.soldergeo_btn, 0, 2)
|
||||
|
||||
## Form Layout
|
||||
# ## Form Layout
|
||||
geo_form_layout = QtWidgets.QFormLayout()
|
||||
self.generation_box.addLayout(geo_form_layout)
|
||||
|
||||
## Geometry Object to be used for solderpaste dispensing
|
||||
# ## Geometry Object to be used for solderpaste dispensing
|
||||
self.geo_obj_combo = FCComboBox(callback=self.on_rmb_combo)
|
||||
self.geo_obj_combo.setModel(self.app.collection)
|
||||
self.geo_obj_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex()))
|
||||
|
@ -346,11 +346,11 @@ class SolderPaste(FlatCAMTool):
|
|||
grid3.addWidget(step3_lbl, 0, 0)
|
||||
grid3.addWidget(self.solder_gcode_btn, 0, 2)
|
||||
|
||||
## Form Layout
|
||||
# ## Form Layout
|
||||
cnc_form_layout = QtWidgets.QFormLayout()
|
||||
self.generation_box.addLayout(cnc_form_layout)
|
||||
|
||||
## Gerber Object to be used for solderpaste dispensing
|
||||
# ## Gerber Object to be used for solderpaste dispensing
|
||||
self.cnc_obj_combo = FCComboBox(callback=self.on_rmb_combo)
|
||||
self.cnc_obj_combo.setModel(self.app.collection)
|
||||
self.cnc_obj_combo.setRootModelIndex(self.app.collection.index(3, 0, QtCore.QModelIndex()))
|
||||
|
@ -412,7 +412,7 @@ class SolderPaste(FlatCAMTool):
|
|||
# action to be added in the combobox context menu
|
||||
self.combo_context_del_action = QtWidgets.QAction(QtGui.QIcon('share/trash16.png'), _("Delete Object"))
|
||||
|
||||
## Signals
|
||||
# ## Signals
|
||||
self.combo_context_del_action.triggered.connect(self.on_delete_object)
|
||||
self.addtool_btn.clicked.connect(self.on_tool_add)
|
||||
self.addtool_entry.returnPressed.connect(self.on_tool_add)
|
||||
|
@ -995,7 +995,7 @@ class SolderPaste(FlatCAMTool):
|
|||
|
||||
if reset:
|
||||
self.flat_geometry = []
|
||||
## If iterable, expand recursively.
|
||||
# ## If iterable, expand recursively.
|
||||
try:
|
||||
for geo in geometry:
|
||||
if geo is not None:
|
||||
|
@ -1003,7 +1003,7 @@ class SolderPaste(FlatCAMTool):
|
|||
reset=False,
|
||||
pathonly=pathonly)
|
||||
|
||||
## Not iterable, do the actual indexing and add.
|
||||
# ## Not iterable, do the actual indexing and add.
|
||||
except TypeError:
|
||||
if pathonly and type(geometry) == Polygon:
|
||||
self.flat_geometry.append(geometry.exterior)
|
||||
|
@ -1380,7 +1380,7 @@ class SolderPaste(FlatCAMTool):
|
|||
gcode += obj.cnc_tools[tool]['gcode']
|
||||
lines = StringIO(gcode)
|
||||
|
||||
## Write
|
||||
# ## Write
|
||||
if filename is not None:
|
||||
try:
|
||||
with open(filename, 'w') as f:
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 4/24/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
from FlatCAMObj import *
|
||||
|
@ -32,7 +32,7 @@ class ToolTransform(FlatCAMTool):
|
|||
|
||||
self.transform_lay = QtWidgets.QVBoxLayout()
|
||||
self.layout.addLayout(self.transform_lay)
|
||||
## Title
|
||||
# ## Title
|
||||
title_label = QtWidgets.QLabel("%s" % self.toolName)
|
||||
title_label.setStyleSheet("""
|
||||
QLabel
|
||||
|
@ -56,11 +56,11 @@ class ToolTransform(FlatCAMTool):
|
|||
self.empty_label4.setFixedWidth(70)
|
||||
self.transform_lay.addWidget(self.empty_label)
|
||||
|
||||
## Rotate Title
|
||||
# ## Rotate Title
|
||||
rotate_title_label = QtWidgets.QLabel("<font size=3><b>%s</b></font>" % self.rotateName)
|
||||
self.transform_lay.addWidget(rotate_title_label)
|
||||
|
||||
## Layout
|
||||
# ## Layout
|
||||
form_layout = QtWidgets.QFormLayout()
|
||||
self.transform_lay.addLayout(form_layout)
|
||||
form_child = QtWidgets.QHBoxLayout()
|
||||
|
@ -94,11 +94,11 @@ class ToolTransform(FlatCAMTool):
|
|||
|
||||
self.transform_lay.addWidget(self.empty_label1)
|
||||
|
||||
## Skew Title
|
||||
# ## Skew Title
|
||||
skew_title_label = QtWidgets.QLabel("<font size=3><b>%s</b></font>" % self.skewName)
|
||||
self.transform_lay.addWidget(skew_title_label)
|
||||
|
||||
## Form Layout
|
||||
# ## Form Layout
|
||||
form1_layout = QtWidgets.QFormLayout()
|
||||
self.transform_lay.addLayout(form1_layout)
|
||||
form1_child_1 = QtWidgets.QHBoxLayout()
|
||||
|
@ -151,11 +151,11 @@ class ToolTransform(FlatCAMTool):
|
|||
|
||||
self.transform_lay.addWidget(self.empty_label2)
|
||||
|
||||
## Scale Title
|
||||
# ## Scale Title
|
||||
scale_title_label = QtWidgets.QLabel("<font size=3><b>%s</b></font>" % self.scaleName)
|
||||
self.transform_lay.addWidget(scale_title_label)
|
||||
|
||||
## Form Layout
|
||||
# ## Form Layout
|
||||
form2_layout = QtWidgets.QFormLayout()
|
||||
self.transform_lay.addLayout(form2_layout)
|
||||
form2_child_1 = QtWidgets.QHBoxLayout()
|
||||
|
@ -225,11 +225,11 @@ class ToolTransform(FlatCAMTool):
|
|||
|
||||
self.transform_lay.addWidget(self.empty_label3)
|
||||
|
||||
## Offset Title
|
||||
# ## Offset Title
|
||||
offset_title_label = QtWidgets.QLabel("<font size=3><b>%s</b></font>" % self.offsetName)
|
||||
self.transform_lay.addWidget(offset_title_label)
|
||||
|
||||
## Form Layout
|
||||
# ## Form Layout
|
||||
form3_layout = QtWidgets.QFormLayout()
|
||||
self.transform_lay.addLayout(form3_layout)
|
||||
form3_child_1 = QtWidgets.QHBoxLayout()
|
||||
|
@ -280,11 +280,11 @@ class ToolTransform(FlatCAMTool):
|
|||
|
||||
self.transform_lay.addWidget(self.empty_label4)
|
||||
|
||||
## Flip Title
|
||||
# ## Flip Title
|
||||
flip_title_label = QtWidgets.QLabel("<font size=3><b>%s</b></font>" % self.flipName)
|
||||
self.transform_lay.addWidget(flip_title_label)
|
||||
|
||||
## Form Layout
|
||||
# ## Form Layout
|
||||
form4_layout = QtWidgets.QFormLayout()
|
||||
form4_child_hlay = QtWidgets.QHBoxLayout()
|
||||
self.transform_lay.addLayout(form4_child_hlay)
|
||||
|
@ -355,7 +355,7 @@ class ToolTransform(FlatCAMTool):
|
|||
|
||||
self.transform_lay.addStretch()
|
||||
|
||||
## Signals
|
||||
# ## Signals
|
||||
self.rotate_button.clicked.connect(self.on_rotate)
|
||||
self.skewx_button.clicked.connect(self.on_skewx)
|
||||
self.skewy_button.clicked.connect(self.on_skewy)
|
||||
|
@ -401,7 +401,7 @@ class ToolTransform(FlatCAMTool):
|
|||
FlatCAMTool.install(self, icon, separator, shortcut='ALT+R', **kwargs)
|
||||
|
||||
def set_tool_ui(self):
|
||||
## Initialize form
|
||||
# ## Initialize form
|
||||
if self.app.defaults["tools_transform_rotate"]:
|
||||
self.rotate_entry.set_value(self.app.defaults["tools_transform_rotate"])
|
||||
else:
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# Author: Juan Pablo Caram (c) #
|
||||
|
@ -11,12 +11,12 @@
|
|||
# This is not an aid to install FlatCAM from source on #
|
||||
# Windows platforms. It is only useful when FlatCAM is up #
|
||||
# and running and ready to be packaged. #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
# File Modified (major mod): Marius Adrian Stanciu #
|
||||
# Date: 3/10/2019 #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
|
||||
# Files not needed: Qt, tk.dll, tcl.dll, tk/, tcl/, vtk/,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Matthieu Berthomé #
|
||||
# Date: 5/26/2017 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Matthieu Berthomé #
|
||||
# Date: 5/26/2017 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Matthieu Berthomé #
|
||||
# Date: 5/26/2017 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
############################################################
|
||||
# ########################################################## ##
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
############################################################
|
||||
# ########################################################## ##
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 377 B |
Binary file not shown.
After Width: | Height: | Size: 715 B |
Binary file not shown.
After Width: | Height: | Size: 199 B |
|
@ -120,7 +120,7 @@ class TclCommandCutout(TclCommand):
|
|||
geo_obj.solid_geometry = cascaded_union([LineString(segment) for segment in cuts])
|
||||
|
||||
try:
|
||||
obj.app.new_object("geometry", name + "_cutout", geo_init_me)
|
||||
self.app.new_object("geometry", name + "_cutout", geo_init_me)
|
||||
self.app.inform.emit("[success] Rectangular-form Cutout operation finished.")
|
||||
except Exception as e:
|
||||
return "Operation failed: %s" % str(e)
|
||||
|
|
|
@ -165,6 +165,11 @@ class TclCommandGeoCutout(TclCommandSignaled):
|
|||
|
||||
# Get min and max data for each object as we just cut rectangles across X or Y
|
||||
xmin, ymin, xmax, ymax = cutout_obj.bounds()
|
||||
cutout_obj.options['xmin'] = xmin
|
||||
cutout_obj.options['ymin'] = ymin
|
||||
cutout_obj.options['xmax'] = xmax
|
||||
cutout_obj.options['ymax'] = ymax
|
||||
|
||||
px = 0.5 * (xmin + xmax) + margin
|
||||
py = 0.5 * (ymin + ymax) + margin
|
||||
lenghtx = (xmax - xmin) + (margin * 2)
|
||||
|
@ -179,48 +184,102 @@ class TclCommandGeoCutout(TclCommandSignaled):
|
|||
|
||||
if isinstance(cutout_obj, FlatCAMGeometry):
|
||||
# rename the obj name so it can be identified as cutout
|
||||
cutout_obj.options["name"] += "_cutout"
|
||||
# cutout_obj.options["name"] += "_cutout"
|
||||
|
||||
# if gaps_u == 8 or gaps_u == '2lr':
|
||||
# subtract_rectangle(cutout_obj,
|
||||
# xmin - gapsize, # botleft_x
|
||||
# py - gapsize + lenghty / 4, # botleft_y
|
||||
# xmax + gapsize, # topright_x
|
||||
# py + gapsize + lenghty / 4) # topright_y
|
||||
# subtract_rectangle(cutout_obj,
|
||||
# xmin - gapsize,
|
||||
# py - gapsize - lenghty / 4,
|
||||
# xmax + gapsize,
|
||||
# py + gapsize - lenghty / 4)
|
||||
#
|
||||
# if gaps_u == 8 or gaps_u == '2tb':
|
||||
# subtract_rectangle(cutout_obj,
|
||||
# px - gapsize + lenghtx / 4,
|
||||
# ymin - gapsize,
|
||||
# px + gapsize + lenghtx / 4,
|
||||
# ymax + gapsize)
|
||||
# subtract_rectangle(cutout_obj,
|
||||
# px - gapsize - lenghtx / 4,
|
||||
# ymin - gapsize,
|
||||
# px + gapsize - lenghtx / 4,
|
||||
# ymax + gapsize)
|
||||
#
|
||||
# if gaps_u == 4 or gaps_u == 'lr':
|
||||
# subtract_rectangle(cutout_obj,
|
||||
# xmin - gapsize,
|
||||
# py - gapsize,
|
||||
# xmax + gapsize,
|
||||
# py + gapsize)
|
||||
#
|
||||
# if gaps_u == 4 or gaps_u == 'tb':
|
||||
# subtract_rectangle(cutout_obj,
|
||||
# px - gapsize,
|
||||
# ymin - gapsize,
|
||||
# px + gapsize,
|
||||
# ymax + gapsize)
|
||||
|
||||
def geo_init(geo_obj, app_obj):
|
||||
geo = deepcopy(cutout_obj.solid_geometry)
|
||||
|
||||
if gaps_u == 8 or gaps_u == '2lr':
|
||||
subtract_rectangle(cutout_obj,
|
||||
geo = substract_rectangle_geo(geo,
|
||||
xmin - gapsize, # botleft_x
|
||||
py - gapsize + lenghty / 4, # botleft_y
|
||||
xmax + gapsize, # topright_x
|
||||
py + gapsize + lenghty / 4) # topright_y
|
||||
subtract_rectangle(cutout_obj,
|
||||
geo = substract_rectangle_geo(geo,
|
||||
xmin - gapsize,
|
||||
py - gapsize - lenghty / 4,
|
||||
xmax + gapsize,
|
||||
py + gapsize - lenghty / 4)
|
||||
|
||||
if gaps_u == 8 or gaps_u == '2tb':
|
||||
subtract_rectangle(cutout_obj,
|
||||
geo = substract_rectangle_geo(geo,
|
||||
px - gapsize + lenghtx / 4,
|
||||
ymin - gapsize,
|
||||
px + gapsize + lenghtx / 4,
|
||||
ymax + gapsize)
|
||||
subtract_rectangle(cutout_obj,
|
||||
geo = substract_rectangle_geo(geo,
|
||||
px - gapsize - lenghtx / 4,
|
||||
ymin - gapsize,
|
||||
px + gapsize - lenghtx / 4,
|
||||
ymax + gapsize)
|
||||
|
||||
if gaps_u == 4 or gaps_u == 'lr':
|
||||
subtract_rectangle(cutout_obj,
|
||||
geo = substract_rectangle_geo(geo,
|
||||
xmin - gapsize,
|
||||
py - gapsize,
|
||||
xmax + gapsize,
|
||||
py + gapsize)
|
||||
|
||||
if gaps_u == 4 or gaps_u == 'tb':
|
||||
subtract_rectangle(cutout_obj,
|
||||
geo = substract_rectangle_geo(geo,
|
||||
px - gapsize,
|
||||
ymin - gapsize,
|
||||
px + gapsize,
|
||||
ymax + gapsize)
|
||||
geo_obj.solid_geometry = deepcopy(geo)
|
||||
geo_obj.options['xmin'] = cutout_obj.options['xmin']
|
||||
geo_obj.options['ymin'] = cutout_obj.options['ymin']
|
||||
geo_obj.options['xmax'] = cutout_obj.options['xmax']
|
||||
geo_obj.options['ymax'] = cutout_obj.options['ymax']
|
||||
|
||||
cutout_obj.plot()
|
||||
self.app.inform.emit("[success] Any-form Cutout operation finished.")
|
||||
app_obj.disable_plots(objects=[cutout_obj])
|
||||
|
||||
app_obj.inform.emit("[success] Any-form Cutout operation finished.")
|
||||
|
||||
outname = cutout_obj.options["name"] + "_cutout"
|
||||
self.app.new_object('geometry', outname, geo_init)
|
||||
|
||||
# cutout_obj.plot()
|
||||
# self.app.inform.emit("[success] Any-form Cutout operation finished.")
|
||||
# self.app.plots_updated.emit()
|
||||
elif isinstance(cutout_obj, FlatCAMGerber):
|
||||
|
||||
def geo_init(geo_obj, app_obj):
|
||||
|
@ -267,7 +326,12 @@ class TclCommandGeoCutout(TclCommandSignaled):
|
|||
ymin - gapsize,
|
||||
px + gapsize,
|
||||
ymax + gapsize)
|
||||
geo_obj.solid_geometry = geo
|
||||
geo_obj.solid_geometry = deepcopy(geo)
|
||||
geo_obj.options['xmin'] = cutout_obj.options['xmin']
|
||||
geo_obj.options['ymin'] = cutout_obj.options['ymin']
|
||||
geo_obj.options['xmax'] = cutout_obj.options['xmax']
|
||||
geo_obj.options['ymax'] = cutout_obj.options['ymax']
|
||||
app_obj.inform.emit("[success] Any-form Cutout operation finished.")
|
||||
|
||||
outname = cutout_obj.options["name"] + "_cutout"
|
||||
self.app.new_object('geometry', outname, geo_init)
|
||||
|
|
Loading…
Reference in New Issue