- working on adding DPI setting for PNG export in the Film Tool

This commit is contained in:
Marius Stanciu 2020-10-05 12:53:06 +03:00 committed by Marius
parent d5cf7b4980
commit f99a5a8073
7 changed files with 114 additions and 41 deletions

View File

@ -7,6 +7,10 @@ CHANGELOG for FlatCAM beta
=================================================
5.10.2020
- working on adding DPI setting for PNG export in the Film Tool
26.09.2020
- the Selected Tab is now Properties Tab for FlatCAM objects

View File

@ -461,6 +461,7 @@ class PreferencesUIManager:
"tools_film_file_type_radio": self.ui.tools_defaults_form.tools_film_group.file_type_radio,
"tools_film_orientation": self.ui.tools_defaults_form.tools_film_group.orientation_radio,
"tools_film_pagesize": self.ui.tools_defaults_form.tools_film_group.pagesize_combo,
"tools_film_png_dpi": self.ui.tools_defaults_form.tools_film_group.png_dpi_spinner,
# Panelize Tool
"tools_panelize_spacing_columns": self.ui.tools_defaults_form.tools_panelize_group.pspacing_columns,

View File

@ -1,7 +1,7 @@
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import Qt, QSettings
from PyQt5 import QtWidgets
from PyQt5.QtCore import QSettings
from appGUI.GUIElements import RadioSet, FCEntry, FCDoubleSpinner, FCCheckBox, FCComboBox, FCColorEntry
from appGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, FCComboBox, FCColorEntry, FCLabel, FCSpinner
from appGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
@ -28,7 +28,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
self.decimals = decimals
# ## Parameters
self.film_label = QtWidgets.QLabel("<b>%s:</b>" % _("Parameters"))
self.film_label = FCLabel("<b>%s:</b>" % _("Parameters"))
self.film_label.setToolTip(
_("Create a PCB film from a Gerber or Geometry object.\n"
"The file is saved in SVG format.")
@ -40,7 +40,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
self.film_type_radio = RadioSet([{'label': 'Pos', 'value': 'pos'},
{'label': 'Neg', 'value': 'neg'}])
ftypelbl = QtWidgets.QLabel('%s:' % _('Film Type'))
ftypelbl = FCLabel('%s:' % _('Film Type'))
ftypelbl.setToolTip(
_("Generate a Positive black film or a Negative film.\n"
"Positive means that it will print the features\n"
@ -53,7 +53,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
grid0.addWidget(self.film_type_radio, 0, 1)
# Film Color
self.film_color_label = QtWidgets.QLabel('%s:' % _('Film Color'))
self.film_color_label = FCLabel('%s:' % _('Film Color'))
self.film_color_label.setToolTip(
_("Set the film color when positive film is selected.")
)
@ -68,7 +68,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
self.film_boundary_entry.set_range(0, 9999.9999)
self.film_boundary_entry.setSingleStep(0.1)
self.film_boundary_label = QtWidgets.QLabel('%s:' % _("Border"))
self.film_boundary_label = FCLabel('%s:' % _("Border"))
self.film_boundary_label.setToolTip(
_("Specify a border around the object.\n"
"Only for negative film.\n"
@ -87,7 +87,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
self.film_scale_stroke_entry.set_range(0, 9999.9999)
self.film_scale_stroke_entry.setSingleStep(0.1)
self.film_scale_stroke_label = QtWidgets.QLabel('%s:' % _("Scale Stroke"))
self.film_scale_stroke_label = FCLabel('%s:' % _("Scale Stroke"))
self.film_scale_stroke_label.setToolTip(
_("Scale the line stroke thickness of each feature in the SVG file.\n"
"It means that the line that envelope each SVG feature will be thicker or thinner,\n"
@ -96,7 +96,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
grid0.addWidget(self.film_scale_stroke_label, 3, 0)
grid0.addWidget(self.film_scale_stroke_entry, 3, 1)
self.film_adj_label = QtWidgets.QLabel('<b>%s</b>' % _("Film Adjustments"))
self.film_adj_label = FCLabel('<b>%s</b>' % _("Film Adjustments"))
self.film_adj_label.setToolTip(
_("Sometime the printers will distort the print shape, especially the Laser types.\n"
"This section provide the tools to compensate for the print distortions.")
@ -117,7 +117,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
)
grid0.addWidget(self.film_scale_cb, 5, 0, 1, 2)
self.film_scalex_label = QtWidgets.QLabel('%s:' % _("X factor"))
self.film_scalex_label = FCLabel('%s:' % _("X factor"))
self.film_scalex_entry = FCDoubleSpinner()
self.film_scalex_entry.set_range(-999.9999, 999.9999)
self.film_scalex_entry.set_precision(self.decimals)
@ -126,7 +126,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
grid0.addWidget(self.film_scalex_label, 6, 0)
grid0.addWidget(self.film_scalex_entry, 6, 1)
self.film_scaley_label = QtWidgets.QLabel('%s:' % _("Y factor"))
self.film_scaley_label = FCLabel('%s:' % _("Y factor"))
self.film_scaley_entry = FCDoubleSpinner()
self.film_scaley_entry.set_range(-999.9999, 999.9999)
self.film_scaley_entry.set_precision(self.decimals)
@ -148,7 +148,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
)
grid0.addWidget(self.film_skew_cb, 8, 0, 1, 2)
self.film_skewx_label = QtWidgets.QLabel('%s:' % _("X angle"))
self.film_skewx_label = FCLabel('%s:' % _("X angle"))
self.film_skewx_entry = FCDoubleSpinner()
self.film_skewx_entry.set_range(-999.9999, 999.9999)
self.film_skewx_entry.set_precision(self.decimals)
@ -157,7 +157,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
grid0.addWidget(self.film_skewx_label, 9, 0)
grid0.addWidget(self.film_skewx_entry, 9, 1)
self.film_skewy_label = QtWidgets.QLabel('%s:' % _("Y angle"))
self.film_skewy_label = FCLabel('%s:' % _("Y angle"))
self.film_skewy_entry = FCDoubleSpinner()
self.film_skewy_entry.set_range(-999.9999, 999.9999)
self.film_skewy_entry.set_precision(self.decimals)
@ -166,7 +166,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
grid0.addWidget(self.film_skewy_label, 10, 0)
grid0.addWidget(self.film_skewy_entry, 10, 1)
self.film_skew_ref_label = QtWidgets.QLabel('%s:' % _("Reference"))
self.film_skew_ref_label = FCLabel('%s:' % _("Reference"))
self.film_skew_ref_label.setToolTip(
_("The reference point to be used as origin for the skew.\n"
"It can be one of the four points of the geometry bounding box.")
@ -198,7 +198,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
{'label': _('Y'), 'value': 'y'},
{'label': _('Both'), 'value': 'both'}],
stretch=False)
self.film_mirror_axis_label = QtWidgets.QLabel('%s:' % _("Mirror axis"))
self.film_mirror_axis_label = FCLabel('%s:' % _("Mirror axis"))
grid0.addWidget(self.film_mirror_axis_label, 13, 0)
grid0.addWidget(self.film_mirror_axis, 13, 1)
@ -213,7 +213,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
{'label': _('PDF'), 'value': 'pdf'}
], stretch=False)
self.file_type_label = QtWidgets.QLabel(_("Film Type:"))
self.file_type_label = FCLabel(_("Film Type:"))
self.file_type_label.setToolTip(
_("The file type of the saved film. Can be:\n"
"- 'SVG' -> open-source vectorial format\n"
@ -224,7 +224,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
grid0.addWidget(self.file_type_radio, 15, 1)
# Page orientation
self.orientation_label = QtWidgets.QLabel('%s:' % _("Page Orientation"))
self.orientation_label = FCLabel('%s:' % _("Page Orientation"))
self.orientation_label.setToolTip(_("Can be:\n"
"- Portrait\n"
"- Landscape"))
@ -237,7 +237,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
grid0.addWidget(self.orientation_radio, 16, 1)
# Page Size
self.pagesize_label = QtWidgets.QLabel('%s:' % _("Page Size"))
self.pagesize_label = FCLabel('%s:' % _("Page Size"))
self.pagesize_label.setToolTip(_("A selection of standard ISO 216 page sizes."))
self.pagesize_combo = FCComboBox()
@ -302,6 +302,17 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
grid0.addWidget(self.pagesize_label, 17, 0)
grid0.addWidget(self.pagesize_combo, 17, 1)
# PNG DPI
self.png_dpi_label = FCLabel('%s:' % "PNG DPI")
self.png_dpi_label.setToolTip(
_("Default value is 96 DPI. Change this value to scale the PNG file.")
)
self.png_dpi_spinner = FCSpinner()
self.png_dpi_spinner.set_range(0, 100000)
grid0.addWidget(self.png_dpi_label, 19, 0)
grid0.addWidget(self.png_dpi_spinner, 19, 1)
self.layout.addStretch()
# Film Tool

View File

@ -1854,6 +1854,7 @@ class GeometryObject(FlatCAMObj, Geometry):
return
self.multigeo = True
# Object initialization function for app.app_obj.new_object()
# RUNNING ON SEPARATE THREAD!
def job_init_single_geometry(job_obj, app_obj):
@ -2115,9 +2116,9 @@ class GeometryObject(FlatCAMObj, Geometry):
is_first = True if tooluid_key == tool_lst[0] else False
is_last = True if tooluid_key == tool_lst[-1] else False
res, start_gcode = job_obj.geometry_tool_gcode_gen(tooluid_key, tools_dict, first_pt=(0, 0),
tolerance = tol,
tolerance=tol,
is_first=is_first, is_last=is_last,
toolchange = True)
toolchange=True)
if res == 'fail':
log.debug("GeometryObject.mtool_gen_cncjob() --> generate_from_geometry2() failed")
return 'fail'
@ -2303,8 +2304,8 @@ class GeometryObject(FlatCAMObj, Geometry):
toolchangexy=toolchangexy,
extracut=extracut, extracut_length=extracut_length,
startz=startz, endz=endz, endxy=endxy,
pp_geometry_name=ppname_g
)
pp_geometry_name=ppname_g)
job_obj.source_file = res
# tell gcode_parse from which point to start drawing the lines depending on what kind of object is the
# source of gcode
@ -2872,13 +2873,13 @@ class GeometryObject(FlatCAMObj, Geometry):
self.plot()
@staticmethod
def merge(geo_list, geo_final, multigeo=None, fuse_tools=None):
def merge(geo_list, geo_final, multi_geo=None, fuse_tools=None):
"""
Merges the geometry of objects in grb_list into the geometry of geo_final.
:param geo_list: List of GerberObject Objects to join.
:param geo_final: Destination GerberObject object.
:param multigeo: if the merged geometry objects are of type MultiGeo
:param multi_geo: if the merged geometry objects are of type MultiGeo
:param fuse_tools: If True will try to fuse tools of the same type for the Geometry objects
:return: None
"""
@ -2908,7 +2909,7 @@ class GeometryObject(FlatCAMObj, Geometry):
GeometryObject.merge(geo_list=geo_obj, geo_final=geo_final)
# If not list, just append
else:
if multigeo is None or multigeo is False:
if multi_geo is None or multi_geo is False:
geo_final.multigeo = False
else:
geo_final.multigeo = True
@ -2966,19 +2967,23 @@ class GeometryObject(FlatCAMObj, Geometry):
new_tool_nr = 1
for i_lst in intersect_list:
new_solid_geo = []
last_tool = None
for old_tool in i_lst:
new_solid_geo += new_tools[old_tool]['solid_geometry']
last_tool = old_tool
if new_solid_geo:
if new_solid_geo and last_tool:
final_tools[new_tool_nr] = \
{
k: deepcopy(new_tools[old_tool][k]) for k in new_tools[old_tool] if k != 'solid_geometry'
k: deepcopy(new_tools[last_tool][k]) for k in new_tools[last_tool] if k != 'solid_geometry'
}
final_tools[new_tool_nr]['solid_geometry'] = deepcopy(new_solid_geo)
new_tool_nr += 1
else:
final_tools = new_tools
# if not final_tools:
# return 'fail'
geo_final.tools = final_tools
@staticmethod

View File

@ -9,7 +9,7 @@ from PyQt5 import QtCore, QtWidgets, QtGui
from appTool import AppTool
from appGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, \
OptionalHideInputSection, FCComboBox, FCFileSaveDialog, FCButton, FCLabel
OptionalHideInputSection, FCComboBox, FCFileSaveDialog, FCButton, FCLabel, FCSpinner
from copy import deepcopy
import logging
@ -138,6 +138,8 @@ class Film(AppTool):
self.ui.orientation_radio.set_value(self.app.defaults["tools_film_orientation"])
self.ui.pagesize_combo.set_value(self.app.defaults["tools_film_pagesize"])
self.ui.png_dpi_spinner.set_value(self.app.defaults["tools_film_png_dpi"])
self.ui.tf_type_obj_combo.set_value('grb')
self.ui.tf_type_box_combo.set_value('grb')
# run once to update the obj_type attribute in the FCCombobox so the last object is showed in cb
@ -187,8 +189,8 @@ class Film(AppTool):
def generate_positive_normal_film(self, name, boxname, factor, ftype='svg'):
log.debug("ToolFilm.Film.generate_positive_normal_film() started ...")
scale_factor_x = None
scale_factor_y = None
scale_factor_x = 1
scale_factor_y = 1
skew_factor_x = None
skew_factor_y = None
mirror = None
@ -328,8 +330,8 @@ class Film(AppTool):
def generate_negative_film(self, name, boxname, factor, ftype='svg'):
log.debug("ToolFilm.Film.generate_negative_film() started ...")
scale_factor_x = None
scale_factor_y = None
scale_factor_x = 1
scale_factor_y = 1
skew_factor_x = None
skew_factor_y = None
mirror = None
@ -390,7 +392,7 @@ class Film(AppTool):
def export_negative(self, obj_name, box_name, filename, boundary,
scale_stroke_factor=0.00,
scale_factor_x=None, scale_factor_y=None,
scale_factor_x=1, scale_factor_y=1,
skew_factor_x=None, skew_factor_y=None, skew_reference='center',
mirror=None,
use_thread=True, ftype='svg'):
@ -434,6 +436,12 @@ class Film(AppTool):
self.app.inform.emit('[WARNING_NOTCL] %s: %s' % (_("No object Box. Using instead"), obj))
box = obj
new_png_dpi = self.ui.png_dpi_spinner.get_value()
dpi_rate = new_png_dpi / 96
if dpi_rate != 1:
scale_factor_x += dpi_rate
scale_factor_y += dpi_rate
def make_negative_film():
exported_svg = obj.export_svg(scale_stroke_factor=scale_stroke_factor,
scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y,
@ -513,7 +521,10 @@ class Film(AppTool):
try:
doc_final = StringIO(doc_final)
drawing = svg2rlg(doc_final)
renderPM.drawToFile(drawing, filename, 'PNG')
if new_png_dpi == 96:
renderPM.drawToFile(drawing, filename, 'PNG')
else:
renderPM.drawToFile(drawing, filename, 'PNG', dpi=new_png_dpi)
except Exception as e:
log.debug("FilmTool.export_negative() --> PNG output --> %s" % str(e))
return 'fail'
@ -566,7 +577,7 @@ class Film(AppTool):
def export_positive(self, obj_name, box_name, filename,
scale_stroke_factor=0.00,
scale_factor_x=None, scale_factor_y=None,
scale_factor_x=1, scale_factor_y=1,
skew_factor_x=None, skew_factor_y=None, skew_reference='center',
mirror=None, orientation_val='p', pagesize_val='A4', color_val='black', opacity_val=1.0,
use_thread=True, ftype='svg'):
@ -620,6 +631,12 @@ class Film(AppTool):
color = color_val
transparency_level = opacity_val
new_png_dpi = self.ui.png_dpi_spinner.get_value()
dpi_rate = new_png_dpi / 96
if dpi_rate != 1:
scale_factor_x += dpi_rate
scale_factor_y += dpi_rate
def make_positive_film(p_size, orientation, color, transparency_level):
log.debug("FilmTool.export_positive().make_positive_film()")
@ -692,7 +709,10 @@ class Film(AppTool):
try:
doc_final = StringIO(doc_final)
drawing = svg2rlg(doc_final)
renderPM.drawToFile(drawing, filename, 'PNG')
if new_png_dpi == 96:
renderPM.drawToFile(drawing, filename, 'PNG')
else:
renderPM.drawToFile(drawing, filename, 'PNG', dpi=new_png_dpi)
except Exception as e:
log.debug("FilmTool.export_positive() --> PNG output --> %s" % str(e))
return 'fail'
@ -1199,6 +1219,20 @@ class FilmUI:
self.on_film_type(val='hide')
# PNG DPI
self.png_dpi_label = FCLabel('%s:' % "PNG DPI")
self.png_dpi_label.setToolTip(
_("Default value is 96 DPI. Change this value to scale the PNG file.")
)
self.png_dpi_spinner = FCSpinner(callback=self.confirmation_message_int)
self.png_dpi_spinner.set_range(0, 100000)
grid1.addWidget(self.png_dpi_label, 4, 0)
grid1.addWidget(self.png_dpi_spinner, 4, 1)
self.png_dpi_label.hide()
self.png_dpi_spinner.hide()
# Buttons
self.film_object_button = FCButton(_("Save Film"))
self.film_object_button.setIcon(QtGui.QIcon(self.app.resource_location + '/save_as.png'))
@ -1214,7 +1248,7 @@ class FilmUI:
font-weight: bold;
}
""")
grid1.addWidget(self.film_object_button, 4, 0, 1, 2)
grid1.addWidget(self.film_object_button, 6, 0, 1, 2)
self.layout.addStretch()
@ -1254,11 +1288,22 @@ class FilmUI:
self.orientation_radio.show()
self.pagesize_label.show()
self.pagesize_combo.show()
self.png_dpi_label.hide()
self.png_dpi_spinner.hide()
elif val == 'png':
self.png_dpi_label.show()
self.png_dpi_spinner.show()
self.orientation_label.hide()
self.orientation_radio.hide()
self.pagesize_label.hide()
self.pagesize_combo.hide()
else:
self.orientation_label.hide()
self.orientation_radio.hide()
self.pagesize_label.hide()
self.pagesize_combo.hide()
self.png_dpi_label.hide()
self.png_dpi_spinner.hide()
def on_punch_source(self, val):
if val == 'pad' and self.punch_cb.get_value():

View File

@ -2255,14 +2255,20 @@ class Geometry(object):
geom = geom_svg
if scale_factor_x:
if scale_factor_x and not scale_factor_y:
geom = affinity.scale(geom_svg, scale_factor_x, 1.0)
if scale_factor_y:
elif not scale_factor_x and scale_factor_y:
geom = affinity.scale(geom_svg, 1.0, scale_factor_y)
if skew_factor_x:
elif scale_factor_x and scale_factor_y:
geom = affinity.scale(geom_svg, scale_factor_x, scale_factor_y)
if skew_factor_x and not skew_factor_y:
geom = affinity.skew(geom_svg, skew_factor_x, 0.0, origin=skew_ref)
if skew_factor_y:
elif not skew_factor_x and skew_factor_y:
geom = affinity.skew(geom_svg, 0.0, skew_factor_y, origin=skew_ref)
elif skew_factor_x and skew_factor_y:
geom = affinity.skew(geom_svg, skew_factor_x, skew_factor_y, origin=skew_ref)
if mirror:
if mirror == 'x':
geom = affinity.scale(geom_svg, 1.0, -1.0)

View File

@ -533,6 +533,7 @@ class FlatCAMDefaults:
"tools_film_file_type_radio": 'svg',
"tools_film_orientation": 'p',
"tools_film_pagesize": 'A4',
"tools_film_png_dpi": 96,
# Panel Tool
"tools_panelize_spacing_columns": 0.0,