Преглед на файлове

Multiple depth cut functional.

Juan Pablo Caram преди 10 години
родител
ревизия
051b82009d
променени са 4 файла, в които са добавени 105 реда и са изтрити 22 реда
  1. 24 7
      FlatCAMObj.py
  2. 8 1
      GUIElements.py
  3. 29 4
      ObjectUI.py
  4. 44 10
      camlib.py

+ 24 - 7
FlatCAMObj.py

@@ -1026,7 +1026,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             "painttooldia": 0.0625,
             "paintoverlap": 0.15,
             "paintmargin": 0.01,
-            "paintmethod": "standard"
+            "paintmethod": "standard",
+            "multidepth": False,
+            "depthperpass": -0.002
         })
 
         # Attributes to be included in serialization
@@ -1055,7 +1057,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             "painttooldia": self.ui.painttooldia_entry,
             "paintoverlap": self.ui.paintoverlap_entry,
             "paintmargin": self.ui.paintmargin_entry,
-            "paintmethod": self.ui.paintmethod_combo
+            "paintmethod": self.ui.paintmethod_combo,
+            "multidepth": self.ui.mpass_cb,
+            "depthperpass": self.ui.maxdepth_entry
         })
 
         self.ui.plot_cb.stateChanged.connect(self.on_plot_cb_click)
@@ -1137,11 +1141,19 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         self.read_form()
         self.generatecncjob()
 
-    def generatecncjob(self, z_cut=None, z_move=None,
-                       feedrate=None, tooldia=None, outname=None,
-                       spindlespeed=None):
+    def generatecncjob(self,
+                       z_cut=None,
+                       z_move=None,
+                       feedrate=None,
+                       tooldia=None,
+                       outname=None,
+                       spindlespeed=None,
+                       multidepth=None,
+                       depthperpass=None):
         """
-        Creates a CNCJob out of this Geometry object.
+        Creates a CNCJob out of this Geometry object. The actual
+        work is done by the target FlatCAMCNCjob object's
+        `generate_from_geometry_2()` method.
 
         :param z_cut: Cut depth (negative)
         :param z_move: Hight of the tool when travelling (not cutting)
@@ -1157,6 +1169,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         z_move = z_move if z_move is not None else self.options["travelz"]
         feedrate = feedrate if feedrate is not None else self.options["feedrate"]
         tooldia = tooldia if tooldia is not None else self.options["cnctooldia"]
+        multidepth = multidepth if multidepth is not None else self.options["multidepth"]
+        depthperpass = depthperpass if depthperpass is not None else self.options["depthperpass"]
 
         # To allow default value to be "" (optional in gui) and translate to None
         # if not isinstance(spindlespeed, int):
@@ -1186,7 +1200,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             job_obj.spindlespeed = spindlespeed
             app_obj.progress.emit(40)
             # TODO: The tolerance should not be hard coded. Just for testing.
-            job_obj.generate_from_geometry_2(self, tolerance=0.0005)
+            job_obj.generate_from_geometry_2(self,
+                                             multidepth=multidepth,
+                                             depthpercut=depthperpass,
+                                             tolerance=0.0005)
 
             app_obj.progress.emit(50)
             job_obj.gcode_parse()

+ 8 - 1
GUIElements.py

@@ -246,9 +246,16 @@ class VerticalScrollArea(QtGui.QScrollArea):
         return QtGui.QWidget.eventFilter(self, source, event)
 
 
-class OptionalInputSection():
+class OptionalInputSection:
 
     def __init__(self, cb, optinputs):
+        """
+        Associates the a checkbox with a set of inputs.
+
+        :param cb: Checkbox that enables the optional inputs.
+        :param optinputs: List of widgets that are optional.
+        :return:
+        """
         assert isinstance(cb, FCCheckBox), \
             "Expected an FCCheckBox, got %s" % type(cb)
 

+ 29 - 4
ObjectUI.py

@@ -222,7 +222,9 @@ class GeometryObjectUI(ObjectUI):
         )
         self.custom_box.addWidget(self.plot_cb)
 
-        ## Create CNC Job
+        #-----------------------------------
+        # Create CNC Job
+        #-----------------------------------
         self.cncjob_label = QtGui.QLabel('<b>Create CNC Job:</b>')
         self.cncjob_label.setToolTip(
             "Create a CNC Job object\n"
@@ -283,15 +285,38 @@ class GeometryObjectUI(ObjectUI):
         self.cncspindlespeed_entry = IntEntry(allow_empty=True)
         grid1.addWidget(self.cncspindlespeed_entry, 4, 1)
 
+        # Multi-pass
+        mpasslabel = QtGui.QLabel('Multi-Depth:')
+        mpasslabel.setToolTip(
+            "Use multiple passes to limit\n"
+            "the cut depth in each pass. Will\n"
+            "cut multiple times until Cut Z is\n"
+            "reached."
+        )
+        grid1.addWidget(mpasslabel, 5, 0)
+        self.mpass_cb = FCCheckBox()
+        grid1.addWidget(self.mpass_cb, 5, 1)
+
+        maxdepthlabel = QtGui.QLabel('Depth/pass:')
+        maxdepthlabel.setToolTip(
+            "Depth of each pass."
+        )
+        grid1.addWidget(maxdepthlabel, 6, 0)
+        self.maxdepth_entry = LengthEntry()
+        grid1.addWidget(self.maxdepth_entry, 6, 1)
+
+        self.ois_mpass = OptionalInputSection(self.mpass_cb, [self.maxdepth_entry])
+
+        # Button
         self.generate_cnc_button = QtGui.QPushButton('Generate')
         self.generate_cnc_button.setToolTip(
             "Generate the CNC Job object."
         )
         self.custom_box.addWidget(self.generate_cnc_button)
 
-        ################
-        ## Paint area ##
-        ################
+        #------------------------------
+        # Paint area
+        #------------------------------
         self.paint_label = QtGui.QLabel('<b>Paint Area:</b>')
         self.paint_label.setToolTip(
             "Creates tool paths to cover the\n"

+ 44 - 10
camlib.py

@@ -2715,8 +2715,13 @@ class CNCjob(Geometry):
 
         self.gcode = gcode
 
-    def generate_from_geometry_2(self, geometry, append=True, tooldia=None, tolerance=0,
-                                 multipass=False, depthpercut=None):
+    def generate_from_geometry_2(self,
+                                 geometry,
+                                 append=True,
+                                 tooldia=None,
+                                 tolerance=0,
+                                 multidepth=False,
+                                 depthpercut=None):
         """
         Second algorithm to generate from Geometry.
 
@@ -2732,6 +2737,7 @@ class CNCjob(Geometry):
         """
         assert isinstance(geometry, Geometry), \
             "Expected a Geometry, got %s" % type(geometry)
+
         log.debug("generate_from_geometry_2()")
 
         ## Flatten the geometry
@@ -2768,7 +2774,7 @@ class CNCjob(Geometry):
         self.gcode += self.feedminutecode + "\n"
         self.gcode += "F%.2f\n" % self.feedrate
         self.gcode += "G00 Z%.4f\n" % self.z_move  # Move (up) to travel height
-        if(self.spindlespeed != None):
+        if self.spindlespeed is not None:
             self.gcode += "M03 S%d\n" % int(self.spindlespeed)  # Spindle start with configured speed
         else:
             self.gcode += "M03\n"  # Spindle start
@@ -2794,7 +2800,7 @@ class CNCjob(Geometry):
                 if pt != geo.coords[0] and pt == geo.coords[-1]:
                     geo.coords = list(geo.coords)[::-1]
 
-                if not multipass:
+                if not multidepth:
                     # G-code
                     # Note: self.linear2gcode() and self.point2gcode() will
                     # lower and raise the tool every time.
@@ -2804,24 +2810,52 @@ class CNCjob(Geometry):
                         self.gcode += self.point2gcode(geo)
                     else:
                         log.warning("G-code generation not implemented for %s" % (str(type(geo))))
+
+                #--------- Multi-pass ---------
                 else:
                     if depthpercut is None:
                         depthpercut = self.z_cut
 
                     depth = 0
+                    reverse = False
                     while depth > self.z_cut:
                         depth -= depthpercut
+                        log.debug("DEPTH: %f" % depth)
                         # TODO: Working...
                         # G-code
                         # Note: self.linear2gcode() and self.point2gcode() will
                         # lower and raise the tool every time.
-                        # if type(geo) == LineString or type(geo) == LinearRing:
-                        #     self.gcode += self.linear2gcode(geo, tolerance=tolerance)
-                        # elif type(geo) == Point:
-                        #     self.gcode += self.point2gcode(geo)
-                        # else:
-                        #     log.warning("G-code generation not implemented for %s" % (str(type(geo))))
 
+                        # Cut at specific depth and do not leave the tool.
+                        if type(geo) == LineString or type(geo) == LinearRing:
+                            self.gcode += self.linear2gcode(geo, tolerance=tolerance,
+                                                            zcut=depth,
+                                                            up=False)
+
+                        # Ignore multi-pass for points.
+                        elif type(geo) == Point:
+                            self.gcode += self.point2gcode(geo)
+                            break  # Ignoring ...
+
+                        else:
+                            log.warning("G-code generation not implemented for %s" % (str(type(geo))))
+
+                        # Reverse coordinates if not a loop so we can continue
+                        # cutting without returning to the beginhing.
+                        if type(geo) == LineString:
+                            geo.coords = list(geo.coords)[::-1]
+                            reverse = True
+
+                    # If geometry is reversed, revert.
+                    if reverse:
+                        if type(geo) == LineString:
+                            geo.coords = list(geo.coords)[::-1]
+
+                    # Lift the tool
+                    self.gcode += "G00 Z%.4f\n" % self.z_move
+                    # self.gcode += "( End of path. )\n"
+
+                # Did deletion at the beginning.
                 # Delete from index, update current location and continue.
                 #rti.delete(hits[0], geo.coords[0])
                 #rti.delete(hits[0], geo.coords[-1])