- fixed a bug in rotate from shortcut function
- finished generating the solder paste dispense geometry
This commit is contained in:
@@ -4076,7 +4076,7 @@ class App(QtCore.QObject):
|
|||||||
py = 0.5 * (yminimal + ymaximal)
|
py = 0.5 * (yminimal + ymaximal)
|
||||||
|
|
||||||
for sel_obj in obj_list:
|
for sel_obj in obj_list:
|
||||||
sel_obj.rotate(-num, point=(px, py))
|
sel_obj.rotate(-float(num), point=(px, py))
|
||||||
sel_obj.plot()
|
sel_obj.plot()
|
||||||
self.object_changed.emit(sel_obj)
|
self.object_changed.emit(sel_obj)
|
||||||
self.inform.emit("[success] Rotation done.")
|
self.inform.emit("[success] Rotation done.")
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ CAD program, and create G-Code for Isolation routing.
|
|||||||
- added a new parameter for the Tcl CommandIsolate, named: 'follow'. When follow = 1 (True) the resulting geometry will follow the Gerber paths.
|
- added a new parameter for the Tcl CommandIsolate, named: 'follow'. When follow = 1 (True) the resulting geometry will follow the Gerber paths.
|
||||||
- added a new setting in Edit -> Preferences -> General that allow to select the type of saving for the FlatCAM project: either compressed or uncompressed. Compression introduce an time overhead to the saving/restoring of a FlatCAM project.
|
- added a new setting in Edit -> Preferences -> General that allow to select the type of saving for the FlatCAM project: either compressed or uncompressed. Compression introduce an time overhead to the saving/restoring of a FlatCAM project.
|
||||||
- started to work on Solder Paste Dispensing Tool
|
- started to work on Solder Paste Dispensing Tool
|
||||||
|
- fixed a bug in rotate from shortcut function
|
||||||
|
- finished generating the solder paste dispense geometry
|
||||||
|
|
||||||
18.02.2019
|
18.02.2019
|
||||||
|
|
||||||
|
|||||||
@@ -2392,8 +2392,6 @@ class Gerber (Geometry):
|
|||||||
log.debug("Bare op-code %d." % current_operation_code)
|
log.debug("Bare op-code %d." % current_operation_code)
|
||||||
# flash = Gerber.create_flash_geometry(Point(path[-1]),
|
# flash = Gerber.create_flash_geometry(Point(path[-1]),
|
||||||
# self.apertures[current_aperture])
|
# self.apertures[current_aperture])
|
||||||
if follow:
|
|
||||||
continue
|
|
||||||
flash = Gerber.create_flash_geometry(
|
flash = Gerber.create_flash_geometry(
|
||||||
Point(current_x, current_y), self.apertures[current_aperture],
|
Point(current_x, current_y), self.apertures[current_aperture],
|
||||||
int(self.steps_per_circle))
|
int(self.steps_per_circle))
|
||||||
|
|||||||
@@ -63,16 +63,15 @@ class ToolSolderPaste(FlatCAMTool):
|
|||||||
form_layout.addRow(self.object_label, self.obj_combo)
|
form_layout.addRow(self.object_label, self.obj_combo)
|
||||||
|
|
||||||
# Offset distance
|
# Offset distance
|
||||||
self.offset_entry = FloatEntry()
|
self.nozzle_dia_entry = FloatEntry()
|
||||||
self.offset_entry.setValidator(QtGui.QDoubleValidator(-99.9999, 0.0000, 4))
|
self.nozzle_dia_entry.setValidator(QtGui.QDoubleValidator(0.0000, 9.9999, 4))
|
||||||
self.offset_label = QtWidgets.QLabel(" Solder Offset:")
|
self.nozzle_dia_label = QtWidgets.QLabel("Nozzle Diameter:")
|
||||||
self.offset_label.setToolTip(
|
self.nozzle_dia_label.setToolTip(
|
||||||
"The offset for the solder paste.\n"
|
"The offset for the solder paste.\n"
|
||||||
"Due of the diameter of the solder paste dispenser\n"
|
"Due of the diameter of the solder paste dispenser\n"
|
||||||
"we need to adjust the quantity of solder paste\n"
|
"we need to adjust the quantity of solder paste."
|
||||||
"so it will not overflow over the pad."
|
|
||||||
)
|
)
|
||||||
form_layout.addRow(self.offset_label, self.offset_entry)
|
form_layout.addRow(self.nozzle_dia_label, self.nozzle_dia_entry)
|
||||||
|
|
||||||
# Z dispense start
|
# Z dispense start
|
||||||
self.z_start_entry = FCEntry()
|
self.z_start_entry = FCEntry()
|
||||||
@@ -248,14 +247,104 @@ class ToolSolderPaste(FlatCAMTool):
|
|||||||
self.reset_fields()
|
self.reset_fields()
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def distance(pt1, pt2):
|
||||||
|
return sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2)
|
||||||
|
|
||||||
def on_create_geo(self):
|
def on_create_geo(self):
|
||||||
|
proc = self.app.proc_container.new("Creating Solder Paste dispensing geometry.")
|
||||||
|
|
||||||
name = self.obj_combo.currentText()
|
name = self.obj_combo.currentText()
|
||||||
|
obj = self.app.collection.get_by_name(name)
|
||||||
|
|
||||||
|
if type(obj.solid_geometry) is not list:
|
||||||
|
obj.solid_geometry = [obj.solid_geometry]
|
||||||
|
|
||||||
|
try:
|
||||||
|
offset = self.nozzle_dia_entry.get_value() / 2
|
||||||
|
except Exception as e:
|
||||||
|
log.debug("ToolSoderPaste.on_create_geo() --> %s" % str(e))
|
||||||
|
self.app.inform.emit("[ERROR_NOTCL] Failed. Offset value is missing ...")
|
||||||
|
return
|
||||||
|
|
||||||
|
if offset is None:
|
||||||
|
self.app.inform.emit("[ERROR_NOTCL] Failed. Offset value is missing ...")
|
||||||
|
return
|
||||||
|
|
||||||
def geo_init(geo_obj, app_obj):
|
def geo_init(geo_obj, app_obj):
|
||||||
pass
|
geo_obj.solid_geometry = []
|
||||||
|
geo_obj.multigeo = False
|
||||||
|
geo_obj.multitool = False
|
||||||
|
geo_obj.tools = {}
|
||||||
|
|
||||||
# self.app.new_object("geometry", name + "_cutout", geo_init)
|
def solder_line(p, offset):
|
||||||
# self.app.inform.emit("[success] Rectangular CutOut operation finished.")
|
xmin, ymin, xmax, ymax = p.bounds
|
||||||
|
|
||||||
|
min = [xmin, ymin]
|
||||||
|
max = [xmax, ymax]
|
||||||
|
min_r = [xmin, ymax]
|
||||||
|
max_r = [xmax, ymin]
|
||||||
|
|
||||||
|
diagonal_1 = LineString([min, max])
|
||||||
|
diagonal_2 = LineString([min_r, max_r])
|
||||||
|
round_diag_1 = round(diagonal_1.intersection(p).length, 4)
|
||||||
|
round_diag_2 = round(diagonal_2.intersection(p).length, 4)
|
||||||
|
|
||||||
|
if round_diag_1 == round_diag_2:
|
||||||
|
l = distance((xmin, ymin), (xmax, ymin))
|
||||||
|
h = distance((xmin, ymin), (xmin, ymax))
|
||||||
|
if offset >= l /2 or offset >= h / 2:
|
||||||
|
return "fail"
|
||||||
|
if l > h:
|
||||||
|
h_half = h / 2
|
||||||
|
start = [xmin, (ymin + h_half)]
|
||||||
|
stop = [(xmin + l), (ymin + h_half)]
|
||||||
|
else:
|
||||||
|
l_half = l / 2
|
||||||
|
start = [(xmin + l_half), ymin]
|
||||||
|
stop = [(xmin + l_half), (ymin + h)]
|
||||||
|
geo = LineString([start, stop])
|
||||||
|
elif round_diag_1 > round_diag_2:
|
||||||
|
geo = diagonal_1.intersection(p)
|
||||||
|
else:
|
||||||
|
geo = diagonal_2.intersection(p)
|
||||||
|
|
||||||
|
offseted_poly = p.buffer(-offset)
|
||||||
|
geo = geo.intersection(offseted_poly)
|
||||||
|
return geo
|
||||||
|
|
||||||
|
for g in obj.solid_geometry:
|
||||||
|
if type(g) == MultiPolygon:
|
||||||
|
for poly in g:
|
||||||
|
geom = solder_line(poly, offset=offset)
|
||||||
|
if geom == 'fail':
|
||||||
|
app_obj.inform.emit("[ERROR_NOTCL] The Nozzle diameter is too big for certain features.")
|
||||||
|
return 'fail'
|
||||||
|
if not geom.is_empty:
|
||||||
|
geo_obj.solid_geometry.append(geom)
|
||||||
|
elif type(g) == Polygon:
|
||||||
|
geom = solder_line(g, offset=offset)
|
||||||
|
if geom == 'fail':
|
||||||
|
app_obj.inform.emit("[ERROR_NOTCL] The Nozzle diameter is too big for certain features.")
|
||||||
|
return 'fail'
|
||||||
|
if not geom.is_empty:
|
||||||
|
geo_obj.solid_geometry.append(geom)
|
||||||
|
|
||||||
|
def job_thread(app_obj):
|
||||||
|
try:
|
||||||
|
app_obj.new_object("geometry", name + "_temp_solderpaste", geo_init)
|
||||||
|
except Exception as e:
|
||||||
|
proc.done()
|
||||||
|
traceback.print_stack()
|
||||||
|
return
|
||||||
|
proc.done()
|
||||||
|
|
||||||
|
self.app.inform.emit("Generating Solder Paste dispensing geometry...")
|
||||||
|
# Promise object with the new name
|
||||||
|
self.app.collection.promise(name)
|
||||||
|
|
||||||
|
# Background
|
||||||
|
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
|
||||||
# self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab)
|
# self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab)
|
||||||
|
|
||||||
def on_create_gcode(self):
|
def on_create_gcode(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user