Esempio n. 1
0
    def contour(self, bit_diameter, count=1, overlap=0.5):
        """ @brief Finds a set of isolines on a distance field image.
            @param bit_diameter Tool diameter (in mm)
            @param count Number of offsets
            @param overlap Overlap between offsets
            @returns A list of Paths
        """
        if self.depth != 'f' or self.channels != 1:
            raise ValueError('Invalid image type for contour cut '+
                '(requires floating-point, 1-channel image)')

        max_distance = max(self.array.flatten())
        levels = [bit_diameter/2]
        step = bit_diameter * overlap
        if count == -1:
            while levels[-1] < max_distance:
                levels.append(levels[-1] + step)
            levels[-1] = max_distance
        else:
            for i in range(count-1):
                levels.append(levels[-1] + step)
        levels = (ctypes.c_float*len(levels))(*levels)

        ptr = ctypes.POINTER(ctypes.POINTER(Path_))()
        path_count = libfab.find_paths(
            self.width, self.height, self.pixels,
            1./self.pixels_per_mm, len(levels),
            levels, ptr)

        paths = [Path.from_ptr(ptr[i]) for i in range(path_count)]
        libfab.free_paths(ptr, path_count)

        return Path.sort(paths)
Esempio n. 2
0
    def run(self, paths):
        """ @brief Convert the path from the previous panel into a shopbot file.
            @param paths List of Paths
        """

        koko.FRAME.status = 'Converting to .sbp file'

        values = self.get_values()
        if not values:  return False

        # Reverse direction for climb cutting
        if values['type']:
            paths = Path.sort([p.reverse() for p in paths])

        # Check to see if all of the z values are the same.  If so,
        # we can use 2D cutting commands; if not, we'll need
        # to do full three-axis motion control
        zmin = paths[0].points[0][2]
        flat = True
        for p in paths:
            if not all(pt[2] == zmin for pt in p.points):
                flat = False

        ## @var file
        # tempfile.NamedTemporaryFile to store OpenSBP commands
        self.file = tempfile.NamedTemporaryFile(suffix=self.extension)

        self.file.write("SA\r\n")   # plot absolute
        self.file.write("TR,%s,1,\r\n" % values['spindle']) # spindle speed
        self.file.write("SO,1,1\r\n") # set output number 1 to on
        self.file.write("pause,2,\r\n") # pause for spindle to spin up

        scale = 1 if values['units'] else 1/25.4 # mm vs inch units

        # Cut and jog speeds
        self.file.write("MS,%f,%f\r\n" %
            (values['cut_speed']*scale, values['cut_speed']*scale))
        self.file.write("JS,%f,%f\r\n" %
            (values['jog_speed']*scale, values['jog_speed']*scale))

        self.file.write("JZ,%f\r\n" % (values['jog']*scale)) # Move up

        xy  = lambda x,y:   (scale*x, scale*y)
        xyz = lambda x,y,z: (scale*x, scale*y, scale*z)


        for p in paths:

            # Move to the start of this path with the pen up
            self.file.write("J2,%f,%f\r\n" % xy(*p.points[0][0:2]))

            if flat:    self.file.write("MZ,%f\r\n" % (zmin*scale))
            else:       self.file.write("M3,%f,%f,%f\r\n" % xyz(*p.points[0]))

            # Cut each point in the segment
            for pt in p.points:
                if flat:    self.file.write("M2,%f,%f\r\n" % xy(*pt[0:2]))
                else:       self.file.write("M3,%f,%f,%f\r\n" % xyz(*pt))

            # Lift then pen up at the end of the segment
            self.file.write("MZ,%f\r\n" % (values['jog']*scale))

        self.file.flush()

        koko.FRAME.status = ''
        return True
Esempio n. 3
0
    def run(self, paths):
        ''' Convert the path from the previous panel into a g-code file
        '''

        koko.FRAME.status = 'Converting to .g file'

        values = self.get_values()
        if not values: return False

        # Reverse direction for climb cutting
        if values['type']:
            paths = Path.sort([p.reverse() for p in paths])

        # Check to see if all of the z values are the same.  If so,
        # we can use 2D cutting commands; if not, we'll need
        # to do full three-axis motion control
        zmin = paths[0].points[0][2]
        flat = True
        for p in paths:
            if not all(pt[2] == zmin for pt in p.points):
                flat = False

        # Create a temporary file to store the .sbp instructions
        self.file = tempfile.NamedTemporaryFile(suffix=self.extension)

        self.file.write("%%\n")  # tape start
        self.file.write("G17\n")  # XY plane
        self.file.write("G20\n")  # Inch mode
        self.file.write("G40\n")  # Cancel tool diameter compensation
        self.file.write("G49\n")  # Cancel tool length offset
        self.file.write("G54\n")  # Coordinate system 1
        self.file.write("G80\n")  # Cancel motion
        self.file.write("G90\n")  # Absolute programming
        self.file.write("G94\n")  # Feedrate is per minute

        scale = 1 / 25.4  # inch units

        self.file.write("T%dM06\n" % values['tool'])  # Tool selection + change
        self.file.write("F%0.4f\n" %
                        (60 * scale * values['feed']))  # Feed rate
        self.file.write("S%0.4f\n" % values['spindle'])  # spindle speed
        if values['coolant']: self.file.write("M08\n")  # coolant on

        # Move up before starting spindle
        self.file.write("G00Z%0.4f\n" % (scale * values['jog']))
        self.file.write("M03\n")  # spindle on (clockwise)
        self.file.write("G04 P1\n")  # pause one second to spin up spindle

        xy = lambda x, y: (scale * x, scale * y)
        xyz = lambda x, y, z: (scale * x, scale * y, scale * z)

        for p in paths:

            # Move to the start of this path at the jog height
            self.file.write("G00X%0.4fY%0.4fZ%0.4f\n" %
                            xyz(p.points[0][0], p.points[0][1], values['jog']))

            # Plunge to the desired depth
            self.file.write(
                "G01Z%0.4f F%0.4f\n" %
                (p.points[0][2] * scale, 60 * scale * values['plunge']))

            # Restore XY feed rate
            self.file.write("F%0.4f\n" % (60 * scale * values['feed']))

            # Cut each point in the segment
            for pt in p.points:
                if flat: self.file.write("X%0.4fY%0.4f\n" % xy(*pt[0:2]))
                else: self.file.write("X%0.4fY%0.4fZ%0.4f\n" % xyz(*pt))

            # Lift the bit up to the jog height at the end of the segment
            self.file.write("Z%0.4f\n" % (scale * values['jog']))

        self.file.write("M05\n")  # spindle stop
        if values['coolant']: self.file.write("M09\n")  # coolant off
        self.file.write("M30\n")  # program end and reset
        self.file.write("%%\n")  # tape end
        self.file.flush()

        koko.FRAME.status = ''
        return True
Esempio n. 4
0
    def run(self, paths):
        ''' Convert the path from the previous panel into a g-code file
        '''

        koko.FRAME.status = 'Converting to .g file'

        values = self.get_values()
        if not values:  return False

        # Reverse direction for climb cutting
        if values['type']:
            paths = Path.sort([p.reverse() for p in paths])


        # Check to see if all of the z values are the same.  If so,
        # we can use 2D cutting commands; if not, we'll need
        # to do full three-axis motion control
        zmin = paths[0].points[0][2]
        flat = True
        for p in paths:
            if not all(pt[2] == zmin for pt in p.points):
                flat = False

        # Create a temporary file to store the .sbp instructions
        self.file = tempfile.NamedTemporaryFile(suffix=self.extension)

        self.file.write("%%\n")     # tape start
        self.file.write("G17\n")    # XY plane
        self.file.write("G20\n")    # Inch mode
        self.file.write("G40\n")    # Cancel tool diameter compensation
        self.file.write("G49\n")    # Cancel tool length offset
        self.file.write("G54\n")    # Coordinate system 1
        self.file.write("G80\n")    # Cancel motion
        self.file.write("G90\n")    # Absolute programming
        self.file.write("G94\n")    # Feedrate is per minute

        scale = 1/25.4 # inch units

        self.file.write("T%dM06\n" % values['tool']) # Tool selection + change
        self.file.write("F%0.4f\n" % (60*scale*values['feed']))  # Feed rate
        self.file.write("S%0.4f\n" % values['spindle']) # spindle speed
        if values['coolant']:   self.file.write("M08\n") # coolant on

        # Move up before starting spindle
        self.file.write("G00Z%0.4f\n" % (scale*values['jog']))
        self.file.write("M03\n") # spindle on (clockwise)
        self.file.write("G04 P1\n") # pause one second to spin up spindle

        xy  = lambda x,y:   (scale*x, scale*y)
        xyz = lambda x,y,z: (scale*x, scale*y, scale*z)


        for p in paths:

            # Move to the start of this path at the jog height
            self.file.write("G00X%0.4fY%0.4fZ%0.4f\n" %
                            xyz(p.points[0][0], p.points[0][1], values['jog']))

            # Plunge to the desired depth
            self.file.write("G01Z%0.4f F%0.4f\n" %
                            (p.points[0][2]*scale, 60*scale*values['plunge']))

            # Restore XY feed rate
            self.file.write("F%0.4f\n" % (60*scale*values['feed']))

            # Cut each point in the segment
            for pt in p.points:
                if flat:    self.file.write("X%0.4fY%0.4f\n" % xy(*pt[0:2]))
                else:       self.file.write("X%0.4fY%0.4fZ%0.4f\n" % xyz(*pt))

            # Lift the bit up to the jog height at the end of the segment
            self.file.write("Z%0.4f\n" % (scale*values['jog']))

        self.file.write("M05\n") # spindle stop
        if values['coolant']:   self.file.write("M09\n") # coolant off
        self.file.write("M30\n") # program end and reset
        self.file.write("%%\n")  # tape end
        self.file.flush()

        koko.FRAME.status = ''
        return True