- fixed the Tcl Command AlignDrill

- fixed the Tcl Command AlignDrillGrid
- fixed the Tcl COmmand Panelize, Excellon panelization section
- Fixed an issue in Tool Calibration export_excellon method call
- PEP8 corrections all over the app
This commit is contained in:
Marius Stanciu 2020-11-02 03:32:00 +02:00 committed by Marius
parent fac4caf961
commit 374c29b4b0
63 changed files with 492 additions and 537 deletions

View File

@ -7,6 +7,14 @@ CHANGELOG for FlatCAM beta
================================================= =================================================
2.11.2020
- fixed the Tcl Command AlignDrill
- fixed the Tcl Command AlignDrillGrid
- fixed the Tcl COmmand Panelize, Excellon panelization section
- Fixed an issue in Tool Calibration export_excellon method call
- PEP8 corrections all over the app
1.11.2020 1.11.2020
- updated the French Translation (by Olivier Cornet) - updated the French Translation (by Olivier Cornet)
@ -20,6 +28,7 @@ CHANGELOG for FlatCAM beta
- in Join Excellon functionality made sure that the new Combo Exellon object will have copied the data from source objects and not just references, therefore will survive the delete of its parents - in Join Excellon functionality made sure that the new Combo Exellon object will have copied the data from source objects and not just references, therefore will survive the delete of its parents
- updated Turkish translation (by Mehmet Kaya) - updated Turkish translation (by Mehmet Kaya)
- updated all the languages except Turkish - updated all the languages except Turkish
- in the Tool PDF fixed the creation of Excellon objects to the current Excellon object data structure
31.10.2020 31.10.2020

View File

@ -1971,8 +1971,7 @@ class ToolsDB2(QtWidgets.QWidget):
else: else:
new_name = "new_tool_1" new_name = "new_tool_1"
dict_elem = {} dict_elem = {'name': new_name}
dict_elem['name'] = new_name
if type(self.app.defaults["geometry_cnctooldia"]) == float: if type(self.app.defaults["geometry_cnctooldia"]) == float:
dict_elem['tooldia'] = self.app.defaults["geometry_cnctooldia"] dict_elem['tooldia'] = self.app.defaults["geometry_cnctooldia"]
else: else:

View File

@ -11,7 +11,6 @@ from PyQt5.QtCore import Qt
from camlib import distance, arc, FlatCAMRTreeStorage from camlib import distance, arc, FlatCAMRTreeStorage
from appGUI.GUIElements import FCEntry, FCComboBox, FCTable, FCDoubleSpinner, RadioSet, FCSpinner, FCButton from appGUI.GUIElements import FCEntry, FCComboBox, FCTable, FCDoubleSpinner, RadioSet, FCSpinner, FCButton
from appEditors.AppGeoEditor import FCShapeTool, DrawTool, DrawToolShape, DrawToolUtilityShape, AppGeoEditor from appEditors.AppGeoEditor import FCShapeTool, DrawTool, DrawToolShape, DrawToolUtilityShape, AppGeoEditor
from appParsers.ParseExcellon import Excellon
from shapely.geometry import LineString, LinearRing, MultiLineString, Polygon, MultiPolygon, Point from shapely.geometry import LineString, LinearRing, MultiLineString, Polygon, MultiPolygon, Point
import shapely.affinity as affinity import shapely.affinity as affinity

View File

@ -12,7 +12,7 @@
# ######################################################### ## # ######################################################### ##
from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtCore import Qt, QSettings from PyQt5.QtCore import Qt
from camlib import distance, arc, three_point_circle, Geometry, FlatCAMRTreeStorage from camlib import distance, arc, three_point_circle, Geometry, FlatCAMRTreeStorage
from appTool import AppTool from appTool import AppTool
@ -20,7 +20,7 @@ from appGUI.GUIElements import OptionalInputSection, FCCheckBox, FCLabel, FCComb
FCDoubleSpinner, FCButton, FCInputDialog, FCTree, NumericalEvalTupleEntry FCDoubleSpinner, FCButton, FCInputDialog, FCTree, NumericalEvalTupleEntry
from appParsers.ParseFont import * from appParsers.ParseFont import *
from shapely.geometry import LineString, LinearRing, MultiLineString, Polygon, MultiPolygon from shapely.geometry import LineString, LinearRing, MultiLineString, Polygon, MultiPolygon, Point
from shapely.ops import unary_union, linemerge from shapely.ops import unary_union, linemerge
import shapely.affinity as affinity import shapely.affinity as affinity
from shapely.geometry.polygon import orient from shapely.geometry.polygon import orient

View File

@ -6,7 +6,7 @@
# ########################################################## # ##########################################################
from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtCore import Qt, QSettings from PyQt5.QtCore import Qt
from shapely.geometry import LineString, LinearRing, MultiLineString, Point, Polygon, MultiPolygon, box from shapely.geometry import LineString, LinearRing, MultiLineString, Point, Polygon, MultiPolygon, box
from shapely.ops import unary_union from shapely.ops import unary_union

View File

@ -332,7 +332,7 @@ class AppTextEditor(QtWidgets.QWidget):
r = self.code_editor.find(str(text_to_be_found), flags) r = self.code_editor.find(str(text_to_be_found), flags)
if r is False: if r is False:
self.code_editor.moveCursor(QtGui.QTextCursor.Start) self.code_editor.moveCursor(QtGui.QTextCursor.Start)
r = self.code_editor.find(str(text_to_be_found), flags) self.code_editor.find(str(text_to_be_found), flags)
def handleReplaceGCode(self): def handleReplaceGCode(self):

View File

@ -462,7 +462,6 @@ class AppGCodeEditor(QtCore.QObject):
end_sel = my_text_cursor.selectionEnd() end_sel = my_text_cursor.selectionEnd()
else: else:
pos_list = [] pos_list = []
end_sel = 0
my_text_cursor = self.edit_area.textCursor() my_text_cursor = self.edit_area.textCursor()
m6_pos = my_text_cursor.selectionEnd() m6_pos = my_text_cursor.selectionEnd()

View File

@ -12,7 +12,7 @@
# ########################################################## # ##########################################################
from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtCore import Qt, pyqtSlot, pyqtSignal, QSettings from PyQt5.QtCore import Qt, pyqtSlot, pyqtSignal
from PyQt5.QtWidgets import QTextEdit, QCompleter, QAction from PyQt5.QtWidgets import QTextEdit, QCompleter, QAction
from PyQt5.QtGui import QKeySequence, QTextCursor from PyQt5.QtGui import QKeySequence, QTextCursor
@ -2079,7 +2079,7 @@ class FCPlainTextAreaExtended(QtWidgets.QPlainTextEdit):
""" """
pos = self.textCursor().position() pos = self.textCursor().position()
self.moveCursor(QtGui.QTextCursor.StartOfLine) self.moveCursor(QtGui.QTextCursor.StartOfLine)
line_text = self.textCursor().block().text() self.textCursor().block().text()
if self.textCursor().block().text().startswith(" "): if self.textCursor().block().text().startswith(" "):
# skip the white space # skip the white space
self.moveCursor(QtGui.QTextCursor.NextWord) self.moveCursor(QtGui.QTextCursor.NextWord)
@ -2407,7 +2407,7 @@ class FCInputDialogSpinnerButton(QtWidgets.QDialog):
class FCButton(QtWidgets.QPushButton): class FCButton(QtWidgets.QPushButton):
def __init__(self, text=None, checkable=None, click_callback=None, parent=None): def __init__(self, text=None, checkable=None, click_callback=None, parent=None):
super(FCButton, self).__init__(text, parent) super(FCButton, self).__init__(text, parent)
if not checkable is None: if checkable is not None:
self.setCheckable(checkable) self.setCheckable(checkable)
if not click_callback is None: if not click_callback is None:

View File

@ -10,6 +10,8 @@
# File Modified (major mod): Marius Adrian Stanciu # # File Modified (major mod): Marius Adrian Stanciu #
# Date: 3/10/2019 # # Date: 3/10/2019 #
# ########################################################## # ##########################################################
from PyQt5.QtCore import QSettings
import platform import platform
from appGUI.GUIElements import * from appGUI.GUIElements import *
@ -20,6 +22,7 @@ from appGUI.preferences.general.GeneralPreferencesUI import GeneralPreferencesUI
from appGUI.preferences.geometry.GeometryPreferencesUI import GeometryPreferencesUI from appGUI.preferences.geometry.GeometryPreferencesUI import GeometryPreferencesUI
from appGUI.preferences.gerber.GerberPreferencesUI import GerberPreferencesUI from appGUI.preferences.gerber.GerberPreferencesUI import GerberPreferencesUI
from appEditors.AppGeoEditor import FCShapeTool from appEditors.AppGeoEditor import FCShapeTool
from matplotlib.backend_bases import KeyEvent as mpl_key_event from matplotlib.backend_bases import KeyEvent as mpl_key_event
import webbrowser import webbrowser

View File

@ -170,8 +170,8 @@ class ObjectUI(QtWidgets.QWidget):
def confirmation_message_int(self, accepted, minval, maxval): def confirmation_message_int(self, accepted, minval, maxval):
if accepted is False: if accepted is False:
self.app.inform[str, bool].emit('[WARNING_NOTCL] %s: [%d, %d]' % self.app.inform[str, bool].emit(
(_("Edited value is out of range"), minval, maxval), False) '[WARNING_NOTCL] %s: [%d, %d]' % (_("Edited value is out of range"), minval, maxval), False)
else: else:
self.app.inform[str, bool].emit('[success] %s' % _("Edited value is within limits."), False) self.app.inform[str, bool].emit('[success] %s' % _("Edited value is within limits."), False)

View File

@ -575,13 +575,13 @@ class CursorBig(QtCore.QObject):
def set_data(self, pos, **kwargs): def set_data(self, pos, **kwargs):
"""Internal event handler to draw the cursor when the mouse moves.""" """Internal event handler to draw the cursor when the mouse moves."""
if 'edge_color' in kwargs: # if 'edge_color' in kwargs:
color = kwargs['edge_color'] # color = kwargs['edge_color']
else: # else:
if self.app.defaults['global_theme'] == 'white': # if self.app.defaults['global_theme'] == 'white':
color = '#000000FF' # color = '#000000FF'
else: # else:
color = '#FFFFFFFF' # color = '#FFFFFFFF'
position = [pos[0][0], pos[0][1]] position = [pos[0][0], pos[0][1]]
self.mouse_position_updated.emit(position) self.mouse_position_updated.emit(position)

View File

@ -29,9 +29,10 @@ class GLUTess:
pass pass
def _on_combine(self, coords, data, weight): def _on_combine(self, coords, data, weight):
return (coords[0], coords[1], coords[2]) return coords[0], coords[1], coords[2]
def _on_error(self, errno): @staticmethod
def _on_error(errno):
print("GLUTess error:", errno) print("GLUTess error:", errno)
def _on_end_primitive(self): def _on_end_primitive(self):

View File

@ -339,7 +339,7 @@ class ShapeCollectionVisual(CompoundVisual):
if update: if update:
self.__update() self.__update()
def update_visibility(self, state:bool, indexes=None) -> None: def update_visibility(self, state: bool, indexes=None) -> None:
# Lock sub-visuals updates # Lock sub-visuals updates
self.update_lock.acquire(True) self.update_lock.acquire(True)
if indexes is None: if indexes is None:
@ -540,8 +540,9 @@ class ShapeCollectionVisual(CompoundVisual):
def redraw(self, indexes=None, update_colors=None): def redraw(self, indexes=None, update_colors=None):
""" """
Redraws collection Redraws collection
:param indexes: list :param indexes: list
Shape indexes to get from process pool Shape indexes to get from process pool
:param update_colors:
""" """
# Only one thread can update data # Only one thread can update data
self.results_lock.acquire(True) self.results_lock.acquire(True)

View File

@ -2265,7 +2265,7 @@ class CNCJobObject(FlatCAMObj, CNCjob):
processed_body_gcode += gline + '\n' processed_body_gcode += gline + '\n'
gcode = processed_body_gcode gcode = processed_body_gcode
g = self.gc_header + '\n' + self.gc_start + '\n' + preamble + '\n' + \ g = self.gc_header + '\n' + self.gc_start + '\n' + preamble + '\n' + \
gcode + '\n' + postamble + end_gcode gcode + '\n' + postamble + end_gcode
else: else:
# try: # try:
@ -2286,6 +2286,7 @@ class CNCJobObject(FlatCAMObj, CNCjob):
# _("G-code does not have a G94 code.\n" # _("G-code does not have a G94 code.\n"
# "Append Code snippet will not be used..")) # "Append Code snippet will not be used.."))
# g = self.gc_header + '\n' + gcode + postamble + end_gcode # g = self.gc_header + '\n' + gcode + postamble + end_gcode
g = ''
if preamble != '' and postamble != '': if preamble != '' and postamble != '':
g = self.gc_header + self.gc_start + '\n' + preamble + '\n' + gcode + '\n' + \ g = self.gc_header + self.gc_start + '\n' + preamble + '\n' + gcode + '\n' + \
postamble + '\n' + end_gcode postamble + '\n' + end_gcode

View File

@ -11,16 +11,13 @@
# ########################################################## # ##########################################################
from shapely.geometry import Point, LineString from shapely.geometry import LineString
from copy import deepcopy
from appParsers.ParseExcellon import Excellon from appParsers.ParseExcellon import Excellon
from appObjects.FlatCAMObj import * from appObjects.FlatCAMObj import *
import itertools import itertools
import numpy as np import numpy as np
from collections import defaultdict
import gettext import gettext
import appTranslation as fcTranslate import appTranslation as fcTranslate
@ -1016,10 +1013,10 @@ class ExcellonObject(FlatCAMObj, Excellon):
# in case that the tool used has the same diameter with the hole, and since the maximum resolution # in case that the tool used has the same diameter with the hole, and since the maximum resolution
# for FlatCAM is 6 decimals, # for FlatCAM is 6 decimals,
# we add a tenth of the minimum value, meaning 0.0000001, which from our point of view is "almost zero" # we add a tenth of the minimum value, meaning 0.0000001, which from our point of view is "almost zero"
for tool in tools: for m_tool in tools:
for slot in self.tools[tool]['slots']: for slot in self.tools[m_tool]['slots']:
toolstable_tool = float('%.*f' % (self.decimals, float(tooldia))) toolstable_tool = float('%.*f' % (self.decimals, float(tooldia)))
file_tool = float('%.*f' % (self.decimals, float(self.tools[tool]["tooldia"]))) file_tool = float('%.*f' % (self.decimals, float(self.tools[m_tool]["tooldia"])))
# I add the 0.0001 value to account for the rounding error in converting from IN to MM and reverse # I add the 0.0001 value to account for the rounding error in converting from IN to MM and reverse
# for the file_tool (tooldia actually) # for the file_tool (tooldia actually)
@ -1164,8 +1161,8 @@ class ExcellonObject(FlatCAMObj, Excellon):
r_color[3] = 1 r_color[3] = 1
new_color = '#' new_color = '#'
for idx in range(len(r_color)): for idx_c in range(len(r_color)):
new_color += '%x' % int(r_color[idx] * 255) new_color += '%x' % int(r_color[idx_c] * 255)
# do it until a valid color is generated # do it until a valid color is generated
# a valid color has the # symbol, another 6 chars for the color and the last 2 chars for alpha # a valid color has the # symbol, another 6 chars for the color and the last 2 chars for alpha
# for a total of 9 chars # for a total of 9 chars

View File

@ -10,7 +10,7 @@
# File modified by: Marius Stanciu # # File modified by: Marius Stanciu #
# ########################################################## # ##########################################################
from shapely.geometry import Polygon, MultiPolygon, MultiLineString, LineString, LinearRing, box from shapely.geometry import MultiLineString, LineString, LinearRing, box
import shapely.affinity as affinity import shapely.affinity as affinity
from camlib import Geometry, grace from camlib import Geometry, grace
@ -2606,7 +2606,7 @@ class GeometryObject(FlatCAMObj, Geometry):
# Type(cpoly) == FlatCAMRTreeStorage | None # Type(cpoly) == FlatCAMRTreeStorage | None
cpoly = None cpoly = None
if paint_method == 0: # Standard if paint_method == 0: # Standard
cpoly = self.clear_polygon(bbox, cpoly = self.clear_polygon(bbox,
tooldia=tooldia, tooldia=tooldia,
steps_per_circle=obj.circle_steps, steps_per_circle=obj.circle_steps,
@ -2614,7 +2614,7 @@ class GeometryObject(FlatCAMObj, Geometry):
contour=True, contour=True,
connect=True, connect=True,
prog_plot=False) prog_plot=False)
elif paint_method == 1: # Seed elif paint_method == 1: # Seed
cpoly = self.clear_polygon2(bbox, cpoly = self.clear_polygon2(bbox,
tooldia=tooldia, tooldia=tooldia,
steps_per_circle=obj.circle_steps, steps_per_circle=obj.circle_steps,
@ -2622,7 +2622,7 @@ class GeometryObject(FlatCAMObj, Geometry):
contour=True, contour=True,
connect=True, connect=True,
prog_plot=False) prog_plot=False)
elif paint_method == 2: # Lines elif paint_method == 2: # Lines
cpoly = self.clear_polygon3(bbox, cpoly = self.clear_polygon3(bbox,
tooldia=tooldia, tooldia=tooldia,
steps_per_circle=obj.circle_steps, steps_per_circle=obj.circle_steps,

View File

@ -11,13 +11,11 @@
# ########################################################## # ##########################################################
from shapely.geometry import Point, Polygon, MultiPolygon, MultiLineString, LineString, LinearRing from shapely.geometry import Point, MultiLineString, LineString, LinearRing
from shapely.ops import unary_union
from appParsers.ParseGerber import Gerber from appParsers.ParseGerber import Gerber
from appObjects.FlatCAMObj import * from appObjects.FlatCAMObj import *
import math
import numpy as np import numpy as np
from copy import deepcopy from copy import deepcopy
@ -210,7 +208,7 @@ class GerberObject(FlatCAMObj, Gerber):
pass pass
self.apertures_row = 0 self.apertures_row = 0
aper_no = self.apertures_row + 1
sort = [] sort = []
for k in list(self.apertures.keys()): for k in list(self.apertures.keys()):
sort.append(int(k)) sort.append(int(k))
@ -397,7 +395,7 @@ class GerberObject(FlatCAMObj, Gerber):
non_copper = bounding_box.difference(self.solid_geometry) non_copper = bounding_box.difference(self.solid_geometry)
if non_copper is None or non_copper.is_empty: if non_copper is None or non_copper.is_empty:
self.app.inform.emit("[ERROR_NOTCL] %s" % _("Operation could not be done.")) app_obj.inform.emit("[ERROR_NOTCL] %s" % _("Operation could not be done."))
return "fail" return "fail"
geo_obj.solid_geometry = non_copper geo_obj.solid_geometry = non_copper
@ -423,7 +421,7 @@ class GerberObject(FlatCAMObj, Gerber):
bounding_box = bounding_box.envelope bounding_box = bounding_box.envelope
if bounding_box is None or bounding_box.is_empty: if bounding_box is None or bounding_box.is_empty:
self.app.inform.emit("[ERROR_NOTCL] %s" % _("Operation could not be done.")) app_obj.inform.emit("[ERROR_NOTCL] %s" % _("Operation could not be done."))
return "fail" return "fail"
geo_obj.solid_geometry = bounding_box geo_obj.solid_geometry = bounding_box
@ -532,17 +530,16 @@ class GerberObject(FlatCAMObj, Gerber):
"startz": self.app.defaults['geometry_startz'] "startz": self.app.defaults['geometry_startz']
}) })
geo_obj.tools = {} geo_obj.tools = {'1': {}}
geo_obj.tools['1'] = {}
geo_obj.tools.update({ geo_obj.tools.update({
'1': { '1': {
'tooldia': dia, 'tooldia': dia,
'offset': 'Path', 'offset': 'Path',
'offset_value': 0.0, 'offset_value': 0.0,
'type': _('Rough'), 'type': _('Rough'),
'tool_type': tool_type, 'tool_type': tool_type,
'data': default_data, 'data': default_data,
'solid_geometry': geo_obj.solid_geometry 'solid_geometry': geo_obj.solid_geometry
} }
}) })
@ -679,17 +676,16 @@ class GerberObject(FlatCAMObj, Gerber):
"startz": self.app.defaults['geometry_startz'] "startz": self.app.defaults['geometry_startz']
}) })
geo_obj.tools = {} geo_obj.tools = {'1': {}}
geo_obj.tools['1'] = {}
geo_obj.tools.update({ geo_obj.tools.update({
'1': { '1': {
'tooldia': dia, 'tooldia': dia,
'offset': 'Path', 'offset': 'Path',
'offset_value': 0.0, 'offset_value': 0.0,
'type': _('Rough'), 'type': _('Rough'),
'tool_type': tool_type, 'tool_type': tool_type,
'data': default_data, 'data': default_data,
'solid_geometry': geo_obj.solid_geometry 'solid_geometry': geo_obj.solid_geometry
} }
}) })
@ -776,7 +772,7 @@ class GerberObject(FlatCAMObj, Gerber):
else: else:
follow_name = outname follow_name = outname
def follow_init(follow_obj, app): def follow_init(follow_obj, app_obj):
# Propagate options # Propagate options
follow_obj.options["cnctooldia"] = str(self.app.defaults["tools_iso_tooldia"]) follow_obj.options["cnctooldia"] = str(self.app.defaults["tools_iso_tooldia"])
follow_obj.solid_geometry = self.follow_geometry follow_obj.solid_geometry = self.follow_geometry
@ -854,7 +850,7 @@ class GerberObject(FlatCAMObj, Gerber):
log.debug("FlatCAMObj.GerberObject.convert_units()") log.debug("FlatCAMObj.GerberObject.convert_units()")
factor = Gerber.convert_units(self, units) Gerber.convert_units(self, units)
# self.options['isotooldia'] = float(self.options['isotooldia']) * factor # self.options['isotooldia'] = float(self.options['isotooldia']) * factor
# self.options['bboxmargin'] = float(self.options['bboxmargin']) * factor # self.options['bboxmargin'] = float(self.options['bboxmargin']) * factor

View File

@ -16,7 +16,6 @@ from appGUI.ObjectUI import *
import tkinter as tk import tkinter as tk
import sys import sys
from copy import deepcopy
import gettext import gettext
import appTranslation as fcTranslate import appTranslation as fcTranslate
@ -219,7 +218,7 @@ class ScriptObject(FlatCAMObj):
# it means that the script finished with an error # it means that the script finished with an error
result = self.app.shell.tcl.eval("set errorInfo") result = self.app.shell.tcl.eval("set errorInfo")
log.error("Exec command Exception: %s\n" % result) log.error("Exec command Exception: %s\n" % result)
self.app.shell.append_error('ERROR: %s\n '% result) self.app.shell.append_error('ERROR: %s\n' % result)
self.app.ui.fcinfo.lock_pmaps = False self.app.ui.fcinfo.lock_pmaps = False
self.app.shell.close_processing() self.app.shell.close_processing()

View File

@ -1090,14 +1090,14 @@ class ObjectCollection(QtCore.QAbstractItemModel):
def add_act(o_name): def add_act(o_name):
obj_for_icon = self.get_by_name(o_name) obj_for_icon = self.get_by_name(o_name)
add_action = QtWidgets.QAction(parent=self.app.ui.menuobjects) menu_action = QtWidgets.QAction(parent=self.app.ui.menuobjects)
add_action.setCheckable(True) menu_action.setCheckable(True)
add_action.setText(o_name) menu_action.setText(o_name)
add_action.setIcon(QtGui.QIcon(icon_files[obj_for_icon.kind])) menu_action.setIcon(QtGui.QIcon(icon_files[obj_for_icon.kind]))
add_action.triggered.connect( menu_action.triggered.connect(
lambda: self.set_active(o_name) if add_action.isChecked() is True else lambda: self.set_active(o_name) if menu_action.isChecked() is True else
self.set_inactive(o_name)) self.set_inactive(o_name))
self.app.ui.menuobjects.addAction(add_action) self.app.ui.menuobjects.addAction(menu_action)
for name in gerber_list: for name in gerber_list:
add_act(name) add_act(name)

View File

@ -9,13 +9,12 @@ from shapely.geometry import LineString
from shapely.affinity import rotate from shapely.affinity import rotate
from ezdxf.math.vector import Vector as ezdxf_vector from ezdxf.math.vector import Vector as ezdxf_vector
from appParsers.ParseFont import *
from appParsers.ParseDXF_Spline import *
import logging import logging
log = logging.getLogger('base2') log = logging.getLogger('base2')
from appParsers.ParseFont import *
from appParsers.ParseDXF_Spline import *
def distance(pt1, pt2): def distance(pt1, pt2):
return math.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2) return math.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2)
@ -107,12 +106,12 @@ def dxfarc2shapely(arc, n_points=100):
arc_center = ocs.to_wcs(arc.dxf.center) arc_center = ocs.to_wcs(arc.dxf.center)
start_angle = arc.dxf.start_angle + 180 start_angle = arc.dxf.start_angle + 180
end_angle = arc.dxf.end_angle + 180 end_angle = arc.dxf.end_angle + 180
dir = 'CW' direction = 'CW'
else: else:
arc_center = arc.dxf.center arc_center = arc.dxf.center
start_angle = arc.dxf.start_angle start_angle = arc.dxf.start_angle
end_angle = arc.dxf.end_angle end_angle = arc.dxf.end_angle
dir = 'CCW' direction = 'CCW'
center_x = arc_center[0] center_x = arc_center[0]
center_y = arc_center[1] center_y = arc_center[1]
@ -127,7 +126,7 @@ def dxfarc2shapely(arc, n_points=100):
step_angle = float(abs(end_angle - start_angle) / n_points) step_angle = float(abs(end_angle - start_angle) / n_points)
while angle <= end_angle: while angle <= end_angle:
if dir == 'CCW': if direction == 'CCW':
x = center_x + radius * math.cos(math.radians(angle)) x = center_x + radius * math.cos(math.radians(angle))
y = center_y + radius * math.sin(math.radians(angle)) y = center_y + radius * math.sin(math.radians(angle))
else: else:
@ -138,7 +137,7 @@ def dxfarc2shapely(arc, n_points=100):
# in case the number of segments do not cover everything until the end of the arc # in case the number of segments do not cover everything until the end of the arc
if angle != end_angle: if angle != end_angle:
if dir == 'CCW': if direction == 'CCW':
x = center_x + radius * math.cos(math.radians(end_angle)) x = center_x + radius * math.cos(math.radians(end_angle))
y = center_y + radius * math.sin(math.radians(end_angle)) y = center_y + radius * math.sin(math.radians(end_angle))
else: else:
@ -164,12 +163,12 @@ def dxfellipse2shapely(ellipse, ellipse_segments=100):
center = ocs.to_wcs(ellipse.dxf.center) center = ocs.to_wcs(ellipse.dxf.center)
start_angle = ocs.to_wcs(ellipse.dxf.start_param) start_angle = ocs.to_wcs(ellipse.dxf.start_param)
end_angle = ocs.to_wcs(ellipse.dxf.end_param) end_angle = ocs.to_wcs(ellipse.dxf.end_param)
dir = 'CW' direction = 'CW'
else: else:
center = ellipse.dxf.center center = ellipse.dxf.center
start_angle = ellipse.dxf.start_param start_angle = ellipse.dxf.start_param
end_angle = ellipse.dxf.end_param end_angle = ellipse.dxf.end_param
dir = 'CCW' direction = 'CCW'
# print("Dir = %s" % dir) # print("Dir = %s" % dir)
major_axis = ellipse.dxf.major_axis major_axis = ellipse.dxf.major_axis
@ -189,7 +188,7 @@ def dxfellipse2shapely(ellipse, ellipse_segments=100):
angle = start_angle angle = start_angle
for step in range(line_seg + 1): for step in range(line_seg + 1):
if dir == 'CW': if direction == 'CW':
major_dim = normalize_2(major_axis) major_dim = normalize_2(major_axis)
minor_dim = normalize_2(Vector([ratio * k for k in major_axis])) minor_dim = normalize_2(Vector([ratio * k for k in major_axis]))
vx = (major_dim[0] + major_dim[1]) * math.cos(angle) vx = (major_dim[0] + major_dim[1]) * math.cos(angle)
@ -381,6 +380,7 @@ def get_geo(dxf_object, container):
return geo return geo
def getdxftext(exf_object, object_type, units=None): def getdxftext(exf_object, object_type, units=None):
pass pass

View File

@ -400,7 +400,7 @@ class Vector(list):
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
def __str__(self): def __str__(self):
return "[%s]" % ", ".join([("%15g" % (x)).strip() for x in self]) return "[%s]" % ", ".join([("%15g" % x).strip() for x in self])
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
def eq(self, v, acc=_accuracy): def eq(self, v, acc=_accuracy):
@ -805,7 +805,6 @@ class Vector(list):
# #
# #----------------------------------------------------------------------- # #-----------------------------------------------------------------------
# def __call__(self, i, x): # def __call__(self, i, x):
# # FIXME should interpolate to find the interval
# C = self.coefficients(i) # C = self.coefficients(i)
# return ((C[0]*x + C[1])*x + C[2])*x + C[3] # return ((C[0]*x + C[1])*x + C[2])*x + C[3]
# #

View File

@ -10,13 +10,15 @@
# ## and made it work with Python 3 # # ## and made it work with Python 3 #
# ###################################################################### # ######################################################################
import re, os, sys, glob import re
import os
import sys
import glob
from shapely.geometry import Point, Polygon from shapely.geometry import Polygon
from shapely.affinity import translate, scale from shapely.affinity import translate, scale
from shapely.geometry import MultiPolygon from shapely.geometry import MultiPolygon
import freetype as ft import freetype as ft
from fontTools import ttLib from fontTools import ttLib
@ -32,7 +34,7 @@ if '_' not in builtins.__dict__:
log = logging.getLogger('base2') log = logging.getLogger('base2')
class ParseFont(): class ParseFont:
FONT_SPECIFIER_NAME_ID = 4 FONT_SPECIFIER_NAME_ID = 4
FONT_SPECIFIER_FAMILY_ID = 1 FONT_SPECIFIER_FAMILY_ID = 1
@ -69,12 +71,12 @@ class ParseFont():
if os.path.isfile(executable): if os.path.isfile(executable):
data = os.popen(executable).readlines() data = os.popen(executable).readlines()
match = re.compile('\d+: (.+)') match = re.compile('\d+: (.+)')
set = [] set_lst = []
for line in data: for line in data:
result = match.match(line) result = match.match(line)
if result: if result:
set.append(result.group(1)) set_lst.append(result.group(1))
return set return set_lst
else: else:
directories = [ directories = [
# what seems to be the standard installation point # what seems to be the standard installation point
@ -91,7 +93,7 @@ class ParseFont():
dir_set = [] dir_set = []
for directory in directories: for directory in directories:
directory = directory = os.path.expanduser(os.path.expandvars(directory)) directory = os.path.expanduser(os.path.expandvars(directory))
try: try:
if os.path.isdir(directory): if os.path.isdir(directory):
for path, children, files in os.walk(directory): for path, children, files in os.walk(directory):
@ -116,7 +118,7 @@ class ParseFont():
dir_set = [] dir_set = []
for directory in directories: for directory in directories:
directory = directory = os.path.expanduser(os.path.expandvars(directory)) directory = os.path.expanduser(os.path.expandvars(directory))
try: try:
if os.path.isdir(directory): if os.path.isdir(directory):
for path, children, files in os.walk(directory): for path, children, files in os.walk(directory):
@ -144,7 +146,7 @@ class ParseFont():
winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_LOCAL_MACHINE,
keyName keyName
) )
except OSError as err: except OSError:
pass pass
if not k: if not k:
@ -195,7 +197,7 @@ class ParseFont():
break break
return name, family return name, family
def __init__(self, app, parent=None): def __init__(self, app):
super(ParseFont, self).__init__() super(ParseFont, self).__init__()
self.app = app self.app = app
@ -217,7 +219,7 @@ class ParseFont():
if paths is None: if paths is None:
if sys.platform == 'win32': if sys.platform == 'win32':
font_directory = ParseFont.get_win32_font_path() font_directory = ParseFont.get_win32_font_path()
paths = [font_directory,] paths = [font_directory, ]
# now get all installed fonts directly... # now get all installed fonts directly...
for f in self.get_win32_fonts(font_directory): for f in self.get_win32_fonts(font_directory):
@ -275,7 +277,7 @@ class ParseFont():
else: else:
try: try:
name = name.replace(" Regular", '') name = name.replace(" Regular", '')
except Exception as e: except Exception:
pass pass
self.regular_f.update({name: font}) self.regular_f.update({name: font})
log.debug("Font parsing is finished.") log.debug("Font parsing is finished.")
@ -318,7 +320,7 @@ class ParseFont():
if previous > 0 and glyph_index > 0: if previous > 0 and glyph_index > 0:
delta = face.get_kerning(previous, glyph_index) delta = face.get_kerning(previous, glyph_index)
pen_x += delta.x pen_x += delta.x
except Exception as e: except Exception:
pass pass
face.load_glyph(glyph_index) face.load_glyph(glyph_index)

View File

@ -2,16 +2,13 @@ from PyQt5 import QtWidgets
from camlib import Geometry, arc, arc_angle, ApertureMacro, grace from camlib import Geometry, arc, arc_angle, ApertureMacro, grace
import numpy as np import numpy as np
# import re
# import logging
import traceback import traceback
from copy import deepcopy from copy import deepcopy
# import sys
from shapely.ops import unary_union, linemerge from shapely.ops import unary_union, linemerge
# from shapely.affinity import scale, translate
import shapely.affinity as affinity import shapely.affinity as affinity
from shapely.geometry import box as shply_box from shapely.geometry import box as shply_box
from shapely.geometry import Point
from lxml import etree as ET from lxml import etree as ET
import ezdxf import ezdxf
@ -315,12 +312,12 @@ class Gerber(Geometry):
First is ``G54D11*`` and seconds is ``G36*``. First is ``G54D11*`` and seconds is ``G36*``.
:param filename: Gerber file to parse. :param filename: Gerber file to parse.
:type filename: str :type filename: str
:param follow: If true, will not create polygons, just lines :param follow: If true, will not create polygons, just lines
following the gerber path. following the gerber path.
:type follow: bool :type follow: bool
:return: None :return: None
""" """
with open(filename, 'r') as gfile: with open(filename, 'r') as gfile:
@ -1837,12 +1834,10 @@ class Gerber(Geometry):
geos_length = 1 geos_length = 1
if geos_length == 1: if geos_length == 1:
geo_qrcode = [] geo_qrcode = [Polygon(geos[0].exterior)]
geo_qrcode.append(Polygon(geos[0].exterior))
for i_el in geos[0].interiors: for i_el in geos[0].interiors:
geo_qrcode.append(Polygon(i_el).buffer(0, resolution=res)) geo_qrcode.append(Polygon(i_el).buffer(0, resolution=res))
for poly in geo_qrcode: geos = [poly for poly in geo_qrcode]
geos.append(poly)
if type(self.solid_geometry) == list: if type(self.solid_geometry) == list:
self.solid_geometry += geos self.solid_geometry += geos
@ -1864,15 +1859,14 @@ class Gerber(Geometry):
self.solid_geometry = [self.solid_geometry] self.solid_geometry = [self.solid_geometry]
if '0' not in self.apertures: if '0' not in self.apertures:
self.apertures['0'] = {} self.apertures['0'] = {
self.apertures['0']['type'] = 'REG' 'type': 'REG',
self.apertures['0']['size'] = 0.0 'size': 0.0,
self.apertures['0']['geometry'] = [] 'geometry': []
}
for pol in self.solid_geometry: for pol in self.solid_geometry:
new_el = {} new_el = {'solid': pol, 'follow': pol.exterior}
new_el['solid'] = pol
new_el['follow'] = pol.exterior
self.apertures['0']['geometry'].append(new_el) self.apertures['0']['geometry'].append(new_el)
def import_dxf_as_gerber(self, filename, units='MM'): def import_dxf_as_gerber(self, filename, units='MM'):
@ -1914,15 +1908,14 @@ class Gerber(Geometry):
# create the self.apertures data structure # create the self.apertures data structure
if '0' not in self.apertures: if '0' not in self.apertures:
self.apertures['0'] = {} self.apertures['0'] = {
self.apertures['0']['type'] = 'REG' 'type': 'REG',
self.apertures['0']['size'] = 0.0 'size': 0.0,
self.apertures['0']['geometry'] = [] 'geometry': []
}
for pol in flat_geo: for pol in flat_geo:
new_el = {} new_el = {'solid': pol, 'follow': pol}
new_el['solid'] = pol
new_el['follow'] = pol
self.apertures['0']['geometry'].append(deepcopy(new_el)) self.apertures['0']['geometry'].append(deepcopy(new_el))
def scale(self, xfactor, yfactor=None, point=None): def scale(self, xfactor, yfactor=None, point=None):

View File

@ -82,12 +82,10 @@ class PdfParser(QtCore.QObject):
self.restore_gs_re = re.compile(r'^.*Q.*$') self.restore_gs_re = re.compile(r'^.*Q.*$')
# graphic stack where we save parameters like transformation, line_width # graphic stack where we save parameters like transformation, line_width
self.gs = {}
# each element is a list composed of sublist elements # each element is a list composed of sublist elements
# (each sublist has 2 lists each having 2 elements: first is offset like: # (each sublist has 2 lists each having 2 elements: first is offset like:
# offset_geo = [off_x, off_y], second element is scale list with 2 elements, like: scale_geo = [sc_x, sc_yy]) # offset_geo = [off_x, off_y], second element is scale list with 2 elements, like: scale_geo = [sc_x, sc_yy])
self.gs['transform'] = [] self.gs = {'transform': [], 'line_width': []}
self.gs['line_width'] = [] # each element is a float
# conversion factor to INCH # conversion factor to INCH
self.point_to_unit_factor = 0.01388888888 self.point_to_unit_factor = 0.01388888888
@ -102,15 +100,17 @@ class PdfParser(QtCore.QObject):
# 1 inch = 72 points => 1 point = 1 / 72 = 0.01388888888 inch # 1 inch = 72 points => 1 point = 1 / 72 = 0.01388888888 inch
self.point_to_unit_factor = 1 / 72 self.point_to_unit_factor = 1 / 72
path = {} path = {
path['lines'] = [] # it's a list of lines subpaths 'lines': [], # it's a list of lines subpaths
path['bezier'] = [] # it's a list of bezier arcs subpaths 'bezier': [], # it's a list of bezier arcs subpaths
path['rectangle'] = [] # it's a list of rectangle subpaths 'rectangle': [] # it's a list of rectangle subpaths
}
subpath = {} subpath = {
subpath['lines'] = [] # it's a list of points 'lines': [], # it's a list of points
subpath['bezier'] = [] # it's a list of sublists each like this [start, c1, c2, stop] 'bezier': [], # it's a list of sublists each like this [start, c1, c2, stop]
subpath['rectangle'] = [] # it's a list of sublists of points 'rectangle': [] # it's a list of sublists of points
}
# store the start point (when 'm' command is encountered) # store the start point (when 'm' command is encountered)
current_subpath = None current_subpath = None
@ -141,12 +141,14 @@ class PdfParser(QtCore.QObject):
# store the apertures with clear geometry here # store the apertures with clear geometry here
# we are interested only in the circular geometry (drill holes) therefore we target only Bezier subpaths # we are interested only in the circular geometry (drill holes) therefore we target only Bezier subpaths
clear_apertures_dict = {}
# everything will be stored in the '0' aperture since we are dealing with clear polygons not strokes # everything will be stored in the '0' aperture since we are dealing with clear polygons not strokes
clear_apertures_dict['0'] = {} clear_apertures_dict = {
clear_apertures_dict['0']['size'] = 0.0 '0': {
clear_apertures_dict['0']['type'] = 'C' 'size': 0.0,
clear_apertures_dict['0']['geometry'] = [] 'type': 'C',
'geometry': []
}
}
# on stroke color change we create a new apertures dictionary and store the old one in a storage from where # on stroke color change we create a new apertures dictionary and store the old one in a storage from where
# it will be transformed into Gerber object # it will be transformed into Gerber object
@ -527,14 +529,10 @@ class PdfParser(QtCore.QObject):
for pdf_geo in path_geo: for pdf_geo in path_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in pdf_geo: for poly in pdf_geo:
new_el = {} new_el = {'solid': poly, 'follow': poly.exterior}
new_el['solid'] = poly
new_el['follow'] = poly.exterior
apertures_dict[copy(found_aperture)]['geometry'].append(deepcopy(new_el)) apertures_dict[copy(found_aperture)]['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'solid': pdf_geo, 'follow': pdf_geo.exterior}
new_el['solid'] = pdf_geo
new_el['follow'] = pdf_geo.exterior
apertures_dict[copy(found_aperture)]['geometry'].append(deepcopy(new_el)) apertures_dict[copy(found_aperture)]['geometry'].append(deepcopy(new_el))
else: else:
if str(aperture) in apertures_dict.keys(): if str(aperture) in apertures_dict.keys():
@ -546,14 +544,10 @@ class PdfParser(QtCore.QObject):
for pdf_geo in path_geo: for pdf_geo in path_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in pdf_geo: for poly in pdf_geo:
new_el = {} new_el = {'solid': poly, 'follow': poly.exterior}
new_el['solid'] = poly
new_el['follow'] = poly.exterior
apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'solid': pdf_geo, 'follow': pdf_geo.exterior}
new_el['solid'] = pdf_geo
new_el['follow'] = pdf_geo.exterior
apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el))
else: else:
apertures_dict[str(aperture)] = {} apertures_dict[str(aperture)] = {}
@ -563,14 +557,10 @@ class PdfParser(QtCore.QObject):
for pdf_geo in path_geo: for pdf_geo in path_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in pdf_geo: for poly in pdf_geo:
new_el = {} new_el = {'solid': poly, 'follow': poly.exterior}
new_el['solid'] = poly
new_el['follow'] = poly.exterior
apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'solid': pdf_geo, 'follow': pdf_geo.exterior}
new_el['solid'] = pdf_geo
new_el['follow'] = pdf_geo.exterior
apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el))
continue continue
@ -675,12 +665,10 @@ class PdfParser(QtCore.QObject):
if path_geo: if path_geo:
try: try:
for g in path_geo: for g in path_geo:
new_el = {} new_el = {'clear': g}
new_el['clear'] = g
clear_apertures_dict['0']['geometry'].append(new_el) clear_apertures_dict['0']['geometry'].append(new_el)
except TypeError: except TypeError:
new_el = {} new_el = {'clear': path_geo}
new_el['clear'] = path_geo
clear_apertures_dict['0']['geometry'].append(new_el) clear_apertures_dict['0']['geometry'].append(new_el)
# now that we finished searching for drill holes (this is not very precise because holes in the # now that we finished searching for drill holes (this is not very precise because holes in the
@ -690,12 +678,10 @@ class PdfParser(QtCore.QObject):
for pdf_geo in path_geo: for pdf_geo in path_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in pdf_geo: for poly in pdf_geo:
new_el = {} new_el = {'clear': poly}
new_el['clear'] = poly
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'clear': pdf_geo}
new_el['clear'] = pdf_geo
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
except KeyError: except KeyError:
# in case there is no stroke width yet therefore no aperture # in case there is no stroke width yet therefore no aperture
@ -706,12 +692,10 @@ class PdfParser(QtCore.QObject):
for pdf_geo in path_geo: for pdf_geo in path_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in pdf_geo: for poly in pdf_geo:
new_el = {} new_el = {'clear': poly}
new_el['clear'] = poly
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'clear': pdf_geo}
new_el['clear'] = pdf_geo
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
else: else:
# else, add the geometry as usual # else, add the geometry as usual
@ -719,14 +703,10 @@ class PdfParser(QtCore.QObject):
for pdf_geo in path_geo: for pdf_geo in path_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in pdf_geo: for poly in pdf_geo:
new_el = {} new_el = {'solid': poly, 'follow': poly.exterior}
new_el['solid'] = poly
new_el['follow'] = poly.exterior
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'solid': pdf_geo, 'follow': pdf_geo.exterior}
new_el['solid'] = pdf_geo
new_el['follow'] = pdf_geo.exterior
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
except KeyError: except KeyError:
# in case there is no stroke width yet therefore no aperture # in case there is no stroke width yet therefore no aperture
@ -737,14 +717,10 @@ class PdfParser(QtCore.QObject):
for pdf_geo in path_geo: for pdf_geo in path_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in pdf_geo: for poly in pdf_geo:
new_el = {} new_el = {'solid': poly, 'follow': poly.exterior}
new_el['solid'] = poly
new_el['follow'] = poly.exterior
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'solid': pdf_geo, 'follow': pdf_geo.exterior}
new_el['solid'] = pdf_geo
new_el['follow'] = pdf_geo.exterior
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
continue continue
@ -890,50 +866,41 @@ class PdfParser(QtCore.QObject):
for pdf_geo in path_geo: for pdf_geo in path_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in pdf_geo: for poly in pdf_geo:
new_el = {} new_el = {'solid': poly, 'follow': poly.exterior}
new_el['solid'] = poly
new_el['follow'] = poly.exterior
apertures_dict[copy(found_aperture)]['geometry'].append(deepcopy(new_el)) apertures_dict[copy(found_aperture)]['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'solid': pdf_geo, 'follow': pdf_geo.exterior}
new_el['solid'] = pdf_geo
new_el['follow'] = pdf_geo.exterior
apertures_dict[copy(found_aperture)]['geometry'].append(deepcopy(new_el)) apertures_dict[copy(found_aperture)]['geometry'].append(deepcopy(new_el))
else: else:
if str(aperture) in apertures_dict.keys(): if str(aperture) in apertures_dict.keys():
aperture += 1 aperture += 1
apertures_dict[str(aperture)] = {} apertures_dict[str(aperture)] = {
apertures_dict[str(aperture)]['size'] = round(applied_size, 5) 'size': round(applied_size, 5),
apertures_dict[str(aperture)]['type'] = 'C' 'type': 'C',
apertures_dict[str(aperture)]['geometry'] = [] 'geometry': []
}
for pdf_geo in path_geo: for pdf_geo in path_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in pdf_geo: for poly in pdf_geo:
new_el = {} new_el = {'solid': poly, 'follow': poly.exterior}
new_el['solid'] = poly
new_el['follow'] = poly.exterior
apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'solid': pdf_geo, 'follow': pdf_geo.exterior}
new_el['solid'] = pdf_geo
new_el['follow'] = pdf_geo.exterior
apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el))
else: else:
apertures_dict[str(aperture)] = {} apertures_dict[str(aperture)] = {
apertures_dict[str(aperture)]['size'] = round(applied_size, 5) 'size': round(applied_size, 5),
apertures_dict[str(aperture)]['type'] = 'C' 'type': 'C',
apertures_dict[str(aperture)]['geometry'] = [] 'geometry': []
}
for pdf_geo in path_geo: for pdf_geo in path_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in pdf_geo: for poly in pdf_geo:
new_el = {} new_el = {'solid': poly, 'follow': poly.exterior}
new_el['solid'] = poly
new_el['follow'] = poly.exterior
apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'solid': pdf_geo, 'follow': pdf_geo.exterior}
new_el['solid'] = pdf_geo
new_el['follow'] = pdf_geo.exterior
apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el)) apertures_dict[str(aperture)]['geometry'].append(deepcopy(new_el))
# ############################################# ## # ############################################# ##
@ -946,60 +913,52 @@ class PdfParser(QtCore.QObject):
for pdf_geo in path_geo: for pdf_geo in path_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in fill_geo: for poly in fill_geo:
new_el = {} new_el = {'clear': poly}
new_el['clear'] = poly
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'clear': pdf_geo}
new_el['clear'] = pdf_geo
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
except KeyError: except KeyError:
# in case there is no stroke width yet therefore no aperture # in case there is no stroke width yet therefore no aperture
apertures_dict['0'] = {} apertures_dict['0'] = {
apertures_dict['0']['size'] = round(applied_size, 5) 'size': round(applied_size, 5),
apertures_dict['0']['type'] = 'C' 'type': 'C',
apertures_dict['0']['geometry'] = [] 'geometry': []
}
for pdf_geo in fill_geo: for pdf_geo in fill_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in pdf_geo: for poly in pdf_geo:
new_el = {} new_el = {'clear': poly}
new_el['clear'] = poly
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'clear': pdf_geo}
new_el['clear'] = pdf_geo
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
else: else:
try: try:
for pdf_geo in path_geo: for pdf_geo in path_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in fill_geo: for poly in fill_geo:
new_el = {} new_el = {'solid': poly, 'follow': poly.exterior}
new_el['solid'] = poly
new_el['follow'] = poly.exterior
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'solid': pdf_geo, 'follow': pdf_geo.exterior}
new_el['solid'] = pdf_geo
new_el['follow'] = pdf_geo.exterior
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
except KeyError: except KeyError:
# in case there is no stroke width yet therefore no aperture # in case there is no stroke width yet therefore no aperture
apertures_dict['0'] = {} apertures_dict['0'] = {
apertures_dict['0']['size'] = round(applied_size, 5) 'size': round(applied_size, 5),
apertures_dict['0']['type'] = 'C' 'type': 'C',
apertures_dict['0']['geometry'] = [] 'geometry': []
}
for pdf_geo in fill_geo: for pdf_geo in fill_geo:
if isinstance(pdf_geo, MultiPolygon): if isinstance(pdf_geo, MultiPolygon):
for poly in pdf_geo: for poly in pdf_geo:
new_el = {} new_el = {'solid': poly, 'follow': poly.exterior}
new_el['solid'] = poly
new_el['follow'] = poly.exterior
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
else: else:
new_el = {} new_el = {'solid': pdf_geo, 'follow': pdf_geo.exterior}
new_el['solid'] = pdf_geo
new_el['follow'] = pdf_geo.exterior
apertures_dict['0']['geometry'].append(deepcopy(new_el)) apertures_dict['0']['geometry'].append(deepcopy(new_el))
continue continue

View File

@ -24,7 +24,7 @@ from svg.path import Line, Arc, CubicBezier, QuadraticBezier, parse_path
# from svg.path.path import Move # from svg.path.path import Move
# from svg.path.path import Close # from svg.path.path import Close
import svg.path import svg.path
from shapely.geometry import LineString, MultiLineString from shapely.geometry import LineString, MultiLineString, Point
from shapely.affinity import skew, affine_transform, rotate from shapely.affinity import skew, affine_transform, rotate
import numpy as np import numpy as np
@ -286,6 +286,8 @@ def svgcircle2shapely(circle, n_points=64, factor=1.0):
:type circle: xml.etree.ElementTree.Element :type circle: xml.etree.ElementTree.Element
:param n_points: circle resolution; nr of points to b e used to approximate a circle :param n_points: circle resolution; nr of points to b e used to approximate a circle
:type n_points: int :type n_points: int
:param factor:
:type factor: float
:return: Shapely representation of the circle. :return: Shapely representation of the circle.
:rtype: shapely.geometry.polygon.LinearRing :rtype: shapely.geometry.polygon.LinearRing
""" """
@ -310,6 +312,8 @@ def svgellipse2shapely(ellipse, n_points=64, factor=1.0):
:type ellipse: xml.etree.ElementTree.Element :type ellipse: xml.etree.ElementTree.Element
:param n_points: Number of discrete points in output. :param n_points: Number of discrete points in output.
:type n_points: int :type n_points: int
:param factor:
:type factor: float
:return: Shapely representation of the ellipse. :return: Shapely representation of the ellipse.
:rtype: shapely.geometry.polygon.LinearRing :rtype: shapely.geometry.polygon.LinearRing
""" """

View File

@ -147,8 +147,10 @@ class AppPreProcTools(object, metaclass=ABCPreProcRegister):
def load_preprocessors(app): def load_preprocessors(app):
preprocessors_path_search = [os.path.join(app.data_path, 'preprocessors', '*.py'), preprocessors_path_search = [
os.path.join('preprocessors', '*.py')] os.path.join(app.data_path, 'preprocessors', '*.py'),
os.path.join('preprocessors', '*.py')
]
import glob import glob
for path_search in preprocessors_path_search: for path_search in preprocessors_path_search:
for file in glob.glob(path_search): for file in glob.glob(path_search):

View File

@ -383,7 +383,7 @@ class AlignUI:
grid0.setColumnStretch(1, 1) grid0.setColumnStretch(1, 1)
self.layout.addLayout(grid0) self.layout.addLayout(grid0)
self.aligned_label =FCLabel('<b>%s:</b>' % _("MOVING object")) self.aligned_label = FCLabel('<b>%s:</b>' % _("MOVING object"))
grid0.addWidget(self.aligned_label, 0, 0, 1, 2) grid0.addWidget(self.aligned_label, 0, 0, 1, 2)
self.aligned_label.setToolTip( self.aligned_label.setToolTip(
@ -478,7 +478,7 @@ class AlignUI:
grid0.addWidget(separator_line, 14, 0, 1, 2) grid0.addWidget(separator_line, 14, 0, 1, 2)
# Buttons # Buttons
self.align_object_button =FCButton(_("Align Object")) self.align_object_button = FCButton(_("Align Object"))
self.align_object_button.setIcon(QtGui.QIcon(self.app.resource_location + '/align16.png')) self.align_object_button.setIcon(QtGui.QIcon(self.app.resource_location + '/align16.png'))
self.align_object_button.setToolTip( self.align_object_button.setToolTip(
_("Align the specified object to the aligner object.\n" _("Align the specified object to the aligner object.\n"

View File

@ -639,7 +639,7 @@ class ToolCalibration(AppTool):
if obj.tools: if obj.tools:
obj_init.tools = deepcopy(obj.tools) obj_init.tools = deepcopy(obj.tools)
except Exception as ee: except Exception as ee:
log.debug("ToolCalibration.new_calibrated_object.initialize_geometry() --> %s" % str(ee)) app.log.debug("ToolCalibration.new_calibrated_object.initialize_geometry() --> %s" % str(ee))
obj_init.scale(xfactor=scalex, yfactor=scaley, point=(origin_x, origin_y)) obj_init.scale(xfactor=scalex, yfactor=scaley, point=(origin_x, origin_y))
obj_init.skew(angle_x=skewx, angle_y=skewy, point=(origin_x, origin_y)) obj_init.skew(angle_x=skewx, angle_y=skewy, point=(origin_x, origin_y))
@ -649,7 +649,7 @@ class ToolCalibration(AppTool):
except (AttributeError, TypeError): except (AttributeError, TypeError):
pass pass
def initialize_gerber(obj_init, app): def initialize_gerber(obj_init, app_obj):
obj_init.solid_geometry = deepcopy(obj.solid_geometry) obj_init.solid_geometry = deepcopy(obj.solid_geometry)
try: try:
obj_init.follow_geometry = deepcopy(obj.follow_geometry) obj_init.follow_geometry = deepcopy(obj.follow_geometry)
@ -671,12 +671,12 @@ class ToolCalibration(AppTool):
obj_init.skew(angle_x=skewx, angle_y=skewy, point=(origin_x, origin_y)) obj_init.skew(angle_x=skewx, angle_y=skewy, point=(origin_x, origin_y))
try: try:
obj_init.source_file = self.app.f_handlers.export_gerber(obj_name=obj_name, filename=None, obj_init.source_file = app_obj.f_handlers.export_gerber(obj_name=obj_name, filename=None,
local_use=obj_init, use_thread=False) local_use=obj_init, use_thread=False)
except (AttributeError, TypeError): except (AttributeError, TypeError):
pass pass
def initialize_excellon(obj_init, app): def initialize_excellon(obj_init, app_obj):
obj_init.tools = deepcopy(obj.tools) obj_init.tools = deepcopy(obj.tools)
# drills are offset, so they need to be deep copied # drills are offset, so they need to be deep copied
@ -689,8 +689,8 @@ class ToolCalibration(AppTool):
obj_init.create_geometry() obj_init.create_geometry()
obj_init.source_file = self.app.export.export_excellon(obj_name=obj_name, local_use=obj, filename=None, obj_init.source_file = app_obj.f_handlers.export_excellon(obj_name=obj_name, local_use=obj, filename=None,
use_thread=False) use_thread=False)
obj = self.cal_object obj = self.cal_object
obj_name = obj_name obj_name = obj_name

View File

@ -245,9 +245,7 @@ class ToolCopperThieving(AppTool):
break break
if aperture_found: if aperture_found:
geo_elem = {} geo_elem = {'solid': self.robber_geo, 'follow': self.robber_line}
geo_elem['solid'] = self.robber_geo
geo_elem['follow'] = self.robber_line
self.grb_object.apertures[aperture_found]['geometry'].append(deepcopy(geo_elem)) self.grb_object.apertures[aperture_found]['geometry'].append(deepcopy(geo_elem))
else: else:
ap_keys = list(self.grb_object.apertures.keys()) ap_keys = list(self.grb_object.apertures.keys())
@ -261,9 +259,7 @@ class ToolCopperThieving(AppTool):
self.grb_object.apertures[new_apid]['size'] = self.rb_thickness self.grb_object.apertures[new_apid]['size'] = self.rb_thickness
self.grb_object.apertures[new_apid]['geometry'] = [] self.grb_object.apertures[new_apid]['geometry'] = []
geo_elem = {} geo_elem = {'solid': self.robber_geo, 'follow': self.robber_line}
geo_elem['solid'] = self.robber_geo
geo_elem['follow'] = self.robber_line
self.grb_object.apertures[new_apid]['geometry'].append(deepcopy(geo_elem)) self.grb_object.apertures[new_apid]['geometry'].append(deepcopy(geo_elem))
geo_obj = self.grb_object.solid_geometry geo_obj = self.grb_object.solid_geometry
@ -857,18 +853,14 @@ class ToolCopperThieving(AppTool):
geo_list.append(poly) geo_list.append(poly)
# append into the '0' aperture # append into the '0' aperture
geo_elem = {} geo_elem = {'solid': poly, 'follow': poly.exterior}
geo_elem['solid'] = poly
geo_elem['follow'] = poly.exterior
app_obj.grb_object.apertures['0']['geometry'].append(deepcopy(geo_elem)) app_obj.grb_object.apertures['0']['geometry'].append(deepcopy(geo_elem))
except TypeError: except TypeError:
# append to the new solid geometry # append to the new solid geometry
geo_list.append(app_obj.new_solid_geometry) geo_list.append(app_obj.new_solid_geometry)
# append into the '0' aperture # append into the '0' aperture
geo_elem = {} geo_elem = {'solid': app_obj.new_solid_geometry, 'follow': app_obj.new_solid_geometry.exterior}
geo_elem['solid'] = app_obj.new_solid_geometry
geo_elem['follow'] = app_obj.new_solid_geometry.exterior
app_obj.grb_object.apertures['0']['geometry'].append(deepcopy(geo_elem)) app_obj.grb_object.apertures['0']['geometry'].append(deepcopy(geo_elem))
app_obj.grb_object.solid_geometry = MultiPolygon(geo_list).buffer(0.0000001).buffer(-0.0000001) app_obj.grb_object.solid_geometry = MultiPolygon(geo_list).buffer(0.0000001).buffer(-0.0000001)
@ -993,9 +985,7 @@ class ToolCopperThieving(AppTool):
break break
if aperture_found: if aperture_found:
geo_elem = {} geo_elem = {'solid': robber_solid_geo, 'follow': robber_line}
geo_elem['solid'] = robber_solid_geo
geo_elem['follow'] = robber_line
grb_obj.apertures[aperture_found]['geometry'].append(deepcopy(geo_elem)) grb_obj.apertures[aperture_found]['geometry'].append(deepcopy(geo_elem))
else: else:
ap_keys = list(grb_obj.apertures.keys()) ap_keys = list(grb_obj.apertures.keys())

View File

@ -264,9 +264,7 @@ class ToolCorners(AppTool):
geo_buff = geo.buffer(line_thickness / 2.0, resolution=self.grb_steps_per_circle, join_style=2) geo_buff = geo.buffer(line_thickness / 2.0, resolution=self.grb_steps_per_circle, join_style=2)
geo_buff_list.append(geo_buff) geo_buff_list.append(geo_buff)
dict_el = {} dict_el = {'follow': geo, 'solid': geo_buff}
dict_el['follow'] = geo
dict_el['solid'] = geo_buff
new_apertures[aperture_found]['geometry'].append(deepcopy(dict_el)) new_apertures[aperture_found]['geometry'].append(deepcopy(dict_el))
else: else:
ap_keys = list(new_apertures.keys()) ap_keys = list(new_apertures.keys())
@ -674,4 +672,4 @@ class CornersUI:
self.app.inform[str, bool].emit('[WARNING_NOTCL] %s: [%d, %d]' % self.app.inform[str, bool].emit('[WARNING_NOTCL] %s: [%d, %d]' %
(_("Edited value is out of range"), minval, maxval), False) (_("Edited value is out of range"), minval, maxval), False)
else: else:
self.app.inform[str, bool].emit('[success] %s' % _("Edited value is within limits."), False) self.app.inform[str, bool].emit('[success] %s' % _("Edited value is within limits."), False)

View File

@ -389,7 +389,7 @@ class CutOut(AppTool):
def on_tool_default_add(self, dia=None, muted=None): def on_tool_default_add(self, dia=None, muted=None):
dia = dia dia = dia if dia else str(self.app.defaults["tools_cutout_tooldia"])
self.default_data.update({ self.default_data.update({
"plot": True, "plot": True,
@ -442,7 +442,7 @@ class CutOut(AppTool):
}) })
self.cut_tool_dict.update({ self.cut_tool_dict.update({
'tooldia': str(self.app.defaults["tools_cutout_tooldia"]), 'tooldia': dia,
'offset': 'Path', 'offset': 'Path',
'offset_value': 0.0, 'offset_value': 0.0,
'type': _('Rough'), 'type': _('Rough'),
@ -874,16 +874,18 @@ class CutOut(AppTool):
if not holes: if not holes:
return 'fail' return 'fail'
tools = {} tools = {
tools[1] = {} 1: {
tools[1]["tooldia"] = mb_dia "tooldia": mb_dia,
tools[1]['drills'] = holes "drills": holes,
tools[1]['solid_geometry'] = [] "solid_geometry": []
}
}
exc_obj.tools = tools exc_obj.tools = tools
exc_obj.create_geometry() exc_obj.create_geometry()
exc_obj.source_file = app_o.f_handlers.export_excellon(obj_name=exc_obj.options['name'], exc_obj.source_file = app_o.f_handlers.export_excellon(obj_name=exc_obj.options['name'],
local_use=exc_obj,filename=None, local_use=exc_obj, filename=None,
use_thread=False) use_thread=False)
# calculate the bounds # calculate the bounds
xmin, ymin, xmax, ymax = CutOut.recursive_bounds(exc_obj.solid_geometry) xmin, ymin, xmax, ymax = CutOut.recursive_bounds(exc_obj.solid_geometry)
@ -1244,11 +1246,13 @@ class CutOut(AppTool):
if not holes: if not holes:
return 'fail' return 'fail'
tools = {} tools = {
tools[1] = {} 1: {
tools[1]["tooldia"] = mb_dia "tooldia": mb_dia,
tools[1]['drills'] = holes "drills": holes,
tools[1]['solid_geometry'] = [] "solid_geometry": []
}
}
exc_obj.tools = tools exc_obj.tools = tools
exc_obj.create_geometry() exc_obj.create_geometry()
@ -1602,11 +1606,13 @@ class CutOut(AppTool):
if not holes: if not holes:
return 'fail' return 'fail'
tools = {} tools = {
tools[1] = {} 1: {
tools[1]["tooldia"] = mb_dia "tooldia": mb_dia,
tools[1]['drills'] = holes "drills": holes,
tools[1]['solid_geometry'] = [] "solid_geometry": []
}
}
exc_obj.tools = tools exc_obj.tools = tools
exc_obj.create_geometry() exc_obj.create_geometry()

View File

@ -190,9 +190,9 @@ class ToolEtchCompensation(AppTool):
# update the apertures attributes (keys in the apertures dict) # update the apertures attributes (keys in the apertures dict)
for ap in new_apertures: for ap in new_apertures:
type = new_apertures[ap]['type'] ap_type = new_apertures[ap]['type']
for k in new_apertures[ap]: for k in new_apertures[ap]:
if type == 'R' or type == 'O': if ap_type == 'R' or ap_type == 'O':
if k == 'width' or k == 'height': if k == 'width' or k == 'height':
new_apertures[ap][k] += offset new_apertures[ap][k] += offset
else: else:
@ -207,9 +207,9 @@ class ToolEtchCompensation(AppTool):
# in case of 'R' or 'O' aperture type we need to update the aperture 'size' after # in case of 'R' or 'O' aperture type we need to update the aperture 'size' after
# the 'width' and 'height' keys were updated # the 'width' and 'height' keys were updated
for ap in new_apertures: for ap in new_apertures:
type = new_apertures[ap]['type'] ap_type = new_apertures[ap]['type']
for k in new_apertures[ap]: for k in new_apertures[ap]:
if type == 'R' or type == 'O': if ap_type == 'R' or ap_type == 'O':
if k == 'size': if k == 'size':
new_apertures[ap][k] = math.sqrt( new_apertures[ap][k] = math.sqrt(
new_apertures[ap]['width'] ** 2 + new_apertures[ap]['height'] ** 2) new_apertures[ap]['width'] ** 2 + new_apertures[ap]['height'] ** 2)
@ -233,8 +233,8 @@ class ToolEtchCompensation(AppTool):
new_obj.apertures = deepcopy(new_apertures) new_obj.apertures = deepcopy(new_apertures)
new_obj.solid_geometry = deepcopy(new_solid_geometry) new_obj.solid_geometry = deepcopy(new_solid_geometry)
new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None, local_use=new_obj, new_obj.source_file = app_obj.f_handlers.export_gerber(obj_name=outname, filename=None, local_use=new_obj,
use_thread=False) use_thread=False)
self.app.app_obj.new_object('gerber', outname, init_func) self.app.app_obj.new_object('gerber', outname, init_func)

View File

@ -270,9 +270,7 @@ class ToolFiducials(AppTool):
if aperture_found: if aperture_found:
for geo in geo_list: for geo in geo_list:
dict_el = {} dict_el = {'follow': geo.centroid, 'solid': geo}
dict_el['follow'] = geo.centroid
dict_el['solid'] = geo
g_obj.apertures[aperture_found]['geometry'].append(deepcopy(dict_el)) g_obj.apertures[aperture_found]['geometry'].append(deepcopy(dict_el))
else: else:
ap_keys = list(g_obj.apertures.keys()) ap_keys = list(g_obj.apertures.keys())
@ -287,9 +285,7 @@ class ToolFiducials(AppTool):
g_obj.apertures[new_apid]['geometry'] = [] g_obj.apertures[new_apid]['geometry'] = []
for geo in geo_list: for geo in geo_list:
dict_el = {} dict_el = {'follow': geo.centroid, 'solid': geo}
dict_el['follow'] = geo.centroid
dict_el['solid'] = geo
g_obj.apertures[new_apid]['geometry'].append(deepcopy(dict_el)) g_obj.apertures[new_apid]['geometry'].append(deepcopy(dict_el))
s_list = [] s_list = []
@ -330,9 +326,7 @@ class ToolFiducials(AppTool):
geo_buff_list.append(geo_buff_h) geo_buff_list.append(geo_buff_h)
geo_buff_list.append(geo_buff_v) geo_buff_list.append(geo_buff_v)
dict_el = {} dict_el = {'follow': geo_buff_h.centroid, 'solid': geo_buff_h}
dict_el['follow'] = geo_buff_h.centroid
dict_el['solid'] = geo_buff_h
g_obj.apertures[aperture_found]['geometry'].append(deepcopy(dict_el)) g_obj.apertures[aperture_found]['geometry'].append(deepcopy(dict_el))
dict_el['follow'] = geo_buff_v.centroid dict_el['follow'] = geo_buff_v.centroid
dict_el['solid'] = geo_buff_v dict_el['solid'] = geo_buff_v
@ -344,10 +338,11 @@ class ToolFiducials(AppTool):
else: else:
new_apid = '10' new_apid = '10'
g_obj.apertures[new_apid] = {} g_obj.apertures[new_apid] = {
g_obj.apertures[new_apid]['type'] = 'C' 'type': 'C',
g_obj.apertures[new_apid]['size'] = line_thickness 'size': line_thickness,
g_obj.apertures[new_apid]['geometry'] = [] 'geometry': []
}
for geo in geo_list: for geo in geo_list:
geo_buff_h = geo[0].buffer(line_thickness / 2.0, self.grb_steps_per_circle) geo_buff_h = geo[0].buffer(line_thickness / 2.0, self.grb_steps_per_circle)
@ -355,9 +350,7 @@ class ToolFiducials(AppTool):
geo_buff_list.append(geo_buff_h) geo_buff_list.append(geo_buff_h)
geo_buff_list.append(geo_buff_v) geo_buff_list.append(geo_buff_v)
dict_el = {} dict_el = {'follow': geo_buff_h.centroid, 'solid': geo_buff_h}
dict_el['follow'] = geo_buff_h.centroid
dict_el['solid'] = geo_buff_h
g_obj.apertures[new_apid]['geometry'].append(deepcopy(dict_el)) g_obj.apertures[new_apid]['geometry'].append(deepcopy(dict_el))
dict_el['follow'] = geo_buff_v.centroid dict_el['follow'] = geo_buff_v.centroid
dict_el['solid'] = geo_buff_v dict_el['solid'] = geo_buff_v
@ -412,9 +405,7 @@ class ToolFiducials(AppTool):
for geo in geo_list: for geo in geo_list:
geo_buff_list.append(geo) geo_buff_list.append(geo)
dict_el = {} dict_el = {'follow': geo.centroid, 'solid': geo}
dict_el['follow'] = geo.centroid
dict_el['solid'] = geo
g_obj.apertures[aperture_found]['geometry'].append(deepcopy(dict_el)) g_obj.apertures[aperture_found]['geometry'].append(deepcopy(dict_el))
else: else:
ap_keys = list(g_obj.apertures.keys()) ap_keys = list(g_obj.apertures.keys())
@ -423,19 +414,18 @@ class ToolFiducials(AppTool):
else: else:
new_apid = '10' new_apid = '10'
g_obj.apertures[new_apid] = {} g_obj.apertures[new_apid] = {
g_obj.apertures[new_apid]['type'] = 'R' 'type': 'R',
g_obj.apertures[new_apid]['size'] = new_ap_size 'size': new_ap_size,
g_obj.apertures[new_apid]['width'] = fid_size 'width': fid_size,
g_obj.apertures[new_apid]['height'] = fid_size 'height': fid_size,
g_obj.apertures[new_apid]['geometry'] = [] 'geometry': []
}
for geo in geo_list: for geo in geo_list:
geo_buff_list.append(geo) geo_buff_list.append(geo)
dict_el = {} dict_el = {'follow': geo.centroid, 'solid': geo}
dict_el['follow'] = geo.centroid
dict_el['solid'] = geo
g_obj.apertures[new_apid]['geometry'].append(deepcopy(dict_el)) g_obj.apertures[new_apid]['geometry'].append(deepcopy(dict_el))
s_list = [] s_list = []

View File

@ -613,7 +613,8 @@ class Film(AppTool):
drawing = svg2rlg(doc_final) drawing = svg2rlg(doc_final)
p_size = self.ui.pagesize_combo.get_value() p_size = self.ui.pagesize_combo.get_value()
if p_size == 'Bounds': renderPDF.drawToFile(drawing, filename) if p_size == 'Bounds':
renderPDF.drawToFile(drawing, filename)
else: else:
if self.ui.orientation_radio.get_value() == 'p': if self.ui.orientation_radio.get_value() == 'p':
page_size = portrait(self.ui.pagesize[p_size]) page_size = portrait(self.ui.pagesize[p_size])

View File

@ -79,11 +79,10 @@ class ToolImage(AppTool):
def on_file_importimage(self): def on_file_importimage(self):
""" """
Callback for menu item File->Import IMAGE. Callback for menu item File->Import IMAGE.
:param type_of_obj: to import the IMAGE as Geometry or as Gerber
:type type_of_obj: str
:return: None :return: None
""" """
mask = []
self.app.log.debug("on_file_importimage()") self.app.log.debug("on_file_importimage()")
_filter = "Image Files(*.BMP *.PNG *.JPG *.JPEG);;" \ _filter = "Image Files(*.BMP *.PNG *.JPG *.JPEG);;" \
@ -147,7 +146,7 @@ class ToolImage(AppTool):
geo_obj.import_image(filename, units=units, dpi=dpi, mode=mode, mask=mask) geo_obj.import_image(filename, units=units, dpi=dpi, mode=mode, mask=mask)
geo_obj.multigeo = False geo_obj.multigeo = False
with self.app.proc_container.new(_("Importing Image")) as proc: with self.app.proc_container.new(_("Importing Image")):
# Object name # Object name
name = outname or filename.split('/')[-1].split('\\')[-1] name = outname or filename.split('/')[-1].split('\\')[-1]

View File

@ -131,21 +131,18 @@ class ToolInvertGerber(AppTool):
new_apertures = {} new_apertures = {}
if '0' not in new_apertures: if '0' not in new_apertures:
new_apertures['0'] = {} new_apertures['0'] = {
new_apertures['0']['type'] = 'C' 'type': 'C',
new_apertures['0']['size'] = 0.0 'size': 0.0,
new_apertures['0']['geometry'] = [] 'geometry': []
}
try: try:
for poly in new_solid_geometry: for poly in new_solid_geometry:
new_el = {} new_el = {'solid': poly, 'follow': poly.exterior}
new_el['solid'] = poly
new_el['follow'] = poly.exterior
new_apertures['0']['geometry'].append(new_el) new_apertures['0']['geometry'].append(new_el)
except TypeError: except TypeError:
new_el = {} new_el = {'solid': new_solid_geometry, 'follow': new_solid_geometry.exterior}
new_el['solid'] = new_solid_geometry
new_el['follow'] = new_solid_geometry.exterior
new_apertures['0']['geometry'].append(new_el) new_apertures['0']['geometry'].append(new_el)
def init_func(new_obj, app_obj): def init_func(new_obj, app_obj):
@ -157,8 +154,8 @@ class ToolInvertGerber(AppTool):
new_obj.apertures = deepcopy(new_apertures) new_obj.apertures = deepcopy(new_apertures)
new_obj.solid_geometry = deepcopy(new_solid_geometry) new_obj.solid_geometry = deepcopy(new_solid_geometry)
new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None, new_obj.source_file = app_obj.f_handlers.export_gerber(obj_name=outname, filename=None,
local_use=new_obj, use_thread=False) local_use=new_obj, use_thread=False)
self.app.app_obj.new_object('gerber', outname, init_func) self.app.app_obj.new_object('gerber', outname, init_func)
@ -315,4 +312,4 @@ class InvertUI:
self.app.inform[str, bool].emit('[WARNING_NOTCL] %s: [%d, %d]' % self.app.inform[str, bool].emit('[WARNING_NOTCL] %s: [%d, %d]' %
(_("Edited value is out of range"), minval, maxval), False) (_("Edited value is out of range"), minval, maxval), False)
else: else:
self.app.inform[str, bool].emit('[success] %s' % _("Edited value is within limits."), False) self.app.inform[str, bool].emit('[success] %s' % _("Edited value is within limits."), False)

View File

@ -793,8 +793,8 @@ class ToolIsolation(AppTool, Gerber):
parent=self.app.ui) parent=self.app.ui)
tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png')) tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png'))
def find_optimal(val): def find_optimal(valor):
tool_add_popup.set_value(float(val)) tool_add_popup.set_value(float(valor))
self.optimal_found_sig.connect(find_optimal) self.optimal_found_sig.connect(find_optimal)
@ -1620,8 +1620,7 @@ class ToolIsolation(AppTool, Gerber):
self.app.proc_container.update_view_text(' %s' % _("Subtracting Geo")) self.app.proc_container.update_view_text(' %s' % _("Subtracting Geo"))
geo_obj.solid_geometry = self.area_subtraction(geo_obj.solid_geometry) geo_obj.solid_geometry = self.area_subtraction(geo_obj.solid_geometry)
geo_obj.tools = {} geo_obj.tools = {'1': {}}
geo_obj.tools['1'] = {}
geo_obj.tools.update({ geo_obj.tools.update({
'1': { '1': {
'tooldia': float(tool_dia), 'tooldia': float(tool_dia),

View File

@ -635,7 +635,7 @@ class ToolMilling(AppTool, Excellon):
# Get source object. # Get source object.
try: try:
self.excellon_obj = self.app.collection.get_by_name(self.obj_name) self.excellon_obj = self.app.collection.get_by_name(self.obj_name)
except Exception as e: except Exception:
self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), str(self.obj_name))) self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), str(self.obj_name)))
return return

View File

@ -160,7 +160,7 @@ class ToolMove(AppTool):
if obj.options['plot'] and obj.visible is True] if obj.options['plot'] and obj.visible is True]
def job_move(app_obj): def job_move(app_obj):
with self.app.proc_container.new(_("Moving...")) as proc: with self.app.proc_container.new(_("Moving...")):
if not obj_list: if not obj_list:
app_obj.app.inform.emit('[WARNING_NOTCL] %s' % _("No object(s) selected.")) app_obj.app.inform.emit('[WARNING_NOTCL] %s' % _("No object(s) selected."))

View File

@ -109,9 +109,10 @@ class ToolPDF(AppTool):
short_name = filename.split('/')[-1].split('\\')[-1] short_name = filename.split('/')[-1].split('\\')[-1]
self.parsing_promises.append(short_name) self.parsing_promises.append(short_name)
self.pdf_parsed[short_name] = {} self.pdf_parsed[short_name] = {
self.pdf_parsed[short_name]['pdf'] = {} 'pdf': {},
self.pdf_parsed[short_name]['filename'] = filename 'filename': filename
}
self.pdf_decompressed[short_name] = '' self.pdf_decompressed[short_name] = ''
@ -181,22 +182,26 @@ class ToolPDF(AppTool):
name_tool = 0 name_tool = 0
for dia in sorted_dia: for dia in sorted_dia:
name_tool += 1 name_tool += 1
tool = str(name_tool)
# create tools dictionary exc_obj.tools[tool] = {
spec = {"C": dia, 'solid_geometry': []} 'tooldia': dia,
exc_obj.tools[str(name_tool)] = spec 'drills': [],
'solid_geometry': []
}
# create drill list of dictionaries # update the drill list
for dia_points in points: for dia_points in points:
if dia == dia_points: if dia == dia_points:
for pt in points[dia_points]: for pt in points[dia_points]:
exc_obj.drills.append({'point': Point(pt), 'tool': str(name_tool)}) exc_obj.tools[tool]['drills'].append(Point(pt))
break break
ret = exc_obj.create_geometry() ret = exc_obj.create_geometry()
if ret == 'fail': if ret == 'fail':
log.debug("Could not create geometry for Excellon object.") log.debug("Could not create geometry for Excellon object.")
return "fail" return "fail"
for tool in exc_obj.tools: for tool in exc_obj.tools:
if exc_obj.tools[tool]['solid_geometry']: if exc_obj.tools[tool]['solid_geometry']:
return return

View File

@ -472,14 +472,14 @@ class ToolPunchGerber(AppTool):
# since there may be drills that do not drill into a pad we test only for # since there may be drills that do not drill into a pad we test only for
# drills in a pad # drills in a pad
if drill_pt.within(elem['solid']): if drill_pt.within(elem['solid']):
geo_elem = {} geo_elem = {'clear': drill_pt}
geo_elem['clear'] = drill_pt
if clear_apid_size not in holes_apertures: if clear_apid_size not in holes_apertures:
holes_apertures[clear_apid_size] = {} holes_apertures[clear_apid_size] = {
holes_apertures[clear_apid_size]['type'] = 'C' 'type': 'C',
holes_apertures[clear_apid_size]['size'] = clear_apid_size 'size': clear_apid_size,
holes_apertures[clear_apid_size]['geometry'] = [] 'geometry': []
}
holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem))
@ -498,8 +498,8 @@ class ToolPunchGerber(AppTool):
new_obj.apertures = deepcopy(new_apertures) new_obj.apertures = deepcopy(new_apertures)
new_obj.solid_geometry = deepcopy(punched_solid_geometry) new_obj.solid_geometry = deepcopy(punched_solid_geometry)
new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None, new_obj.source_file = app_obj.f_handlers.export_gerber(obj_name=outname, filename=None,
local_use=new_obj, use_thread=False) local_use=new_obj, use_thread=False)
self.app.app_obj.new_object('gerber', outname, init_func) self.app.app_obj.new_object('gerber', outname, init_func)
@ -605,14 +605,14 @@ class ToolPunchGerber(AppTool):
# since there may be drills that do not drill into a pad we test only for drills in a pad # since there may be drills that do not drill into a pad we test only for drills in a pad
if geo.within(elem['solid']): if geo.within(elem['solid']):
geo_elem = {} geo_elem = {'clear': geo.centroid}
geo_elem['clear'] = geo.centroid
if clear_apid_size not in holes_apertures: if clear_apid_size not in holes_apertures:
holes_apertures[clear_apid_size] = {} holes_apertures[clear_apid_size] = {
holes_apertures[clear_apid_size]['type'] = 'C' 'type': 'C',
holes_apertures[clear_apid_size]['size'] = clear_apid_size 'size': clear_apid_size,
holes_apertures[clear_apid_size]['geometry'] = [] 'geometry': []
}
holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem))
@ -631,8 +631,8 @@ class ToolPunchGerber(AppTool):
new_obj.apertures = deepcopy(new_apertures) new_obj.apertures = deepcopy(new_apertures)
new_obj.solid_geometry = deepcopy(punched_solid_geometry) new_obj.solid_geometry = deepcopy(punched_solid_geometry)
new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None, new_obj.source_file = app_obj.f_handlers.export_gerber(obj_name=outname, filename=None,
local_use=new_obj, use_thread=False) local_use=new_obj, use_thread=False)
self.app.app_obj.new_object('gerber', outname, init_func) self.app.app_obj.new_object('gerber', outname, init_func)
@ -754,14 +754,14 @@ class ToolPunchGerber(AppTool):
# since there may be drills that do not drill into a pad we test only for geos in a pad # since there may be drills that do not drill into a pad we test only for geos in a pad
if geo.within(elem['solid']): if geo.within(elem['solid']):
geo_elem = {} geo_elem = {'clear': geo.centroid}
geo_elem['clear'] = geo.centroid
if clear_apid_size not in holes_apertures: if clear_apid_size not in holes_apertures:
holes_apertures[clear_apid_size] = {} holes_apertures[clear_apid_size] = {
holes_apertures[clear_apid_size]['type'] = 'C' 'type': 'C',
holes_apertures[clear_apid_size]['size'] = clear_apid_size 'size': clear_apid_size,
holes_apertures[clear_apid_size]['geometry'] = [] 'geometry': []
}
holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem))
@ -780,8 +780,8 @@ class ToolPunchGerber(AppTool):
new_obj.apertures = deepcopy(new_apertures) new_obj.apertures = deepcopy(new_apertures)
new_obj.solid_geometry = deepcopy(punched_solid_geometry) new_obj.solid_geometry = deepcopy(punched_solid_geometry)
new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None, new_obj.source_file = app_obj.f_handlers.export_gerber(obj_name=outname, filename=None,
local_use=new_obj, use_thread=False) local_use=new_obj, use_thread=False)
self.app.app_obj.new_object('gerber', outname, init_func) self.app.app_obj.new_object('gerber', outname, init_func)
@ -898,14 +898,14 @@ class ToolPunchGerber(AppTool):
# since there may be drills that do not drill into a pad we test only for geos in a pad # since there may be drills that do not drill into a pad we test only for geos in a pad
if geo.within(elem['solid']): if geo.within(elem['solid']):
geo_elem = {} geo_elem = {'clear': geo.centroid}
geo_elem['clear'] = geo.centroid
if clear_apid_size not in holes_apertures: if clear_apid_size not in holes_apertures:
holes_apertures[clear_apid_size] = {} holes_apertures[clear_apid_size] = {
holes_apertures[clear_apid_size]['type'] = 'C' 'type': 'C',
holes_apertures[clear_apid_size]['size'] = clear_apid_size 'size': clear_apid_size,
holes_apertures[clear_apid_size]['geometry'] = [] 'geometry': []
}
holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem))
@ -924,8 +924,8 @@ class ToolPunchGerber(AppTool):
new_obj.apertures = deepcopy(new_apertures) new_obj.apertures = deepcopy(new_apertures)
new_obj.solid_geometry = deepcopy(punched_solid_geometry) new_obj.solid_geometry = deepcopy(punched_solid_geometry)
new_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None, new_obj.source_file = app_obj.f_handlers.export_gerber(obj_name=outname, filename=None,
local_use=new_obj, use_thread=False) local_use=new_obj, use_thread=False)
self.app.app_obj.new_object('gerber', outname, init_func) self.app.app_obj.new_object('gerber', outname, init_func)

View File

@ -270,9 +270,11 @@ class QRCode(AppTool):
# don't know if the condition is required since I already made sure above that the new_apid is a new one # don't know if the condition is required since I already made sure above that the new_apid is a new one
if new_apid not in self.grb_object.apertures: if new_apid not in self.grb_object.apertures:
self.grb_object.apertures[new_apid] = {} self.grb_object.apertures[new_apid] = {
self.grb_object.apertures[new_apid]['geometry'] = [] 'type': 'R',
self.grb_object.apertures[new_apid]['type'] = 'R' 'geometry': []
}
# TODO: HACK # TODO: HACK
# I've artificially added 1% to the height and width because otherwise after loading the # I've artificially added 1% to the height and width because otherwise after loading the
# exported file, it will not be correctly reconstructed (it will be made from multiple shapes instead of # exported file, it will not be correctly reconstructed (it will be made from multiple shapes instead of
@ -282,15 +284,15 @@ class QRCode(AppTool):
self.grb_object.apertures[new_apid]['size'] = deepcopy(math.sqrt(box_size ** 2 + box_size ** 2)) self.grb_object.apertures[new_apid]['size'] = deepcopy(math.sqrt(box_size ** 2 + box_size ** 2))
if '0' not in self.grb_object.apertures: if '0' not in self.grb_object.apertures:
self.grb_object.apertures['0'] = {} self.grb_object.apertures['0'] = {
self.grb_object.apertures['0']['geometry'] = [] 'type': 'REG',
self.grb_object.apertures['0']['type'] = 'REG' 'size': 0.0,
self.grb_object.apertures['0']['size'] = 0.0 'geometry': []
}
# in case that the QRCode geometry is dropped onto a copper region (found in the '0' aperture) # in case that the QRCode geometry is dropped onto a copper region (found in the '0' aperture)
# make sure that I place a cutout there # make sure that I place a cutout there
zero_elem = {} zero_elem = {'clear': offset_mask_geo}
zero_elem['clear'] = offset_mask_geo
self.grb_object.apertures['0']['geometry'].append(deepcopy(zero_elem)) self.grb_object.apertures['0']['geometry'].append(deepcopy(zero_elem))
try: try:
@ -304,13 +306,13 @@ class QRCode(AppTool):
try: try:
for geo in self.qrcode_geometry: for geo in self.qrcode_geometry:
geo_elem = {} geo_elem = {
geo_elem['solid'] = translate(geo, xoff=pos[0], yoff=pos[1]) 'solid': translate(geo, xoff=pos[0], yoff=pos[1]),
geo_elem['follow'] = translate(geo.centroid, xoff=pos[0], yoff=pos[1]) 'follow': translate(geo.centroid, xoff=pos[0], yoff=pos[1])
}
self.grb_object.apertures[new_apid]['geometry'].append(deepcopy(geo_elem)) self.grb_object.apertures[new_apid]['geometry'].append(deepcopy(geo_elem))
except TypeError: except TypeError:
geo_elem = {} geo_elem = {'solid': self.qrcode_geometry}
geo_elem['solid'] = self.qrcode_geometry
self.grb_object.apertures[new_apid]['geometry'].append(deepcopy(geo_elem)) self.grb_object.apertures[new_apid]['geometry'].append(deepcopy(geo_elem))
# update the source file with the new geometry: # update the source file with the new geometry:

View File

@ -631,16 +631,18 @@ class RulesCheck(AppTool):
copper_list = [] copper_list = []
copper_name_1 = self.ui.copper_t_object.currentText() copper_name_1 = self.ui.copper_t_object.currentText()
if copper_name_1 != '' and self.ui.copper_t_cb.get_value(): if copper_name_1 != '' and self.ui.copper_t_cb.get_value():
elem_dict = {} elem_dict = {
elem_dict['name'] = deepcopy(copper_name_1) 'name': deepcopy(copper_name_1),
elem_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_name_1).apertures) 'apertures': deepcopy(app_obj.collection.get_by_name(copper_name_1).apertures)
}
copper_list.append(elem_dict) copper_list.append(elem_dict)
copper_name_2 = self.ui.copper_b_object.currentText() copper_name_2 = self.ui.copper_b_object.currentText()
if copper_name_2 != '' and self.ui.copper_b_cb.get_value(): if copper_name_2 != '' and self.ui.copper_b_cb.get_value():
elem_dict = {} elem_dict = {
elem_dict['name'] = deepcopy(copper_name_2) 'name': deepcopy(copper_name_2),
elem_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_name_2).apertures) 'apertures': deepcopy(app_obj.collection.get_by_name(copper_name_2).apertures)
}
copper_list.append(elem_dict) copper_list.append(elem_dict)
trace_size = float(self.ui.trace_size_entry.get_value()) trace_size = float(self.ui.trace_size_entry.get_value())
@ -664,7 +666,7 @@ class RulesCheck(AppTool):
if copper_t_obj != '': if copper_t_obj != '':
copper_t_dict['name'] = deepcopy(copper_t_obj) copper_t_dict['name'] = deepcopy(copper_t_obj)
copper_t_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_t_obj).apertures) copper_t_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(copper_t_obj).apertures)
self.results.append(self.pool.apply_async(self.check_inside_gerber_clearance, self.results.append(self.pool.apply_async(self.check_inside_gerber_clearance,
args=(copper_t_dict, args=(copper_t_dict,
@ -675,7 +677,7 @@ class RulesCheck(AppTool):
copper_b_dict = {} copper_b_dict = {}
if copper_b_obj != '': if copper_b_obj != '':
copper_b_dict['name'] = deepcopy(copper_b_obj) copper_b_dict['name'] = deepcopy(copper_b_obj)
copper_b_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_b_obj).apertures) copper_b_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(copper_b_obj).apertures)
self.results.append(self.pool.apply_async(self.check_inside_gerber_clearance, self.results.append(self.pool.apply_async(self.check_inside_gerber_clearance,
args=(copper_b_dict, args=(copper_b_dict,
@ -683,7 +685,7 @@ class RulesCheck(AppTool):
_("BOTTOM -> Copper to Copper clearance")))) _("BOTTOM -> Copper to Copper clearance"))))
if self.ui.copper_t_cb.get_value() is False and self.ui.copper_b_cb.get_value() is False: if self.ui.copper_t_cb.get_value() is False and self.ui.copper_b_cb.get_value() is False:
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Copper to Copper clearance"), _("Copper to Copper clearance"),
_("At least one Gerber object has to be selected for this rule but none is selected."))) _("At least one Gerber object has to be selected for this rule but none is selected.")))
return return
@ -697,29 +699,29 @@ class RulesCheck(AppTool):
copper_top = self.ui.copper_t_object.currentText() copper_top = self.ui.copper_t_object.currentText()
if copper_top != '' and self.ui.copper_t_cb.get_value(): if copper_top != '' and self.ui.copper_t_cb.get_value():
top_dict['name'] = deepcopy(copper_top) top_dict['name'] = deepcopy(copper_top)
top_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_top).apertures) top_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(copper_top).apertures)
copper_bottom = self.ui.copper_b_object.currentText() copper_bottom = self.ui.copper_b_object.currentText()
if copper_bottom != '' and self.ui.copper_b_cb.get_value(): if copper_bottom != '' and self.ui.copper_b_cb.get_value():
bottom_dict['name'] = deepcopy(copper_bottom) bottom_dict['name'] = deepcopy(copper_bottom)
bottom_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_bottom).apertures) bottom_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(copper_bottom).apertures)
copper_outline = self.ui.outline_object.currentText() copper_outline = self.ui.outline_object.currentText()
if copper_outline != '' and self.ui.out_cb.get_value(): if copper_outline != '' and self.ui.out_cb.get_value():
outline_dict['name'] = deepcopy(copper_outline) outline_dict['name'] = deepcopy(copper_outline)
outline_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_outline).apertures) outline_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(copper_outline).apertures)
try: try:
copper_outline_clearance = float(self.ui.clearance_copper2ol_entry.get_value()) copper_outline_clearance = float(self.ui.clearance_copper2ol_entry.get_value())
except Exception as e: except Exception as e:
log.debug("RulesCheck.execute.worker_job() --> %s" % str(e)) log.debug("RulesCheck.execute.worker_job() --> %s" % str(e))
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Copper to Outline clearance"), _("Copper to Outline clearance"),
_("Value is not valid."))) _("Value is not valid.")))
return return
if not top_dict and not bottom_dict or not outline_dict: if not top_dict and not bottom_dict or not outline_dict:
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Copper to Outline clearance"), _("Copper to Outline clearance"),
_("One of the copper Gerber objects or the Outline Gerber object is not valid."))) _("One of the copper Gerber objects or the Outline Gerber object is not valid.")))
return return
@ -732,7 +734,7 @@ class RulesCheck(AppTool):
if outline_dict: if outline_dict:
objs.append(outline_dict) objs.append(outline_dict)
else: else:
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Copper to Outline clearance"), _("Copper to Outline clearance"),
_("Outline Gerber object presence is mandatory for this rule but it is not selected."))) _("Outline Gerber object presence is mandatory for this rule but it is not selected.")))
return return
@ -750,7 +752,7 @@ class RulesCheck(AppTool):
silk_silk_clearance = float(self.ui.clearance_silk2silk_entry.get_value()) silk_silk_clearance = float(self.ui.clearance_silk2silk_entry.get_value())
except Exception as e: except Exception as e:
log.debug("RulesCheck.execute.worker_job() --> %s" % str(e)) log.debug("RulesCheck.execute.worker_job() --> %s" % str(e))
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Silk to Silk clearance"), _("Silk to Silk clearance"),
_("Value is not valid."))) _("Value is not valid.")))
return return
@ -759,7 +761,7 @@ class RulesCheck(AppTool):
silk_obj = self.ui.ss_t_object.currentText() silk_obj = self.ui.ss_t_object.currentText()
if silk_obj != '': if silk_obj != '':
silk_dict['name'] = deepcopy(silk_obj) silk_dict['name'] = deepcopy(silk_obj)
silk_dict['apertures'] = deepcopy(self.app.collection.get_by_name(silk_obj).apertures) silk_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(silk_obj).apertures)
self.results.append(self.pool.apply_async(self.check_inside_gerber_clearance, self.results.append(self.pool.apply_async(self.check_inside_gerber_clearance,
args=(silk_dict, args=(silk_dict,
@ -769,7 +771,7 @@ class RulesCheck(AppTool):
silk_obj = self.ui.ss_b_object.currentText() silk_obj = self.ui.ss_b_object.currentText()
if silk_obj != '': if silk_obj != '':
silk_dict['name'] = deepcopy(silk_obj) silk_dict['name'] = deepcopy(silk_obj)
silk_dict['apertures'] = deepcopy(self.app.collection.get_by_name(silk_obj).apertures) silk_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(silk_obj).apertures)
self.results.append(self.pool.apply_async(self.check_inside_gerber_clearance, self.results.append(self.pool.apply_async(self.check_inside_gerber_clearance,
args=(silk_dict, args=(silk_dict,
@ -777,7 +779,7 @@ class RulesCheck(AppTool):
_("BOTTOM -> Silk to Silk clearance")))) _("BOTTOM -> Silk to Silk clearance"))))
if self.ui.ss_t_cb.get_value() is False and self.ui.ss_b_cb.get_value() is False: if self.ui.ss_t_cb.get_value() is False and self.ui.ss_b_cb.get_value() is False:
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Silk to Silk clearance"), _("Silk to Silk clearance"),
_("At least one Gerber object has to be selected for this rule but none is selected."))) _("At least one Gerber object has to be selected for this rule but none is selected.")))
return return
@ -797,38 +799,38 @@ class RulesCheck(AppTool):
silk_top = self.ui.ss_t_object.currentText() silk_top = self.ui.ss_t_object.currentText()
if silk_top != '' and self.ui.ss_t_cb.get_value(): if silk_top != '' and self.ui.ss_t_cb.get_value():
silk_t_dict['name'] = deepcopy(silk_top) silk_t_dict['name'] = deepcopy(silk_top)
silk_t_dict['apertures'] = deepcopy(self.app.collection.get_by_name(silk_top).apertures) silk_t_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(silk_top).apertures)
top_ss = True top_ss = True
silk_bottom = self.ui.ss_b_object.currentText() silk_bottom = self.ui.ss_b_object.currentText()
if silk_bottom != '' and self.ui.ss_b_cb.get_value(): if silk_bottom != '' and self.ui.ss_b_cb.get_value():
silk_b_dict['name'] = deepcopy(silk_bottom) silk_b_dict['name'] = deepcopy(silk_bottom)
silk_b_dict['apertures'] = deepcopy(self.app.collection.get_by_name(silk_bottom).apertures) silk_b_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(silk_bottom).apertures)
bottom_ss = True bottom_ss = True
sm_top = self.ui.sm_t_object.currentText() sm_top = self.ui.sm_t_object.currentText()
if sm_top != '' and self.ui.sm_t_cb.get_value(): if sm_top != '' and self.ui.sm_t_cb.get_value():
sm_t_dict['name'] = deepcopy(sm_top) sm_t_dict['name'] = deepcopy(sm_top)
sm_t_dict['apertures'] = deepcopy(self.app.collection.get_by_name(sm_top).apertures) sm_t_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(sm_top).apertures)
top_sm = True top_sm = True
sm_bottom = self.ui.sm_b_object.currentText() sm_bottom = self.ui.sm_b_object.currentText()
if sm_bottom != '' and self.ui.sm_b_cb.get_value(): if sm_bottom != '' and self.ui.sm_b_cb.get_value():
sm_b_dict['name'] = deepcopy(sm_bottom) sm_b_dict['name'] = deepcopy(sm_bottom)
sm_b_dict['apertures'] = deepcopy(self.app.collection.get_by_name(sm_bottom).apertures) sm_b_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(sm_bottom).apertures)
bottom_sm = True bottom_sm = True
try: try:
silk_sm_clearance = float(self.ui.clearance_silk2sm_entry.get_value()) silk_sm_clearance = float(self.ui.clearance_silk2sm_entry.get_value())
except Exception as e: except Exception as e:
log.debug("RulesCheck.execute.worker_job() --> %s" % str(e)) log.debug("RulesCheck.execute.worker_job() --> %s" % str(e))
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Silk to Solder Mask Clearance"), _("Silk to Solder Mask Clearance"),
_("Value is not valid."))) _("Value is not valid.")))
return return
if (not silk_t_dict and not silk_b_dict) or (not sm_t_dict and not sm_b_dict): if (not silk_t_dict and not silk_b_dict) or (not sm_t_dict and not sm_b_dict):
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Silk to Solder Mask Clearance"), _("Silk to Solder Mask Clearance"),
_("One or more of the Gerber objects is not valid."))) _("One or more of the Gerber objects is not valid.")))
return return
@ -846,7 +848,7 @@ class RulesCheck(AppTool):
silk_sm_clearance, silk_sm_clearance,
_("BOTTOM -> Silk to Solder Mask Clearance")))) _("BOTTOM -> Silk to Solder Mask Clearance"))))
else: else:
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Silk to Solder Mask Clearance"), _("Silk to Solder Mask Clearance"),
_("Both Silk and Solder Mask Gerber objects has to be either both Top or both Bottom."))) _("Both Silk and Solder Mask Gerber objects has to be either both Top or both Bottom.")))
return return
@ -860,29 +862,29 @@ class RulesCheck(AppTool):
silk_top = self.ui.ss_t_object.currentText() silk_top = self.ui.ss_t_object.currentText()
if silk_top != '' and self.ui.ss_t_cb.get_value(): if silk_top != '' and self.ui.ss_t_cb.get_value():
top_dict['name'] = deepcopy(silk_top) top_dict['name'] = deepcopy(silk_top)
top_dict['apertures'] = deepcopy(self.app.collection.get_by_name(silk_top).apertures) top_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(silk_top).apertures)
silk_bottom = self.ui.ss_b_object.currentText() silk_bottom = self.ui.ss_b_object.currentText()
if silk_bottom != '' and self.ui.ss_b_cb.get_value(): if silk_bottom != '' and self.ui.ss_b_cb.get_value():
bottom_dict['name'] = deepcopy(silk_bottom) bottom_dict['name'] = deepcopy(silk_bottom)
bottom_dict['apertures'] = deepcopy(self.app.collection.get_by_name(silk_bottom).apertures) bottom_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(silk_bottom).apertures)
copper_outline = self.ui.outline_object.currentText() copper_outline = self.ui.outline_object.currentText()
if copper_outline != '' and self.ui.out_cb.get_value(): if copper_outline != '' and self.ui.out_cb.get_value():
outline_dict['name'] = deepcopy(copper_outline) outline_dict['name'] = deepcopy(copper_outline)
outline_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_outline).apertures) outline_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(copper_outline).apertures)
try: try:
copper_outline_clearance = float(self.ui.clearance_copper2ol_entry.get_value()) copper_outline_clearance = float(self.ui.clearance_copper2ol_entry.get_value())
except Exception as e: except Exception as e:
log.debug("RulesCheck.execute.worker_job() --> %s" % str(e)) log.debug("RulesCheck.execute.worker_job() --> %s" % str(e))
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Silk to Outline Clearance"), _("Silk to Outline Clearance"),
_("Value is not valid."))) _("Value is not valid.")))
return return
if not top_dict and not bottom_dict or not outline_dict: if not top_dict and not bottom_dict or not outline_dict:
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Silk to Outline Clearance"), _("Silk to Outline Clearance"),
_("One of the Silk Gerber objects or the Outline Gerber object is not valid."))) _("One of the Silk Gerber objects or the Outline Gerber object is not valid.")))
return return
@ -896,7 +898,7 @@ class RulesCheck(AppTool):
if outline_dict: if outline_dict:
objs.append(outline_dict) objs.append(outline_dict)
else: else:
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Silk to Outline Clearance"), _("Silk to Outline Clearance"),
_("Outline Gerber object presence is mandatory for this rule but it is not selected."))) _("Outline Gerber object presence is mandatory for this rule but it is not selected.")))
return return
@ -914,7 +916,7 @@ class RulesCheck(AppTool):
sm_sm_clearance = float(self.ui.clearance_sm2sm_entry.get_value()) sm_sm_clearance = float(self.ui.clearance_sm2sm_entry.get_value())
except Exception as e: except Exception as e:
log.debug("RulesCheck.execute.worker_job() --> %s" % str(e)) log.debug("RulesCheck.execute.worker_job() --> %s" % str(e))
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Minimum Solder Mask Sliver"), _("Minimum Solder Mask Sliver"),
_("Value is not valid."))) _("Value is not valid.")))
return return
@ -923,7 +925,7 @@ class RulesCheck(AppTool):
solder_obj = self.ui.sm_t_object.currentText() solder_obj = self.ui.sm_t_object.currentText()
if solder_obj != '': if solder_obj != '':
sm_dict['name'] = deepcopy(solder_obj) sm_dict['name'] = deepcopy(solder_obj)
sm_dict['apertures'] = deepcopy(self.app.collection.get_by_name(solder_obj).apertures) sm_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(solder_obj).apertures)
self.results.append(self.pool.apply_async(self.check_inside_gerber_clearance, self.results.append(self.pool.apply_async(self.check_inside_gerber_clearance,
args=(sm_dict, args=(sm_dict,
@ -933,7 +935,7 @@ class RulesCheck(AppTool):
solder_obj = self.ui.sm_b_object.currentText() solder_obj = self.ui.sm_b_object.currentText()
if solder_obj != '': if solder_obj != '':
sm_dict['name'] = deepcopy(solder_obj) sm_dict['name'] = deepcopy(solder_obj)
sm_dict['apertures'] = deepcopy(self.app.collection.get_by_name(solder_obj).apertures) sm_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(solder_obj).apertures)
self.results.append(self.pool.apply_async(self.check_inside_gerber_clearance, self.results.append(self.pool.apply_async(self.check_inside_gerber_clearance,
args=(sm_dict, args=(sm_dict,
@ -941,7 +943,7 @@ class RulesCheck(AppTool):
_("BOTTOM -> Minimum Solder Mask Sliver")))) _("BOTTOM -> Minimum Solder Mask Sliver"))))
if self.ui.sm_t_cb.get_value() is False and self.ui.sm_b_cb.get_value() is False: if self.ui.sm_t_cb.get_value() is False and self.ui.sm_b_cb.get_value() is False:
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Minimum Solder Mask Sliver"), _("Minimum Solder Mask Sliver"),
_("At least one Gerber object has to be selected for this rule but none is selected."))) _("At least one Gerber object has to be selected for this rule but none is selected.")))
return return
@ -956,36 +958,36 @@ class RulesCheck(AppTool):
copper_top = self.ui.copper_t_object.currentText() copper_top = self.ui.copper_t_object.currentText()
if copper_top != '' and self.ui.copper_t_cb.get_value(): if copper_top != '' and self.ui.copper_t_cb.get_value():
top_dict['name'] = deepcopy(copper_top) top_dict['name'] = deepcopy(copper_top)
top_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_top).apertures) top_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(copper_top).apertures)
copper_bottom = self.ui.copper_b_object.currentText() copper_bottom = self.ui.copper_b_object.currentText()
if copper_bottom != '' and self.ui.copper_b_cb.get_value(): if copper_bottom != '' and self.ui.copper_b_cb.get_value():
bottom_dict['name'] = deepcopy(copper_bottom) bottom_dict['name'] = deepcopy(copper_bottom)
bottom_dict['apertures'] = deepcopy(self.app.collection.get_by_name(copper_bottom).apertures) bottom_dict['apertures'] = deepcopy(app_obj.collection.get_by_name(copper_bottom).apertures)
excellon_1 = self.ui.e1_object.currentText() excellon_1 = self.ui.e1_object.currentText()
if excellon_1 != '' and self.ui.e1_cb.get_value(): if excellon_1 != '' and self.ui.e1_cb.get_value():
exc_1_dict['name'] = deepcopy(excellon_1) exc_1_dict['name'] = deepcopy(excellon_1)
exc_1_dict['tools'] = deepcopy( exc_1_dict['tools'] = deepcopy(
self.app.collection.get_by_name(excellon_1).tools) app_obj.collection.get_by_name(excellon_1).tools)
excellon_2 = self.ui.e2_object.currentText() excellon_2 = self.ui.e2_object.currentText()
if excellon_2 != '' and self.ui.e2_cb.get_value(): if excellon_2 != '' and self.ui.e2_cb.get_value():
exc_2_dict['name'] = deepcopy(excellon_2) exc_2_dict['name'] = deepcopy(excellon_2)
exc_2_dict['tools'] = deepcopy( exc_2_dict['tools'] = deepcopy(
self.app.collection.get_by_name(excellon_2).tools) app_obj.collection.get_by_name(excellon_2).tools)
try: try:
ring_val = float(self.ui.ring_integrity_entry.get_value()) ring_val = float(self.ui.ring_integrity_entry.get_value())
except Exception as e: except Exception as e:
log.debug("RulesCheck.execute.worker_job() --> %s" % str(e)) log.debug("RulesCheck.execute.worker_job() --> %s" % str(e))
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Minimum Annular Ring"), _("Minimum Annular Ring"),
_("Value is not valid."))) _("Value is not valid.")))
return return
if (not top_dict and not bottom_dict) or (not exc_1_dict and not exc_2_dict): if (not top_dict and not bottom_dict) or (not exc_1_dict and not exc_2_dict):
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Minimum Annular Ring"), _("Minimum Annular Ring"),
_("One of the Copper Gerber objects or the Excellon objects is not valid."))) _("One of the Copper Gerber objects or the Excellon objects is not valid.")))
return return
@ -1001,7 +1003,7 @@ class RulesCheck(AppTool):
elif exc_2_dict: elif exc_2_dict:
objs.append(exc_2_dict) objs.append(exc_2_dict)
else: else:
self.app.inform.emit('[ERROR_NOTCL] %s. %s' % ( app_obj.inform.emit('[ERROR_NOTCL] %s. %s' % (
_("Minimum Annular Ring"), _("Minimum Annular Ring"),
_("Excellon object presence is mandatory for this rule but none is selected."))) _("Excellon object presence is mandatory for this rule but none is selected.")))
return return
@ -1016,16 +1018,18 @@ class RulesCheck(AppTool):
exc_list = [] exc_list = []
exc_name_1 = self.ui.e1_object.currentText() exc_name_1 = self.ui.e1_object.currentText()
if exc_name_1 != '' and self.ui.e1_cb.get_value(): if exc_name_1 != '' and self.ui.e1_cb.get_value():
elem_dict = {} elem_dict = {
elem_dict['name'] = deepcopy(exc_name_1) 'name': deepcopy(exc_name_1),
elem_dict['tools'] = deepcopy(self.app.collection.get_by_name(exc_name_1).tools) 'tools': deepcopy(app_obj.collection.get_by_name(exc_name_1).tools)
}
exc_list.append(elem_dict) exc_list.append(elem_dict)
exc_name_2 = self.ui.e2_object.currentText() exc_name_2 = self.ui.e2_object.currentText()
if exc_name_2 != '' and self.ui.e2_cb.get_value(): if exc_name_2 != '' and self.ui.e2_cb.get_value():
elem_dict = {} elem_dict = {
elem_dict['name'] = deepcopy(exc_name_2) 'name': deepcopy(exc_name_2),
elem_dict['tools'] = deepcopy(self.app.collection.get_by_name(exc_name_2).tools) 'tools': deepcopy(app_obj.collection.get_by_name(exc_name_2).tools)
}
exc_list.append(elem_dict) exc_list.append(elem_dict)
hole_clearance = float(self.ui.clearance_d2d_entry.get_value()) hole_clearance = float(self.ui.clearance_d2d_entry.get_value())
@ -1036,16 +1040,18 @@ class RulesCheck(AppTool):
exc_list = [] exc_list = []
exc_name_1 = self.ui.e1_object.currentText() exc_name_1 = self.ui.e1_object.currentText()
if exc_name_1 != '' and self.ui.e1_cb.get_value(): if exc_name_1 != '' and self.ui.e1_cb.get_value():
elem_dict = {} elem_dict = {
elem_dict['name'] = deepcopy(exc_name_1) 'name': deepcopy(exc_name_1),
elem_dict['tools'] = deepcopy(self.app.collection.get_by_name(exc_name_1).tools) 'tools': deepcopy(app_obj.collection.get_by_name(exc_name_1).tools)
}
exc_list.append(elem_dict) exc_list.append(elem_dict)
exc_name_2 = self.ui.e2_object.currentText() exc_name_2 = self.ui.e2_object.currentText()
if exc_name_2 != '' and self.ui.e2_cb.get_value(): if exc_name_2 != '' and self.ui.e2_cb.get_value():
elem_dict = {} elem_dict = {
elem_dict['name'] = deepcopy(exc_name_2) 'name': deepcopy(exc_name_2),
elem_dict['tools'] = deepcopy(self.app.collection.get_by_name(exc_name_2).tools) 'tools': deepcopy(app_obj.collection.get_by_name(exc_name_2).tools)
}
exc_list.append(elem_dict) exc_list.append(elem_dict)
drill_size = float(self.ui.drill_size_entry.get_value()) drill_size = float(self.ui.drill_size_entry.get_value())
@ -1056,7 +1062,7 @@ class RulesCheck(AppTool):
output.append(p.get()) output.append(p.get())
self.tool_finished.emit(output) self.tool_finished.emit(output)
self.app.proc_container.view.set_idle() app_obj.proc_container.view.set_idle()
log.debug("RuleCheck() finished") log.debug("RuleCheck() finished")

View File

@ -195,9 +195,7 @@ class ToolSub(AppTool):
def worker_job(app_obj): def worker_job(app_obj):
# SUBTRACTOR geometry (always the same) # SUBTRACTOR geometry (always the same)
sub_geometry = {} sub_geometry = {'solid': [], 'clear': []}
sub_geometry['solid'] = []
sub_geometry['clear'] = []
# iterate over SUBTRACTOR geometry and load it in the sub_geometry dict # iterate over SUBTRACTOR geometry and load it in the sub_geometry dict
for s_apid in app_obj.sub_grb_obj.apertures: for s_apid in app_obj.sub_grb_obj.apertures:
for s_el in app_obj.sub_grb_obj.apertures[s_apid]['geometry']: for s_el in app_obj.sub_grb_obj.apertures[s_apid]['geometry']:
@ -206,13 +204,13 @@ class ToolSub(AppTool):
if "clear" in s_el: if "clear" in s_el:
sub_geometry['clear'].append(s_el["clear"]) sub_geometry['clear'].append(s_el["clear"])
for apid in app_obj.target_grb_obj.apertures: for ap_id in app_obj.target_grb_obj.apertures:
# TARGET geometry # TARGET geometry
target_geo = [geo for geo in app_obj.target_grb_obj.apertures[apid]['geometry']] target_geo = [geo for geo in app_obj.target_grb_obj.apertures[ap_id]['geometry']]
# send the job to the multiprocessing JOB # send the job to the multiprocessing JOB
app_obj.results.append( app_obj.results.append(
app_obj.pool.apply_async(app_obj.aperture_intersection, args=(apid, target_geo, sub_geometry)) app_obj.pool.apply_async(app_obj.aperture_intersection, args=(ap_id, target_geo, sub_geometry))
) )
output = [] output = []
@ -348,8 +346,8 @@ class ToolSub(AppTool):
grb_obj.solid_geometry = deepcopy(poly_buff) grb_obj.solid_geometry = deepcopy(poly_buff)
grb_obj.follow_geometry = deepcopy(follow_buff) grb_obj.follow_geometry = deepcopy(follow_buff)
grb_obj.source_file = self.app.f_handlers.export_gerber(obj_name=outname, filename=None, grb_obj.source_file = app_obj.f_handlers.export_gerber(obj_name=outname, filename=None,
local_use=grb_obj, use_thread=False) local_use=grb_obj, use_thread=False)
with self.app.proc_container.new(_("Generating new object ...")): with self.app.proc_container.new(_("Generating new object ...")):
ret = self.app.app_obj.new_object('gerber', outname, obj_init, autoselected=False) ret = self.app.app_obj.new_object('gerber', outname, obj_init, autoselected=False)
@ -542,7 +540,7 @@ class ToolSub(AppTool):
for tool in geo_obj.tools: for tool in geo_obj.tools:
geo_obj.tools[tool]['solid_geometry'] = deepcopy(self.new_solid_geometry) geo_obj.tools[tool]['solid_geometry'] = deepcopy(self.new_solid_geometry)
except Exception as e: except Exception as e:
log.debug("ToolSub.new_geo_object() --> %s" % str(e)) app_obj.log.debug("ToolSub.new_geo_object() --> %s" % str(e))
geo_obj.multigeo = False geo_obj.multigeo = False
with self.app.proc_container.new(_("Generating new object ...")): with self.app.proc_container.new(_("Generating new object ...")):

View File

@ -3172,12 +3172,12 @@ class CNCjob(Geometry):
# Depth parameters # Depth parameters
self.z_cut = tool_dict['tools_drill_cutz'] self.z_cut = tool_dict['tools_drill_cutz']
old_zcut = deepcopy(tool_dict["tools_drill_cutz"]) # multidepth use this old_zcut = deepcopy(tool_dict["tools_drill_cutz"]) # multidepth use this
self.multidepth = tool_dict['tools_drill_multidepth'] self.multidepth = tool_dict['tools_drill_multidepth']
self.z_depthpercut = tool_dict['tools_drill_depthperpass'] self.z_depthpercut = tool_dict['tools_drill_depthperpass']
self.z_move = tool_dict['tools_drill_travelz'] self.z_move = tool_dict['tools_drill_travelz']
self.f_plunge = tool_dict["tools_drill_f_plunge"] # used directly in the preprocessor Toolchange method self.f_plunge = tool_dict["tools_drill_f_plunge"] # used directly in the preprocessor Toolchange method
self.f_retract = tool_dict["tools_drill_f_retract"] # used in the current method self.f_retract = tool_dict["tools_drill_f_retract"] # used in the current method
# Feedrate parameters # Feedrate parameters
self.z_feedrate = tool_dict['tools_drill_feedrate_z'] self.z_feedrate = tool_dict['tools_drill_feedrate_z']
@ -5283,8 +5283,8 @@ class CNCjob(Geometry):
self.z_move = float(z_move) if z_move is not None else None self.z_move = float(z_move) if z_move is not None else None
self.feedrate = float(feedrate) if feedrate else self.app.defaults["geometry_feedrate"] self.feedrate = float(feedrate) if feedrate else self.app.defaults["geometry_feedrate"]
self.z_feedrate = float(feedrate_z) if feedrate_z is not None else self.app.defaults["geometry_feedrate_z"] self.z_feedrate = float(feedrate_z) if feedrate_z is not None else self.app.defaults["geometry_feedrate_z"]
self.feedrate_rapid = float(feedrate_rapid) if feedrate_rapid else self.app.defaults["geometry_feedrate_rapid"] self.feedrate_rapid = float(feedrate_rapid) if feedrate_rapid else self.app.defaults["geometry_feedrate_rapid"]
self.spindlespeed = int(spindlespeed) if spindlespeed != 0 else None self.spindlespeed = int(spindlespeed) if spindlespeed != 0 else None
self.spindledir = spindledir self.spindledir = spindledir

View File

@ -36,6 +36,7 @@ def PolygonPath(polygon):
geometric object""" geometric object"""
this = Polygon(polygon) this = Polygon(polygon)
assert this.geom_type == 'Polygon' assert this.geom_type == 'Polygon'
def coding(ob): def coding(ob):
# The codes will be all "LINETO" commands, except for "MOVETO"s at the # The codes will be all "LINETO" commands, except for "MOVETO"s at the
# beginning of each subpath # beginning of each subpath
@ -43,12 +44,9 @@ def PolygonPath(polygon):
vals = ones(n, dtype=Path.code_type) * Path.LINETO vals = ones(n, dtype=Path.code_type) * Path.LINETO
vals[0] = Path.MOVETO vals[0] = Path.MOVETO
return vals return vals
vertices = concatenate(
[asarray(this.exterior)] vertices = concatenate([asarray(this.exterior)] + [asarray(r) for r in this.interiors])
+ [asarray(r) for r in this.interiors]) codes = concatenate([coding(this.exterior)] + [coding(r) for r in this.interiors])
codes = concatenate(
[coding(this.exterior)]
+ [coding(r) for r in this.interiors])
return Path(vertices, codes) return Path(vertices, codes)

View File

@ -79,8 +79,7 @@ class TclCommand(object):
:return: current command :return: current command
""" """
command_string = [] command_string = [self.aliases[0]]
command_string.append(self.aliases[0])
if self.original_args is not None: if self.original_args is not None:
for arg in self.original_args: for arg in self.original_args:
@ -417,7 +416,7 @@ class TclCommandSignaled(TclCommand):
# set detail for processing, it will be there until next open or close # set detail for processing, it will be there until next open or close
self.app.shell.open_processing(self.get_current_command()) self.app.shell.open_processing(self.get_current_command())
def handle_finished(obj): def handle_finished():
self.app.shell_command_finished.disconnect(handle_finished) self.app.shell_command_finished.disconnect(handle_finished)
if self.error is not None: if self.error is not None:
self.raise_tcl_unknown_error(self.error) self.raise_tcl_unknown_error(self.error)

View File

@ -108,8 +108,10 @@ class TclCommandAlignDrill(TclCommandSignaled):
xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis] xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
tooldia = args['dia']
# Tools # Tools
tools = {"1": {"C": args['dia']}} # tools = {"1": {"C": args['dia']}}
def alligndrill_init_me(init_obj, app_obj): def alligndrill_init_me(init_obj, app_obj):
""" """
@ -126,8 +128,8 @@ class TclCommandAlignDrill(TclCommandSignaled):
for hole in holes: for hole in holes:
point = Point(hole) point = Point(hole)
point_mirror = affinity.scale(point, xscale, yscale, origin=(px, py)) point_mirror = affinity.scale(point, xscale, yscale, origin=(px, py))
drills.append({"point": point, "tool": "1"}) drills.append(point)
drills.append({"point": point_mirror, "tool": "1"}) drills.append(point_mirror)
else: else:
if 'box' not in args: if 'box' not in args:
return "ERROR: -grid can be used only for -box" return "ERROR: -grid can be used only for -box"
@ -167,11 +169,17 @@ class TclCommandAlignDrill(TclCommandSignaled):
for hole in localholes: for hole in localholes:
point = Point(hole) point = Point(hole)
point_mirror = affinity.scale(point, xscale, yscale, origin=(px, py)) point_mirror = affinity.scale(point, xscale, yscale, origin=(px, py))
drills.append({"point": point, "tool": "1"}) drills.append(point)
drills.append({"point": point_mirror, "tool": "1"}) drills.append(point_mirror)
init_obj.tools = {
'1': {
'tooldia': tooldia,
'drills': drills,
'solid_geometry': []
}
}
init_obj.tools = tools
init_obj.drills = drills
init_obj.create_geometry() init_obj.create_geometry()
# Box # Box

View File

@ -80,8 +80,9 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
else: else:
gridoffsety = args['gridoffsety'] gridoffsety = args['gridoffsety']
tooldia = args['dia']
# Tools # Tools
tools = {"1": {"C": args['dia']}} # tools = {"1": {"C": args['dia']}}
def aligndrillgrid_init_me(init_obj, app_obj): def aligndrillgrid_init_me(init_obj, app_obj):
""" """
@ -101,13 +102,18 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
for col in range(args['columns']): for col in range(args['columns']):
point = Point(currentx + gridoffsetx, currenty + gridoffsety) point = Point(currentx + gridoffsetx, currenty + gridoffsety)
drills.append({"point": point, "tool": "1"}) drills.append(point)
currentx = currentx + args['gridx'] currentx = currentx + args['gridx']
currenty = currenty + args['gridy'] currenty = currenty + args['gridy']
init_obj.tools = tools init_obj.tools = {
init_obj.drills = drills '1': {
'tooldia': tooldia,
'drills': drills,
'solid_geometry': []
}
}
init_obj.create_geometry() init_obj.create_geometry()
# Create the new object # Create the new object

View File

@ -154,7 +154,7 @@ class TclCommandCncjob(TclCommandSignaled):
if "dpp" in args: if "dpp" in args:
args["multidepth"] = True args["multidepth"] = True
if args["dpp"] is None: if args["dpp"] is None:
args["dpp"] =self.app.defaults["geometry_depthperpass"] args["dpp"] = self.app.defaults["geometry_depthperpass"]
else: else:
args["dpp"] = float(args["dpp"]) args["dpp"] = float(args["dpp"])
else: else:
@ -188,7 +188,7 @@ class TclCommandCncjob(TclCommandSignaled):
args["dwell"] = self.app.defaults["geometry_dwell"] args["dwell"] = self.app.defaults["geometry_dwell"]
args["dwelltime"] = self.app.defaults["geometry_dwelltime"] args["dwelltime"] = self.app.defaults["geometry_dwelltime"]
args["pp"] = args["pp"] if "pp" in args and args["pp"] else self.app.defaults["geometry_ppname_g"] args["pp"] = args["pp"] if "pp" in args and args["pp"] else self.app.defaults["geometry_ppname_g"]
if "toolchangez" in args: if "toolchangez" in args:
args["toolchange"] = True args["toolchange"] = True

View File

@ -252,7 +252,7 @@ class TclCommandCopperClear(TclCommand):
# Non-Copper clear all polygons in the non-copper clear object # Non-Copper clear all polygons in the non-copper clear object
if 'all' in args: if 'all' in args:
self.app.ncclear_tool.clear_copper_tcl(ncc_obj=obj, self.app.ncclear_tool.clear_copper_tcl(ncc_obj=obj,
select_method=0, # ITSELF select_method=0, # ITSELF
ncctooldia=tooldia, ncctooldia=tooldia,
overlap=overlap, overlap=overlap,
order=order, order=order,
@ -283,7 +283,7 @@ class TclCommandCopperClear(TclCommand):
self.app.ncclear_tool.clear_copper_tcl(ncc_obj=obj, self.app.ncclear_tool.clear_copper_tcl(ncc_obj=obj,
sel_obj=box_obj, sel_obj=box_obj,
select_method=2, # REFERENCE OBJECT select_method=2, # REFERENCE OBJECT
ncctooldia=tooldia, ncctooldia=tooldia,
overlap=overlap, overlap=overlap,
order=order, order=order,

View File

@ -80,5 +80,5 @@ class TclCommandExportGcode(TclCommandSignaled):
self.raise_tcl_error('!!!Promises exists, but should not here!!!') self.raise_tcl_error('!!!Promises exists, but should not here!!!')
del args['name'] del args['name']
modified_gcode = obj.get_gcode(**args) obj.get_gcode(**args)
return return

View File

@ -49,4 +49,4 @@ class TclCommandExportGerber(TclCommand):
""" """
if 'filename' not in args: if 'filename' not in args:
args['filename'] = self.app.defaults["global_last_save_folder"] + '/' + args['name'] args['filename'] = self.app.defaults["global_last_save_folder"] + '/' + args['name']
self.app.f_handlers.export_gerber(use_thread=False,**args) self.app.f_handlers.export_gerber(use_thread=False, **args)

View File

@ -1,7 +1,6 @@
from tclCommands.TclCommand import TclCommand from tclCommands.TclCommand import TclCommand
import collections import collections
from copy import copy
class TclCommandExportSVG(TclCommand): class TclCommandExportSVG(TclCommand):

View File

@ -65,4 +65,4 @@ class TclCommandFollow(TclCommandSignaled):
return "Operation failed: %s" % str(e) return "Operation failed: %s" % str(e)
# in the end toggle the visibility of the origin object so we can see the generated Geometry # in the end toggle the visibility of the origin object so we can see the generated Geometry
# self.app.collection.get_by_name(name).ui.plot_cb.toggle() # self.app.collection.get_by_name(name).ui.plot_cb.toggle()

View File

@ -8,7 +8,6 @@
from tclCommands.TclCommand import TclCommand from tclCommands.TclCommand import TclCommand
import collections import collections
import os
import logging import logging
import gettext import gettext
import appTranslation as fcTranslate import appTranslation as fcTranslate

View File

@ -77,7 +77,7 @@ class TclCommandMillDrills(TclCommandSignaled):
try: try:
obj = self.app.collection.get_by_name(str(name)) obj = self.app.collection.get_by_name(str(name))
except Exception as e: except Exception:
obj = None obj = None
self.raise_tcl_error("Could not retrieve object: %s" % name) self.raise_tcl_error("Could not retrieve object: %s" % name)

View File

@ -167,7 +167,8 @@ class TclCommandPanelize(TclCommand):
# for col in range(columns): # for col in range(columns):
# local_outname = outname + ".tmp." + str(col) + "." + str(row) # local_outname = outname + ".tmp." + str(col) + "." + str(row)
# if isinstance(obj, ExcellonObject): # if isinstance(obj, ExcellonObject):
# self.app.app_obj.new_object("excellon", local_outname, initialize_local_excellon, plot=False, # self.app.app_obj.new_object("excellon", local_outname, initialize_local_excellon,
# plot=False,
# autoselected=False) # autoselected=False)
# else: # else:
# self.app.app_obj.new_object("geometry", local_outname, initialize_local, plot=False, # self.app.app_obj.new_object("geometry", local_outname, initialize_local, plot=False,
@ -199,41 +200,36 @@ class TclCommandPanelize(TclCommand):
def job_init_excellon(obj_fin, app_obj): def job_init_excellon(obj_fin, app_obj):
currenty = 0.0 currenty = 0.0
obj_fin.tools = obj.tools.copy() obj_fin.tools = obj.tools.copy()
obj_fin.drills = [] if 'drills' not in obj_fin.tools:
obj_fin.slots = [] obj_fin.tools['drills'] = []
obj_fin.solid_geometry = [] if 'slots' not in obj_fin.tools:
obj_fin.tools['slots'] = []
if 'solid_geometry' not in obj_fin.tools:
obj_fin.tools['solid_geometry'] = []
for option in obj.options: for option in obj.options:
if option != 'name': if option != 'name':
try: try:
obj_fin.options[option] = obj.options[option] obj_fin.options[option] = obj.options[option]
except Exception as e: except Exception as e:
log.warning("Failed to copy option: %s" % str(option)) app_obj.log.warning("Failed to copy option: %s" % str(option))
log.debug("TclCommandPanelize.execute().panelize2() --> %s" % str(e)) app_obj.log.debug("TclCommandPanelize.execute().panelize2() --> %s" % str(e))
for row in range(rows): for row in range(rows):
currentx = 0.0 currentx = 0.0
for col in range(columns): for col in range(columns):
if obj.drills: if 'drills' in obj.tools:
for tool_dict in obj.drills: for drill_pt in obj.tools['drills']:
point_offseted = affinity.translate(tool_dict['point'], currentx, currenty) point_offseted = affinity.translate(drill_pt, currentx, currenty)
obj_fin.drills.append( obj_fin.tools['drills'].append(point_offseted)
{ if 'slots' in obj.tools:
"point": point_offseted, for slot_tuple in obj.tools['slots']:
"tool": tool_dict['tool'] start_offseted = affinity.translate(slot_tuple[0], currentx, currenty)
} stop_offseted = affinity.translate(slot_tuple[1], currentx, currenty)
) obj_fin.tools['slots'].append(
if obj.slots: (start_offseted, stop_offseted)
for tool_dict in obj.slots:
start_offseted = affinity.translate(tool_dict['start'], currentx, currenty)
stop_offseted = affinity.translate(tool_dict['stop'], currentx, currenty)
obj_fin.slots.append(
{
"start": start_offseted,
"stop": stop_offseted,
"tool": tool_dict['tool']
}
) )
currentx += lenghtx currentx += lenghtx
currenty += lenghty currenty += lenghty
@ -292,17 +288,15 @@ class TclCommandPanelize(TclCommand):
self.app.app_obj.new_object("geometry", outname, job_init_geometry, plot=False, autoselected=True) self.app.app_obj.new_object("geometry", outname, job_init_geometry, plot=False, autoselected=True)
if threaded is True: if threaded is True:
proc = self.app.proc_container.new("Generating panel ... Please wait.") self.app.proc_container.new("Generating panel ... Please wait.")
def job_thread(app_obj): def job_thread(app_obj):
try: try:
panelize_2() panelize_2()
self.app.inform.emit("[success] Panel created successfully.") app_obj.inform.emit("[success] Panel created successfully.")
except Exception as ee: except Exception as ee:
proc.done()
log.debug(str(ee)) log.debug(str(ee))
return return
proc.done()
self.app.collection.promise(outname) self.app.collection.promise(outname)
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]}) self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})

View File

@ -67,7 +67,7 @@ class TclCommandPlotObjects(TclCommand):
names = [x.strip() for x in args['names'].split(",") if x != ''] names = [x.strip() for x in args['names'].split(",") if x != '']
objs = [] objs = []
for name in names: for name in names:
obj= self.app.collection.get_by_name(name) obj = self.app.collection.get_by_name(name)
obj.options["plot"] = True if plot_status is True else False obj.options["plot"] = True if plot_status is True else False
objs.append(obj) objs.append(obj)

View File

@ -50,4 +50,4 @@ class TclCommandSaveSys(TclCommandSignaled):
:return: None or exception :return: None or exception
""" """
self.app.preferencesUiManager.save_defaults(args) self.app.preferencesUiManager.save_defaults(args)

View File

@ -104,10 +104,9 @@ class TclCommandScale(TclCommand):
raise Exception raise Exception
except Exception as e: except Exception as e:
self.raise_tcl_error('%s\n%s' % (_("Expected -origin <origin> or " self.raise_tcl_error('%s\n%s' % (_("Expected -origin <origin> or "
"-origin <min_bounds> or " "-origin <min_bounds> or "
"-origin <center> or " "-origin <center> or "
"- origin 3.0,4.2."), str(e)) "- origin 3.0,4.2."), str(e)))
)
return 'fail' return 'fail'
if 'factor' in args: if 'factor' in args:

View File

@ -52,7 +52,7 @@ class TclCommandSetPath(TclCommand):
"By using this command there is no need for usage of the absolute path to the files.", "By using this command there is no need for usage of the absolute path to the files.",
'args': collections.OrderedDict([ 'args': collections.OrderedDict([
('path', 'A folder path to where the user is supposed to have the file that he will work with.\n' ('path', 'A folder path to where the user is supposed to have the file that he will work with.\n'
'WARNING: No spaces allowed. Use quotes around the path if it contains spaces.'), 'WARNING: No spaces allowed. Use quotes around the path if it contains spaces.'),
]), ]),
'examples': ['set_path D:\\Project_storage_path'] 'examples': ['set_path D:\\Project_storage_path']
} }

View File

@ -87,4 +87,3 @@ class TclCommandSetSys(TclCommand):
else: else:
self.raise_tcl_error("No such system parameter \"{}\".".format(param)) self.raise_tcl_error("No such system parameter \"{}\".".format(param))