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

- added options for trace segmentation that can be useful for auto-levelling (code snippet from Lei Zheng from a rejected pull request on FlatCAM https://bitbucket.org/realthunder/ )

Marius Stanciu 7 лет назад
Родитель
Сommit
4f7b2bbb34
5 измененных файлов с 108 добавлено и 3 удалено
  1. 8 0
      FlatCAMApp.py
  2. 22 0
      FlatCAMGUI.py
  3. 14 1
      FlatCAMObj.py
  4. 1 1
      README.md
  5. 63 1
      camlib.py

+ 8 - 0
FlatCAMApp.py

@@ -363,6 +363,8 @@ class App(QtCore.QObject):
             "excellon_optimization_type": self.excellon_defaults_form.excellon_group.excellon_optimization_radio,
             "excellon_gcode_type": self.excellon_defaults_form.excellon_group.excellon_gcode_type_radio,
             "geometry_plot": self.geometry_defaults_form.geometry_group.plot_cb,
+            "geometry_segx": self.geometry_defaults_form.geometry_group.segx_entry,
+            "geometry_segy": self.geometry_defaults_form.geometry_group.segy_entry,
             "geometry_cutz": self.geometry_defaults_form.geometry_group.cutz_entry,
             "geometry_travelz": self.geometry_defaults_form.geometry_group.travelz_entry,
             "geometry_feedrate": self.geometry_defaults_form.geometry_group.cncfeedrate_entry,
@@ -486,6 +488,8 @@ class App(QtCore.QObject):
             "excellon_gcode_type": "drills",
 
             "geometry_plot": True,
+            "geometry_segx": 0.0,
+            "geometry_segy": 0.0,
             "geometry_cutz": -0.002,
             "geometry_travelz": 0.1,
             "geometry_toolchange": False,
@@ -628,6 +632,8 @@ class App(QtCore.QObject):
             "excellon_units": self.excellon_options_form.excellon_group.excellon_units_radio,
             "excellon_optimization_type": self.excellon_options_form.excellon_group.excellon_optimization_radio,
             "geometry_plot": self.geometry_options_form.geometry_group.plot_cb,
+            "geometry_segx": self.geometry_options_form.geometry_group.segx_entry,
+            "geometry_segy": self.geometry_options_form.geometry_group.segy_entry,
             "geometry_cutz": self.geometry_options_form.geometry_group.cutz_entry,
             "geometry_travelz": self.geometry_options_form.geometry_group.travelz_entry,
             "geometry_feedrate": self.geometry_options_form.geometry_group.cncfeedrate_entry,
@@ -709,6 +715,8 @@ class App(QtCore.QObject):
             "excellon_endz": 2.0,
             "excellon_zeros": "L",
             "geometry_plot": True,
+            "geometry_segx": 0.0,
+            "geometry_segy": 0.0,
             "geometry_cutz": -0.002,
             "geometry_travelz": 0.1,
             "geometry_feedrate": 3.0,

+ 22 - 0
FlatCAMGUI.py

@@ -2260,6 +2260,28 @@ class GeometryPrefGroupUI(OptionsGroupUI):
         self.pp_geometry_name_cb.setFocusPolicy(Qt.StrongFocus)
         grid2.addWidget(self.pp_geometry_name_cb, 16, 1)
 
+        # Size of trace segment on X axis
+        segx_label = QtWidgets.QLabel("Seg. X size:")
+        segx_label.setToolTip(
+            "The size of the trace segment on the X axis.\n"
+            "Useful for auto-leveling.\n"
+            "A value of 0 means no segmentation on the X axis."
+        )
+        grid2.addWidget(segx_label, 17, 0)
+        self.segx_entry = FCEntry()
+        grid2.addWidget(self.segx_entry, 17, 1)
+
+        # Size of trace segment on Y axis
+        segy_label = QtWidgets.QLabel("Seg. Y size:")
+        segy_label.setToolTip(
+            "The size of the trace segment on the Y axis.\n"
+            "Useful for auto-leveling.\n"
+            "A value of 0 means no segmentation on the Y axis."
+        )
+        grid2.addWidget(segy_label, 18, 0)
+        self.segy_entry = FCEntry()
+        grid2.addWidget(self.segy_entry, 18, 1)
+
         # ------------------------------
         ## Paint area
         # ------------------------------

+ 14 - 1
FlatCAMObj.py

@@ -2962,7 +2962,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         else:
             self.app.inform.emit("[error_notcl] Failed. No tool selected in the tool table ...")
 
-    def mtool_gen_cncjob(self, use_thread=True):
+    def mtool_gen_cncjob(self, segx=None, segy=None, use_thread=True):
         """
         Creates a multi-tool CNCJob out of this Geometry object.
         The actual work is done by the target FlatCAMCNCjob object's
@@ -2986,6 +2986,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         # use the name of the first tool selected in self.geo_tools_table which has the diameter passed as tool_dia
         outname = "%s_%s" % (self.options["name"], 'cnc')
 
+        segx = segx if segx is not None else float(self.app.defaults['geometry_segx'])
+        segy = segy if segy is not None else float(self.app.defaults['geometry_segy'])
+
         # Object initialization function for app.new_object()
         # RUNNING ON SEPARATE THREAD!
         def job_init_single_geometry(job_obj, app_obj):
@@ -3004,6 +3007,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             # job_obj.create_geometry()
 
             job_obj.options['Tools_in_use'] = self.get_selected_tools_table_items()
+            job_obj.segx = segx
+            job_obj.segy = segy
 
             for tooluid_key in self.sel_tools:
                 tool_cnt += 1
@@ -3345,6 +3350,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                        toolchange=None, toolchangez=None, toolchangexy=None,
                        extracut=None, startz=None, endz=None,
                        ppname_g=None,
+                       segx=None,
+                       segy=None,
                        use_thread=True):
         """
         Only used for TCL Command.
@@ -3376,6 +3383,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         multidepth = multidepth if multidepth is not None else self.options["multidepth"]
         depthperpass = depthperpass if depthperpass is not None else self.options["depthperpass"]
 
+        segx = segx if segx is not None else float(self.app.defaults['geometry_segx'])
+        segy = segy if segy is not None else float(self.app.defaults['geometry_segy'])
+
         extracut = extracut if extracut is not None else self.options["extracut"]
         startz = startz if startz is not None else self.options["startz"]
         endz = endz if endz is not None else self.options["endz"]
@@ -3410,6 +3420,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             job_obj.options['type'] = 'Geometry'
             job_obj.options['tool_dia'] = tooldia
 
+            job_obj.segx = segx
+            job_obj.segy = segy
+
             # TODO: The tolerance should not be hard coded. Just for testing.
             job_obj.generate_from_geometry_2(self, tooldia=tooldia, offset=offset, tolerance=0.0005,
                                              z_cut=z_cut, z_move=z_move,

+ 1 - 1
README.md

@@ -14,7 +14,7 @@ CAD program, and create G-Code for Isolation routing.
 - added more key shortcuts into the application; they are now displayed in the GUI menu's
 - reorganized the Edit -> Preferences -> Global
 - redesigned the messagebox that is showed when quiting ot creating a New Project: now it has an option ('Cancel') to abort the process returning to the app
-
+- added options for trace segmentation that can be useful for auto-levelling (code snippet from Lei Zheng from a rejected pull request on FlatCAM https://bitbucket.org/realthunder/ )
 
 26.01.2019
 

+ 63 - 1
camlib.py

@@ -4332,6 +4332,8 @@ class CNCjob(Geometry):
                  spindlespeed=None, dwell=True, dwelltime=1000,
                  toolchangez=0.787402,
                  endz=2.0,
+                 segx=None,
+                 segy=None,
                  steps_per_circle=None):
 
         # Used when parsing G-code arcs
@@ -4376,6 +4378,9 @@ class CNCjob(Geometry):
         self.dwell = dwell
         self.dwelltime = dwelltime
 
+        self.segx = float(segx) if segx is not None else 0.0
+        self.segy = float(segy) if segy is not None else 0.0
+
         self.input_geometry_bounds = None
 
         # Attributes to be included in serialization
@@ -5456,6 +5461,61 @@ class CNCjob(Geometry):
         self.solid_geometry = cascaded_union([geo['geom'] for geo in self.gcode_parsed])
         return self.solid_geometry
 
+    # code snippet added by Lei Zheng in a rejected pull request on FlatCAM https://bitbucket.org/realthunder/
+    def segment(self, coords):
+        """
+        break long linear lines to make it more auto level friendly
+        """
+
+        if len(coords) < 2 or self.segx <= 0 and self.segy <= 0:
+            return list(coords)
+
+        path = [coords[0]]
+
+        # break the line in either x or y dimension only
+        def linebreak_single(line, dim, dmax):
+            if dmax <= 0:
+                return None
+
+            if line[1][dim] > line[0][dim]:
+                sign = 1.0
+                d = line[1][dim] - line[0][dim]
+            else:
+                sign = -1.0
+                d = line[0][dim] - line[1][dim]
+            if d > dmax:
+                # make sure we don't make any new lines too short
+                if d > dmax * 2:
+                    dd = dmax
+                else:
+                    dd = d / 2
+                other = dim ^ 1
+                return (line[0][dim] + dd * sign, line[0][other] + \
+                        dd * (line[1][other] - line[0][other]) / d)
+            return None
+
+        # recursively breaks down a given line until it is within the
+        # required step size
+        def linebreak(line):
+            pt_new = linebreak_single(line, 0, self.segx)
+            if pt_new is None:
+                pt_new2 = linebreak_single(line, 1, self.segy)
+            else:
+                pt_new2 = linebreak_single((line[0], pt_new), 1, self.segy)
+            if pt_new2 is not None:
+                pt_new = pt_new2[::-1]
+
+            if pt_new is None:
+                path.append(line[1])
+            else:
+                path.append(pt_new)
+                linebreak((pt_new, line[1]))
+
+        for pt in coords[1:]:
+            linebreak((path[-1], pt))
+
+        return path
+
     def linear2gcode(self, linear, tolerance=0, down=True, up=True,
                      z_cut=None, z_move=None, zdownrate=None,
                      feedrate=None, feedrate_z=None, feedrate_rapid=None, cont=False):
@@ -5500,7 +5560,9 @@ class CNCjob(Geometry):
 
         gcode = ""
 
-        path = list(target_linear.coords)
+        # path = list(target_linear.coords)
+        path = self.segment(target_linear.coords)
+
         p = self.pp_geometry
 
         # Move fast to 1st point