- Tool Cutout - some work in gaps thickness control for the free form cutout
This commit is contained in:
@@ -12,6 +12,7 @@ CHANGELOG for FlatCAM beta
|
|||||||
- Tool Cutout - more work in gaps thickness control feature
|
- Tool Cutout - more work in gaps thickness control feature
|
||||||
- Tool Cutout - added some icons to buttons
|
- Tool Cutout - added some icons to buttons
|
||||||
- Tool Cutout - done handling the gaps thickness control for the rectangular cutout; TODO: check all app for the usage of geometry_spindledir and geometry_optimization_type defaults in tools and in options
|
- Tool Cutout - done handling the gaps thickness control for the rectangular cutout; TODO: check all app for the usage of geometry_spindledir and geometry_optimization_type defaults in tools and in options
|
||||||
|
- Tool Cutout - some work in gaps thickness control for the free form cutout
|
||||||
|
|
||||||
4.08.2020
|
4.08.2020
|
||||||
|
|
||||||
|
|||||||
@@ -292,6 +292,7 @@ class CutOut(AppTool):
|
|||||||
|
|
||||||
def geo_init(geo_obj, app_obj):
|
def geo_init(geo_obj, app_obj):
|
||||||
solid_geo = []
|
solid_geo = []
|
||||||
|
gaps_solid_geo = None
|
||||||
|
|
||||||
if cutout_obj.kind == 'gerber':
|
if cutout_obj.kind == 'gerber':
|
||||||
if isinstance(cutout_obj.solid_geometry, list):
|
if isinstance(cutout_obj.solid_geometry, list):
|
||||||
@@ -397,7 +398,10 @@ class CutOut(AppTool):
|
|||||||
geo = geo_buf.exterior
|
geo = geo_buf.exterior
|
||||||
else:
|
else:
|
||||||
geo = object_geo
|
geo = object_geo
|
||||||
|
|
||||||
solid_geo = cutout_handler(geom=geo)
|
solid_geo = cutout_handler(geom=geo)
|
||||||
|
if self.ui.thin_cb.get_value():
|
||||||
|
gaps_solid_geo = self.subtract_geo(geo, solid_geo)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
__ = iter(object_geo)
|
__ = iter(object_geo)
|
||||||
@@ -412,7 +416,13 @@ class CutOut(AppTool):
|
|||||||
geom_struct_buff = geom_struct.buffer(-margin + abs(dia / 2))
|
geom_struct_buff = geom_struct.buffer(-margin + abs(dia / 2))
|
||||||
geom_struct = geom_struct_buff.interiors
|
geom_struct = geom_struct_buff.interiors
|
||||||
|
|
||||||
solid_geo += cutout_handler(geom=geom_struct)
|
c_geo = cutout_handler(geom=geom_struct)
|
||||||
|
solid_geo += c_geo
|
||||||
|
if self.ui.thin_cb.get_value():
|
||||||
|
try:
|
||||||
|
gaps_solid_geo += self.subtract_geo(geom_struct, c_geo)
|
||||||
|
except TypeError:
|
||||||
|
gaps_solid_geo.append(self.subtract_geo(geom_struct, c_geo))
|
||||||
|
|
||||||
if not solid_geo:
|
if not solid_geo:
|
||||||
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
||||||
@@ -438,7 +448,7 @@ class CutOut(AppTool):
|
|||||||
'offset_value': 0.0,
|
'offset_value': 0.0,
|
||||||
'type': _('Rough'),
|
'type': _('Rough'),
|
||||||
'tool_type': 'C1',
|
'tool_type': 'C1',
|
||||||
'data': self.default_data,
|
'data': deepcopy(self.default_data),
|
||||||
'solid_geometry': geo_obj.solid_geometry
|
'solid_geometry': geo_obj.solid_geometry
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -448,6 +458,23 @@ class CutOut(AppTool):
|
|||||||
geo_obj.tools[1]['data']['multidepth'] = self.ui.mpass_cb.get_value()
|
geo_obj.tools[1]['data']['multidepth'] = self.ui.mpass_cb.get_value()
|
||||||
geo_obj.tools[1]['data']['depthperpass'] = self.ui.maxdepth_entry.get_value()
|
geo_obj.tools[1]['data']['depthperpass'] = self.ui.maxdepth_entry.get_value()
|
||||||
|
|
||||||
|
if gaps_solid_geo is not None:
|
||||||
|
geo_obj.tools.update({
|
||||||
|
2: {
|
||||||
|
'tooldia': str(dia),
|
||||||
|
'offset': 'Path',
|
||||||
|
'offset_value': 0.0,
|
||||||
|
'type': _('Rough'),
|
||||||
|
'tool_type': 'C1',
|
||||||
|
'data': deepcopy(self.default_data),
|
||||||
|
'solid_geometry': gaps_solid_geo
|
||||||
|
}
|
||||||
|
})
|
||||||
|
geo_obj.tools[2]['data']['name'] = outname
|
||||||
|
geo_obj.tools[2]['data']['cutz'] = self.ui.thin_depth_entry.get_value()
|
||||||
|
geo_obj.tools[2]['data']['multidepth'] = self.ui.mpass_cb.get_value()
|
||||||
|
geo_obj.tools[2]['data']['depthperpass'] = self.ui.maxdepth_entry.get_value()
|
||||||
|
|
||||||
outname = cutout_obj.options["name"] + "_cutout"
|
outname = cutout_obj.options["name"] + "_cutout"
|
||||||
ret = self.app.app_obj.new_object('geometry', outname, geo_init)
|
ret = self.app.app_obj.new_object('geometry', outname, geo_init)
|
||||||
|
|
||||||
@@ -610,8 +637,7 @@ class CutOut(AppTool):
|
|||||||
solid_geo = cutout_rect_handler(geom=geo)
|
solid_geo = cutout_rect_handler(geom=geo)
|
||||||
|
|
||||||
if self.ui.thin_cb.get_value():
|
if self.ui.thin_cb.get_value():
|
||||||
gaps_solid_geo = self.invert_cutout(geo, solid_geo)
|
gaps_solid_geo = self.subtract_geo(geo, solid_geo)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if cutout_obj.kind == 'geometry':
|
if cutout_obj.kind == 'geometry':
|
||||||
try:
|
try:
|
||||||
@@ -624,12 +650,13 @@ class CutOut(AppTool):
|
|||||||
xmin, ymin, xmax, ymax = geom_struct.bounds
|
xmin, ymin, xmax, ymax = geom_struct.bounds
|
||||||
geom_struct = box(xmin, ymin, xmax, ymax)
|
geom_struct = box(xmin, ymin, xmax, ymax)
|
||||||
|
|
||||||
solid_geo += cutout_rect_handler(geom=geom_struct)
|
c_geo = cutout_rect_handler(geom=geom_struct)
|
||||||
|
solid_geo += c_geo
|
||||||
if self.ui.thin_cb.get_value():
|
if self.ui.thin_cb.get_value():
|
||||||
try:
|
try:
|
||||||
gaps_solid_geo += self.invert_cutout(geom_struct, solid_geo)
|
gaps_solid_geo += self.subtract_geo(geom_struct, c_geo)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
gaps_solid_geo.append(self.invert_cutout(geom_struct, solid_geo))
|
gaps_solid_geo.append(self.subtract_geo(geom_struct, c_geo))
|
||||||
elif cutout_obj.kind == 'gerber' and margin >= 0:
|
elif cutout_obj.kind == 'gerber' and margin >= 0:
|
||||||
try:
|
try:
|
||||||
__ = iter(object_geo)
|
__ = iter(object_geo)
|
||||||
@@ -643,12 +670,13 @@ class CutOut(AppTool):
|
|||||||
|
|
||||||
geom_struct = geom_struct.buffer(margin + abs(dia / 2))
|
geom_struct = geom_struct.buffer(margin + abs(dia / 2))
|
||||||
|
|
||||||
solid_geo += cutout_rect_handler(geom=geom_struct)
|
c_geo = cutout_rect_handler(geom=geom_struct)
|
||||||
|
solid_geo += c_geo
|
||||||
if self.ui.thin_cb.get_value():
|
if self.ui.thin_cb.get_value():
|
||||||
try:
|
try:
|
||||||
gaps_solid_geo += self.invert_cutout(geom_struct, solid_geo)
|
gaps_solid_geo += self.subtract_geo(geom_struct, c_geo)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
gaps_solid_geo.append(self.invert_cutout(geom_struct, solid_geo))
|
gaps_solid_geo.append(self.subtract_geo(geom_struct, c_geo))
|
||||||
elif cutout_obj.kind == 'gerber' and margin < 0:
|
elif cutout_obj.kind == 'gerber' and margin < 0:
|
||||||
app_obj.inform.emit(
|
app_obj.inform.emit(
|
||||||
'[WARNING_NOTCL] %s' % _("Rectangular cutout with negative margin is not possible."))
|
'[WARNING_NOTCL] %s' % _("Rectangular cutout with negative margin is not possible."))
|
||||||
@@ -784,7 +812,7 @@ class CutOut(AppTool):
|
|||||||
cut_poly = self.cutting_geo(pos=(snapped_pos[0], snapped_pos[1]))
|
cut_poly = self.cutting_geo(pos=(snapped_pos[0], snapped_pos[1]))
|
||||||
|
|
||||||
# first subtract geometry for the total solid_geometry
|
# first subtract geometry for the total solid_geometry
|
||||||
new_solid_geometry = CutOut.subtract_polygon(self.man_cutout_obj.solid_geometry, cut_poly)
|
new_solid_geometry = CutOut.subtract_geo(self.man_cutout_obj.solid_geometry, cut_poly)
|
||||||
new_solid_geometry = linemerge(new_solid_geometry)
|
new_solid_geometry = linemerge(new_solid_geometry)
|
||||||
self.man_cutout_obj.solid_geometry = new_solid_geometry
|
self.man_cutout_obj.solid_geometry = new_solid_geometry
|
||||||
|
|
||||||
@@ -1189,70 +1217,6 @@ class CutOut(AppTool):
|
|||||||
|
|
||||||
return unary_union(diffs)
|
return unary_union(diffs)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def invert_cutout(target_geo, subtractor_geo):
|
|
||||||
"""
|
|
||||||
|
|
||||||
:param target_geo:
|
|
||||||
:param subtractor_geo:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
flat_geometry = CutOut.flatten(geometry=target_geo)
|
|
||||||
|
|
||||||
toolgeo = cascaded_union(subtractor_geo)
|
|
||||||
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 unary_union(diffs)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def intersect_poly_with_geo(solid_geo, pts, margin):
|
|
||||||
"""
|
|
||||||
Intersections with a polygon made from points from the given object.
|
|
||||||
This only operates on the paths in the original geometry,
|
|
||||||
i.e. it converts polygons into paths.
|
|
||||||
|
|
||||||
:param solid_geo: Geometry from which to get intersections.
|
|
||||||
:param pts: a tuple of coordinates in format (x0, y0, x1, y1)
|
|
||||||
:type pts: tuple
|
|
||||||
:param margin: a distance (buffer) applied to each solid_geo
|
|
||||||
|
|
||||||
x0: x coord for lower left vertex of the polygon.
|
|
||||||
y0: y coord for lower left vertex of the polygon.
|
|
||||||
x1: x coord for upper right vertex of the polygon.
|
|
||||||
y1: y coord for upper right vertex of the polygon.
|
|
||||||
|
|
||||||
:return: none
|
|
||||||
"""
|
|
||||||
|
|
||||||
x0 = pts[0]
|
|
||||||
y0 = pts[1]
|
|
||||||
x1 = pts[2]
|
|
||||||
y1 = pts[3]
|
|
||||||
|
|
||||||
points = [(x0, y0), (x1, y0), (x1, y1), (x0, y1)]
|
|
||||||
|
|
||||||
# pathonly should be allways True, otherwise polygons are not subtracted
|
|
||||||
flat_geometry = CutOut.flatten(geometry=solid_geo)
|
|
||||||
|
|
||||||
log.debug("%d paths" % len(flat_geometry))
|
|
||||||
|
|
||||||
polygon = Polygon(points)
|
|
||||||
toolgeo = cascaded_union(polygon)
|
|
||||||
|
|
||||||
intersects = []
|
|
||||||
for target in flat_geometry:
|
|
||||||
if type(target) == LineString or type(target) == LinearRing:
|
|
||||||
intersects.append(target.intersection(toolgeo))
|
|
||||||
else:
|
|
||||||
log.warning("Not implemented.")
|
|
||||||
|
|
||||||
return unary_union(intersects)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def flatten(geometry):
|
def flatten(geometry):
|
||||||
"""
|
"""
|
||||||
@@ -1310,7 +1274,7 @@ class CutOut(AppTool):
|
|||||||
return bounds_rec(geometry)
|
return bounds_rec(geometry)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def subtract_polygon(target_geo, subtractor):
|
def subtract_geo(target_geo, subtractor):
|
||||||
"""
|
"""
|
||||||
Subtract subtractor polygon from the target_geo. This only operates on the paths in the target_geo,
|
Subtract subtractor polygon from the target_geo. This only operates on the paths in the target_geo,
|
||||||
i.e. it converts polygons into paths.
|
i.e. it converts polygons into paths.
|
||||||
|
|||||||
Reference in New Issue
Block a user