Paint specific polygons in Drawing tool.

This commit is contained in:
Juan Pablo Caram
2016-09-23 16:24:33 -04:00
parent 8afb0704fd
commit 7a9a84c781

View File

@@ -10,7 +10,7 @@ from PyQt4 import QtGui, QtCore, Qt
import FlatCAMApp import FlatCAMApp
from camlib import * from camlib import *
from FlatCAMTool import FlatCAMTool from FlatCAMTool import FlatCAMTool
from ObjectUI import LengthEntry from ObjectUI import LengthEntry, RadioSet
from shapely.geometry import Polygon, LineString, Point, LinearRing from shapely.geometry import Polygon, LineString, Point, LinearRing
from shapely.geometry import MultiPoint, MultiPolygon from shapely.geometry import MultiPoint, MultiPolygon
@@ -70,6 +70,94 @@ class BufferSelectionTool(FlatCAMTool):
self.fcdraw.buffer(buffer_distance) self.fcdraw.buffer(buffer_distance)
class PaintOptionsTool(FlatCAMTool):
"""
Inputs to specify how to paint the selected polygons.
"""
toolName = "Paint Options"
def __init__(self, app, fcdraw):
FlatCAMTool.__init__(self, app)
self.app = app
self.fcdraw = fcdraw
## Title
title_label = QtGui.QLabel("<font size=4><b>%s</b></font>" % self.toolName)
self.layout.addWidget(title_label)
## Form Layout
form_layout = QtGui.QFormLayout()
self.layout.addLayout(form_layout)
# Tool dia
ptdlabel = QtGui.QLabel('Tool dia:')
ptdlabel.setToolTip(
"Diameter of the tool to\n"
"be used in the operation."
)
self.painttooldia_entry = LengthEntry()
form_layout.addRow(ptdlabel, self.painttooldia_entry)
# Overlap
ovlabel = QtGui.QLabel('Overlap:')
ovlabel.setToolTip(
"How much (fraction) of the tool\n"
"width to overlap each tool pass."
)
self.paintoverlap_entry = LengthEntry()
form_layout.addRow(ovlabel, self.paintoverlap_entry)
# Margin
marginlabel = QtGui.QLabel('Margin:')
marginlabel.setToolTip(
"Distance by which to avoid\n"
"the edges of the polygon to\n"
"be painted."
)
self.paintmargin_entry = LengthEntry()
form_layout.addRow(marginlabel, self.paintmargin_entry)
# Method
methodlabel = QtGui.QLabel('Method:')
methodlabel.setToolTip(
"Algorithm to paint the polygon:<BR>"
"<B>Standard</B>: Fixed step inwards.<BR>"
"<B>Seed-based</B>: Outwards from seed."
)
self.paintmethod_combo = RadioSet([
{"label": "Standard", "value": "standard"},
{"label": "Seed-based", "value": "seed"}
])
form_layout.addRow(methodlabel, self.paintmethod_combo)
## Buttons
hlay = QtGui.QHBoxLayout()
self.layout.addLayout(hlay)
hlay.addStretch()
self.paint_button = QtGui.QPushButton("Paint")
hlay.addWidget(self.paint_button)
self.layout.addStretch()
## Signals
self.paint_button.clicked.connect(self.on_paint)
def on_paint(self):
tooldia = self.painttooldia_entry.get_value()
overlap = self.paintoverlap_entry.get_value()
margin = self.paintoverlap_entry.get_value()
method = self.paintmethod_combo.get_value()
self.fcdraw.paint(tooldia, overlap, margin, method)
class DrawToolShape(object): class DrawToolShape(object):
""" """
Encapsulates "shapes" under a common class. Encapsulates "shapes" under a common class.
@@ -657,8 +745,10 @@ class FlatCAMDraw(QtCore.QObject):
# self.copy_menuitem = self.menu.addAction(QtGui.QIcon('share/copy16.png'), "Copy Objects 'c'") # self.copy_menuitem = self.menu.addAction(QtGui.QIcon('share/copy16.png'), "Copy Objects 'c'")
self.delete_menuitem = self.menu.addAction(QtGui.QIcon('share/deleteshape16.png'), "Delete Shape '-'") self.delete_menuitem = self.menu.addAction(QtGui.QIcon('share/deleteshape16.png'), "Delete Shape '-'")
self.buffer_menuitem = self.menu.addAction(QtGui.QIcon('share/buffer16.png'), "Buffer selection 'b'") self.buffer_menuitem = self.menu.addAction(QtGui.QIcon('share/buffer16.png'), "Buffer selection 'b'")
self.paint_menuitem = self.menu.addAction(QtGui.QIcon('share/paint16.png'), "Paint selection")
self.menu.addSeparator() self.menu.addSeparator()
self.paint_menuitem.triggered.connect(self.on_paint_tool)
self.buffer_menuitem.triggered.connect(self.on_buffer_tool) self.buffer_menuitem.triggered.connect(self.on_buffer_tool)
self.delete_menuitem.triggered.connect(self.on_delete_btn) self.delete_menuitem.triggered.connect(self.on_delete_btn)
self.union_menuitem.triggered.connect(self.union) self.union_menuitem.triggered.connect(self.union)
@@ -872,6 +962,10 @@ class FlatCAMDraw(QtCore.QObject):
buff_tool = BufferSelectionTool(self.app, self) buff_tool = BufferSelectionTool(self.app, self)
buff_tool.run() buff_tool.run()
def on_paint_tool(self):
paint_tool = PaintOptionsTool(self.app, self)
paint_tool.run()
def on_tool_select(self, tool): def on_tool_select(self, tool):
""" """
Behavior of the toolbar. Tool initialization. Behavior of the toolbar. Tool initialization.
@@ -1370,6 +1464,61 @@ class FlatCAMDraw(QtCore.QObject):
self.replot() self.replot()
def paint(self, tooldia, overlap, margin, method):
selected = self.get_selected()
if len(selected) == 0:
self.app.inform.emit("[warning] Nothing selected for painting.")
return
for param in [tooldia, overlap, margin]:
if not isinstance(param, float):
param_name = [k for k, v in locals().iteritems() if v is param][0]
self.app.inform.emit("[warning] Invalid value for {}".format())
# Todo: Check for valid method.
# Todo: This is the 3rd implementation on painting polys... try to consolidate
results = []
def recurse(geo):
try:
for subg in geo:
for subsubg in recurse(subg):
yield subsubg
except TypeError:
if isinstance(geo, Polygon):
yield geo
raise StopIteration
for geo in selected:
local_results = []
for poly in recurse(geo.geo):
if method == "seed":
# Type(cp) == FlatCAMRTreeStorage | None
cp = Geometry.clear_polygon2(poly.buffer(-margin),
tooldia, overlap=overlap)
else:
# Type(cp) == FlatCAMRTreeStorage | None
cp = Geometry.clear_polygon(poly.buffer(-margin),
tooldia, overlap=overlap)
if cp is not None:
local_results += list(cp.get_objects())
results.append(cascaded_union(local_results))
# This is a dirty patch:
for r in results:
self.add_shape(DrawToolShape(r))
self.replot()
def distance(pt1, pt2): def distance(pt1, pt2):
return sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2) return sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2)