- Film Tool - made sure that the reference point is used for all transformations in case of negative film; negative film now use the color setting from Preferences too

This commit is contained in:
Marius Stanciu
2021-02-26 15:52:33 +02:00
committed by Marius
parent ca29bc0ca3
commit 8ae0049ed4
2 changed files with 68 additions and 67 deletions

View File

@@ -12,6 +12,7 @@ CHANGELOG for FlatCAM beta
- fixes in Drilling & Milling Plugins for the error: "RuntimeError: wrapped C/C++ object of type ... has been deleted" - fixes in Drilling & Milling Plugins for the error: "RuntimeError: wrapped C/C++ object of type ... has been deleted"
- Milling Tool (Plugin) - fix to use the tool diameter set in the Milling plugin tool; selection in the Tools Table is now by row - Milling Tool (Plugin) - fix to use the tool diameter set in the Milling plugin tool; selection in the Tools Table is now by row
- Film Tool - made sure that the reference point is used for all transformations in case of positive film - Film Tool - made sure that the reference point is used for all transformations in case of positive film
- Film Tool - made sure that the reference point is used for all transformations in case of negative film; negative film now use the color setting from Preferences too
13.02.2021 13.02.2021

View File

@@ -365,17 +365,13 @@ class Film(AppTool):
filename = str(filename) filename = str(filename)
if str(filename) != "": if str(filename) != "":
pagesize = self.ui.pagesize_combo.get_value()
orientation = self.ui.orientation_radio.get_value()
color = self.app.defaults['tools_film_color']
self.export_positive(name, boxname, filename, self.export_positive(name, boxname, filename,
scale_stroke_factor=factor, scale_stroke_factor=factor,
scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y, scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y,
skew_factor_x=skew_factor_x, skew_factor_y=skew_factor_y, skew_factor_x=skew_factor_x, skew_factor_y=skew_factor_y,
reference_point=reference_point, reference_point=reference_point,
mirror=mirror, mirror=mirror,
pagesize_val=pagesize, orientation_val=orientation, color_val=color, opacity_val=1.0, opacity_val=1.0,
ftype=ftype ftype=ftype
) )
return return
@@ -532,7 +528,7 @@ class Film(AppTool):
scale_stroke_factor=0.00, scale_stroke_factor=0.00,
scale_factor_x=1, scale_factor_y=1, scale_factor_x=1, scale_factor_y=1,
skew_factor_x=None, skew_factor_y=None, reference_point='center', skew_factor_x=None, skew_factor_y=None, reference_point='center',
mirror=None, mirror=None, opacity_val=1.0,
use_thread=True, ftype='svg'): use_thread=True, ftype='svg'):
""" """
Exports a Geometry Object to an SVG file in negative. Exports a Geometry Object to an SVG file in negative.
@@ -547,10 +543,11 @@ class Film(AppTool):
:param scale_factor_y: factor to scale the svg geometry on the Y axis :param scale_factor_y: factor to scale the svg geometry on the Y axis
:param skew_factor_x: factor to skew the svg geometry on the X axis :param skew_factor_x: factor to skew the svg geometry on the X axis
:param skew_factor_y: factor to skew the svg geometry on the Y axis :param skew_factor_y: factor to skew the svg geometry on the Y axis
:param reference_point: reference to use for transformation. Can be 'bottomleft', 'bottomright', 'topleft', :param reference_point: reference to use for transformation. Can be 'bottomleft', 'bottomright', 'topleft',
'topright', 'center' and those are the 5 points of the bounding box of the 'topright', 'center' and those are the 5 points of the bounding box of the
geometry to be altered. geometry to be altered.
:param mirror: can be 'x' or 'y' or 'both'. Axis on which to mirror the svg geometry :param mirror: can be 'x' or 'y' or 'both'. Axis on which to mirror the svg geometry
:param opacity_val:
:param use_thread: if to be run in a separate thread; boolean :param use_thread: if to be run in a separate thread; boolean
:param ftype: the type of file for saving the film: 'svg', 'png' or 'pdf' :param ftype: the type of file for saving the film: 'svg', 'png' or 'pdf'
:return: :return:
@@ -560,7 +557,7 @@ class Film(AppTool):
if filename is None: if filename is None:
filename = self.app.defaults["global_last_save_folder"] filename = self.app.defaults["global_last_save_folder"]
self.app.log.debug("export_svg() negative") self.app.log.debug("Film.export_svg() negative")
try: try:
obj = self.app.collection.get_by_name(str(obj_name)) obj = self.app.collection.get_by_name(str(obj_name))
@@ -579,23 +576,39 @@ class Film(AppTool):
scale_factor_x = scale_factor_x scale_factor_x = scale_factor_x
scale_factor_y = scale_factor_y scale_factor_y = scale_factor_y
def make_negative_film(scale_factor_x, scale_factor_y): def get_complementary(color):
log.debug("FilmTool.export_negative().make_negative_film()") # strip the # from the beginning
color = color[1:]
scale_reference = 'center' # convert the string into hex
color = int(color, 16)
# invert the three bytes
# as good as substracting each of RGB component by 255(FF)
comp_color = 0xFFFFFF ^ color
# convert the color back to hex by prefixing a #
comp_color = "#%06X" % comp_color
# return the result
return comp_color
p_size = self.ui.pagesize_combo.get_value()
orientation = self.ui.orientation_radio.get_value()
color = obj.options['tools_film_color']
transparency_level = opacity_val
def make_negative_film(color, transparency_level, scale_factor_x, scale_factor_y):
log.debug("FilmTool.export_negative().make_negative_film()")
self.screen_dpi = self.app.qapp.screens()[0].logicalDotsPerInch() self.screen_dpi = self.app.qapp.screens()[0].logicalDotsPerInch()
new_png_dpi = self.ui.png_dpi_spinner.get_value() new_png_dpi = self.ui.png_dpi_spinner.get_value()
dpi_rate = new_png_dpi / self.screen_dpi dpi_rate = new_png_dpi / self.screen_dpi
# Determine bounding area for svg export
bounds = box.bounds()
tr_scale_reference = (bounds[0], bounds[1])
if dpi_rate != 1 and ftype == 'png': if dpi_rate != 1 and ftype == 'png':
scale_factor_x += dpi_rate scale_factor_x += dpi_rate
scale_factor_y += dpi_rate scale_factor_y += dpi_rate
scale_reference = (bounds[0], bounds[1])
if box.kind.lower() == 'geometry': if box.kind.lower() == 'geometry':
flat_geo = [] flat_geo = []
@@ -608,44 +621,41 @@ class Film(AppTool):
else: else:
box_geo = unary_union(box.flatten()) box_geo = unary_union(box.flatten())
skew_ref = 'center' xmin, ymin, xmax, ymax = box_geo.bounds
if reference_point != 'center': ref_val = 'center'
xmin, ymin, xmax, ymax = box_geo.bounds if reference_point == 'topleft':
if reference_point == 'topleft': ref_val = (xmin, ymax)
skew_ref = (xmin, ymax) elif reference_point == 'bottomleft':
elif reference_point == 'bottomleft': ref_val = (xmin, ymin)
skew_ref = (xmin, ymin) elif reference_point == 'topright':
elif reference_point == 'topright': ref_val = (xmax, ymax)
skew_ref = (xmax, ymax) elif reference_point == 'bottomright':
elif reference_point == 'bottomright': ref_val = (xmax, ymin)
skew_ref = (xmax, ymin)
transformed_box_geo = box_geo transformed_box_geo = box_geo
if scale_factor_x and not scale_factor_y: if scale_factor_x and not scale_factor_y:
transformed_box_geo = affinity.scale(transformed_box_geo, scale_factor_x, 1.0, transformed_box_geo = affinity.scale(transformed_box_geo, scale_factor_x, 1.0, origin=ref_val)
origin=tr_scale_reference)
elif not scale_factor_x and scale_factor_y: elif not scale_factor_x and scale_factor_y:
transformed_box_geo = affinity.scale(transformed_box_geo, 1.0, scale_factor_y, transformed_box_geo = affinity.scale(transformed_box_geo, 1.0, scale_factor_y, origin=ref_val)
origin=tr_scale_reference)
elif scale_factor_x and scale_factor_y: elif scale_factor_x and scale_factor_y:
transformed_box_geo = affinity.scale(transformed_box_geo, scale_factor_x, scale_factor_y, transformed_box_geo = affinity.scale(transformed_box_geo, scale_factor_x, scale_factor_y,
origin=tr_scale_reference) origin=ref_val)
if skew_factor_x and not skew_factor_y: if skew_factor_x and not skew_factor_y:
transformed_box_geo = affinity.skew(transformed_box_geo, skew_factor_x, 0.0, origin=skew_ref) transformed_box_geo = affinity.skew(transformed_box_geo, skew_factor_x, 0.0, origin=ref_val)
elif not skew_factor_x and skew_factor_y: elif not skew_factor_x and skew_factor_y:
transformed_box_geo = affinity.skew(transformed_box_geo, 0.0, skew_factor_y, origin=skew_ref) transformed_box_geo = affinity.skew(transformed_box_geo, 0.0, skew_factor_y, origin=ref_val)
elif skew_factor_x and skew_factor_y: elif skew_factor_x and skew_factor_y:
transformed_box_geo = affinity.skew(transformed_box_geo, skew_factor_x, skew_factor_y, origin=skew_ref) transformed_box_geo = affinity.skew(transformed_box_geo, skew_factor_x, skew_factor_y, origin=ref_val)
if mirror: if mirror:
if mirror == 'x': if mirror == 'x':
transformed_box_geo = affinity.scale(transformed_box_geo, 1.0, -1.0) transformed_box_geo = affinity.scale(transformed_box_geo, 1.0, -1.0, origin=ref_val)
if mirror == 'y': if mirror == 'y':
transformed_box_geo = affinity.scale(transformed_box_geo, -1.0, 1.0) transformed_box_geo = affinity.scale(transformed_box_geo, -1.0, 1.0, origin=ref_val)
if mirror == 'both': if mirror == 'both':
transformed_box_geo = affinity.scale(transformed_box_geo, -1.0, -1.0) transformed_box_geo = affinity.scale(transformed_box_geo, -1.0, -1.0, origin=ref_val)
bounds = transformed_box_geo.bounds bounds = transformed_box_geo.bounds
size = bounds[2] - bounds[0], bounds[3] - bounds[1] size = bounds[2] - bounds[0], bounds[3] - bounds[1]
@@ -654,7 +664,7 @@ class Film(AppTool):
scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y, scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y,
skew_factor_x=skew_factor_x, skew_factor_y=skew_factor_y, skew_factor_x=skew_factor_x, skew_factor_y=skew_factor_y,
mirror=mirror, mirror=mirror,
scale_reference=scale_reference, skew_reference=reference_point scale_reference=reference_point, skew_reference=reference_point
) )
uom = obj.units.lower() uom = obj.units.lower()
@@ -681,12 +691,12 @@ class Film(AppTool):
# Change the attributes of the exported SVG # Change the attributes of the exported SVG
# We don't need stroke-width - wrong, we do when we have lines with certain width # We don't need stroke-width - wrong, we do when we have lines with certain width
# We set opacity to maximum # We set opacity to maximum
# We set the color to WHITE # We set the color to the inversed color
root = ET.fromstring(exported_svg) root = ET.fromstring(exported_svg)
for child in root: for child in root:
child.set('fill', '#FFFFFF') child.set('fill', get_complementary(color))
child.set('opacity', '1.0') child.set('opacity', str(transparency_level))
child.set('stroke', '#FFFFFF') child.set('stroke', get_complementary(color))
# first_svg_elem = 'rect x="' + minx + '" ' + 'y="' + miny_rect + '" ' # first_svg_elem = 'rect x="' + minx + '" ' + 'y="' + miny_rect + '" '
# first_svg_elem += 'width="' + svgwidth + '" ' + 'height="' + svgheight + '" ' # first_svg_elem += 'width="' + svgwidth + '" ' + 'height="' + svgheight + '" '
@@ -699,7 +709,7 @@ class Film(AppTool):
'width': svgwidth, 'width': svgwidth,
'height': svgheight, 'height': svgheight,
'id': 'neg_rect', 'id': 'neg_rect',
'style': 'fill:#000000;opacity:1.0;stroke-width:0.0' 'style': 'fill:%s;opacity:1.0;stroke-width:0.0' % str(color)
} }
root.insert(0, ET.Element(first_svg_elem_tag, first_svg_elem_attribs)) root.insert(0, ET.Element(first_svg_elem_tag, first_svg_elem_attribs))
@@ -737,7 +747,7 @@ class Film(AppTool):
"Most likely another app is holding the file open and not accessible.")) "Most likely another app is holding the file open and not accessible."))
return 'fail' return 'fail'
except Exception as e: except Exception as e:
log.error("FilmTool.export_negative() --> PNG output --> %s" % str(e)) self.app.log.error("FilmTool.export_negative() --> PNG output --> %s" % str(e))
return 'fail' return 'fail'
else: # PDF else: # PDF
try: try:
@@ -746,10 +756,9 @@ class Film(AppTool):
else: else:
unit = mm unit = mm
p_size = self.ui.pagesize_combo.get_value()
if p_size == 'Bounds': if p_size == 'Bounds':
page_size = None page_size = None
elif self.ui.orientation_radio.get_value() == 'p': elif orientation == 'p':
page_size = portrait(self.ui.pagesize[p_size]) page_size = portrait(self.ui.pagesize[p_size])
else: else:
page_size = landscape(self.ui.pagesize[p_size]) page_size = landscape(self.ui.pagesize[p_size])
@@ -787,7 +796,7 @@ class Film(AppTool):
"Most likely another app is holding the file open and not accessible.")) "Most likely another app is holding the file open and not accessible."))
return 'fail' return 'fail'
except Exception as e: except Exception as e:
log.error("FilmTool.export_negative() --> PDF output --> %s" % str(e)) self.app.log.error("FilmTool.export_negative() --> PDF output --> %s" % str(e))
return 'fail' return 'fail'
if self.app.defaults["global_open_style"] is False: if self.app.defaults["global_open_style"] is False:
@@ -799,7 +808,8 @@ class Film(AppTool):
def job_thread_film(): def job_thread_film():
with self.app.proc_container.new(_("Working...")): with self.app.proc_container.new(_("Working...")):
try: try:
make_negative_film(scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y) make_negative_film(color=color, transparency_level=transparency_level,
scale_factor_x=scale_factor_x, scale_factor_y=scale_factor_y)
except Exception as e: except Exception as e:
log.error("export_negative() process -> %s" % str(e)) log.error("export_negative() process -> %s" % str(e))
return return
@@ -812,7 +822,7 @@ class Film(AppTool):
scale_stroke_factor=0.00, scale_stroke_factor=0.00,
scale_factor_x=1, scale_factor_y=1, scale_factor_x=1, scale_factor_y=1,
skew_factor_x=None, skew_factor_y=None, reference_point='center', skew_factor_x=None, skew_factor_y=None, reference_point='center',
mirror=None, orientation_val='p', pagesize_val='A4', color_val='black', opacity_val=1.0, mirror=None, opacity_val=1.0,
use_thread=True, ftype='svg'): use_thread=True, ftype='svg'):
""" """
@@ -830,9 +840,6 @@ class Film(AppTool):
'topright' and those are the 4 points of the bounding box of the geometry 'topright' and those are the 4 points of the bounding box of the geometry
to be altered. to be altered.
:param mirror: can be 'x' or 'y' or 'both'. Axis on which to mirror the svg geometry :param mirror: can be 'x' or 'y' or 'both'. Axis on which to mirror the svg geometry
:param orientation_val:
:param pagesize_val:
:param color_val:
:param opacity_val: :param opacity_val:
:param use_thread: if to be run in a separate thread; boolean :param use_thread: if to be run in a separate thread; boolean
:param ftype: the type of file for saving the film: 'svg', 'png' or 'pdf' :param ftype: the type of file for saving the film: 'svg', 'png' or 'pdf'
@@ -844,7 +851,7 @@ class Film(AppTool):
if filename is None: if filename is None:
filename = self.app.defaults["global_last_save_folder"] filename = self.app.defaults["global_last_save_folder"]
self.app.log.debug("export_svg() black") self.app.log.debug("Film.export_positive() black")
try: try:
obj = self.app.collection.get_by_name(str(obj_name)) obj = self.app.collection.get_by_name(str(obj_name))
@@ -863,12 +870,12 @@ class Film(AppTool):
scale_factor_x = scale_factor_x scale_factor_x = scale_factor_x
scale_factor_y = scale_factor_y scale_factor_y = scale_factor_y
p_size = pagesize_val p_size = self.ui.pagesize_combo.get_value()
orientation = orientation_val orientation = self.ui.orientation_radio.get_value()
color = color_val color = obj.options['tools_film_color']
transparency_level = opacity_val transparency_level = opacity_val
def make_positive_film(p_size, orientation, color, transparency_level, scale_factor_x, scale_factor_y): def make_positive_film(color, transparency_level, scale_factor_x, scale_factor_y):
log.debug("FilmTool.export_positive().make_positive_film()") log.debug("FilmTool.export_positive().make_positive_film()")
self.screen_dpi = self.app.qapp.screens()[0].logicalDotsPerInch() self.screen_dpi = self.app.qapp.screens()[0].logicalDotsPerInch()
@@ -876,10 +883,6 @@ class Film(AppTool):
new_png_dpi = self.ui.png_dpi_spinner.get_value() new_png_dpi = self.ui.png_dpi_spinner.get_value()
dpi_rate = new_png_dpi / self.screen_dpi dpi_rate = new_png_dpi / self.screen_dpi
# Determine bounding area for svg export
bounds = box.bounds()
tr_scale_reference = (bounds[0], bounds[1])
if dpi_rate != 1 and ftype == 'png': if dpi_rate != 1 and ftype == 'png':
scale_factor_x += dpi_rate scale_factor_x += dpi_rate
scale_factor_y += dpi_rate scale_factor_y += dpi_rate
@@ -956,11 +959,8 @@ class Film(AppTool):
# This contain the measure units # This contain the measure units
uom = obj.units.lower() uom = obj.units.lower()
# Define a boundary around SVG of about 1.0mm (~39mils) # Define a boundary around SVG
if uom in "mm": boundary = self.ui.boundary_entry.get_value()
boundary = 1.0
else:
boundary = 0.0393701
# Convert everything to strings for use in the xml doc # Convert everything to strings for use in the xml doc
svgwidth = str(size[0] + (2 * boundary)) svgwidth = str(size[0] + (2 * boundary))
@@ -1009,7 +1009,7 @@ class Film(AppTool):
except Exception as e: except Exception as e:
self.app.log.error("FilmTool.export_positive() --> PNG output --> %s" % str(e)) self.app.log.error("FilmTool.export_positive() --> PNG output --> %s" % str(e))
return 'fail' return 'fail'
else: else: # PDF
try: try:
if self.units == 'IN': if self.units == 'IN':
unit = inch unit = inch