Просмотр исходного кода

Merged in sopak/flatcam (pull request #4)

shell comand updates

jpcgt 11 лет назад
Родитель
Сommit
91616cae6c
2 измененных файлов с 241 добавлено и 4 удалено
  1. 186 3
      FlatCAMApp.py
  2. 55 1
      README.md

+ 186 - 3
FlatCAMApp.py

@@ -1848,6 +1848,161 @@ class App(QtCore.QObject):
 
             self.open_gcode(str(filename), **kwa)
 
+
+        def cutout(name, *args):
+            a, kwa = h(*args)
+            types = {'dia': float,
+                     'margin': float,
+                     'gapsize': float,
+                     'gaps': str}
+
+            for key in kwa:
+                if key not in types:
+                    return 'Unknown parameter: %s' % key
+                kwa[key] = types[key](kwa[key])
+
+
+
+            try:
+                obj = self.collection.get_by_name(str(name))
+            except:
+                return "Could not retrieve object: %s" % name
+
+
+            def geo_init_me(geo_obj, app_obj):
+                margin = kwa['margin']+kwa['dia']/2
+                gap_size = kwa['dia']+kwa['gapsize']
+                minx, miny, maxx, maxy = obj.bounds()
+                minx -= margin
+                maxx += margin
+                miny -= margin
+                maxy += margin
+                midx = 0.5 * (minx + maxx)
+                midy = 0.5 * (miny + maxy)
+                hgap = 0.5 * gap_size
+                pts = [[midx - hgap, maxy],
+                       [minx, maxy],
+                       [minx, midy + hgap],
+                       [minx, midy - hgap],
+                       [minx, miny],
+                       [midx - hgap, miny],
+                       [midx + hgap, miny],
+                       [maxx, miny],
+                       [maxx, midy - hgap],
+                       [maxx, midy + hgap],
+                       [maxx, maxy],
+                       [midx + hgap, maxy]]
+                cases = {"tb": [[pts[0], pts[1], pts[4], pts[5]],
+                                [pts[6], pts[7], pts[10], pts[11]]],
+                         "lr": [[pts[9], pts[10], pts[1], pts[2]],
+                                [pts[3], pts[4], pts[7], pts[8]]],
+                         "4": [[pts[0], pts[1], pts[2]],
+                               [pts[3], pts[4], pts[5]],
+                               [pts[6], pts[7], pts[8]],
+                               [pts[9], pts[10], pts[11]]]}
+                cuts = cases[kwa['gaps']]
+                geo_obj.solid_geometry = cascaded_union([LineString(segment) for segment in cuts])
+
+            try:
+                obj.app.new_object("geometry", name+ "_cutout", geo_init_me)
+            except Exception, e:
+                return "Operation failed: %s" % str(e)
+
+            return 'Ok'
+
+        def mirror(name, *args):
+            a, kwa = h(*args)
+            types = {'box': str,
+                     'axis': str}
+
+            for key in kwa:
+                if key not in types:
+                    return 'Unknown parameter: %s' % key
+                kwa[key] = types[key](kwa[key])
+
+            try:
+                obj = self.collection.get_by_name(str(name))
+            except:
+                return "Could not retrieve object: %s" % name
+
+            try:
+                box = self.collection.get_by_name(kwa['box'])
+            except:
+                return "Could not retrieve object box: %s" % kwa['box']
+
+            if obj is None:
+                return "Object not found: %s" % name
+
+            if box is None:
+                return "Object box not found: %s" % kwa['box']
+
+
+            if not isinstance(obj, FlatCAMGerber) and not isinstance(obj, FlatCAMExcellon):
+                return "ERROR: Only Gerber and Excellon objects can be mirrored."
+
+            try:
+                xmin, ymin, xmax, ymax = box.bounds()
+                px = 0.5*(xmin+xmax)
+                py = 0.5*(ymin+ymax)
+            
+                obj.mirror(kwa['axis'], [px, py])
+                obj.plot()
+
+            except Exception, e:
+                return "Operation failed: %s" % str(e)
+
+            return 'Ok'
+
+
+        def drillcncjob(name, *args):
+            a, kwa = h(*args)
+            types = {'tools': str,
+                     'outname': str,
+                     'drillz': float,
+                     'travelz': float,
+                     'feedrate': float}
+
+            for key in kwa:
+                if key not in types:
+                    return 'Unknown parameter: %s' % key
+                kwa[key] = types[key](kwa[key])
+
+            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
+
+            if not isinstance(obj, FlatCAMExcellon):
+                return "ERROR: Only Excellon objects can be drilled."
+
+            try:
+              
+                # Get the tools from the list
+                job_name = kwa["outname"]
+        
+                # Object initialization function for app.new_object()
+                def job_init(job_obj, app_obj):
+                    assert isinstance(job_obj, FlatCAMCNCjob)
+                    
+                    job_obj.z_cut = kwa["drillz"]
+                    job_obj.z_move = kwa["travelz"]
+                    job_obj.feedrate = kwa["feedrate"]
+                    job_obj.generate_from_excellon_by_tool(obj, kwa["tools"])
+                    
+                    job_obj.gcode_parse()
+                    
+                    job_obj.create_geometry()
+        
+                obj.app.new_object("cncjob", job_name, job_init)
+
+            except Exception, e:
+                return "Operation failed: %s" % str(e)
+
+            return 'Ok'
+
         def isolate(name, *args):
             a, kwa = h(*args)
             types = {'dia': float,
@@ -1908,9 +2063,10 @@ class App(QtCore.QObject):
                 obj = self.collection.get_by_name(str(obj_name))
             except:
                 return "Could not retrieve object: %s" % obj_name
-            if obj is None:
-                return "Object not found: %s" % obj_name
-            obj.export_gcode(str(filename), str(preamble), str(postamble))
+            try:
+                obj.export_gcode(str(filename), str(preamble), str(postamble))
+            except Exception, e:
+                return "Operation failed: %s" % str(e)
 
         def paint_poly(obj_name, inside_pt_x, inside_pt_y, tooldia, overlap):
             try:
@@ -2109,6 +2265,33 @@ class App(QtCore.QObject):
                         "   dia: Tool diameter\n   passes: # of tool width\n" +
                         "   overlap: Fraction of tool diameter to overlap passes"
             },
+            'cutout': {
+                'fcn': cutout,
+                'help': "Creates cutout board.\n" +
+                        "> cutout <name> [-dia <3.0 (float)>] [-margin <0.0 (float)>] [-gapsize <0.5 (float)>] [-gaps <lr (4|tb|lr)>]\n" +
+                        "   name: Name of the object\n" +
+                        "   dia: Tool diameter\n   margin: # margin over bounds\n" +
+                        "   gapsize: size of gap\n   gaps: type of gaps"
+            },
+            'mirror': {
+                'fcn': mirror,
+                'help': "Mirror board.\n" +
+                        "> mirror <nameMirroredObject> -box <nameOfBox> [-axis <3.0 (X X|Y)>]\n" +
+                        "   name: Name of the object to mirror\n" +
+                        "   box: Name of   object which act as box (cutout for example)\n" +
+                        "   axis: axis mirror over x o y"
+            },
+            'drillcncjob': {
+                'fcn': drillcncjob,
+                'help': "Drill CNC job.\n" +
+                        "> drillcncjob <name> -tools <str> -drillz <float> -travelz <float> -feedrate <float> -outname <str> \n" +
+                        "   name: Name of the object\n" +
+                        "   tools: coma separated indexes of tools (example: 1,3 or 2)\n" +
+                        "   drillz: drill into material (example: -2)\n" +
+                        "   travelz: travel above  material (example: 2)\n" +
+                        "   feedrate: drilling feed rate\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" +

+ 55 - 1
README.md

@@ -5,4 +5,58 @@ FlatCAM: 2D Post-processing for Manufacturing
 
 FlatCAM is a program for preparing CNC jobs for making PCBs on a CNC router.
 Among other things, it can take a Gerber file generated by your favorite PCB
-CAD program, and create G-Code for Isolation routing. But there's more.
+CAD program, and create G-Code for Isolation routing. But there's more.
+
+
+
+
+
+This  fork is  mainly for improving shell  commands.
+
+added so far:
+
+* cutout
+* mirror
+* cncdrilljob
+
+
+todo:
+
+* commandline  witch  reads  whole shell sequence from given file
+
+
+example of  shell flow:
+
+```
+#!flatcam shell
+
+
+new 
+open_gerber /home/sopak/kicad/ThermalShield/Gerber/ThermalPicoShield2-Margin.gbr  -outname Margin
+open_gerber /home/sopak/kicad/ThermalShield/Gerber/ThermalPicoShield2-B_Cu.gbr  -outname BottomCu
+open_excellon /home/sopak/kicad/ThermalShield/Gerber/ThermalPicoShield2.drl -outname Drills
+
+mirror BottomCu -box Margin -axis X
+
+mirror Drills -box Margin -axis X
+
+cutout Margin -dia 3 -margin 0 -gapsize 0.6 -gaps lr
+
+isolate BottomCu -dia 0.4 -overlap 1
+
+drillcncjob Drills -tools 1 -drillz -2 -travelz 2 -feedrate 5 -outname Drills_cncjob_0.8
+
+drillcncjob Drills -tools 2 -drillz -2 -travelz 2 -feedrate 5 -outname Drills_cncjob_3.0
+
+cncjob BottomCu_iso -tooldia 0.4
+
+cncjob Margin_cutout -tooldia 3
+
+write_gcode BottomCu_iso_cnc /home/sopak/kicad/ThermalShield/Gerber/ThermalPicoShield2-B_Cu.gbr_iso_cnc.ngc
+
+write_gcode Margin_cutout_cnc /home/sopak/kicad/ThermalShield/Gerber/ThermalPicoShield2-Margin.gbr_cutout_cnc.ngc
+
+write_gcode Drills_cncjob_3.0 /home/sopak/kicad/ThermalShield/Gerber/ThermalPicoShield2.drl_Drills_cncjob_3.0.ngc
+
+write_gcode Drills_cncjob_0.8 /home/sopak/kicad/ThermalShield/Gerber/ThermalPicoShield2.drl_Drills_cncjob_0.8.ngc
+```