Browse Source

- fixed a bug in rotate from shortcut function
- finished generating the solder paste dispense geometry

Marius Stanciu 7 years ago
parent
commit
3ee6eb4a87
4 changed files with 103 additions and 14 deletions
  1. 1 1
      FlatCAMApp.py
  2. 2 0
      README.md
  3. 0 2
      camlib.py
  4. 100 11
      flatcamTools/ToolSolderPaste.py

+ 1 - 1
FlatCAMApp.py

@@ -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.")

+ 2 - 0
README.md

@@ -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
 
 

+ 0 - 2
camlib.py

@@ -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))

+ 100 - 11
flatcamTools/ToolSolderPaste.py

@@ -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.offset_entry.setValidator(QtGui.QDoubleValidator(-99.9999, 0.0000, 4))
-        self.offset_label = QtWidgets.QLabel(" Solder Offset:")
-        self.offset_label.setToolTip(
+        self.nozzle_dia_entry = FloatEntry()
+        self.nozzle_dia_entry.setValidator(QtGui.QDoubleValidator(0.0000, 9.9999, 4))
+        self.nozzle_dia_label = QtWidgets.QLabel("Nozzle Diameter:")
+        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"
-            "so it will not overflow over the pad."
+            "we need to adjust the quantity of solder paste."
         )
         )
-        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)
 
 
-        def geo_init(geo_obj, app_obj):
-           pass
+        if type(obj.solid_geometry) is not list:
+            obj.solid_geometry = [obj.solid_geometry]
 
 
-        # self.app.new_object("geometry", name + "_cutout", geo_init)
-        # self.app.inform.emit("[success] Rectangular CutOut operation finished.")
+        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):
+            geo_obj.solid_geometry = []
+            geo_obj.multigeo = False
+            geo_obj.multitool = False
+            geo_obj.tools = {}
+
+            def solder_line(p, offset):
+                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):