- fixed Tcl Command CncJob
- fixed crash due of Properties Tool trying to have a convex hull area on FlatCAMCNCJob objects which is not possible due of their nature - modified Tcl Command SubtractRectangle - fixed and modernized the Tcl Command Scale to be able to scale on X axis or on Y axis or on both and having as scale reference either the (0, 0) point or the minimum point of the bounding box or the center of the bounding box. - fixed and modernized the Tcl Command Skew
This commit is contained in:
@@ -6016,7 +6016,12 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if self.multitool is False: # single tool usage
|
if self.multitool is False: # single tool usage
|
||||||
self.plot2(tooldia=float(self.options["tooldia"]), obj=self, visible=visible, kind=kind)
|
try:
|
||||||
|
dia_plot = float(self.options["tooldia"])
|
||||||
|
except ValueError:
|
||||||
|
# we may have a tuple with only one element and a comma
|
||||||
|
dia_plot = [float(el) for el in self.options["tooldia"].split(',') if el != ''][0]
|
||||||
|
self.plot2(dia_plot, obj=self, visible=visible, kind=kind)
|
||||||
else:
|
else:
|
||||||
# multiple tools usage
|
# multiple tools usage
|
||||||
for tooluid_key in self.cnc_tools:
|
for tooluid_key in self.cnc_tools:
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ CAD program, and create G-Code for Isolation routing.
|
|||||||
- fixed issue #298. The changes in postprocessors done in Preferences dis not update the object UI layout as it was supposed to. The selection of Marlin postproc. did not unhidden the Feedrate Rapids entry.
|
- fixed issue #298. The changes in postprocessors done in Preferences dis not update the object UI layout as it was supposed to. The selection of Marlin postproc. did not unhidden the Feedrate Rapids entry.
|
||||||
- fixed minor issues
|
- fixed minor issues
|
||||||
- fixed Tcl Command AddPolygon, AddPolyline
|
- fixed Tcl Command AddPolygon, AddPolyline
|
||||||
|
- fixed Tcl Command CncJob
|
||||||
|
- fixed crash due of Properties Tool trying to have a convex hull area on FlatCAMCNCJob objects which is not possible due of their nature
|
||||||
|
- modified Tcl Command SubtractRectangle
|
||||||
|
- fixed and modernized the Tcl Command Scale to be able to scale on X axis or on Y axis or on both and having as scale reference either the (0, 0) point or the minimum point of the bounding box or the center of the bounding box.
|
||||||
|
- fixed and modernized the Tcl Command Skew
|
||||||
|
|
||||||
24.08.2019
|
24.08.2019
|
||||||
|
|
||||||
|
|||||||
14
camlib.py
14
camlib.py
@@ -6001,7 +6001,10 @@ class CNCjob(Geometry):
|
|||||||
flat_geometry = self.flatten(temp_solid_geometry, pathonly=True)
|
flat_geometry = self.flatten(temp_solid_geometry, pathonly=True)
|
||||||
log.debug("%d paths" % len(flat_geometry))
|
log.debug("%d paths" % len(flat_geometry))
|
||||||
|
|
||||||
self.tooldia = float(tooldia) if tooldia else None
|
try:
|
||||||
|
self.tooldia = float(tooldia) if tooldia else None
|
||||||
|
except ValueError:
|
||||||
|
self.tooldia = [float(el) for el in tooldia.split(',') if el != ''] if tooldia else None
|
||||||
|
|
||||||
self.z_cut = float(z_cut) if z_cut else None
|
self.z_cut = float(z_cut) if z_cut else None
|
||||||
self.z_move = float(z_move) if z_move else None
|
self.z_move = float(z_move) if z_move else None
|
||||||
@@ -6669,6 +6672,10 @@ class CNCjob(Geometry):
|
|||||||
if tooldia is None:
|
if tooldia is None:
|
||||||
tooldia = self.tooldia
|
tooldia = self.tooldia
|
||||||
|
|
||||||
|
# this should be unlikely unless when upstream the tooldia is a tuple made by one dia and a comma like (2.4,)
|
||||||
|
if isinstance(tooldia, list):
|
||||||
|
tooldia = tooldia[0] if tooldia[0] is not None else self.tooldia
|
||||||
|
|
||||||
if tooldia == 0:
|
if tooldia == 0:
|
||||||
for geo in gcode_parsed:
|
for geo in gcode_parsed:
|
||||||
if kind == 'all':
|
if kind == 'all':
|
||||||
@@ -7042,7 +7049,10 @@ class CNCjob(Geometry):
|
|||||||
|
|
||||||
bounds_coords = bounds_rec(self.solid_geometry)
|
bounds_coords = bounds_rec(self.solid_geometry)
|
||||||
else:
|
else:
|
||||||
|
minx = Inf
|
||||||
|
miny = Inf
|
||||||
|
maxx = -Inf
|
||||||
|
maxy = -Inf
|
||||||
for k, v in self.cnc_tools.items():
|
for k, v in self.cnc_tools.items():
|
||||||
minx = Inf
|
minx = Inf
|
||||||
miny = Inf
|
miny = Inf
|
||||||
|
|||||||
@@ -169,25 +169,26 @@ class Properties(FlatCAMTool):
|
|||||||
area = length * width
|
area = length * width
|
||||||
self.addChild(dims, ['%s:' % _('Box Area'), '%.4f %s' % (area, 'in2')], True)
|
self.addChild(dims, ['%s:' % _('Box Area'), '%.4f %s' % (area, 'in2')], True)
|
||||||
|
|
||||||
# calculate and add convex hull area
|
if not isinstance(obj, FlatCAMCNCjob):
|
||||||
geo = obj.solid_geometry
|
# calculate and add convex hull area
|
||||||
if isinstance(geo, MultiPolygon):
|
geo = obj.solid_geometry
|
||||||
env_obj = geo.convex_hull
|
if isinstance(geo, MultiPolygon):
|
||||||
elif (isinstance(geo, MultiPolygon) and len(geo) == 1) or \
|
env_obj = geo.convex_hull
|
||||||
(isinstance(geo, list) and len(geo) == 1) and isinstance(geo[0], Polygon):
|
elif (isinstance(geo, MultiPolygon) and len(geo) == 1) or \
|
||||||
env_obj = cascaded_union(obj.solid_geometry)
|
(isinstance(geo, list) and len(geo) == 1) and isinstance(geo[0], Polygon):
|
||||||
env_obj = env_obj.convex_hull
|
env_obj = cascaded_union(obj.solid_geometry)
|
||||||
else:
|
env_obj = env_obj.convex_hull
|
||||||
env_obj = cascaded_union(obj.solid_geometry)
|
else:
|
||||||
env_obj = env_obj.convex_hull
|
env_obj = cascaded_union(obj.solid_geometry)
|
||||||
|
env_obj = env_obj.convex_hull
|
||||||
|
|
||||||
area_chull = env_obj.area
|
area_chull = env_obj.area
|
||||||
if self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() == 'mm':
|
if self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() == 'mm':
|
||||||
area_chull = area_chull / 100
|
area_chull = area_chull / 100
|
||||||
self.addChild(dims, ['%s:' % _('Convex_Hull Area'), '%.4f %s' % (area_chull, 'cm2')], True)
|
self.addChild(dims, ['%s:' % _('Convex_Hull Area'), '%.4f %s' % (area_chull, 'cm2')], True)
|
||||||
else:
|
else:
|
||||||
area_chull = area_chull
|
area_chull = area_chull
|
||||||
self.addChild(dims, ['%s:' % _('Convex_Hull Area'), '%.4f %s' % (area_chull, 'in2')], True)
|
self.addChild(dims, ['%s:' % _('Convex_Hull Area'), '%.4f %s' % (area_chull, 'in2')], True)
|
||||||
|
|
||||||
self.addChild(units,
|
self.addChild(units,
|
||||||
['FlatCAM units:',
|
['FlatCAM units:',
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from ObjectCollection import *
|
|||||||
|
|
||||||
class TclCommandClearShell(TclCommand):
|
class TclCommandClearShell(TclCommand):
|
||||||
"""
|
"""
|
||||||
Tcl shell command to creates a circle in the given Geometry object.
|
Tcl shell command to clear the text in the Tcl Shell browser.
|
||||||
|
|
||||||
example:
|
example:
|
||||||
|
|
||||||
|
|||||||
@@ -24,15 +24,18 @@ class TclCommandCncjob(TclCommandSignaled):
|
|||||||
|
|
||||||
# dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
|
# dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
|
||||||
option_types = collections.OrderedDict([
|
option_types = collections.OrderedDict([
|
||||||
|
('tooldia', float),
|
||||||
('z_cut', float),
|
('z_cut', float),
|
||||||
('z_move', float),
|
('z_move', float),
|
||||||
('feedrate', float),
|
('feedrate', float),
|
||||||
('feedrate_rapid', float),
|
('feedrate_rapid', float),
|
||||||
('tooldia', float),
|
|
||||||
('spindlespeed', int),
|
('spindlespeed', int),
|
||||||
('multidepth', bool),
|
('multidepth', bool),
|
||||||
('extracut', bool),
|
('extracut', bool),
|
||||||
('depthperpass', float),
|
('depthperpass', float),
|
||||||
|
('toolchange', int),
|
||||||
|
('toolchangez', float),
|
||||||
|
('toolchangexy', tuple),
|
||||||
('endz', float),
|
('endz', float),
|
||||||
('ppname_g', str),
|
('ppname_g', str),
|
||||||
('outname', str)
|
('outname', str)
|
||||||
@@ -62,7 +65,7 @@ class TclCommandCncjob(TclCommandSignaled):
|
|||||||
('outname', 'Name of the resulting Geometry object.'),
|
('outname', 'Name of the resulting Geometry object.'),
|
||||||
('ppname_g', 'Name of the Geometry postprocessor. No quotes, case sensitive')
|
('ppname_g', 'Name of the Geometry postprocessor. No quotes, case sensitive')
|
||||||
]),
|
]),
|
||||||
'examples': []
|
'examples': ['cncjob geo_name -tooldia 0.5 -z_cut -1.7 -z_move 2 -feedrate 120 -ppname_g default']
|
||||||
}
|
}
|
||||||
|
|
||||||
def execute(self, args, unnamed_args):
|
def execute(self, args, unnamed_args):
|
||||||
|
|||||||
@@ -21,20 +21,30 @@ class TclCommandScale(TclCommand):
|
|||||||
|
|
||||||
# Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
|
# Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
|
||||||
option_types = collections.OrderedDict([
|
option_types = collections.OrderedDict([
|
||||||
|
('x', float),
|
||||||
|
('y', float),
|
||||||
|
('origin', str)
|
||||||
])
|
])
|
||||||
|
|
||||||
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||||
required = ['name', 'factor']
|
required = ['name']
|
||||||
|
|
||||||
# structured help for current command, args needs to be ordered
|
# structured help for current command, args needs to be ordered
|
||||||
help = {
|
help = {
|
||||||
'main': "Resizes the object by a factor.",
|
'main': "Resizes the object by a factor on X axis and a factor on Y axis, having as scale origin the point ",
|
||||||
'args': collections.OrderedDict([
|
'args': collections.OrderedDict([
|
||||||
('name', 'Name of the object to resize.'),
|
('name', 'Name of the object to resize.'),
|
||||||
('factor', 'Fraction by which to scale.')
|
('factor', 'Fraction by which to scale on both axis. '),
|
||||||
|
('x', 'Fraction by which to scale on X axis. If "factor" is used then this parameter is ignored'),
|
||||||
|
('y', 'Fraction by which to scale on Y axis. If "factor" is used then this parameter is ignored'),
|
||||||
|
('origin', 'Reference used for scale. It can be: "origin" which means point (0, 0) or "min_bounds" which '
|
||||||
|
'means the lower left point of the bounding box or it can be "center" which means the center '
|
||||||
|
'of the bounding box.')
|
||||||
|
|
||||||
]),
|
]),
|
||||||
'examples': ['scale my_geometry 4.2']
|
'examples': ['scale my_geometry 4.2',
|
||||||
|
'scale my_geo -x 3.1 -y 2.8',
|
||||||
|
'scale my_geo 1.2 -origin min_bounds']
|
||||||
}
|
}
|
||||||
|
|
||||||
def execute(self, args, unnamed_args):
|
def execute(self, args, unnamed_args):
|
||||||
@@ -46,6 +56,49 @@ class TclCommandScale(TclCommand):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
name = args['name']
|
name = args['name']
|
||||||
factor = args['factor']
|
try:
|
||||||
|
obj_to_scale = self.app.collection.get_by_name(name)
|
||||||
|
except Exception as e:
|
||||||
|
log.debug("TclCommandCopperClear.execute() --> %s" % str(e))
|
||||||
|
self.raise_tcl_error("%s: %s" % (_("Could not retrieve box object"), name))
|
||||||
|
return "Could not retrieve object: %s" % name
|
||||||
|
|
||||||
self.app.collection.get_by_name(name).scale(factor)
|
if 'origin' not in args:
|
||||||
|
xmin, ymin, xmax, ymax = obj_to_scale.bounds()
|
||||||
|
c_x = xmin + (xmax - xmin) / 2
|
||||||
|
c_y = ymin + (ymax - ymin) / 2
|
||||||
|
point = (c_x, c_y)
|
||||||
|
else:
|
||||||
|
if args['origin'] == 'origin':
|
||||||
|
point = (0, 0)
|
||||||
|
elif args['origin'] == 'min_bounds':
|
||||||
|
xmin, ymin, xmax, ymax = obj_to_scale.bounds()
|
||||||
|
point = (xmin, ymin)
|
||||||
|
elif args['origin'] == 'center':
|
||||||
|
xmin, ymin, xmax, ymax = obj_to_scale.bounds()
|
||||||
|
c_x = xmin + (xmax - xmin) / 2
|
||||||
|
c_y = ymin + (ymax - ymin) / 2
|
||||||
|
point = (c_x, c_y)
|
||||||
|
else:
|
||||||
|
self.raise_tcl_error('%s' % _("Expected -origin <origin> or -origin <min_bounds> or -origin <center>."))
|
||||||
|
return 'fail'
|
||||||
|
|
||||||
|
if 'factor' in args:
|
||||||
|
factor = float(args['factor'])
|
||||||
|
obj_to_scale.scale(factor, point=point)
|
||||||
|
return
|
||||||
|
|
||||||
|
if 'x' not in args and 'y' not in args:
|
||||||
|
self.raise_tcl_error('%s' % _("Expected -x <value> -y <value>."))
|
||||||
|
return 'fail'
|
||||||
|
|
||||||
|
if 'x' in args and 'y' not in args:
|
||||||
|
f_x = float(args['x'])
|
||||||
|
obj_to_scale.scale(f_x, 0, point=point)
|
||||||
|
elif 'x' not in args and 'y' in args:
|
||||||
|
f_y = float(args['y'])
|
||||||
|
obj_to_scale.scale(0, f_y, point=point)
|
||||||
|
elif 'x' in args and 'y' in args:
|
||||||
|
f_x = float(args['x'])
|
||||||
|
f_y = float(args['y'])
|
||||||
|
obj_to_scale.scale(f_x, f_y, point=point)
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ class TclCommandSkew(TclCommand):
|
|||||||
|
|
||||||
# structured help for current command, args needs to be ordered
|
# structured help for current command, args needs to be ordered
|
||||||
help = {
|
help = {
|
||||||
'main': "Shear/Skew an object by angles along x and y dimensions.",
|
'main': "Shear/Skew an object by angles along x and y dimensions. The reference point is the left corner of "
|
||||||
|
"the bounding box of the object.",
|
||||||
'args': collections.OrderedDict([
|
'args': collections.OrderedDict([
|
||||||
('name', 'Name of the object to skew.'),
|
('name', 'Name of the object to skew.'),
|
||||||
('angle_x', 'Angle in degrees by which to skew on the X axis.'),
|
('angle_x', 'Angle in degrees by which to skew on the X axis.'),
|
||||||
@@ -48,7 +49,9 @@ class TclCommandSkew(TclCommand):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
name = args['name']
|
name = args['name']
|
||||||
angle_x = args['angle_x']
|
angle_x = float(args['angle_x'])
|
||||||
angle_y = args['angle_y']
|
angle_y = float(args['angle_y'])
|
||||||
|
|
||||||
self.app.collection.get_by_name(name).skew(angle_x, angle_y)
|
obj_to_skew = self.app.collection.get_by_name(name)
|
||||||
|
xmin, ymin, xmax, ymax = obj_to_skew.bounds()
|
||||||
|
obj_to_skew.skew(angle_x, angle_y, point=(xmin, ymin))
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from tclCommands.TclCommand import TclCommandSignaled
|
|||||||
|
|
||||||
class TclCommandSubtractRectangle(TclCommandSignaled):
|
class TclCommandSubtractRectangle(TclCommandSignaled):
|
||||||
"""
|
"""
|
||||||
Tcl shell command to subtract a rectange from the given Geometry object.
|
Tcl shell command to subtract a rectangle from the given Geometry object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
|
# array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
|
||||||
@@ -13,11 +13,7 @@ class TclCommandSubtractRectangle(TclCommandSignaled):
|
|||||||
# Dictionary of types from Tcl command, needs to be ordered.
|
# Dictionary of types from Tcl command, needs to be ordered.
|
||||||
# For positional arguments
|
# For positional arguments
|
||||||
arg_names = collections.OrderedDict([
|
arg_names = collections.OrderedDict([
|
||||||
('name', str),
|
('name', str)
|
||||||
('x0', float),
|
|
||||||
('y0', float),
|
|
||||||
('x1', float),
|
|
||||||
('y1', float)
|
|
||||||
])
|
])
|
||||||
|
|
||||||
# Dictionary of types from Tcl command, needs to be ordered.
|
# Dictionary of types from Tcl command, needs to be ordered.
|
||||||
@@ -27,7 +23,7 @@ class TclCommandSubtractRectangle(TclCommandSignaled):
|
|||||||
])
|
])
|
||||||
|
|
||||||
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||||
required = ['name', 'x0', 'y0', 'x1', 'y1']
|
required = ['name']
|
||||||
|
|
||||||
# structured help for current command, args needs to be ordered
|
# structured help for current command, args needs to be ordered
|
||||||
help = {
|
help = {
|
||||||
@@ -37,7 +33,7 @@ class TclCommandSubtractRectangle(TclCommandSignaled):
|
|||||||
('x0 y0', 'Bottom left corner coordinates.'),
|
('x0 y0', 'Bottom left corner coordinates.'),
|
||||||
('x1 y1', 'Top right corner coordinates.')
|
('x1 y1', 'Top right corner coordinates.')
|
||||||
]),
|
]),
|
||||||
'examples': []
|
'examples': ['subtract_rectangle geo_obj 8 8 15 15']
|
||||||
}
|
}
|
||||||
|
|
||||||
def execute(self, args, unnamed_args):
|
def execute(self, args, unnamed_args):
|
||||||
@@ -49,12 +45,19 @@ class TclCommandSubtractRectangle(TclCommandSignaled):
|
|||||||
without -somename and we do not have them in known arg_names
|
without -somename and we do not have them in known arg_names
|
||||||
:return: None or exception
|
:return: None or exception
|
||||||
"""
|
"""
|
||||||
|
if 'name' not in args:
|
||||||
|
self.raise_tcl_error("%s:" % _("No Geometry name in args. Provide a name and try again."))
|
||||||
|
return 'fail'
|
||||||
obj_name = args['name']
|
obj_name = args['name']
|
||||||
x0 = args['x0']
|
|
||||||
y0 = args['y0']
|
if len(unnamed_args) != 4:
|
||||||
x1 = args['x1']
|
self.raise_tcl_error("Incomplete coordinates. There are 4 required: x0 y0 x1 y1.")
|
||||||
y1 = args['y1']
|
return 'fail'
|
||||||
|
|
||||||
|
x0 = float(unnamed_args[0])
|
||||||
|
y0 = float(unnamed_args[1])
|
||||||
|
x1 = float(unnamed_args[2])
|
||||||
|
y1 = float(unnamed_args[3])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
obj = self.app.collection.get_by_name(str(obj_name))
|
obj = self.app.collection.get_by_name(str(obj_name))
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class TclCommandVersion(TclCommand):
|
|||||||
'args': collections.OrderedDict([
|
'args': collections.OrderedDict([
|
||||||
|
|
||||||
]),
|
]),
|
||||||
'examples': []
|
'examples': ['version']
|
||||||
}
|
}
|
||||||
|
|
||||||
def execute(self, args, unnamed_args):
|
def execute(self, args, unnamed_args):
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class TclCommandWriteGCode(TclCommandSignaled):
|
|||||||
('preamble', 'Text to append at the beginning.'),
|
('preamble', 'Text to append at the beginning.'),
|
||||||
('postamble', 'Text to append at the end.')
|
('postamble', 'Text to append at the end.')
|
||||||
]),
|
]),
|
||||||
'examples': []
|
'examples': ["write_gcode name c:\\\\gcode_repo"]
|
||||||
}
|
}
|
||||||
|
|
||||||
def execute(self, args, unnamed_args):
|
def execute(self, args, unnamed_args):
|
||||||
|
|||||||
Reference in New Issue
Block a user