- fixed the Follow plugin not marking correctly the resulting Geometry objet as a multigeo
- fixed the Cutout plugin not working with Geometry objects that are made out of a MultiLineString
This commit is contained in:
committed by
Marius Stanciu
parent
6cdb276a08
commit
ff805880e1
@@ -10,6 +10,8 @@ CHANGELOG for FlatCAM beta
|
|||||||
25.01.2022
|
25.01.2022
|
||||||
|
|
||||||
- minor changes
|
- minor changes
|
||||||
|
- fixed the Follow plugin not marking correctly the resulting Geometry objet as a `multigeo`
|
||||||
|
- fixed the Cutout plugin not working with Geometry objects that are made out of a MultiLineString
|
||||||
|
|
||||||
24.01.2022
|
24.01.2022
|
||||||
|
|
||||||
|
|||||||
@@ -375,9 +375,9 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
|||||||
# set Excellon path optimizations algorithm to TSA if the app is run on a 32bit platform
|
# set Excellon path optimizations algorithm to TSA if the app is run on a 32bit platform
|
||||||
# modes 'M' or 'B' are not allowed when the app is running in 32bit platform
|
# modes 'M' or 'B' are not allowed when the app is running in 32bit platform
|
||||||
if val in ['M', 'B']:
|
if val in ['M', 'B']:
|
||||||
self.opt_algorithm_radio.blockSignals(True)
|
self.excellon_optimization_radio.blockSignals(True)
|
||||||
self.excellon_optimization_radio.set_value('T')
|
self.excellon_optimization_radio.set_value('T')
|
||||||
self.opt_algorithm_radio.blockSignals(False)
|
self.excellon_optimization_radio.blockSignals(False)
|
||||||
|
|
||||||
if val == 'M':
|
if val == 'M':
|
||||||
self.optimization_time_label.setDisabled(False)
|
self.optimization_time_label.setDisabled(False)
|
||||||
|
|||||||
@@ -649,14 +649,14 @@ class CutOut(AppTool):
|
|||||||
self.on_freeform_cutout()
|
self.on_freeform_cutout()
|
||||||
|
|
||||||
def on_freeform_cutout(self):
|
def on_freeform_cutout(self):
|
||||||
|
self.app.log.debug("CutOut.on_freeform_cutout() is running....")
|
||||||
name = self.ui.obj_combo.currentText()
|
name = self.ui.obj_combo.currentText()
|
||||||
|
|
||||||
# Get source object.
|
# Get source object.
|
||||||
try:
|
try:
|
||||||
cutout_obj = self.app.collection.get_by_name(str(name))
|
cutout_obj = self.app.collection.get_by_name(str(name))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error("CutOut.on_freeform_cutout() --> %s" % str(e))
|
self.app.log.error("CutOut.on_freeform_cutout() --> %s" % str(e))
|
||||||
self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), name))
|
self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), name))
|
||||||
return "Could not retrieve object: %s" % name
|
return "Could not retrieve object: %s" % name
|
||||||
|
|
||||||
@@ -789,7 +789,11 @@ class CutOut(AppTool):
|
|||||||
|
|
||||||
with self.app.proc_container.new("Generating Cutout ..."):
|
with self.app.proc_container.new("Generating Cutout ..."):
|
||||||
formatted_name = cutout_obj.options["name"].rpartition('.')[0]
|
formatted_name = cutout_obj.options["name"].rpartition('.')[0]
|
||||||
|
if formatted_name != '':
|
||||||
outname = "%s_cutout" % formatted_name
|
outname = "%s_cutout" % formatted_name
|
||||||
|
else:
|
||||||
|
outname = "%s_cutout" % cutout_obj.options["name"]
|
||||||
|
|
||||||
self.app.collection.promise(outname)
|
self.app.collection.promise(outname)
|
||||||
|
|
||||||
has_mouse_bites = True if self.ui.gaptype_combo.get_value() == 2 else False # "mouse bytes"
|
has_mouse_bites = True if self.ui.gaptype_combo.get_value() == 2 else False # "mouse bytes"
|
||||||
@@ -823,7 +827,7 @@ class CutOut(AppTool):
|
|||||||
else:
|
else:
|
||||||
object_geo = cutout_obj.solid_geometry
|
object_geo = cutout_obj.solid_geometry
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
log.error("CutOut.on_freeform_cutout().geo_init() --> %s" % str(err))
|
self.app.log.error("CutOut.on_freeform_cutout().geo_init() --> %s" % str(err))
|
||||||
object_geo = cutout_obj.solid_geometry
|
object_geo = cutout_obj.solid_geometry
|
||||||
else:
|
else:
|
||||||
if cutout_obj.multigeo is False:
|
if cutout_obj.multigeo is False:
|
||||||
@@ -848,13 +852,14 @@ class CutOut(AppTool):
|
|||||||
geo_buf = object_geo.buffer(- margin + abs(cut_dia / 2))
|
geo_buf = object_geo.buffer(- margin + abs(cut_dia / 2))
|
||||||
geo = unary_union(geo_buf.interiors)
|
geo = unary_union(geo_buf.interiors)
|
||||||
else:
|
else:
|
||||||
if isinstance(object_geo, MultiPolygon):
|
if isinstance(object_geo, (MultiPolygon, MultiLineString)):
|
||||||
x0, y0, x1, y1 = object_geo.bounds
|
x0, y0, x1, y1 = object_geo.bounds
|
||||||
object_geo = box(x0, y0, x1, y1)
|
object_geo = box(x0, y0, x1, y1)
|
||||||
geo_buf = object_geo.buffer(0)
|
geo_buf = object_geo.buffer(0)
|
||||||
geo = geo_buf.exterior
|
geo = geo_buf.exterior
|
||||||
|
|
||||||
if geo.is_empty:
|
if geo.is_empty:
|
||||||
|
self.app.log.debug("Cutout.on_freeform_cutout() -> Empty geometry.")
|
||||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
||||||
return 'fail'
|
return 'fail'
|
||||||
|
|
||||||
@@ -877,6 +882,7 @@ class CutOut(AppTool):
|
|||||||
gaps_solid_geo += r_geo
|
gaps_solid_geo += r_geo
|
||||||
|
|
||||||
if not solid_geo:
|
if not solid_geo:
|
||||||
|
self.app.log.debug("Cutout.on_freeform_cutout() -> Empty solid geometry.")
|
||||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
||||||
return "fail"
|
return "fail"
|
||||||
|
|
||||||
@@ -984,6 +990,7 @@ class CutOut(AppTool):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exc_obj.multigeo = True
|
||||||
exc_obj.tools = tools
|
exc_obj.tools = tools
|
||||||
exc_obj.create_geometry()
|
exc_obj.create_geometry()
|
||||||
exc_obj.source_file = app_o.f_handlers.export_excellon(obj_name=exc_obj.options['name'],
|
exc_obj.source_file = app_o.f_handlers.export_excellon(obj_name=exc_obj.options['name'],
|
||||||
@@ -1004,6 +1011,7 @@ class CutOut(AppTool):
|
|||||||
|
|
||||||
ret = app_obj.app_obj.new_object('geometry', outname, geo_init, autoselected=False)
|
ret = app_obj.app_obj.new_object('geometry', outname, geo_init, autoselected=False)
|
||||||
if ret == 'fail':
|
if ret == 'fail':
|
||||||
|
self.app.log.debug("Cutout.on_freeform_cutout() -> Failure in creating an Geometry object..")
|
||||||
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1017,6 +1025,7 @@ class CutOut(AppTool):
|
|||||||
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
|
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
|
||||||
|
|
||||||
def on_rectangular_cutout(self):
|
def on_rectangular_cutout(self):
|
||||||
|
self.app.log.debug("CutOut.on_rectangular_cutout() is running....")
|
||||||
name = self.ui.obj_combo.currentText()
|
name = self.ui.obj_combo.currentText()
|
||||||
|
|
||||||
# Get source object.
|
# Get source object.
|
||||||
@@ -1153,6 +1162,7 @@ class CutOut(AppTool):
|
|||||||
return "fail"
|
return "fail"
|
||||||
|
|
||||||
if not solid_geo:
|
if not solid_geo:
|
||||||
|
self.app.log.debug("Cutout.on_rectangular_cutout() -> Empty solid geometry.")
|
||||||
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
||||||
return "fail"
|
return "fail"
|
||||||
|
|
||||||
@@ -1297,6 +1307,7 @@ class CutOut(AppTool):
|
|||||||
|
|
||||||
ret = app_obj.app_obj.new_object('geometry', outname, geo_init, autoselected=False)
|
ret = app_obj.app_obj.new_object('geometry', outname, geo_init, autoselected=False)
|
||||||
if ret == 'fail':
|
if ret == 'fail':
|
||||||
|
self.app.log.debug("Cutout.on_rectangular_cutout() -> Could not create a Geometry object.")
|
||||||
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -318,6 +318,8 @@ class ToolFollow(AppTool, Gerber):
|
|||||||
self.app.log.warning("ToolFollow.follow_geo() -> Empty Follow Geometry")
|
self.app.log.warning("ToolFollow.follow_geo() -> Empty Follow Geometry")
|
||||||
return 'fail'
|
return 'fail'
|
||||||
|
|
||||||
|
new_obj.multigeo = True
|
||||||
|
|
||||||
# Propagate options
|
# Propagate options
|
||||||
new_obj.options["tools_mill_tooldia"] = app_obj.defaults["tools_mill_tooldia"]
|
new_obj.options["tools_mill_tooldia"] = app_obj.defaults["tools_mill_tooldia"]
|
||||||
new_obj.solid_geometry = follow_geo
|
new_obj.solid_geometry = follow_geo
|
||||||
@@ -383,6 +385,7 @@ class ToolFollow(AppTool, Gerber):
|
|||||||
area_follow = flatten_shapely_geometry(area_follow)
|
area_follow = flatten_shapely_geometry(area_follow)
|
||||||
cleaned_area_follow = [g for g in area_follow if not g.is_empty and g.is_valid and g.geom_type != 'Point']
|
cleaned_area_follow = [g for g in area_follow if not g.is_empty and g.is_valid and g.geom_type != 'Point']
|
||||||
|
|
||||||
|
new_obj.multigeo = True
|
||||||
new_obj.solid_geometry = deepcopy(cleaned_area_follow)
|
new_obj.solid_geometry = deepcopy(cleaned_area_follow)
|
||||||
new_obj.tools = {
|
new_obj.tools = {
|
||||||
1: {
|
1: {
|
||||||
|
|||||||
Reference in New Issue
Block a user