Jelajahi Sumber

Support for milling holes from the shell, command "millholes".

Juan Pablo Caram 10 tahun lalu
induk
melakukan
a2ac2b12be
2 mengubah file dengan 87 tambahan dan 17 penghapusan
  1. 50 4
      FlatCAMApp.py
  2. 37 13
      FlatCAMObj.py

+ 50 - 4
FlatCAMApp.py

@@ -2136,6 +2136,43 @@ class App(QtCore.QObject):
 
             return 'Ok'
 
+        def drillmillgeometry(name, *args):
+            a, kwa = h(*args)
+            types = {'tooldia': float,
+                     'tools': str,
+                     'outname': str}
+
+            for key in kwa:
+                if key not in types:
+                    return 'Unknown parameter: %s' % key
+                kwa[key] = types[key](kwa[key])
+
+            try:
+                if 'tools' in kwa:
+                    kwa['tools'] = [x.strip() for x in kwa['tools'].split(",")]
+            except Exception as e:
+                return "Bad tools: %s" % str(e)
+
+            try:
+                obj = self.collection.get_by_name(str(name))
+            except:
+                return "Could not retrieve object: %s" % name
+
+            if obj is None:
+                return "Object not found: %s" % name
+
+            assert isinstance(obj, FlatCAMExcellon)
+
+            try:
+                success, msg = obj.generate_milling(**kwa)
+            except Exception as e:
+                return "Operation failed: %s" % str(e)
+
+            if not success:
+                return msg
+
+            return 'Ok'
+
         def isolate(name, *args):
             a, kwa = h(*args)
             types = {'dia': float,
@@ -2157,6 +2194,8 @@ class App(QtCore.QObject):
             if obj is None:
                 return "Object not found: %s" % name
 
+            assert isinstance(obj, FlatCAMGerber)
+
             try:
                 obj.isolate(**kwa)
             except Exception, e:
@@ -2289,17 +2328,15 @@ class App(QtCore.QObject):
                 return "Object not found: %s" % obj_name
 
             obj.union()
-            
-
 
-        def join_geometries (obj_name, *obj_names):
+        def join_geometries(obj_name, *obj_names):
             objs = []
             for obj_n in obj_names:
                 obj = self.collection.get_by_name(str(obj_n))
                 if obj is None:
                     return "Object not found: %s" % obj_n
                 else:
-                    objs.append (obj)
+                    objs.append(obj)
 
             def initialize(obj, app):
                 FlatCAMGeometry.merge(objs, obj)
@@ -2501,6 +2538,15 @@ class App(QtCore.QObject):
                         "   spindlespeed: Speed of the spindle in rpm (example: 4000)\n" +
                         "   toolchange: Enable tool changes (example: 1)\n"
             },
+            'millholes': {
+                'fcn': drillmillgeometry,
+                'help': "Create Geometry Object for milling holes from Excellon.\n" +
+                        "> drillmillgeometry <name> -tools <str> -tooldia <float> -outname <str> \n" +
+                        "   name: Name of the Excellon Object\n" +
+                        "   tools: Comma separated indexes of tools (example: 1,3 or 2)\n" +
+                        "   tooldia: Diameter of the milling tool (example: 0.1)\n" +
+                        "   outname: Name of object to create\n"
+            },
             'scale': {
                 'fcn': lambda name, factor: self.collection.get_by_name(str(name)).scale(float(factor)),
                 'help': "Resizes the object by a factor.\n" +

+ 37 - 13
FlatCAMObj.py

@@ -1,4 +1,5 @@
 from PyQt4 import QtCore
+from copy import copy
 from ObjectUI import *
 import FlatCAMApp
 import inspect  # TODO: For debugging only.
@@ -666,7 +667,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
             "tooldia": self.ui.tooldia_entry,
             "toolchange": self.ui.toolchange_cb,
             "toolchangez": self.ui.toolchangez_entry,
-            "spindlespeed":  self.ui.spindlespeed_entry
+            "spindlespeed": self.ui.spindlespeed_entry
         })
 
         assert isinstance(self.ui, ExcellonObjectUI)
@@ -679,27 +680,42 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
         """
         Returns the keys to the self.tools dictionary corresponding
         to the selections on the tool list in the GUI.
+
+        :return: List of tools.
+        :rtype: list
         """
         return [str(x.text()) for x in self.ui.tools_table.selectedItems()]
 
-    def on_generate_milling_button_click(self, *args):
-        self.app.report_usage("excellon_on_create_milling_button")
-        self.read_form()
+    def generate_milling(self, tools=None, outname=None, tooldia=None):
+        """
+        Note: This method is a good template for generic operations as
+        it takes it's options from parameters or otherwise from the
+        object's options and returns a success, msg tuple as feedback
+        for shell operations.
+
+        :return: Success/failure condition tuple (bool, str).
+        :rtype: tuple
+        """
 
         # Get the tools from the list. These are keys
         # to self.tools
-        tools = self.get_selected_tools_list()
+        if tools is None:
+            tools = self.get_selected_tools_list()
+
+        if outname is None:
+            outname = self.options["name"] + "_mill"
+
+        if tooldia is None:
+            tooldia = self.options["tooldia"]
 
         if len(tools) == 0:
             self.app.inform.emit("Please select one or more tools from the list and try again.")
-            return
+            return False, "Error: No tools."
 
         for tool in tools:
-            if self.tools[tool]["C"] < self.options["tooldia"]:
+            if self.tools[tool]["C"] < tooldia:
                 self.app.inform.emit("[warning] Milling tool is larger than hole size. Cancelled.")
-                return
-
-        geo_name = self.options["name"] + "_mill"
+                return False, "Error: Milling tool is larger than hole."
 
         def geo_init(geo_obj, app_obj):
             assert isinstance(geo_obj, FlatCAMGeometry)
@@ -711,19 +727,27 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
                 if hole['tool'] in tools:
                     geo_obj.solid_geometry.append(
                         Point(hole['point']).buffer(self.tools[hole['tool']]["C"] / 2 -
-                                                    self.options["tooldia"] / 2).exterior
+                                                    tooldia / 2).exterior
                     )
 
         def geo_thread(app_obj):
-            app_obj.new_object("geometry", geo_name, geo_init)
+            app_obj.new_object("geometry", outname, geo_init)
             app_obj.progress.emit(100)
 
         # Create a promise with the new name
-        self.app.collection.promise(geo_name)
+        self.app.collection.promise(outname)
 
         # Send to worker
         self.app.worker_task.emit({'fcn': geo_thread, 'params': [self.app]})
 
+        return True, ""
+
+    def on_generate_milling_button_click(self, *args):
+        self.app.report_usage("excellon_on_create_milling_button")
+        self.read_form()
+
+        self.generate_milling()
+
     def on_create_cncjob_button_click(self, *args):
         self.app.report_usage("excellon_on_create_cncjob_button")
         self.read_form()