- some modifications to ToolCutout

This commit is contained in:
Marius Stanciu 2019-05-13 01:57:37 +03:00
parent c9a09b00c0
commit 01c0f901ff
3 changed files with 105 additions and 7 deletions

View File

@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing.
=================================================
12.05.2019
- some modifications to ToolCutout
11.05.2019
- fixed issue in camlib.CNCjob.generate_from_excellon_by_tool() in the drill path optimization algorithm selection when selecting the MH algorithm. The new API's for Google OR-tools required some changes and also the time parameter can be now just an integer therefore I modified the GUI

View File

@ -204,7 +204,8 @@ class Geometry(object):
def subtract_polygon(self, points):
"""
Subtract polygon from the given object. This only operates on the paths in the original geometry, i.e. it converts polygons into paths.
Subtract polygon from the given object. This only operates on the paths in the original geometry,
i.e. it converts polygons into paths.
:param points: The vertices of the polygon.
:return: none

View File

@ -274,6 +274,8 @@ class CutOut(FlatCAMTool):
# true if we want to repeat the gap without clicking again on the button
self.repeat_gap = False
self.flat_geometry = []
## Signals
self.ff_cutout_object_btn.clicked.connect(self.on_freeform_cutout)
self.rect_cutout_object_btn.clicked.connect(self.on_rectangular_cutout)
@ -418,7 +420,15 @@ class CutOut(FlatCAMTool):
geo_obj.solid_geometry = geo.buffer(margin + abs(dia / 2))
else:
geo = cutout_obj.solid_geometry
geo_obj.solid_geometry = geo.buffer(margin + abs(dia / 2)).exterior
geo = geo.buffer(margin + abs(dia / 2))
if isinstance(geo, Polygon):
geo_obj.solid_geometry = deepcopy(geo.exterior)
elif isinstance(geo, MultiPolygon):
solid_geo = []
for poly in geo:
solid_geo.append(poly.exterior)
geo_obj.solid_geometry = deepcopy(solid_geo)
outname = cutout_obj.options["name"] + "_cutout"
self.app.new_object('geometry', outname, geo_init)
@ -541,18 +551,30 @@ class CutOut(FlatCAMTool):
return
# Get min and max data for each object as we just cut rectangles across X or Y
xmin, ymin, xmax, ymax = cutout_obj.bounds()
geo = box(xmin, ymin, xmax, ymax)
if isinstance(cutout_obj.solid_geometry, Polygon):
xmin, ymin, xmax, ymax = cutout_obj.bounds()
geo = box(xmin, ymin, xmax, ymax)
elif isinstance(cutout_obj.solid_geometry, MultiPolygon):
geo = []
for poly in cutout_obj.solid_geometry:
xmin, ymin, xmax, ymax = poly.bounds
poly_geo = box(xmin, ymin, xmax, ymax)
geo.append(poly_geo)
px = 0.5 * (xmin + xmax) + margin
py = 0.5 * (ymin + ymax) + margin
lenghtx = (xmax - xmin) + (margin * 2)
lenghty = (ymax - ymin) + (margin * 2)
gapsize = gapsize / 2 + (dia / 2)
def geo_init(geo_obj, app_obj):
geo_obj.solid_geometry = geo.buffer(margin + abs(dia / 2))
if isinstance(geo, list):
solid_geo = []
for subgeo in geo:
solid_geo.append(subgeo.buffer(margin + abs(dia / 2)))
geo_obj.solid_geometry = deepcopy(solid_geo)
else:
geo_obj.solid_geometry = geo.buffer(margin + abs(dia / 2))
outname = cutout_obj.options["name"] + "_cutout"
self.app.new_object('geometry', outname, geo_init)
@ -745,7 +767,14 @@ class CutOut(FlatCAMTool):
geo_obj.solid_geometry = geo.buffer(margin + abs(dia / 2))
else:
geo = cutout_obj.solid_geometry
geo_obj.solid_geometry = geo.buffer(margin + abs(dia / 2)).exterior
geo = geo.buffer(margin + abs(dia / 2))
if isinstance(geo, Polygon):
geo_obj.solid_geometry = geo.exterior
elif isinstance(geo, MultiPolygon):
solid_geo = []
for poly in geo:
solid_geo.append(poly.exterior)
geo_obj.solid_geometry = deepcopy(solid_geo)
outname = cutout_obj.options["name"] + "_cutout"
self.app.new_object('geometry', outname, geo_init)
@ -819,5 +848,69 @@ class CutOut(FlatCAMTool):
self.app.geo_editor.tool_shape.clear(update=True)
self.app.geo_editor.tool_shape.enabled = False
def flatten(self, geometry=None, reset=True, pathonly=False):
"""
Creates a list of non-iterable linear geometry objects.
Polygons are expanded into its exterior and interiors if specified.
Results are placed in self.flat_geometry
:param geometry: Shapely type or list or list of list of such.
:param reset: Clears the contents of self.flat_geometry.
:param pathonly: Expands polygons into linear elements.
"""
if geometry is None:
geometry = self.solid_geometry
if reset:
self.flat_geometry = []
## If iterable, expand recursively.
try:
for geo in geometry:
if geo is not None:
self.flatten(geometry=geo,
reset=False,
pathonly=pathonly)
## Not iterable, do the actual indexing and add.
except TypeError:
if pathonly and type(geometry) == Polygon:
self.flat_geometry.append(geometry.exterior)
self.flatten(geometry=geometry.interiors,
reset=False,
pathonly=True)
else:
self.flat_geometry.append(geometry)
return self.flat_geometry
def subtract_poly_from_geo(self, solid_geo, points):
"""
Subtract polygon from the given object. This only operates on the paths in the original geometry,
i.e. it converts polygons into paths.
:param points: The vertices of the polygon.
:param geo: Geometry from which to substract. If none, use the solid_geomety property of the object
:return: none
"""
# pathonly should be allways True, otherwise polygons are not subtracted
flat_geometry = self.flatten(geometry=solid_geo, pathonly=True)
log.debug("%d paths" % len(flat_geometry))
polygon = Polygon(points)
toolgeo = cascaded_union(polygon)
diffs = []
for target in flat_geometry:
if type(target) == LineString or type(target) == LinearRing:
diffs.append(target.difference(toolgeo))
else:
log.warning("Not implemented.")
return cascaded_union(diffs)
def reset_fields(self):
self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))