- 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:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user