Added support for "plot" checkboxes and "solid" checkbox for Gerber.
This commit is contained in:
78
FlatCAM.py
78
FlatCAM.py
@@ -266,9 +266,16 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||||||
self.options['bboxmargin'] *= factor
|
self.options['bboxmargin'] *= factor
|
||||||
|
|
||||||
def plot(self, figure):
|
def plot(self, figure):
|
||||||
|
"""
|
||||||
|
Plots the object on to the specified figure.
|
||||||
|
|
||||||
|
:param figure: Matplotlib figure on which to plot.
|
||||||
|
"""
|
||||||
|
|
||||||
FlatCAMObj.plot(self, figure)
|
FlatCAMObj.plot(self, figure)
|
||||||
|
|
||||||
#self.create_geometry()
|
if not self.options["plot"]:
|
||||||
|
return
|
||||||
|
|
||||||
if self.options["mergepolys"]:
|
if self.options["mergepolys"]:
|
||||||
geometry = self.solid_geometry
|
geometry = self.solid_geometry
|
||||||
@@ -282,12 +289,22 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||||||
else:
|
else:
|
||||||
linespec = 'k-'
|
linespec = 'k-'
|
||||||
|
|
||||||
for poly in geometry:
|
if self.options["solid"]:
|
||||||
x, y = poly.exterior.xy
|
for poly in geometry:
|
||||||
self.axes.plot(x, y, linespec)
|
# TODO: Too many things hardcoded.
|
||||||
for ints in poly.interiors:
|
patch = PolygonPatch(poly,
|
||||||
x, y = ints.coords.xy
|
facecolor="#BBF268",
|
||||||
|
edgecolor="#006E20",
|
||||||
|
alpha=0.75,
|
||||||
|
zorder=2)
|
||||||
|
self.axes.add_patch(patch)
|
||||||
|
else:
|
||||||
|
for poly in geometry:
|
||||||
|
x, y = poly.exterior.xy
|
||||||
self.axes.plot(x, y, linespec)
|
self.axes.plot(x, y, linespec)
|
||||||
|
for ints in poly.interiors:
|
||||||
|
x, y = ints.coords.xy
|
||||||
|
self.axes.plot(x, y, linespec)
|
||||||
|
|
||||||
self.app.canvas.queue_draw()
|
self.app.canvas.queue_draw()
|
||||||
|
|
||||||
@@ -346,8 +363,9 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||||||
|
|
||||||
def plot(self, figure):
|
def plot(self, figure):
|
||||||
FlatCAMObj.plot(self, figure)
|
FlatCAMObj.plot(self, figure)
|
||||||
#self.setup_axes(figure)
|
|
||||||
#self.create_geometry()
|
if not self.options["plot"]:
|
||||||
|
return
|
||||||
|
|
||||||
# Plot excellon
|
# Plot excellon
|
||||||
for geo in self.solid_geometry:
|
for geo in self.solid_geometry:
|
||||||
@@ -400,15 +418,11 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||||||
|
|
||||||
self.options.update({
|
self.options.update({
|
||||||
"plot": True,
|
"plot": True,
|
||||||
"solid": False,
|
|
||||||
"multicolored": False,
|
|
||||||
"tooldia": 0.4 / 25.4 # 0.4mm in inches
|
"tooldia": 0.4 / 25.4 # 0.4mm in inches
|
||||||
})
|
})
|
||||||
|
|
||||||
self.form_kinds.update({
|
self.form_kinds.update({
|
||||||
"plot": "cb",
|
"plot": "cb",
|
||||||
"solid": "cb",
|
|
||||||
"multicolored": "cb",
|
|
||||||
"tooldia": "entry_eval"
|
"tooldia": "entry_eval"
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -418,8 +432,11 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||||||
self.ser_attrs += ['options', 'kind']
|
self.ser_attrs += ['options', 'kind']
|
||||||
|
|
||||||
def plot(self, figure):
|
def plot(self, figure):
|
||||||
FlatCAMObj.plot(self, figure)
|
FlatCAMObj.plot(self, figure) # Only sets up axes
|
||||||
#self.setup_axes(figure)
|
|
||||||
|
if not self.options["plot"]:
|
||||||
|
return
|
||||||
|
|
||||||
self.plot2(self.axes, tooldia=self.options["tooldia"])
|
self.plot2(self.axes, tooldia=self.options["tooldia"])
|
||||||
self.app.on_zoom_fit(None)
|
self.app.on_zoom_fit(None)
|
||||||
self.app.canvas.queue_draw()
|
self.app.canvas.queue_draw()
|
||||||
@@ -494,7 +511,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||||||
|
|
||||||
def plot(self, figure):
|
def plot(self, figure):
|
||||||
FlatCAMObj.plot(self, figure)
|
FlatCAMObj.plot(self, figure)
|
||||||
#self.setup_axes(figure)
|
|
||||||
|
if not self.options["plot"]:
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_ = iter(self.solid_geometry)
|
_ = iter(self.solid_geometry)
|
||||||
@@ -1262,6 +1281,11 @@ class App:
|
|||||||
########################################
|
########################################
|
||||||
## EVENT HANDLERS ##
|
## EVENT HANDLERS ##
|
||||||
########################################
|
########################################
|
||||||
|
def on_cb_plot_toggled(self, widget):
|
||||||
|
self.get_current().read_form()
|
||||||
|
self.get_current().plot(self.figure)
|
||||||
|
self.on_zoom_fit(None) # TODO: Does not update correctly otherwise.
|
||||||
|
|
||||||
def on_about(self, widget):
|
def on_about(self, widget):
|
||||||
"""
|
"""
|
||||||
Opens the 'About' dialog box.
|
Opens the 'About' dialog box.
|
||||||
@@ -1269,11 +1293,11 @@ class App:
|
|||||||
:param widget: Ignored.
|
:param widget: Ignored.
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
about = self.builder.get_object("aboutdialog")
|
about = self.builder.get_object("aboutdialog")
|
||||||
response = about.run()
|
response = about.run()
|
||||||
about.destroy()
|
about.destroy()
|
||||||
|
|
||||||
|
|
||||||
def on_create_mirror(self, widget):
|
def on_create_mirror(self, widget):
|
||||||
"""
|
"""
|
||||||
Creates a mirror image of a Gerber object to be used as a bottom
|
Creates a mirror image of a Gerber object to be used as a bottom
|
||||||
@@ -1322,6 +1346,7 @@ class App:
|
|||||||
:param widget: Ignored.
|
:param widget: Ignored.
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Mirror axis. Same as in on_create_mirror.
|
# Mirror axis. Same as in on_create_mirror.
|
||||||
axis = self.get_radio_value({"rb_mirror_x": "X",
|
axis = self.get_radio_value({"rb_mirror_x": "X",
|
||||||
"rb_mirror_y": "Y"})
|
"rb_mirror_y": "Y"})
|
||||||
@@ -1445,6 +1470,7 @@ class App:
|
|||||||
:param widget: Ignored.
|
:param widget: Ignored.
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.toggle_units_ignore:
|
if self.toggle_units_ignore:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1522,6 +1548,7 @@ class App:
|
|||||||
:param param: Ignored.
|
:param param: Ignored.
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def on_success(app_obj, filename):
|
def on_success(app_obj, filename):
|
||||||
app_obj.open_project(filename)
|
app_obj.open_project(filename)
|
||||||
|
|
||||||
@@ -1536,6 +1563,7 @@ class App:
|
|||||||
:param param: Ignored.
|
:param param: Ignored.
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.project_filename is None:
|
if self.project_filename is None:
|
||||||
self.on_file_saveprojectas(None)
|
self.on_file_saveprojectas(None)
|
||||||
else:
|
else:
|
||||||
@@ -1551,6 +1579,7 @@ class App:
|
|||||||
:param param: Ignored.
|
:param param: Ignored.
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def on_success(app_obj, filename):
|
def on_success(app_obj, filename):
|
||||||
assert isinstance(app_obj, App)
|
assert isinstance(app_obj, App)
|
||||||
app_obj.save_project(filename)
|
app_obj.save_project(filename)
|
||||||
@@ -1569,6 +1598,7 @@ class App:
|
|||||||
:param param: Ignore.
|
:param param: Ignore.
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def on_success(app_obj, filename):
|
def on_success(app_obj, filename):
|
||||||
assert isinstance(app_obj, App)
|
assert isinstance(app_obj, App)
|
||||||
app_obj.save_project(filename)
|
app_obj.save_project(filename)
|
||||||
@@ -2016,7 +2046,8 @@ class App:
|
|||||||
# Object initialization function for app.new_object()
|
# Object initialization function for app.new_object()
|
||||||
def job_init(job_obj, app_obj):
|
def job_init(job_obj, app_obj):
|
||||||
assert isinstance(job_obj, FlatCAMCNCjob)
|
assert isinstance(job_obj, FlatCAMCNCjob)
|
||||||
geometry = app_obj.stuff[app_obj.selected_item_name]
|
#geometry = app_obj.stuff[app_obj.selected_item_name]
|
||||||
|
geometry = app_obj.get_current()
|
||||||
assert isinstance(geometry, FlatCAMGeometry)
|
assert isinstance(geometry, FlatCAMGeometry)
|
||||||
geometry.read_form()
|
geometry.read_form()
|
||||||
|
|
||||||
@@ -2027,13 +2058,15 @@ class App:
|
|||||||
job_obj.options["tooldia"] = geometry.options["cnctooldia"]
|
job_obj.options["tooldia"] = geometry.options["cnctooldia"]
|
||||||
|
|
||||||
GLib.idle_add(lambda: app_obj.set_progress_bar(0.4, "Analyzing Geometry..."))
|
GLib.idle_add(lambda: app_obj.set_progress_bar(0.4, "Analyzing Geometry..."))
|
||||||
job_obj.generate_from_geometry(geometry)
|
# TODO: The tolerance should not be hard coded. Just for testing.
|
||||||
|
job_obj.generate_from_geometry(geometry, tolerance=0.001)
|
||||||
|
|
||||||
GLib.idle_add(lambda: app_obj.set_progress_bar(0.5, "Parsing G-Code..."))
|
GLib.idle_add(lambda: app_obj.set_progress_bar(0.5, "Parsing G-Code..."))
|
||||||
job_obj.gcode_parse()
|
job_obj.gcode_parse()
|
||||||
|
|
||||||
GLib.idle_add(lambda: app_obj.set_progress_bar(0.6, "Creating New Geometry..."))
|
# TODO: job_obj.create_geometry creates stuff that is not used.
|
||||||
job_obj.create_geometry()
|
#GLib.idle_add(lambda: app_obj.set_progress_bar(0.6, "Creating New Geometry..."))
|
||||||
|
#job_obj.create_geometry()
|
||||||
|
|
||||||
GLib.idle_add(lambda: app_obj.set_progress_bar(0.8, "Plotting..."))
|
GLib.idle_add(lambda: app_obj.set_progress_bar(0.8, "Plotting..."))
|
||||||
|
|
||||||
@@ -2119,13 +2152,16 @@ class App:
|
|||||||
# Update UI
|
# Update UI
|
||||||
self.build_list() # Update the items list
|
self.build_list() # Update the items list
|
||||||
|
|
||||||
def on_replot(self, widget):
|
def on_toolbar_replot(self, widget):
|
||||||
"""
|
"""
|
||||||
Callback for toolbar button. Re-plots all objects.
|
Callback for toolbar button. Re-plots all objects.
|
||||||
|
|
||||||
:param widget: The widget from which this was called.
|
:param widget: The widget from which this was called.
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
self.get_current().read_form()
|
||||||
|
|
||||||
self.plot_all()
|
self.plot_all()
|
||||||
|
|
||||||
def on_clear_plots(self, widget):
|
def on_clear_plots(self, widget):
|
||||||
|
|||||||
64
FlatCAM.ui
64
FlatCAM.ui
@@ -567,6 +567,7 @@ THE SOFTWARE.</property>
|
|||||||
<property name="xalign">0</property>
|
<property name="xalign">0</property>
|
||||||
<property name="active">True</property>
|
<property name="active">True</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
|
<signal name="toggled" handler="on_cb_plot_toggled" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -575,34 +576,10 @@ THE SOFTWARE.</property>
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="cb_cncjob_solid">
|
<placeholder/>
|
||||||
<property name="label" translatable="yes">Solid</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="draw_indicator">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">4</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="cb_cncjob_multicolored">
|
<placeholder/>
|
||||||
<property name="label" translatable="yes">Multi-colored</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="draw_indicator">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">5</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="box9">
|
<object class="GtkBox" id="box9">
|
||||||
@@ -874,6 +851,7 @@ THE SOFTWARE.</property>
|
|||||||
<property name="xalign">0</property>
|
<property name="xalign">0</property>
|
||||||
<property name="active">True</property>
|
<property name="active">True</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
|
<signal name="toggled" handler="on_cb_plot_toggled" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -1301,6 +1279,7 @@ THE SOFTWARE.</property>
|
|||||||
<property name="xalign">0</property>
|
<property name="xalign">0</property>
|
||||||
<property name="active">True</property>
|
<property name="active">True</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
|
<signal name="toggled" handler="on_cb_plot_toggled" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -1836,6 +1815,7 @@ THE SOFTWARE.</property>
|
|||||||
<property name="xalign">0</property>
|
<property name="xalign">0</property>
|
||||||
<property name="active">True</property>
|
<property name="active">True</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
|
<signal name="toggled" handler="on_cb_plot_toggled" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -2813,7 +2793,7 @@ to application defaults.</property>
|
|||||||
<property name="label" translatable="yes">Re-plot</property>
|
<property name="label" translatable="yes">Re-plot</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="stock_id">gtk-redo</property>
|
<property name="stock_id">gtk-redo</property>
|
||||||
<signal name="clicked" handler="on_replot" swapped="no"/>
|
<signal name="clicked" handler="on_toolbar_replot" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -4078,36 +4058,10 @@ to application defaults.</property>
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="cb_app_cncjob_solid">
|
<placeholder/>
|
||||||
<property name="label" translatable="yes">Solid</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="draw_indicator">True</property>
|
|
||||||
<signal name="toggled" handler="on_options_update" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">37</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="cb_app_cncjob_multicolored">
|
<placeholder/>
|
||||||
<property name="label" translatable="yes">Multi-colored</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="draw_indicator">True</property>
|
|
||||||
<signal name="toggled" handler="on_options_update" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">38</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="box17">
|
<object class="GtkBox" id="box17">
|
||||||
|
|||||||
93
camlib.py
93
camlib.py
@@ -925,11 +925,13 @@ class CNCjob(Geometry):
|
|||||||
"""
|
"""
|
||||||
Creates gcode for this object from an Excellon object
|
Creates gcode for this object from an Excellon object
|
||||||
for the specified tools.
|
for the specified tools.
|
||||||
@param exobj: Excellon object to process
|
|
||||||
@type exobj: Excellon
|
:param exobj: Excellon object to process
|
||||||
@param tools: Comma separated tool names
|
:type exobj: Excellon
|
||||||
@type: tools: str
|
:param tools: Comma separated tool names
|
||||||
@return: None
|
:type: tools: str
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
print "Creating CNC Job from Excellon..."
|
print "Creating CNC Job from Excellon..."
|
||||||
if tools == "all":
|
if tools == "all":
|
||||||
@@ -970,9 +972,21 @@ class CNCjob(Geometry):
|
|||||||
|
|
||||||
self.gcode = gcode
|
self.gcode = gcode
|
||||||
|
|
||||||
def generate_from_geometry(self, geometry, append=True, tooldia=None):
|
def generate_from_geometry(self, geometry, append=True, tooldia=None, tolerance=0):
|
||||||
"""
|
"""
|
||||||
Generates G-Code from a Geometry object.
|
Generates G-Code from a Geometry object. Stores in ``self.gcode``.
|
||||||
|
|
||||||
|
:param geometry: Geometry defining the toolpath
|
||||||
|
:type geometry: Geometry
|
||||||
|
:param append: Wether to append to self.gcode or re-write it.
|
||||||
|
:type append: bool
|
||||||
|
:param tooldia: If given, sets the tooldia property but does
|
||||||
|
not affect the process in any other way.
|
||||||
|
:type tooldia: bool
|
||||||
|
:param tolerance: All points in the simplified object will be within the
|
||||||
|
tolerance distance of the original geometry.
|
||||||
|
:return: None
|
||||||
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
if tooldia is not None:
|
if tooldia is not None:
|
||||||
self.tooldia = tooldia
|
self.tooldia = tooldia
|
||||||
@@ -993,11 +1007,11 @@ class CNCjob(Geometry):
|
|||||||
for geo in geometry.solid_geometry:
|
for geo in geometry.solid_geometry:
|
||||||
|
|
||||||
if type(geo) == Polygon:
|
if type(geo) == Polygon:
|
||||||
self.gcode += self.polygon2gcode(geo)
|
self.gcode += self.polygon2gcode(geo, tolerance=tolerance)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if type(geo) == LineString or type(geo) == LinearRing:
|
if type(geo) == LineString or type(geo) == LinearRing:
|
||||||
self.gcode += self.linear2gcode(geo)
|
self.gcode += self.linear2gcode(geo, tolerance=tolerance)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if type(geo) == Point:
|
if type(geo) == Point:
|
||||||
@@ -1006,7 +1020,7 @@ class CNCjob(Geometry):
|
|||||||
|
|
||||||
if type(geo) == MultiPolygon:
|
if type(geo) == MultiPolygon:
|
||||||
for poly in geo:
|
for poly in geo:
|
||||||
self.gcode += self.polygon2gcode(poly)
|
self.gcode += self.polygon2gcode(poly, tolerance=tolerance)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
print "WARNING: G-code generation not implemented for %s" % (str(type(geo)))
|
print "WARNING: G-code generation not implemented for %s" % (str(type(geo)))
|
||||||
@@ -1017,7 +1031,10 @@ class CNCjob(Geometry):
|
|||||||
|
|
||||||
def pre_parse(self, gtext):
|
def pre_parse(self, gtext):
|
||||||
"""
|
"""
|
||||||
gtext is a single string with g-code
|
Separates parts of the G-Code text into a list of dictionaries.
|
||||||
|
Used by ``self.gcode_parse()``.
|
||||||
|
|
||||||
|
:param gtext: A single string with g-code
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Units: G20-inches, G21-mm
|
# Units: G20-inches, G21-mm
|
||||||
@@ -1177,9 +1194,18 @@ class CNCjob(Geometry):
|
|||||||
|
|
||||||
def plot2(self, axes, tooldia=None, dpi=75, margin=0.1,
|
def plot2(self, axes, tooldia=None, dpi=75, margin=0.1,
|
||||||
color={"T": ["#F0E24D", "#B5AB3A"], "C": ["#5E6CFF", "#4650BD"]},
|
color={"T": ["#F0E24D", "#B5AB3A"], "C": ["#5E6CFF", "#4650BD"]},
|
||||||
alpha={"T": 0.3, "C": 1.0}):
|
alpha={"T": 0.3, "C": 1.0}, tool_tolerance=0.001):
|
||||||
"""
|
"""
|
||||||
Plots the G-code job onto the given axes.
|
Plots the G-code job onto the given axes.
|
||||||
|
|
||||||
|
:param axes: Matplotlib axes on which to plot.
|
||||||
|
:param tooldia: Tool diameter.
|
||||||
|
:param dpi: Not used!
|
||||||
|
:param margin: Not used!
|
||||||
|
:param color: Color specification.
|
||||||
|
:param alpha: Transparency specification.
|
||||||
|
:param tool_tolerance: Tolerance when drawing the toolshape.
|
||||||
|
:return: None
|
||||||
"""
|
"""
|
||||||
if tooldia is None:
|
if tooldia is None:
|
||||||
tooldia = self.tooldia
|
tooldia = self.tooldia
|
||||||
@@ -1194,32 +1220,44 @@ class CNCjob(Geometry):
|
|||||||
axes.plot(x, y, linespec, color=linecolor)
|
axes.plot(x, y, linespec, color=linecolor)
|
||||||
else:
|
else:
|
||||||
for geo in self.gcode_parsed:
|
for geo in self.gcode_parsed:
|
||||||
poly = geo['geom'].buffer(tooldia/2.0)
|
poly = geo['geom'].buffer(tooldia/2.0).simplify(tool_tolerance)
|
||||||
patch = PolygonPatch(poly, facecolor=color[geo['kind'][0]][0],
|
patch = PolygonPatch(poly, facecolor=color[geo['kind'][0]][0],
|
||||||
edgecolor=color[geo['kind'][0]][1],
|
edgecolor=color[geo['kind'][0]][1],
|
||||||
alpha=alpha[geo['kind'][0]], zorder=2)
|
alpha=alpha[geo['kind'][0]], zorder=2)
|
||||||
axes.add_patch(patch)
|
axes.add_patch(patch)
|
||||||
|
|
||||||
def create_geometry(self):
|
def create_geometry(self):
|
||||||
|
# TODO: This takes forever. Too much data?
|
||||||
self.solid_geometry = cascaded_union([geo['geom'] for geo in self.gcode_parsed])
|
self.solid_geometry = cascaded_union([geo['geom'] for geo in self.gcode_parsed])
|
||||||
|
|
||||||
def polygon2gcode(self, polygon):
|
def polygon2gcode(self, polygon, tolerance=0):
|
||||||
"""
|
"""
|
||||||
Creates G-Code for the exterior and all interior paths
|
Creates G-Code for the exterior and all interior paths
|
||||||
of a polygon.
|
of a polygon.
|
||||||
|
|
||||||
:param polygon: A Shapely.Polygon
|
:param polygon: A Shapely.Polygon
|
||||||
:type polygon: Shapely.Polygon
|
:type polygon: Shapely.Polygon
|
||||||
|
:param tolerance: All points in the simplified object will be within the
|
||||||
|
tolerance distance of the original geometry.
|
||||||
|
:type tolerance: float
|
||||||
|
:return: G-code to cut along polygon.
|
||||||
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if tolerance > 0:
|
||||||
|
target_polygon = polygon.simplify(tolerance)
|
||||||
|
else:
|
||||||
|
target_polygon = polygon
|
||||||
|
|
||||||
gcode = ""
|
gcode = ""
|
||||||
t = "G0%d X%.4fY%.4f\n"
|
t = "G0%d X%.4fY%.4f\n"
|
||||||
path = list(polygon.exterior.coords) # Polygon exterior
|
path = list(target_polygon.exterior.coords) # Polygon exterior
|
||||||
gcode += t % (0, path[0][0], path[0][1]) # Move to first point
|
gcode += t % (0, path[0][0], path[0][1]) # Move to first point
|
||||||
gcode += "G01 Z%.4f\n" % self.z_cut # Start cutting
|
gcode += "G01 Z%.4f\n" % self.z_cut # Start cutting
|
||||||
for pt in path[1:]:
|
for pt in path[1:]:
|
||||||
gcode += t % (1, pt[0], pt[1]) # Linear motion to point
|
gcode += t % (1, pt[0], pt[1]) # Linear motion to point
|
||||||
gcode += "G00 Z%.4f\n" % self.z_move # Stop cutting
|
gcode += "G00 Z%.4f\n" % self.z_move # Stop cutting
|
||||||
for ints in polygon.interiors: # Polygon interiors
|
for ints in target_polygon.interiors: # Polygon interiors
|
||||||
path = list(ints.coords)
|
path = list(ints.coords)
|
||||||
gcode += t % (0, path[0][0], path[0][1]) # Move to first point
|
gcode += t % (0, path[0][0], path[0][1]) # Move to first point
|
||||||
gcode += "G01 Z%.4f\n" % self.z_cut # Start cutting
|
gcode += "G01 Z%.4f\n" % self.z_cut # Start cutting
|
||||||
@@ -1228,11 +1266,28 @@ class CNCjob(Geometry):
|
|||||||
gcode += "G00 Z%.4f\n" % self.z_move # Stop cutting
|
gcode += "G00 Z%.4f\n" % self.z_move # Stop cutting
|
||||||
return gcode
|
return gcode
|
||||||
|
|
||||||
def linear2gcode(self, linear):
|
def linear2gcode(self, linear, tolerance=0):
|
||||||
|
"""
|
||||||
|
Generates G-code to cut along the linear feature.
|
||||||
|
|
||||||
|
:param linear: The path to cut along.
|
||||||
|
:type: Shapely.LinearRing or Shapely.Linear String
|
||||||
|
:param tolerance: All points in the simplified object will be within the
|
||||||
|
tolerance distance of the original geometry.
|
||||||
|
:type tolerance: float
|
||||||
|
:return: G-code to cut alon the linear feature.
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
|
||||||
|
if tolerance > 0:
|
||||||
|
target_linear = linear.simplify(tolerance)
|
||||||
|
else:
|
||||||
|
target_linear = linear
|
||||||
|
|
||||||
gcode = ""
|
gcode = ""
|
||||||
t = "G0%d X%.4fY%.4f\n"
|
t = "G0%d X%.4fY%.4f\n"
|
||||||
path = list(linear.coords)
|
path = list(target_linear.coords)
|
||||||
gcode += t%(0, path[0][0], path[0][1]) # Move to first point
|
gcode += t % (0, path[0][0], path[0][1]) # Move to first point
|
||||||
gcode += "G01 Z%.4f\n" % self.z_cut # Start cutting
|
gcode += "G01 Z%.4f\n" % self.z_cut # Start cutting
|
||||||
for pt in path[1:]:
|
for pt in path[1:]:
|
||||||
gcode += t % (1, pt[0], pt[1]) # Linear motion to point
|
gcode += t % (1, pt[0], pt[1]) # Linear motion to point
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"cncjob_multicolored": false, "geometry_paintoverlap": 0.15, "geometry_plot": true, "cncjob_solid": false, "gerber_isotooldia": 0.016, "gerber_plot": true, "gerber_mergepolys": true, "gerber_cutoutgapsize": 0.15, "geometry_feedrate": 5.0, "units": "IN", "excellon_travelz": 0.1, "gerber_multicolored": false, "gerber_solid": false, "excellon_plot": true, "excellon_feedrate": 5.0, "cncjob_tooldia": 0.016, "geometry_travelz": 0.1, "gerber_cutoutmargin": 0.2, "excellon_solid": false, "geometry_paintmargin": 0.01, "geometry_cutz": -0.002, "gerber_noncoppermargin": 0.0, "gerber_gaps": "4", "excellon_multicolored": false, "geometry_painttooldia": 0.0625, "cncjob_plot": true, "excellon_drillz": -0.1, "gerber_bboxrounded": false, "geometry_multicolored": false, "geometry_cnctooldia": 0.016, "geometry_solid": false, "gerber_bboxmargin": 0.0}
|
{"geometry_paintoverlap": 0.15, "geometry_plot": true, "excellon_feedrate": 5.0, "gerber_plot": true, "gerber_mergepolys": true, "excellon_drillz": -0.1, "geometry_feedrate": 5.0, "units": "IN", "excellon_travelz": 0.1, "gerber_multicolored": false, "gerber_solid": true, "excellon_plot": true, "gerber_isotooldia": 0.016, "gerber_bboxmargin": 0.0, "cncjob_tooldia": 0.016, "geometry_travelz": 0.1, "gerber_cutoutmargin": 0.2, "excellon_solid": false, "geometry_paintmargin": 0.01, "geometry_cutz": -0.002, "geometry_cnctooldia": 0.016, "gerber_gaps": "4", "excellon_multicolored": false, "geometry_painttooldia": 0.0625, "cncjob_plot": true, "gerber_cutoutgapsize": 0.15, "gerber_bboxrounded": false, "geometry_multicolored": false, "gerber_noncoppermargin": 0.0, "geometry_solid": false}
|
||||||
Reference in New Issue
Block a user