def drawLoops(loops):
     nloop = 0
     waterlinestring = ""
     waterlinestring += "(waterline begin)"
     for loop in loops:
         p = loop[0]
         loopstring = "(loop begin)" + "\n"
         loopstring += "G0 Z" + str(obj.SafeHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
         loopstring += "G0 X" + \
             str(fmt(p.x)) + " Y" + str(fmt(p.y)) + "F " + PathUtils.fmt(self.horizRapid) + "\n"
         loopstring += "G1 Z" + str(fmt(p.z)) + "\n"
         for p in loop[1:]:
             loopstring += "G1 X" + \
                 str(fmt(p.x)) + " Y" + str(fmt(p.y)) + \
                 " Z" + str(fmt(p.z)) + "\n"
             zheight = p.z
         p = loop[0]
         loopstring += "G1 X" + \
             str(fmt(p.x)) + " Y" + str(fmt(p.y)) + \
             " Z" + str(fmt(zheight)) + "\n"
         loopstring += "(loop end)" + "\n"
         print "    loop ", nloop, " with ", len(loop), " points"
         nloop = nloop + 1
         waterlinestring += loopstring
     waterlinestring += "(waterline end)" + "\n"
     return waterlinestring
Exemple #2
0
 def drawLoops(loops):
     nloop = 0
     waterlinestring = ""
     waterlinestring += "(waterline begin)"
     for loop in loops:
         p = loop[0]
         loopstring = "(loop begin)" + "\n"
         loopstring += "G0 Z" + str(obj.SafeHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
         loopstring += "G0 X" + \
             str(fmt(p.x)) + " Y" + str(fmt(p.y)) + "F " + PathUtils.fmt(self.horizRapid) + "\n"
         loopstring += "G1 Z" + str(fmt(p.z)) + "\n"
         for p in loop[1:]:
             loopstring += "G1 X" + \
                 str(fmt(p.x)) + " Y" + str(fmt(p.y)) + \
                 " Z" + str(fmt(p.z)) + "\n"
             zheight = p.z
         p = loop[0]
         loopstring += "G1 X" + \
             str(fmt(p.x)) + " Y" + str(fmt(p.y)) + \
             " Z" + str(fmt(zheight)) + "\n"
         loopstring += "(loop end)" + "\n"
         print "    loop ", nloop, " with ", len(loop), " points"
         nloop = nloop + 1
         waterlinestring += loopstring
     waterlinestring += "(waterline end)" + "\n"
     return waterlinestring
Exemple #3
0
    def _dropcutter(self, obj, s, bb):
        import ocl
        import time

        cutter = ocl.CylCutter(self.radius * 2, 5)
        pdc = ocl.PathDropCutter()   # create a pdc
        pdc.setSTL(s)
        pdc.setCutter(cutter)
        pdc.minimumZ = 0.25
        pdc.setSampling(obj.SampleInterval)

        # some parameters for this "zigzig" pattern
        xmin = bb.XMin - cutter.getDiameter()
        xmax = bb.XMax + cutter.getDiameter()
        ymin = bb.YMin - cutter.getDiameter()
        ymax = bb.YMax + cutter.getDiameter()

        # number of lines in the y-direction
        Ny = int(bb.YLength / cutter.getDiameter())
        dy = float(ymax - ymin) / Ny  # the y step-over

        path = ocl.Path()                   # create an empty path object

        # add Line objects to the path in this loop
        for n in xrange(0, Ny):
            y = ymin + n * dy
            p1 = ocl.Point(xmin, y, 0)   # start-point of line
            p2 = ocl.Point(xmax, y, 0)   # end-point of line
            if (n % 2 == 0):  # even
                l = ocl.Line(p1, p2)     # line-object
            else:  # odd
                l = ocl.Line(p2, p1)     # line-object

            path.append(l)        # add the line to the path

        pdc.setPath(path)

        # run drop-cutter on the path
        t_before = time.time()
        pdc.run()
        t_after = time.time()
        print "calculation took ", t_after - t_before, " s"

        # retrieve the points
        clp = pdc.getCLPoints()
        print "points received: " + str(len(clp))

        # generate the path commands
        output = ""
        output += "G0 Z" + str(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
        output += "G0 X" + str(clp[0].x) + " Y" + str(clp[0].y) + "F " + PathUtils.fmt(self.horizRapid) + "\n"
        output += "G1 Z" + str(clp[0].z) + " F" + str(self.vertFeed) + "\n"

        for c in clp:
            output += "G1 X" + str(c.x) + " Y" + \
                str(c.y) + " Z" + str(c.z) + "\n"

        return output
    def _dropcutter(self, obj, s, bb):
        import ocl
        import time

        cutter = ocl.CylCutter(self.radius * 2, 5)
        pdc = ocl.PathDropCutter()   # create a pdc
        pdc.setSTL(s)
        pdc.setCutter(cutter)
        pdc.minimumZ = 0.25
        pdc.setSampling(obj.SampleInterval)

        # some parameters for this "zigzig" pattern
        xmin = bb.XMin - cutter.getDiameter()
        xmax = bb.XMax + cutter.getDiameter()
        ymin = bb.YMin - cutter.getDiameter()
        ymax = bb.YMax + cutter.getDiameter()

        # number of lines in the y-direction
        Ny = int(bb.YLength / cutter.getDiameter())
        dy = float(ymax - ymin) / Ny  # the y step-over

        path = ocl.Path()                   # create an empty path object

        # add Line objects to the path in this loop
        for n in xrange(0, Ny):
            y = ymin + n * dy
            p1 = ocl.Point(xmin, y, 0)   # start-point of line
            p2 = ocl.Point(xmax, y, 0)   # end-point of line
            if (n % 2 == 0):  # even
                l = ocl.Line(p1, p2)     # line-object
            else:  # odd
                l = ocl.Line(p2, p1)     # line-object

            path.append(l)        # add the line to the path

        pdc.setPath(path)

        # run drop-cutter on the path
        t_before = time.time()
        pdc.run()
        t_after = time.time()
        print "calculation took ", t_after - t_before, " s"

        # retrieve the points
        clp = pdc.getCLPoints()
        print "points received: " + str(len(clp))

        # generate the path commands
        output = ""
        output += "G0 Z" + str(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
        output += "G0 X" + str(clp[0].x) + " Y" + str(clp[0].y) + "F " + PathUtils.fmt(self.horizRapid) + "\n"
        output += "G1 Z" + str(clp[0].z) + " F" + str(self.vertFeed) + "\n"

        for c in clp:
            output += "G1 X" + str(c.x) + " Y" + \
                str(c.y) + " Z" + str(c.z) + "\n"

        return output
Exemple #5
0
    def execute(self, obj):
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment)+')\n'

        toolLoad = PathUtils.getLastToolLoad(obj)
        if toolLoad is None or toolLoad.ToolNumber == 0:
            self.vertFeed = 100
            self.horizFeed = 100
            self.radius = 0.25
            obj.ToolNumber = 0
            obj.ToolDescription = "UNDEFINED"
        else:
            self.vertFeed = toolLoad.VertFeed.Value
            self.horizFeed = toolLoad.HorizFeed.Value
            tool = PathUtils.getTool(obj, toolLoad.ToolNumber)
            self.radius = tool.Diameter/2
            obj.ToolNumber = toolLoad.ToolNumber
            obj.ToolDescription = toolLoad.Name

        if obj.UserLabel == "":
            obj.Label = obj.Name + " :" + obj.ToolDescription
        else:
            obj.Label = obj.UserLabel + " :" + obj.ToolDescription

        if obj.Base:
            output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value)+"\n"

            wires = []
            for o in obj.Base:
                # we only consider the outer wire if this is a Face
                for w in o[0].Shape.Wires:
                    tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                    wires.append (Part.Wire(tempedges))

                if obj.Algorithm == "OCC Native":
                    output += self.buildpathocc(obj, wires)

            output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value)+"\n"


        # print output
        if output == "":
            output += "(No commands processed)"

        if obj.Active:
            path = Path.Path(output)
            obj.Path = path
            obj.ViewObject.Visibility = True

        else:
            path = Path.Path("(inactive operation)")
            obj.Path = path
            obj.ViewObject.Visibility = False
Exemple #6
0
    def opExecute(self, obj):
        '''opExecute(obj) ... process engraving operation'''
        PathLog.track()

        zValues = []
        if obj.StepDown.Value != 0:
            z = obj.StartDepth.Value - obj.StepDown.Value

            while z > obj.FinalDepth.Value:
                zValues.append(z)
                z -= obj.StepDown.Value
        zValues.append(obj.FinalDepth.Value)
        self.zValues = zValues

        output = ''
        try:
            if self.baseobject.isDerivedFrom('Sketcher::SketchObject') or \
                    self.baseobject.isDerivedFrom('Part::Part2DObject') or \
                    hasattr(self.baseobject, 'ArrayType'):

                output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
                self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))

                # we only consider the outer wire if this is a Face
                wires = []
                for w in self.baseobject.Shape.Wires:
                    tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                    wires.append(Part.Wire(tempedges))
                output += self.buildpathocc(obj, wires, zValues)
                self.wires = wires

            elif isinstance(self.baseobject.Proxy, ArchPanel.PanelSheet):  # process the sheet
                wires = []
                for tag in self.baseobject.Proxy.getTags(self.baseobject, transform=True):
                    output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
                    self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
                    tagWires = []
                    for w in tag.Wires:
                        tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                        tagWires.append(Part.Wire(tempedges))
                    output += self.buildpathocc(obj, tagWires, zValues)
                    wires.extend(tagWires)
                self.wires = wires
            else:
                raise ValueError('Unknown baseobject type for engraving')

            output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
            self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))

        except Exception as e:
            #PathLog.error("Exception: %s" % e)
            PathLog.error(translate("Path", "The Job Base Object has no engraveable element.  Engraving operation will produce no output."))
Exemple #7
0
    def opExecute(self, obj):
        '''opExecute(obj) ... process engraving operation'''
        PathLog.track()

        zValues = []
        if obj.StepDown.Value != 0:
            z = obj.StartDepth.Value - obj.StepDown.Value

            while z > obj.FinalDepth.Value:
                zValues.append(z)
                z -= obj.StepDown.Value
        zValues.append(obj.FinalDepth.Value)
        self.zValues = zValues

        output = ''
        try:
            if self.baseobject.isDerivedFrom('Sketcher::SketchObject') or \
                    self.baseobject.isDerivedFrom('Part::Part2DObject') or \
                    hasattr(self.baseobject, 'ArrayType'):

                output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
                self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))

                # we only consider the outer wire if this is a Face
                wires = []
                for w in self.baseobject.Shape.Wires:
                    tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                    wires.append(Part.Wire(tempedges))
                output += self.buildpathocc(obj, wires, zValues)
                self.wires = wires

            elif isinstance(self.baseobject.Proxy, ArchPanel.PanelSheet):  # process the sheet
                wires = []
                for tag in self.baseobject.Proxy.getTags(self.baseobject, transform=True):
                    output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
                    self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
                    tagWires = []
                    for w in tag.Wires:
                        tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                        tagWires.append(Part.Wire(tempedges))
                    output += self.buildpathocc(obj, tagWires, zValues)
                    wires.extend(tagWires)
                self.wires = wires
            else:
                raise ValueError('Unknown baseobject type for engraving')

            output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
            self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))

        except Exception as e:
            #PathLog.error("Exception: %s" % e)
            PathLog.error(translate("Path", "The Job Base Object has no engraveable element.  Engraving operation will produce no output."))
Exemple #8
0
    def _buildPathLibarea(self, obj, edgelist):
        import PathScripts.PathKurveUtils as PathKurveUtils
        import math
        import area
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment)+')\n'

        if obj.StartPoint and obj.UseStartPoint:
            startpoint = obj.StartPoint
        else:
            startpoint = None

        if obj.EndPoint and obj.UseEndPoint:
            endpoint = obj.EndPoint
        else:
            endpoint = None

        PathKurveUtils.output('mem')
        PathKurveUtils.feedrate_hv(self.horizFeed, self.vertFeed)

        output = ""
        output += "G0 Z" + str(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
        curve = PathKurveUtils.makeAreaCurve(edgelist, obj.Direction, startpoint, endpoint)

        roll_radius = 2.0
        extend_at_start = 0.0
        extend_at_end = 0.0
        lead_in_line_len = 0.0
        lead_out_line_len = 0.0

        if obj.UseComp is False:
            obj.Side = 'On'
        else:
            if obj.Direction == 'CW':
                obj.Side = 'Left'
            else:
                obj.Side = 'Right'

        PathKurveUtils.clear_tags()
        for i in range(len(obj.locs)):
            tag = obj.locs[i]
            h = obj.heights[i]
            l = obj.lengths[i]
            a = math.radians(obj.angles[i])
            PathKurveUtils.add_tag(area.Point(tag.x, tag.y), l, a, h)

        depthparams = depth_params(
            obj.ClearanceHeight.Value,
            obj.SafeHeight.Value, obj.StartDepth.Value, obj.StepDown, 0.0,
            obj.FinalDepth.Value, None)

        PathKurveUtils.profile2(
            curve, obj.Side, self.radius, self.vertFeed, self.horizFeed,
            self.vertRapid, self.horizRapid, obj.OffsetExtra.Value, roll_radius,
            None, None, depthparams, extend_at_start, extend_at_end,
            lead_in_line_len, lead_out_line_len)

        output += PathKurveUtils.retrieve_gcode()
        return output
    def _buildPathLibarea(self, obj, edgelist):
        import PathScripts.PathKurveUtils as PathKurveUtils
        # import math
        # import area
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment) + ')\n'

        if obj.StartPoint and obj.UseStartPoint:
            startpoint = obj.StartPoint
        else:
            startpoint = None

        if obj.EndPoint and obj.UseEndPoint:
            endpoint = obj.EndPoint
        else:
            endpoint = None

        PathKurveUtils.output('mem')
        PathKurveUtils.feedrate_hv(self.horizFeed, self.vertFeed)

        output = ""
        output += "G0 Z" + str(
            obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                self.vertRapid) + "\n"
        curve = PathKurveUtils.makeAreaCurve(edgelist, obj.Direction,
                                             startpoint, endpoint)
        '''The following line uses a profile function written for use with FreeCAD.  It's clean but incomplete.  It doesn't handle
print("x = " + str(point.x))
print("y - " + str(point.y))
            holding tags
            start location
            CRC
            or probably other features in heekscnc'''
        # output += PathKurveUtils.profile(curve, side, radius, vf, hf, offset_extra, rapid_safety_space, clearance, start_depth, step_down, final_depth, use_CRC)
        '''The following calls the original procedure from h
        toolLoad = obj.activeTCeekscnc profile function.  This, in turn, calls many other procedures to modify the profile.
            This procedure is hacked together from heekscnc and has not been thoroughly reviewed or understood for FreeCAD.  It can probably be
            thoroughly optimized and improved but it'll take a smarter mind than mine to do it.  -sliptonic Feb16'''
        roll_radius = 2.0
        extend_at_start = 0.0
        extend_at_end = 0.0
        lead_in_line_len = 0.0
        lead_out_line_len = 0.0

        depthparams = depth_params(obj.ClearanceHeight.Value,
                                   obj.SafeHeight.Value, obj.StartDepth.Value,
                                   obj.StepDown.Value, 0.0,
                                   obj.FinalDepth.Value, None)

        PathKurveUtils.profile2(curve, obj.Side, self.radius, self.vertFeed,
                                self.horizFeed, self.vertRapid,
                                self.horizRapid, obj.OffsetExtra.Value,
                                roll_radius, None, None, depthparams,
                                extend_at_start, extend_at_end,
                                lead_in_line_len, lead_out_line_len)

        output += PathKurveUtils.retrieve_gcode()
        return output
Exemple #10
0
    def _buildPathLibarea(self, obj, edgelist):
        import PathScripts.PathKurveUtils as PathKurveUtils
        # import math
        # import area
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment)+')\n'

        if obj.StartPoint and obj.UseStartPoint:
            startpoint = obj.StartPoint
        else:
            startpoint = None

        if obj.EndPoint and obj.UseEndPoint:
            endpoint = obj.EndPoint
        else:
            endpoint = None

        PathKurveUtils.output('mem')
        PathKurveUtils.feedrate_hv(self.horizFeed, self.vertFeed)

        output = ""
        output += "G0 Z" + str(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
        curve = PathKurveUtils.makeAreaCurve(edgelist, obj.Direction, startpoint, endpoint)

        '''The following line uses a profile function written for use with FreeCAD.  It's clean but incomplete.  It doesn't handle
print("x = " + str(point.x))
print("y - " + str(point.y))
            holding tags
            start location
            CRC
            or probably other features in heekscnc'''
        # output += PathKurveUtils.profile(curve, side, radius, vf, hf, offset_extra, rapid_safety_space, clearance, start_depth, step_down, final_depth, use_CRC)

        '''The following calls the original procedure from h
        toolLoad = obj.activeTCeekscnc profile function.  This, in turn, calls many other procedures to modify the profile.
            This procedure is hacked together from heekscnc and has not been thoroughly reviewed or understood for FreeCAD.  It can probably be
            thoroughly optimized and improved but it'll take a smarter mind than mine to do it.  -sliptonic Feb16'''
        roll_radius = 2.0
        extend_at_start = 0.0
        extend_at_end = 0.0
        lead_in_line_len = 0.0
        lead_out_line_len = 0.0

        depthparams = depth_params(
            obj.ClearanceHeight.Value,
            obj.SafeHeight.Value, obj.StartDepth.Value, obj.StepDown.Value, 0.0,
            obj.FinalDepth.Value, None)

        PathKurveUtils.profile2(
            curve, obj.Side, self.radius, self.vertFeed, self.horizFeed,
            self.vertRapid, self.horizRapid, obj.OffsetExtra.Value, roll_radius,
            None, None, depthparams, extend_at_start, extend_at_end,
            lead_in_line_len, lead_out_line_len)

        output += PathKurveUtils.retrieve_gcode()
        return output
Exemple #11
0
    def _buildPathLibarea(self, obj, edgelist):
        import PathScripts.PathKurveUtils as PathKurveUtils
        # import math
        # import area
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment) + ')\n'

        if obj.StartPoint and obj.UseStartPoint:
            startpoint = obj.StartPoint
        else:
            startpoint = None

        if obj.EndPoint and obj.UseEndPoint:
            endpoint = obj.EndPoint
        else:
            endpoint = None

        PathKurveUtils.output('mem')
        PathKurveUtils.feedrate_hv(self.horizFeed, self.vertFeed)

        output = ""
        output += "G0 Z" + str(
            obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                self.vertRapid) + "\n"
        curve = PathKurveUtils.makeAreaCurve(edgelist, obj.Direction,
                                             startpoint, endpoint)

        roll_radius = 2.0
        extend_at_start = 0.0
        extend_at_end = 0.0
        lead_in_line_len = 0.0
        lead_out_line_len = 0.0

        if obj.UseComp is False:
            obj.Side = 'On'
        else:
            if obj.Direction == 'CW':
                obj.Side = 'Left'
            else:
                obj.Side = 'Right'

        depthparams = depth_params(obj.ClearanceHeight.Value,
                                   obj.SafeHeight.Value, obj.StartDepth.Value,
                                   obj.StepDown.Value, 0.0,
                                   obj.FinalDepth.Value, None)

        PathKurveUtils.profile2(curve, obj.Side, self.radius, self.vertFeed,
                                self.horizFeed, self.vertRapid,
                                self.horizRapid, obj.OffsetExtra.Value,
                                roll_radius, None, None, depthparams,
                                extend_at_start, extend_at_end,
                                lead_in_line_len, lead_out_line_len)

        output += PathKurveUtils.retrieve_gcode()
        return output
def profile(offset_curve,
            side_of_line,
            radius=1.0,
            vertfeed=0.0,
            horizfeed=0.0,
            offset_extra=0.0,
            rapid_safety_space=None,
            clearance=None,
            start_depth=None,
            stepdown=None,
            final_depth=None,
            use_CRC=False,
            roll_on=None,
            roll_off=None,
            roll_start=False,
            roll_end=True,
            roll_radius=None,
            roll_start_pt=None,
            roll_end_pt=None):
    output = ""
    output += "G0 Z" + str(clearance) + "\n"
    #    print("in profile: 151")
    #    offset_curve = area.Curve(curve)
    if offset_curve.getNumVertices() <= 1:
        raise Exception("Sketch has no elements!")
    if side_of_line == "On":
        use_CRC = False

    elif (side_of_line == "Left") or (side_of_line == "Right"):
        # get tool radius plus little bit of extra offset, if needed to clean
        # up profile a little more
        offset = radius + offset_extra
        if side_of_line == 'Left':
            offset_curve.Offset(offset)

        else:
            offset_curve.Offset(-offset)

        if offset_curve is False:
            raise Exception("couldn't offset kurve " + str(offset_curve))
    else:
        raise Exception("Side must be 'Left','Right', or 'On'")


# =========================================================================
#     #roll_on roll_off section
#     roll_on_curve = area.Curve()
#     if offset_curve.getNumVertices() <= 1: return
#     first_span = offset_curve.GetFirstSpan()
#     if roll_on == None:
#         rollstart = first_span.p
#     elif roll_on == 'auto':
#         if roll_radius < 0.0000000001:
#             rollstart = first_span.p
#         v = first_span.GetVector(0.0)
#         if direction == 'right':
#             off_v = area.Point(v.y, -v.x)
#         else:
#             off_v = area.Point(-v.y, v.x)
#         rollstart = first_span.p + off_v * roll_radius
#     else:
#         rollstart = roll_on
#
#     rvertex = area.Vertex(first_span.p)
#
#     if first_span.p == rollstart:
#         rvertex.type = 0
#     else:
#         v = first_span.GetVector(0.0) # get start direction
#         rvertex.c, rvertex.type = area.TangentialArc(first_span.p, rollstart, -v)
#         rvertex.type = -rvertex.type # because TangentialArc was used in reverse
#     # add a start roll on point
#     roll_on_curve.append(rollstart)
#
#     # add the roll on arc
#     roll_on_curve.append(rvertex)
#     #end of roll_on roll_off section
# =========================================================================

# do multiple depths
    layer_count = int((start_depth - final_depth) / stepdown)
    if layer_count * stepdown + 0.00001 < start_depth - final_depth:
        layer_count += 1
    # current_start_depth = start_depth
    prev_depth = start_depth
    for i in range(1, layer_count + 1):
        if i == layer_count:
            depth = final_depth
        else:
            depth = start_depth - i * stepdown
        mat_depth = prev_depth
        start_z = mat_depth
        # first move
        output += "G0 X" + str(PathUtils.fmt(offset_curve.GetFirstSpan().p.x)) +\
            " Y" + str(PathUtils.fmt(offset_curve.GetFirstSpan().p.y)) +\
            " Z" + str(PathUtils.fmt(mat_depth + rapid_safety_space)) + "\n"
        # feed down to depth
        mat_depth = depth
        if start_z > mat_depth:
            mat_depth = start_z
        # feed down in Z
        output += "G1 X" + str(PathUtils.fmt(offset_curve.GetFirstSpan().p.x)) +\
            " Y" + str(PathUtils.fmt(offset_curve.GetFirstSpan().p.y)) + " Z" + str(PathUtils.fmt(depth)) +\
            " F" + str(PathUtils.fmt(vertfeed)) + "\n"
        if use_CRC:
            if side_of_line == 'left':
                output += "G41" + "\n"
            else:
                output += "G42" + "\n"
        # cut the main kurve
        current_perim = 0.0
        lastx = offset_curve.GetFirstSpan().p.x
        lasty = offset_curve.GetFirstSpan().p.y
        for span in offset_curve.GetSpans():
            current_perim += span.Length()
            if span.v.type == 0:  # line
                # feed(span.v.p.x, span.v.p.y, ez)
                output += "G1 X" + str(PathUtils.fmt(span.v.p.x)) + " Y" + str(PathUtils.fmt(span.v.p.y)) +\
                    " Z" + str(PathUtils.fmt(depth)) + " F" + \
                    str(PathUtils.fmt(horizfeed)) + "\n"
                lastx = span.v.p.x
                lasty = span.v.p.y
            elif (span.v.type == 1) or (span.v.type == -1):
                if span.v.type == 1:  # anti-clockwise arc
                    command = 'G3'
                elif span.v.type == -1:  # clockwise arc
                    command = 'G2'
                arc_I = span.v.c.x - lastx
                arc_J = span.v.c.y - lasty
                output += command + "X" + str(PathUtils.fmt(
                    span.v.p.x)) + " Y" + str(PathUtils.fmt(
                        span.v.p.y))  # +" Z"+ str(PathUtils.fmt(depth))
                output += " I" + str(PathUtils.fmt(arc_I)) + " J" + str(
                    PathUtils.fmt(arc_J)) + " F" + str(
                        PathUtils.fmt(horizfeed)
                    ) + '\n'  # " K"+str(PathUtils.fmt(depth)) +"\n"
                lastx = span.v.p.x
                lasty = span.v.p.y
            else:
                raise Exception("valid geometry identifier needed")
        if use_CRC:
            # end_CRC()
            output += "G40" + "\n"
        # rapid up to the clearance height
        output += "G0 Z" + str(PathUtils.fmt(clearance)) + "\n"

    del offset_curve

    return output
def profile(curve, side_of_line, radius=1.0, vertfeed=0.0, horizfeed=0.0, offset_extra=0.0,
            rapid_safety_space=None, clearance=None, start_depth=None, stepdown=None,
            final_depth=None, use_CRC=False,
            roll_on=None, roll_off=None, roll_start=False, roll_end=True, roll_radius=None,
            roll_start_pt=None, roll_end_pt=None):

    output = ""
    output += "G0 Z" + str(clearance) + "\n"
    print "in profile: 151"
    offset_curve = area.Curve(curve)
    if offset_curve.getNumVertices() <= 1:
        raise Exception, "Sketch has no elements!"
    if side_of_line == "On":
        use_CRC = False

    elif (side_of_line == "Left") or (side_of_line == "Right"):
        # get tool radius plus little bit of extra offset, if needed to clean
        # up profile a little more
        offset = radius + offset_extra
        if side_of_line == 'Left':
            offset_curve.Offset(offset)

        else:
            offset_curve.Offset(-offset)

        if offset_curve is False:
            raise Exception, "couldn't offset kurve " + str(offset_curve)
    else:
        raise Exception, "Side must be 'Left','Right', or 'On'"

# =========================================================================
#     #roll_on roll_off section
#     roll_on_curve = area.Curve()
#     if offset_curve.getNumVertices() <= 1: return
#     first_span = offset_curve.GetFirstSpan()
#     if roll_on == None:
#         rollstart = first_span.p
#     elif roll_on == 'auto':
#         if roll_radius < 0.0000000001:
#             rollstart = first_span.p
#         v = first_span.GetVector(0.0)
#         if direction == 'right':
#             off_v = area.Point(v.y, -v.x)
#         else:
#             off_v = area.Point(-v.y, v.x)
#         rollstart = first_span.p + off_v * roll_radius
#     else:
#         rollstart = roll_on
#
#     rvertex = area.Vertex(first_span.p)
#
#     if first_span.p == rollstart:
#         rvertex.type = 0
#     else:
#         v = first_span.GetVector(0.0) # get start direction
#         rvertex.c, rvertex.type = area.TangentialArc(first_span.p, rollstart, -v)
#         rvertex.type = -rvertex.type # because TangentialArc was used in reverse
#     # add a start roll on point
#     roll_on_curve.append(rollstart)
#
#     # add the roll on arc
#     roll_on_curve.append(rvertex)
#     #end of roll_on roll_off section
# =========================================================================

    # do multiple depths
    layer_count = int((start_depth - final_depth) / stepdown)
    if layer_count * stepdown + 0.00001 < start_depth - final_depth:
        layer_count += 1
    current_start_depth = start_depth
    prev_depth = start_depth
    for i in range(1, layer_count + 1):
        if i == layer_count:
            depth = final_depth
        else:
            depth = start_depth - i * stepdown
        mat_depth = prev_depth
        start_z = mat_depth
        # first move
        output += "G0 X" + str(PathUtils.fmt(offset_curve.GetFirstSpan().p.x)) +\
            " Y" + str(PathUtils.fmt(offset_curve.GetFirstSpan().p.y)) +\
            " Z" + str(PathUtils.fmt(mat_depth + rapid_safety_space)) + "\n"
        # feed down to depth
        mat_depth = depth
        if start_z > mat_depth:
            mat_depth = start_z
        # feed down in Z
        output += "G1 X" + str(PathUtils.fmt(offset_curve.GetFirstSpan().p.x)) +\
            " Y" + str(PathUtils.fmt(offset_curve.GetFirstSpan().p.y)) + " Z" + str(PathUtils.fmt(depth)) +\
            " F" + str(PathUtils.fmt(vertfeed)) + "\n"
        if use_CRC:
            if side_of_line == 'left':
                output += "G41" + "\n"
            else:
                output += "G42" + "\n"
        # cut the main kurve
        current_perim = 0.0
        lastx = offset_curve.GetFirstSpan().p.x
        lasty = offset_curve.GetFirstSpan().p.y
        for span in offset_curve.GetSpans():
            current_perim += span.Length()
            if span.v.type == 0:  # line
                # feed(span.v.p.x, span.v.p.y, ez)
                output += "G1 X" + str(PathUtils.fmt(span.v.p.x)) + " Y" + str(PathUtils.fmt(span.v.p.y)) +\
                    " Z" + str(PathUtils.fmt(depth)) + " F" + \
                    str(PathUtils.fmt(horizfeed)) + "\n"
                lastx = span.v.p.x
                lasty = span.v.p.y
            elif (span.v.type == 1) or (span.v.type == -1):
                if span.v.type == 1:  # anti-clockwise arc
                    command = 'G3'
                elif span.v.type == -1:  # clockwise arc
                    command = 'G2'
                arc_I = span.v.c.x - lastx
                arc_J = span.v.c.y - lasty
                output += command + "X" + str(PathUtils.fmt(span.v.p.x)) + " Y" + str(
                    PathUtils.fmt(span.v.p.y))  # +" Z"+ str(PathUtils.fmt(depth))
                output += " I" + str(PathUtils.fmt(arc_I)) + " J" + str(PathUtils.fmt(arc_J)) + " F" + str(
                    PathUtils.fmt(horizfeed)) + '\n'  # " K"+str(PathUtils.fmt(depth)) +"\n"
                lastx = span.v.p.x
                lasty = span.v.p.y
            else:
                raise Exception, "valid geometry identifier needed"
        if use_CRC:
            # end_CRC()
            output += "G40" + "\n"
        # rapid up to the clearance height
        output += "G0 Z" + str(PathUtils.fmt(clearance)) + "\n"

    del offset_curve

    return output
Exemple #14
0
    def execute(self, obj):
        PathLog.track()
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment)+')\n'

        toolLoad = obj.ToolController
        if toolLoad is None or toolLoad.ToolNumber == 0:
            FreeCAD.Console.PrintError("No Tool Controller is selected. We need a tool to build a Path.")
            return
        else:
            self.vertFeed = toolLoad.VertFeed.Value
            self.horizFeed = toolLoad.HorizFeed.Value
            self.vertRapid = toolLoad.VertRapid.Value
            self.horizRapid = toolLoad.HorizRapid.Value
            tool = toolLoad.Proxy.getTool(toolLoad)
            if not tool or tool.Diameter == 0:
                FreeCAD.Console.PrintError("No Tool found or diameter is zero. We need a tool to build a Path.")
                return
            else:
                self.radius = tool.Diameter/2

        if not obj.Base:
            parentJob = PathUtils.findParentJob(obj)
            if parentJob is None:
                return
            baseobject = parentJob.Base
            if baseobject is None:
                return
            holes = self.findHoles(obj, baseobject.Shape)
            for hole in holes:
                self.addDrillableLocation(obj, baseobject, hole[0])

        locations = []
        output = "(Begin Drilling)\n"
        if obj.Base:
            for loc in obj.Base:
                #print loc
                for sub in loc[1]:
                    #locations.append(self._findDrillingVector(loc))

                    if "Face" in sub or "Edge" in sub:
                        s = getattr(loc[0].Shape, sub)
                    else:
                        s = loc[0].Shape

                    if s.ShapeType in ['Wire', 'Edge']:
                        X = s.Edges[0].Curve.Center.x
                        Y = s.Edges[0].Curve.Center.y
                        Z = s.Edges[0].Curve.Center.z
                    elif s.ShapeType in ['Vertex']:
                        X = s.Point.x
                        Y = s.Point.y
                        Z = s.Point.z
                    elif s.ShapeType in ['Face']:
                        #if abs(s.normalAt(0, 0).z) == 1:  # horizontal face
                        X = s.CenterOfMass.x
                        Y = s.CenterOfMass.y
                        Z = s.CenterOfMass.z
                    locations.append(FreeCAD.Vector(X, Y, Z))

            output += "G90 G98\n"
            # rapid to clearance height
            output += "G0 Z" + str(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
            # rapid to first hole location, with spindle still retracted:
            p0 = locations[0]
            output += "G0 X" + fmt(p0.x) + " Y" + fmt(p0.y)  + "F " + PathUtils.fmt(self.horizRapid) + "\n"
            # move tool to clearance plane
            output += "G0 Z" + fmt(obj.ClearanceHeight.Value)  + "F " + PathUtils.fmt(self.vertRapid) + "\n"
            pword = ""
            qword = ""
            if obj.PeckDepth.Value > 0:
                cmd = "G83"
                qword = " Q" + fmt(obj.PeckDepth.Value)
            elif obj.DwellTime > 0:
                cmd = "G82"
                pword = " P" + fmt(obj.DwellTime)
            else:
                cmd = "G81"
            for p in locations:
                output += cmd + \
                    " X" + fmt(p.x) + \
                    " Y" + fmt(p.y) + \
                    " Z" + fmt(obj.FinalDepth.Value) + qword + pword + \
                    " R" + str(obj.RetractHeight.Value) + \
                    " F" + str(self.vertFeed) + "\n" \

            output += "G80\n"

        if obj.Active:
            path = Path.Path(output)
            obj.Path = path
            obj.ViewObject.Visibility = True

        else:
            path = Path.Path("(inactive operation)")
            obj.Path = path
            obj.ViewObject.Visibility = False
Exemple #15
0
    def buildpathocc(self, obj, wires, zValues):
        '''buildpathocc(obj, wires, zValues) ... internal helper function to generate engraving commands.'''
        PathLog.track()

        output = ""

        for wire in wires:
            offset = wire

            # reorder the wire
            offset = DraftGeomUtils.rebaseWire(offset, obj.StartVertex)

            last = None
            for z in zValues:
                if last:
                    self.commandlist.append(Path.Command('G1', {'X': last.x, 'Y': last.y, 'Z': z, 'F': self.vertFeed}))

                for edge in offset.Edges:
                    if not last:
                        # we set the first move to our first point
                        last = edge.Vertexes[0].Point
                        output += "G0" + " X" + PathUtils.fmt(last.x) + " Y" + PathUtils.fmt(last.y) + " Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.horizRapid)  # Rapid to starting position
                        self.commandlist.append(Path.Command('G0', {'X': last.x, 'Y': last.y, 'Z': obj.ClearanceHeight.Value, 'F': self.horizRapid}))
                        output += "G0" + " X" + PathUtils.fmt(last.x) + " Y" + PathUtils.fmt(last.y) + " Z" + PathUtils.fmt(obj.SafeHeight.Value) + "F " + PathUtils.fmt(self.horizRapid)  # Rapid to safe height
                        self.commandlist.append(Path.Command('G0', {'X': last.x, 'Y': last.y, 'Z': obj.SafeHeight.Value, 'F': self.vertRapid}))
                        output += "G1" + " X" + PathUtils.fmt(last.x) + " Y" + PathUtils.fmt(last.y) + " Z" + PathUtils.fmt(z) + "F " + PathUtils.fmt(self.vertFeed) + "\n"  # Vertical feed to depth
                        self.commandlist.append(Path.Command('G0', {'X': last.x, 'Y': last.y, 'Z': z, 'F': self.vertFeed}))

                    if isinstance(edge.Curve, Part.Circle):
                        point = edge.Vertexes[-1].Point
                        if point == last:  # edges can come flipped
                            point = edge.Vertexes[0].Point
                        center = edge.Curve.Center
                        relcenter = center.sub(last)
                        v1 = last.sub(center)
                        v2 = point.sub(center)
                        if v1.cross(v2).z < 0:
                            output += "G2"
                        else:
                            output += "G3"
                        output += " X" + PathUtils.fmt(point.x) + " Y" + PathUtils.fmt(point.y) + " Z" + PathUtils.fmt(z)
                        output += " I" + PathUtils.fmt(relcenter.x) + " J" + PathUtils.fmt(relcenter.y) + " K" + PathUtils.fmt(relcenter.z)
                        output += " F " + PathUtils.fmt(self.horizFeed)
                        output += "\n"

                        cmd = 'G2' if v1.cross(v2).z < 0 else 'G3'
                        args = {}
                        args['X'] = point.x
                        args['Y'] = point.y
                        args['Z'] = z
                        args['I'] = relcenter.x
                        args['J'] = relcenter.y
                        args['K'] = relcenter.z
                        args['F'] = self.horizFeed
                        self.commandlist.append(Path.Command(cmd, args))
                        last = point
                    else:
                        point = edge.Vertexes[-1].Point
                        if point == last:  # edges can come flipped
                            point = edge.Vertexes[0].Point
                        output += "G1 X" + PathUtils.fmt(point.x) + " Y" + PathUtils.fmt(point.y) + " Z" + PathUtils.fmt(z)
                        output += " F " + PathUtils.fmt(self.horizFeed)
                        output += "\n"
                        self.commandlist.append(Path.Command('G1', {'X': point.x, 'Y': point.y, 'Z': z, 'F': self.horizFeed}))
                        last = point
            output += "G0 Z " + PathUtils.fmt(obj.ClearanceHeight.Value)
            self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
        return output
    def _buildPathLibarea(self, obj, edgelist, isHole):
        import PathScripts.PathKurveUtils as PathKurveUtils
        import math
        import area
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment)+')\n'

        if obj.StartPoint and obj.UseStartPoint:
            startpoint = obj.StartPoint
        else:
            startpoint = None

        if obj.EndPoint and obj.UseEndPoint:
            endpoint = obj.EndPoint
        else:
            endpoint = None

        PathKurveUtils.output('mem')
        PathKurveUtils.feedrate_hv(self.horizFeed, self.vertFeed)

        # Reverse the direction for holes
        if isHole:
            direction = "CW" if obj.Direction == "CCW" else "CCW"
        else:
            direction = obj.Direction

        output = ""
        output += "G0 Z" + str(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
        curve = PathKurveUtils.makeAreaCurve(edgelist, direction, startpoint, endpoint)

        '''The following line uses a profile function written for use with FreeCAD.  It's clean but incomplete.  It doesn't handle
print "x = " + str(point.x)
print "y - " + str(point.y)
            holding tags
            start location
            CRC
            or probably other features in heekscnc'''
        # output += PathKurveUtils.profile(curve, side, radius, vf, hf, offset_extra, rapid_safety_space, clearance, start_depth, step_down, final_depth, use_CRC)

        '''The following calls the original procedure from h
        toolLoad = obj.activeTCeekscnc profile function.  This, in turn, calls many other procedures to modify the profile.
            This procedure is hacked together from heekscnc and has not been thoroughly reviewed or understood for FreeCAD.  It can probably be
            thoroughly optimized and improved but it'll take a smarter mind than mine to do it.  -sliptonic Feb16'''
        roll_radius = 2.0
        extend_at_start = 0.0
        extend_at_end = 0.0
        lead_in_line_len = 0.0
        lead_out_line_len = 0.0

        '''

        Right here, I need to know the Holding Tags group from the tree that refers to this profile operation and build up the tags for PathKurve Utils.
        I need to access the location vector, length, angle in radians and height.

        '''
        PathKurveUtils.clear_tags()
        for i in range(len(obj.locs)):
            tag = obj.locs[i]
            h = obj.heights[i]
            l = obj.lengths[i]
            a = math.radians(obj.angles[i])
            PathKurveUtils.add_tag(area.Point(tag.x, tag.y), l, a, h)

        depthparams = depth_params(
            obj.ClearanceHeight.Value,
            obj.SafeHeight.Value, obj.StartDepth.Value, obj.StepDown, 0.0,
            obj.FinalDepth.Value, None)

        PathKurveUtils.profile2(
            curve, obj.Side, self.radius, self.vertFeed, self.horizFeed,
            self.vertRapid, self.horizRapid, obj.OffsetExtra.Value, roll_radius,
            None, None, depthparams, extend_at_start, extend_at_end,
            lead_in_line_len, lead_out_line_len)

        output += PathKurveUtils.retrieve_gcode()
        return output
Exemple #17
0
    def execute(self, obj):
        PathLog.track()

        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment)+')\n'

        toolLoad = obj.ToolController

        if toolLoad is None or toolLoad.ToolNumber == 0:
            FreeCAD.Console.PrintError("No Tool Controller is selected. We need a tool to build a Path.")
            return
        else:
            self.vertFeed = toolLoad.VertFeed.Value
            self.horizFeed = toolLoad.HorizFeed.Value
            self.vertRapid = toolLoad.VertRapid.Value
            self.horizRapid = toolLoad.HorizRapid.Value
            tool = toolLoad.Proxy.getTool(toolLoad)  # PathUtils.getTool(obj, toolLoad.ToolNumber)
            if not tool or tool.Diameter == 0:
                FreeCAD.Console.PrintError("No Tool found or diameter is zero. We need a tool to build a Path.")
                return
            else:
                self.radius = tool.Diameter/2

        wires = []

        parentJob = PathUtils.findParentJob(obj)
        if parentJob is None:
            return
        baseobject = parentJob.Base
        if baseobject is None:
            return
        try:
            if baseobject.isDerivedFrom('Sketcher::SketchObject') or \
                    baseobject.isDerivedFrom('Part::Part2DObject'):

                output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"

                # we only consider the outer wire if this is a Face
                for w in baseobject.Shape.Wires:
                    tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                    wires.append(Part.Wire(tempedges))

                if obj.Algorithm == "OCC Native":
                    output += self.buildpathocc(obj, wires)

            elif isinstance(baseobject.Proxy, ArchPanel.PanelSheet):  # process the sheet

                shapes = baseobject.Proxy.getTags(baseobject, transform=True)
                for shape in shapes:
                    output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
                    for w in shape.Wires:
                        tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                        wires.append(Part.Wire(tempedges))
                    if obj.Algorithm == "OCC Native":
                        output += self.buildpathocc(obj, wires)
            else:
                raise ValueError('Unknown baseobject type for engraving')

            output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"

        except:
            FreeCAD.Console.PrintError("The Job Base Object has no engraveable element.  Engraving operation will produce no output.")

        # print output
        if output == "":
            output += "(No commands processed)"

        if obj.Active:
            path = Path.Path(output)
            obj.Path = path
            obj.ViewObject.Visibility = True

        else:
            path = Path.Path("(inactive operation)")
            obj.Path = path
            obj.ViewObject.Visibility = False
Exemple #18
0
    def _buildPathLibarea(self, obj, edgelist, isHole):
        import PathScripts.PathKurveUtils as PathKurveUtils
        import math
        import area
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment) + ')\n'

        if obj.StartPoint and obj.UseStartPoint:
            startpoint = obj.StartPoint
        else:
            startpoint = None

        if obj.EndPoint and obj.UseEndPoint:
            endpoint = obj.EndPoint
        else:
            endpoint = None

        PathKurveUtils.output('mem')
        PathKurveUtils.feedrate_hv(self.horizFeed, self.vertFeed)

        # Reverse the direction for holes
        if isHole:
            direction = "CW" if obj.Direction == "CCW" else "CCW"
        else:
            direction = obj.Direction

        output = ""
        output += "G0 Z" + str(
            obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                self.vertRapid) + "\n"
        curve = PathKurveUtils.makeAreaCurve(edgelist, direction, startpoint,
                                             endpoint)
        '''The following line uses a profile function written for use with FreeCAD.  It's clean but incomplete.  It doesn't handle
print "x = " + str(point.x)
print "y - " + str(point.y)
            holding tags
            start location
            CRC
            or probably other features in heekscnc'''
        # output += PathKurveUtils.profile(curve, side, radius, vf, hf, offset_extra, rapid_safety_space, clearance, start_depth, step_down, final_depth, use_CRC)
        '''The following calls the original procedure from h
        toolLoad = obj.activeTCeekscnc profile function.  This, in turn, calls many other procedures to modify the profile.
            This procedure is hacked together from heekscnc and has not been thoroughly reviewed or understood for FreeCAD.  It can probably be
            thoroughly optimized and improved but it'll take a smarter mind than mine to do it.  -sliptonic Feb16'''
        roll_radius = 2.0
        extend_at_start = 0.0
        extend_at_end = 0.0
        lead_in_line_len = 0.0
        lead_out_line_len = 0.0
        '''

        Right here, I need to know the Holding Tags group from the tree that refers to this profile operation and build up the tags for PathKurve Utils.
        I need to access the location vector, length, angle in radians and height.

        '''
        PathKurveUtils.clear_tags()
        for i in range(len(obj.locs)):
            tag = obj.locs[i]
            h = obj.heights[i]
            l = obj.lengths[i]
            a = math.radians(obj.angles[i])
            PathKurveUtils.add_tag(area.Point(tag.x, tag.y), l, a, h)

        depthparams = depth_params(obj.ClearanceHeight.Value,
                                   obj.SafeHeight.Value, obj.StartDepth.Value,
                                   obj.StepDown, 0.0, obj.FinalDepth.Value,
                                   None)

        PathKurveUtils.profile2(curve, obj.Side, self.radius, self.vertFeed,
                                self.horizFeed, self.vertRapid,
                                self.horizRapid, obj.OffsetExtra.Value,
                                roll_radius, None, None, depthparams,
                                extend_at_start, extend_at_end,
                                lead_in_line_len, lead_out_line_len)

        output += PathKurveUtils.retrieve_gcode()
        return output
Exemple #19
0
    def opExecute(self, obj):
        '''opExecute(obj) ... process engraving operation'''
        PathLog.track()

        zValues = []
        if obj.StepDown.Value != 0:
            z = obj.StartDepth.Value - obj.StepDown.Value

            while z > obj.FinalDepth.Value:
                zValues.append(z)
                z -= obj.StepDown.Value
        zValues.append(obj.FinalDepth.Value)
        self.zValues = zValues

        output = ''
        try:
            if self.baseobject.isDerivedFrom('Sketcher::SketchObject') or \
                    self.baseobject.isDerivedFrom('Part::Part2DObject') or \
                    hasattr(self.baseobject, 'ArrayType'):

                output += "G0 Z" + PathUtils.fmt(
                    obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                        self.vertRapid) + "\n"
                self.commandlist.append(
                    Path.Command('G0', {
                        'Z': obj.ClearanceHeight.Value,
                        'F': self.vertRapid
                    }))

                # we only consider the outer wire if this is a Face
                wires = []
                for w in self.baseobject.Shape.Wires:
                    tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                    wires.append(Part.Wire(tempedges))
                output += self.buildpathocc(obj, wires, zValues)
                self.wires = wires

            elif isinstance(self.baseobject.Proxy,
                            ArchPanel.PanelSheet):  # process the sheet
                wires = []
                for tag in self.baseobject.Proxy.getTags(self.baseobject,
                                                         transform=True):
                    output += "G0 Z" + PathUtils.fmt(
                        obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                            self.vertRapid) + "\n"
                    self.commandlist.append(
                        Path.Command('G0', {
                            'Z': obj.ClearanceHeight.Value,
                            'F': self.vertRapid
                        }))
                    tagWires = []
                    for w in tag.Wires:
                        tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                        tagWires.append(Part.Wire(tempedges))
                    output += self.buildpathocc(obj, tagWires, zValues)
                    wires.extend(tagWires)
                self.wires = wires
            elif obj.Base:
                wires = []
                for base, subs in obj.Base:
                    edges = []
                    for sub in subs:
                        edges.extend(base.Shape.getElement(sub).Edges)
                    shapeWires = adjustWirePlacement(
                        obj, base, TechDraw.edgeWalker(edges))
                    wires.extend(shapeWires)
                output += self.buildpathocc(obj, wires, zValues)
                self.wires = wires
            elif not obj.BaseShapes:
                raise ValueError(
                    translate('PathEngrave',
                              "Unknown baseobject type for engraving (%s)") %
                    (obj.Base))

            if obj.BaseShapes:
                wires = []
                for shape in obj.BaseShapes:
                    shapeWires = adjustWirePlacement(obj, shape,
                                                     shape.Shape.Wires)
                    output += self.buildpathocc(obj, shapeWires, zValues)
                    wires.extend(shapeWires)
                self.wires = wires
            output += "G0 Z" + PathUtils.fmt(
                obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                    self.vertRapid) + "\n"
            self.commandlist.append(
                Path.Command('G0', {
                    'Z': obj.ClearanceHeight.Value,
                    'F': self.vertRapid
                }))

        except Exception as e:
            PathLog.error(e)
            traceback.print_exc()
            PathLog.error(
                translate(
                    'PathEngrave',
                    'The Job Base Object has no engraveable element.  Engraving operation will produce no output.'
                ))
Exemple #20
0
    def execute(self, obj):
        PathLog.track()

        if not obj.Active:
            path = Path.Path("(inactive operation)")
            obj.Path = path
            obj.ViewObject.Visibility = False
            return

        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment) + ')\n'

        toolLoad = obj.ToolController

        if toolLoad is None or toolLoad.ToolNumber == 0:
            FreeCAD.Console.PrintError(
                "No Tool Controller is selected. We need a tool to build a Path."
            )
            return
        else:
            self.vertFeed = toolLoad.VertFeed.Value
            self.horizFeed = toolLoad.HorizFeed.Value
            self.vertRapid = toolLoad.VertRapid.Value
            self.horizRapid = toolLoad.HorizRapid.Value
            tool = toolLoad.Proxy.getTool(
                toolLoad)  # PathUtils.getTool(obj, toolLoad.ToolNumber)
            if not tool or tool.Diameter == 0:
                FreeCAD.Console.PrintError(
                    "No Tool found or diameter is zero. We need a tool to build a Path."
                )
                return
            else:
                self.radius = tool.Diameter / 2

        wires = []

        parentJob = PathUtils.findParentJob(obj)
        if parentJob is None:
            return
        baseobject = parentJob.Base
        if baseobject is None:
            return
        try:
            if baseobject.isDerivedFrom('Sketcher::SketchObject') or \
                    baseobject.isDerivedFrom('Part::Part2DObject') or \
                    hasattr(baseobject, 'ArrayType'):

                output += "G0 Z" + PathUtils.fmt(
                    obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                        self.vertRapid) + "\n"

                # we only consider the outer wire if this is a Face
                for w in baseobject.Shape.Wires:
                    tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                    wires.append(Part.Wire(tempedges))

                output += self.buildpathocc(obj, wires)

            elif isinstance(baseobject.Proxy,
                            ArchPanel.PanelSheet):  # process the sheet

                shapes = baseobject.Proxy.getTags(baseobject, transform=True)
                for shape in shapes:
                    output += "G0 Z" + PathUtils.fmt(
                        obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                            self.vertRapid) + "\n"
                    for w in shape.Wires:
                        tempedges = PathUtils.cleanedges(w.Edges, 0.5)
                        wires.append(Part.Wire(tempedges))
                    output += self.buildpathocc(obj, wires)
            else:
                raise ValueError('Unknown baseobject type for engraving')

            output += "G0 Z" + PathUtils.fmt(
                obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                    self.vertRapid) + "\n"

        except:
            FreeCAD.Console.PrintError(
                "The Job Base Object has no engraveable element.  Engraving operation will produce no output."
            )

        # print output
        if output == "":
            output += "(No commands processed)"

        path = Path.Path(output)
        obj.Path = path
Exemple #21
0
    def execute(self, obj):
        PathLog.track()
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment)+')\n'

        toolLoad = obj.ToolController
        if toolLoad is None or toolLoad.ToolNumber == 0:
            FreeCAD.Console.PrintError("No Tool Controller is selected. We need a tool to build a Path.")
            return
        else:
            self.vertFeed = toolLoad.VertFeed.Value
            self.horizFeed = toolLoad.HorizFeed.Value
            self.vertRapid = toolLoad.VertRapid.Value
            self.horizRapid = toolLoad.HorizRapid.Value
            tool = toolLoad.Proxy.getTool(toolLoad)
            if not tool or tool.Diameter == 0:
                FreeCAD.Console.PrintError("No Tool found or diameter is zero. We need a tool to build a Path.")
                return
            else:
                self.radius = tool.Diameter/2

        if len(obj.Names) == 0:
            parentJob = PathUtils.findParentJob(obj)
            if parentJob is None:
                return
            baseobject = parentJob.Base
            if baseobject is None:
                return

            # Arch PanelSheet
            if hasattr(baseobject, "Proxy"):
                holes = []
                if isinstance(baseobject.Proxy, ArchPanel.PanelSheet):
                    baseobject.Proxy.execute(baseobject)
                    i = 0
                    holeshapes = baseobject.Proxy.getHoles(baseobject, transform=True)
                    tooldiameter = obj.ToolController.Proxy.getTool(obj.ToolController).Diameter
                    for holeshape in holeshapes:
                        PathLog.debug('Entering new HoleShape')
                        for wire in holeshape.Wires:
                            PathLog.debug('Entering new Wire')
                            for edge in wire.Edges:
                                if PathUtils.isDrillable(baseobject, edge, tooldiameter):
                                    PathLog.debug('Found drillable hole edges: {}'.format(edge))
                                    x = edge.Curve.Center.x
                                    y = edge.Curve.Center.y
                                    diameter = edge.BoundBox.XLength
                                    holes.append({'x': x, 'y': y, 'featureName': baseobject.Name+'.'+'Drill'+str(i), 'd': diameter})
                                    i = i + 1
            else:
                holes = self.findHoles(obj, baseobject.Shape)
                for i in range(len(holes)):
                    holes[i]['featureName'] = baseobject.Name + '.' + holes[i]['featureName']
            names = []
            positions = []
            enabled = []
            diameters = []
            for h in holes:
                if len(names) == 0:
                    self.findHeights(obj, baseobject, h)
                names.append(h['featureName'])
                positions.append(FreeCAD.Vector(h['x'], h['y'], 0))
                enabled.append(1)
                diameters.append(h['d'])
            obj.Names = names
            obj.Positions = positions
            obj.Enabled = enabled
            obj.Diameters = diameters

        locations = []
        output = "(Begin Drilling)\n"

        for i in range(len(obj.Names)):
            if obj.Enabled[i] > 0:
                locations.append({'x': obj.Positions[i].x, 'y': obj.Positions[i].y})
        if len(locations) > 0:
            locations = PathUtils.sort_jobs(locations, ['x', 'y'])
            output += "G90 G98\n"
            # rapid to clearance height
            output += "G0 Z" + str(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
            # rapid to first hole location, with spindle still retracted:

            p0 = locations[0]
            output += "G0 X" + fmt(p0['x']) + " Y" + fmt(p0['y']) + "F " + PathUtils.fmt(self.horizRapid) + "\n"
            # move tool to clearance plane
            output += "G0 Z" + fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
            pword = ""
            qword = ""
            if obj.PeckDepth.Value > 0 and obj.PeckEnabled:
                cmd = "G83"
                qword = " Q" + fmt(obj.PeckDepth.Value)
            elif obj.DwellTime > 0 and obj.DwellEnabled:
                cmd = "G82"
                pword = " P" + fmt(obj.DwellTime)
            else:
                cmd = "G81"
            for p in locations:
                output += cmd + \
                    " X" + fmt(p['x']) + \
                    " Y" + fmt(p['y']) + \
                    " Z" + fmt(obj.FinalDepth.Value) + qword + pword + \
                    " R" + str(obj.RetractHeight.Value) + \
                    " F" + str(self.vertFeed) + "\n" \

            output += "G80\n"

        if obj.Active:
            path = Path.Path(output)
            obj.Path = path
            obj.ViewObject.Visibility = True

        else:
            path = Path.Path("(inactive operation)")
            obj.Path = path
            obj.ViewObject.Visibility = False
Exemple #22
0
    def buildpathocc(self, obj, wires, zValues):
        '''buildpathocc(obj, wires, zValues) ... internal helper function to generate engraving commands.'''
        PathLog.track()

        output = ""

        for wire in wires:
            offset = wire

            # reorder the wire
            offset = DraftGeomUtils.rebaseWire(offset, obj.StartVertex)

            last = None
            for z in zValues:
                if last:
                    self.commandlist.append(
                        Path.Command('G1', {
                            'X': last.x,
                            'Y': last.y,
                            'Z': z,
                            'F': self.vertFeed
                        }))

                for edge in offset.Edges:
                    if not last:
                        # we set the first move to our first point
                        last = edge.Vertexes[0].Point
                        output += "G0" + " X" + PathUtils.fmt(
                            last.x
                        ) + " Y" + PathUtils.fmt(last.y) + " Z" + PathUtils.fmt(
                            obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                                self.horizRapid)  # Rapid to starting position
                        self.commandlist.append(
                            Path.Command(
                                'G0', {
                                    'X': last.x,
                                    'Y': last.y,
                                    'Z': obj.ClearanceHeight.Value,
                                    'F': self.horizRapid
                                }))
                        output += "G0" + " X" + PathUtils.fmt(
                            last.x) + " Y" + PathUtils.fmt(
                                last.y
                            ) + " Z" + PathUtils.fmt(
                                obj.SafeHeight.Value) + "F " + PathUtils.fmt(
                                    self.horizRapid)  # Rapid to safe height
                        self.commandlist.append(
                            Path.Command(
                                'G0', {
                                    'X': last.x,
                                    'Y': last.y,
                                    'Z': obj.SafeHeight.Value,
                                    'F': self.vertRapid
                                }))
                        output += "G1" + " X" + PathUtils.fmt(
                            last.x) + " Y" + PathUtils.fmt(
                                last.y
                            ) + " Z" + PathUtils.fmt(z) + "F " + PathUtils.fmt(
                                self.vertFeed) + "\n"  # Vertical feed to depth
                        self.commandlist.append(
                            Path.Command(
                                'G0', {
                                    'X': last.x,
                                    'Y': last.y,
                                    'Z': z,
                                    'F': self.vertFeed
                                }))

                    if isinstance(edge.Curve, Part.Circle):
                        point = edge.Vertexes[-1].Point
                        if point == last:  # edges can come flipped
                            point = edge.Vertexes[0].Point
                        center = edge.Curve.Center
                        relcenter = center.sub(last)
                        v1 = last.sub(center)
                        v2 = point.sub(center)
                        if v1.cross(v2).z < 0:
                            output += "G2"
                        else:
                            output += "G3"
                        output += " X" + PathUtils.fmt(
                            point.x) + " Y" + PathUtils.fmt(
                                point.y) + " Z" + PathUtils.fmt(z)
                        output += " I" + PathUtils.fmt(
                            relcenter.x) + " J" + PathUtils.fmt(
                                relcenter.y) + " K" + PathUtils.fmt(
                                    relcenter.z)
                        output += " F " + PathUtils.fmt(self.horizFeed)
                        output += "\n"

                        cmd = 'G2' if v1.cross(v2).z < 0 else 'G3'
                        args = {}
                        args['X'] = point.x
                        args['Y'] = point.y
                        args['Z'] = z
                        args['I'] = relcenter.x
                        args['J'] = relcenter.y
                        args['K'] = relcenter.z
                        args['F'] = self.horizFeed
                        self.commandlist.append(Path.Command(cmd, args))
                        last = point
                    else:
                        point = edge.Vertexes[-1].Point
                        if point == last:  # edges can come flipped
                            point = edge.Vertexes[0].Point
                        output += "G1 X" + PathUtils.fmt(
                            point.x) + " Y" + PathUtils.fmt(
                                point.y) + " Z" + PathUtils.fmt(z)
                        output += " F " + PathUtils.fmt(self.horizFeed)
                        output += "\n"
                        self.commandlist.append(
                            Path.Command(
                                'G1', {
                                    'X': point.x,
                                    'Y': point.y,
                                    'Z': z,
                                    'F': self.horizFeed
                                }))
                        last = point
            output += "G0 Z " + PathUtils.fmt(obj.ClearanceHeight.Value)
            self.commandlist.append(
                Path.Command('G0', {
                    'Z': obj.ClearanceHeight.Value,
                    'F': self.vertRapid
                }))
        return output
    def execute(self, obj):
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment)+')\n'

        toolLoad = PathUtils.getLastToolLoad(obj)
        if toolLoad is None or toolLoad.ToolNumber == 0:
            self.vertFeed = 100
            self.horizFeed = 100
            self.vertRapid = 100
            self.horizRapid = 100
            self.radius = 0.25
            obj.ToolNumber = 0
            obj.ToolDescription = "UNDEFINED"
        else:
            self.vertFeed = toolLoad.VertFeed.Value
            self.horizFeed = toolLoad.HorizFeed.Value
            self.vertRapid = toolLoad.VertRapid.Value
            self.horizRapid = toolLoad.HorizRapid.Value
            tool = PathUtils.getTool(obj, toolLoad.ToolNumber)
            if tool.Diameter == 0:
                self.radius = 0.25
            else:
                self.radius = tool.Diameter/2
            obj.ToolNumber = toolLoad.ToolNumber
            obj.ToolDescription = toolLoad.Name

        if obj.UserLabel == "":
            obj.Label = obj.Name + " :" + obj.ToolDescription
        else:
            obj.Label = obj.UserLabel + " :" + obj.ToolDescription

        locations = []
        output = "(Begin Drilling)\n"
        if obj.Base:
            for loc in obj.Base:
                #print loc
                for sub in loc[1]:
                    #locations.append(self._findDrillingVector(loc))

                    if "Face" in sub or "Edge" in sub:
                        s = getattr(loc[0].Shape, sub)
                    else:
                        s = loc[0].Shape

                    if s.ShapeType in ['Wire', 'Edge']:
                        X = s.Edges[0].Curve.Center.x
                        Y = s.Edges[0].Curve.Center.y
                        Z = s.Edges[0].Curve.Center.z
                    elif s.ShapeType in ['Vertex']:
                        X = s.Point.x
                        Y = s.Point.y
                        Z = s.Point.z
                    elif s.ShapeType in ['Face']:
                        #if abs(s.normalAt(0, 0).z) == 1:  # horizontal face
                        X = s.CenterOfMass.x
                        Y = s.CenterOfMass.y
                        Z = s.CenterOfMass.z
                    locations.append(FreeCAD.Vector(X, Y, Z))


            output += "G90 G98\n"
            # rapid to clearance height
            output += "G0 Z" + str(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
            # rapid to first hole location, with spindle still retracted:
            p0 = locations[0]
            output += "G0 X" + fmt(p0.x) + " Y" + fmt(p0.y)  + "F " + PathUtils.fmt(self.horizRapid) + "\n"
            # move tool to clearance plane
            output += "G0 Z" + fmt(obj.ClearanceHeight.Value)  + "F " + PathUtils.fmt(self.vertRapid) + "\n"
            pword = ""
            qword = ""
            if obj.PeckDepth.Value > 0:
                cmd = "G83"
                qword = " Q" + fmt(obj.PeckDepth.Value)
            elif obj.DwellTime > 0:
                cmd = "G82"
                pword = " P" + fmt(obj.DwellTime)
            else:
                cmd = "G81"
            for p in locations:
                output += cmd + \
                    " X" + fmt(p.x) + \
                    " Y" + fmt(p.y) + \
                    " Z" + fmt(obj.FinalDepth.Value) + qword + pword + \
                    " R" + str(obj.RetractHeight.Value) + \
                    " F" + str(self.vertFeed) + "\n" \

            output += "G80\n"

#         path = Path.Path(output)
#         obj.Path = path

        if obj.Active:
            path = Path.Path(output)
            obj.Path = path
            obj.ViewObject.Visibility = True

        else:
            path = Path.Path("(inactive operation)")
            obj.Path = path
            obj.ViewObject.Visibility = False
    def execute(self, obj):
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment)+')\n'

        toolLoad = PathUtils.getLastToolLoad(obj)
        if toolLoad is None or toolLoad.ToolNumber == 0:
            self.vertFeed = 100
            self.horizFeed = 100
            self.vertRapid = 100
            self.horizRapid = 100
            self.radius = 0.25
            obj.ToolNumber = 0
            obj.ToolDescription = "UNDEFINED"
        else:
            self.vertFeed = toolLoad.VertFeed.Value
            self.horizFeed = toolLoad.HorizFeed.Value
            self.vertRapid = toolLoad.VertRapid.Value
            self.horizRapid = toolLoad.HorizRapid.Value
            tool = PathUtils.getTool(obj, toolLoad.ToolNumber)
            if tool.Diameter == 0:
                self.radius = 0.25
            else:
                self.radius = tool.Diameter/2
            obj.ToolNumber = toolLoad.ToolNumber
            obj.ToolDescription = toolLoad.Name

        if obj.UserLabel == "":
            obj.Label = obj.Name + " :" + obj.ToolDescription
        else:
            obj.Label = obj.UserLabel + " :" + obj.ToolDescription

        locations = []
        output = "(Begin Drilling)\n"
        if obj.Base:
            for loc in obj.Base:
                #print loc
                for sub in loc[1]:
                    #locations.append(self._findDrillingVector(loc))

                    if "Face" in sub or "Edge" in sub:
                        s = getattr(loc[0].Shape, sub)
                    else:
                        s = loc[0].Shape

                    if s.ShapeType in ['Wire', 'Edge']:
                        X = s.Edges[0].Curve.Center.x
                        Y = s.Edges[0].Curve.Center.y
                        Z = s.Edges[0].Curve.Center.z
                    elif s.ShapeType in ['Vertex']:
                        X = s.Point.x
                        Y = s.Point.y
                        Z = s.Point.z
                    elif s.ShapeType in ['Face']:
                        #if abs(s.normalAt(0, 0).z) == 1:  # horizontal face
                        X = s.CenterOfMass.x
                        Y = s.CenterOfMass.y
                        Z = s.CenterOfMass.z
                    locations.append(FreeCAD.Vector(X, Y, Z))


            output += "G90 G98\n"
            # rapid to clearance height
            output += "G0 Z" + str(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
            # rapid to first hole location, with spindle still retracted:
            p0 = locations[0]
            output += "G0 X" + fmt(p0.x) + " Y" + fmt(p0.y)  + "F " + PathUtils.fmt(self.horizRapid) + "\n"
            # move tool to clearance plane
            output += "G0 Z" + fmt(obj.ClearanceHeight.Value)  + "F " + PathUtils.fmt(self.vertRapid) + "\n"
            pword = ""
            qword = ""
            if obj.PeckDepth.Value > 0:
                cmd = "G83"
                qword = " Q" + fmt(obj.PeckDepth.Value)
            elif obj.DwellTime > 0:
                cmd = "G82"
                pword = " P" + fmt(obj.DwellTime)
            else:
                cmd = "G81"
            for p in locations:
                output += cmd + \
                    " X" + fmt(p.x) + \
                    " Y" + fmt(p.y) + \
                    " Z" + fmt(obj.FinalDepth.Value) + qword + pword + \
                    " R" + str(obj.RetractHeight.Value) + \
                    " F" + str(self.vertFeed) + "\n" \

            output += "G80\n"

#         path = Path.Path(output)
#         obj.Path = path

        if obj.Active:
            path = Path.Path(output)
            obj.Path = path
            obj.ViewObject.Visibility = True

        else:
            path = Path.Path("(inactive operation)")
            obj.Path = path
            obj.ViewObject.Visibility = False
Exemple #25
0
    def buildpathocc(self, obj, shape):
        """Build pocket Path using Native OCC algorithm."""
        import Part
        import DraftGeomUtils
        from PathScripts.PathUtils import fmt, helicalPlunge, rampPlunge, depth_params

        FreeCAD.Console.PrintMessage(translate("PathPocket", "Generating toolpath with OCC native offsets.\n"))
        extraoffset = obj.MaterialAllowance.Value

        # Build up the offset loops
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment)+')\n'
        output += 'G0 Z' + fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"

        offsets = []
        nextradius = self.radius + extraoffset
        result = DraftGeomUtils.pocket2d(shape, nextradius)
        while result:
            offsets.extend(result)
            nextradius += (self.radius * 2) * (float(obj.StepOver)/100)
            result = DraftGeomUtils.pocket2d(shape, nextradius)

        # revert the list so we start with the outer wires
        if obj.StartAt != 'Edge':
            offsets.reverse()

        plungePos = None
        rampEdge = None
        if obj.UseEntry:
            # Try to find an entry location
            toold = self.radius*2
            helixBounds = DraftGeomUtils.pocket2d(shape, self.radius * (1 + obj.HelixSize))

            if helixBounds:
                rampD = obj.RampSize

                if obj.StartAt == 'Edge':
                    plungePos = helixBounds[0].Edges[0].Vertexes[0].Point
                else:
                    plungePos = offsets[0].Edges[0].Vertexes[0].Point

                    # If it turns out this is invalid for some reason, nuke plungePos
                    [perp, idx] = DraftGeomUtils.findPerpendicular(plungePos, shape.Edges)
                    if not perp or perp.Length < self.radius * (1 + obj.HelixSize):
                        plungePos = None
                        FreeCAD.Console.PrintError(translate("PathPocket", "Helical Entry location not found.\n"))
                    # FIXME: Really need to do a point-in-polygon operation to make sure this is within helixBounds
                    # Or some math to prove that it has to be (doubt that's true)
                    # Maybe reverse helixBounds and pick off that?

            if plungePos is None:  # If we didn't find a place to helix, how about a ramp?
                FreeCAD.Console.PrintMessage(translate("PathPocket", "Attempting ramp entry.\n"))
                if (offsets[0].Edges[0].Length >= toold * rampD) and not (isinstance(offsets[0].Edges[0].Curve, Part.Circle)):
                    rampEdge = offsets[0].Edges[0]
                # The last edge also connects with the starting location- try that
                elif (offsets[0].Edges[-1].Length >= toold * rampD) and not (isinstance(offsets[0].Edges[-1].Curve, Part.Circle)):
                    rampEdge = offsets[0].Edges[-1]
                else:
                    FreeCAD.Console.PrintError(translate("PathPocket", "Ramp Entry location not found.\n"))
                    # print "Neither edge works: " + str(offsets[0].Edges[0]) + ", " + str(offsets[0].Edges[-1])
                    # FIXME: There's got to be a smarter way to find a place to ramp

        # For helix-ing/ramping, know where we were last time
        # FIXME: Can probably get this from the "machine"?
        lastZ = obj.ClearanceHeight.Value

        startPoint = None

        depthparams = depth_params(
                obj.ClearanceHeight.Value,
                obj.SafeHeight.Value,
                obj.StartDepth.Value,
                obj.StepDown,
                obj.FinishDepth.Value,
                obj.FinalDepth.Value)

        for vpos in depthparams.get_depths():

            first = True
            # loop over successive wires
            for currentWire in offsets:
                last = None
                for edge in currentWire.Edges:
                    if not last:
                        # we set the base GO to our fast move to our starting pos
                        if first:
                            # If we can helix, do so
                            if plungePos:
                                output += helicalPlunge(plungePos, obj.RampAngle, vpos, lastZ, self.radius*2, obj.HelixSize, self.horizFeed)
                                lastZ = vpos
                            # Otherwise, see if we can ramp
                            # FIXME: This could be a LOT smarter (eg, searching for a longer leg of the edge to ramp along)
                            elif rampEdge:
                                output += rampPlunge(rampEdge, obj.RampAngle, vpos, lastZ)
                                lastZ = vpos
                            # Otherwise, straight plunge... Don't want to, but sometimes you might not have a choice.
                            # FIXME: At least not with the lazy ramp programming above...
                            else:
                                print "WARNING: Straight-plunging... probably not good, but we didn't find a place to helix or ramp"
                                startPoint = edge.Vertexes[0].Point
                                output += "G0 Z" + fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
                                output += "G0 X" + fmt(startPoint.x) + " Y" + fmt(startPoint.y) +\
                                          " Z" + fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.horizRapid) + "\n"
                            first = False
                        # then move slow down to our starting point for our profile
                        last = edge.Vertexes[0].Point
                        output += "G1 X" + fmt(last.x) + " Y" + fmt(last.y) + " Z" + fmt(vpos) + " F" + fmt(self.vertFeed) + "\n"
                    if DraftGeomUtils.geomType(edge) == "Circle":
                        point = edge.Vertexes[-1].Point
                        if point == last:  # edges can come flipped
                            point = edge.Vertexes[0].Point
                        center = edge.Curve.Center
                        relcenter = center.sub(last)
                        v1 = last.sub(center)
                        v2 = point.sub(center)
                        if v1.cross(v2).z < 0:
                            output += "G2"
                        else:
                            output += "G3"
                        output += " X" + fmt(point.x) + " Y" + fmt(point.y) + " Z" + fmt(vpos)
                        output += " I" + fmt(relcenter.x) + " J" + fmt(relcenter.y) + " K" + fmt(relcenter.z)  + " F" + fmt(self.horizFeed) 
                        output += "\n"
                        last = point
                    else:
                        point = edge.Vertexes[-1].Point
                        if point == last:  # edges can come flipped
                            point = edge.Vertexes[0].Point
                        output += "G1 X" + fmt(point.x) + " Y" + fmt(point.y) + " Z" + fmt(vpos) + " F" + fmt(self.horizFeed)  + "\n"
                        last = point

        # move back up
        output += "G0 Z" + fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
        return output
    def buildpathocc(self, obj, wires):
        import Part
        import DraftGeomUtils
        output = ""

        # absolute coords, millimeters, cancel offsets

        for wire in wires:
            offset = wire

            # reorder the wire
            offset = DraftGeomUtils.rebaseWire(offset, obj.StartVertex)

            # we create the path from the offset shape
            last = None
            for edge in offset.Edges:
                if not last:
                    # we set the first move to our first point
                    last = edge.Vertexes[0].Point
                    output += "G0" + " X" + PathUtils.fmt(last.x) + " Y" + PathUtils.fmt(last.y) + " Z" + PathUtils.fmt(obj.SafeHeight.Value)  # Rapid sto starting position
                    output += "G1" + " X" + PathUtils.fmt(last.x) + " Y" + PathUtils.fmt(last.y) + " Z" + PathUtils.fmt(obj.FinalDepth.Value) + "F " + PathUtils.fmt(self.vertFeed) + "\n"  # Vertical feed to depth
                if isinstance(edge.Curve, Part.Circle):
                    point = edge.Vertexes[-1].Point
                    if point == last:  # edges can come flipped
                        point = edge.Vertexes[0].Point
                    center = edge.Curve.Center
                    relcenter = center.sub(last)
                    v1 = last.sub(center)
                    v2 = point.sub(center)
                    if v1.cross(v2).z < 0:
                        output += "G2"
                    else:
                        output += "G3"
                    output += " X" + PathUtils.fmt(point.x) + " Y" + PathUtils.fmt(point.y) + " Z" + PathUtils.fmt(obj.FinalDepth.Value)
                    output += " I" + PathUtils.fmt(relcenter.x) + " J" + PathUtils.fmt(relcenter.y) + " K" + PathUtils.fmt(relcenter.z)
                    output += " F " + PathUtils.fmt(self.horizFeed)
                    output += "\n"
                    last = point
                else:
                    point = edge.Vertexes[-1].Point
                    if point == last:  # edges can come flipped
                        point = edge.Vertexes[0].Point
                    output += "G1 X" + PathUtils.fmt(point.x) + " Y" + PathUtils.fmt(point.y) + " Z" + PathUtils.fmt(obj.FinalDepth.Value)
                    output += " F " + PathUtils.fmt(self.horizFeed)
                    output += "\n"
                    last = point
            output += "G0 Z " + PathUtils.fmt(obj.SafeHeight.Value)
        return output
Exemple #27
0
    def execute(self, obj):
        PathLog.track()

        if not obj.Active:
            path = Path.Path("(inactive operation)")
            obj.Path = path
            obj.ViewObject.Visibility = False
            return

        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment) + ')\n'

        toolLoad = obj.ToolController
        if toolLoad is None or toolLoad.ToolNumber == 0:
            FreeCAD.Console.PrintError(
                "No Tool Controller is selected. We need a tool to build a Path."
            )
            return
        else:
            self.vertFeed = toolLoad.VertFeed.Value
            self.horizFeed = toolLoad.HorizFeed.Value
            self.vertRapid = toolLoad.VertRapid.Value
            self.horizRapid = toolLoad.HorizRapid.Value
            tool = toolLoad.Proxy.getTool(toolLoad)
            if not tool or tool.Diameter == 0:
                FreeCAD.Console.PrintError(
                    "No Tool found or diameter is zero. We need a tool to build a Path."
                )
                return
            else:
                self.radius = tool.Diameter / 2

        tiplength = 0.0
        if obj.AddTipLength:
            tiplength = PathUtils.drillTipLength(tool)

        if len(obj.Names) == 0:
            parentJob = PathUtils.findParentJob(obj)
            if parentJob is None:
                return
            baseobject = parentJob.Base
            if baseobject is None:
                return

            # Arch PanelSheet
            if hasattr(baseobject, "Proxy"):
                holes = []
                if isinstance(baseobject.Proxy, ArchPanel.PanelSheet):
                    baseobject.Proxy.execute(baseobject)
                    i = 0
                    holeshapes = baseobject.Proxy.getHoles(baseobject,
                                                           transform=True)
                    tooldiameter = obj.ToolController.Proxy.getTool(
                        obj.ToolController).Diameter
                    for holeshape in holeshapes:
                        PathLog.debug('Entering new HoleShape')
                        for wire in holeshape.Wires:
                            PathLog.debug('Entering new Wire')
                            for edge in wire.Edges:
                                if PathUtils.isDrillable(
                                        baseobject, edge, tooldiameter):
                                    PathLog.debug(
                                        'Found drillable hole edges: {}'.
                                        format(edge))
                                    x = edge.Curve.Center.x
                                    y = edge.Curve.Center.y
                                    diameter = edge.BoundBox.XLength
                                    holes.append({
                                        'x':
                                        x,
                                        'y':
                                        y,
                                        'featureName':
                                        baseobject.Name + '.' + 'Drill' +
                                        str(i),
                                        'd':
                                        diameter
                                    })
                                    i = i + 1
            else:
                holes = self.findHoles(obj, baseobject.Shape)
                for i in range(len(holes)):
                    holes[i]['featureName'] = baseobject.Name + '.' + holes[i][
                        'featureName']
            names = []
            positions = []
            enabled = []
            diameters = []
            for h in holes:
                if len(names) == 0:
                    self.setDepths(obj, baseobject, h)
                names.append(h['featureName'])
                positions.append(FreeCAD.Vector(h['x'], h['y'], 0))
                enabled.append(1)
                diameters.append(h['d'])
            obj.Names = names
            obj.Positions = positions
            obj.Enabled = enabled
            obj.Diameters = diameters

        locations = []
        output = "(Begin Drilling)\n"

        for i in range(len(obj.Names)):
            if obj.Enabled[i] > 0:
                locations.append({
                    'x': obj.Positions[i].x,
                    'y': obj.Positions[i].y
                })
        if len(locations) > 0:
            locations = PathUtils.sort_jobs(locations, ['x', 'y'])
            output += "G90 " + obj.ReturnLevel + "\n"
            # rapid to clearance height
            output += "G0 Z" + str(
                obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                    self.vertRapid) + "\n"
            # rapid to first hole location, with spindle still retracted:

            p0 = locations[0]
            output += "G0 X" + fmt(p0['x']) + " Y" + fmt(
                p0['y']) + "F " + PathUtils.fmt(self.horizRapid) + "\n"
            # move tool to clearance plane
            output += "G0 Z" + fmt(
                obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(
                    self.vertRapid) + "\n"
            pword = ""
            qword = ""
            if obj.PeckDepth.Value > 0 and obj.PeckEnabled:
                cmd = "G83"
                qword = " Q" + fmt(obj.PeckDepth.Value)
            elif obj.DwellTime > 0 and obj.DwellEnabled:
                cmd = "G82"
                pword = " P" + fmt(obj.DwellTime)
            else:
                cmd = "G81"
            for p in locations:
                output += cmd + \
                    " X" + fmt(p['x']) + \
                    " Y" + fmt(p['y']) + \
                    " Z" + fmt(obj.FinalDepth.Value - tiplength) + qword + pword + \
                    " R" + str(obj.RetractHeight.Value) + \
                    " F" + str(self.vertFeed) + "\n" \

            output += "G80\n"

        path = Path.Path(output)
        obj.Path = path
Exemple #28
0
    def buildpathocc(self, obj, wires):
        import Part
        import DraftGeomUtils
        output = ""

        # absolute coords, millimeters, cancel offsets

        for wire in wires:
            offset = wire

            # reorder the wire
            offset = DraftGeomUtils.rebaseWire(offset, obj.StartVertex)

            # we create the path from the offset shape
            last = None
            for edge in offset.Edges:
                if not last:
                    # we set the first move to our first point
                    last = edge.Vertexes[0].Point
                    output += "G0" + " X" + PathUtils.fmt(
                        last.x
                    ) + " Y" + PathUtils.fmt(last.y) + " Z" + PathUtils.fmt(
                        obj.SafeHeight.Value)  # Rapid sto starting position
                    output += "G1" + " X" + PathUtils.fmt(
                        last.x
                    ) + " Y" + PathUtils.fmt(last.y) + " Z" + PathUtils.fmt(
                        obj.FinalDepth.Value) + "F " + PathUtils.fmt(
                            self.vertFeed) + "\n"  # Vertical feed to depth
                if isinstance(edge.Curve, Part.Circle):
                    point = edge.Vertexes[-1].Point
                    if point == last:  # edges can come flipped
                        point = edge.Vertexes[0].Point
                    center = edge.Curve.Center
                    relcenter = center.sub(last)
                    v1 = last.sub(center)
                    v2 = point.sub(center)
                    if v1.cross(v2).z < 0:
                        output += "G2"
                    else:
                        output += "G3"
                    output += " X" + PathUtils.fmt(
                        point.x) + " Y" + PathUtils.fmt(
                            point.y) + " Z" + PathUtils.fmt(
                                obj.FinalDepth.Value)
                    output += " I" + PathUtils.fmt(
                        relcenter.x) + " J" + PathUtils.fmt(
                            relcenter.y) + " K" + PathUtils.fmt(relcenter.z)
                    output += " F " + PathUtils.fmt(self.horizFeed)
                    output += "\n"
                    last = point
                else:
                    point = edge.Vertexes[-1].Point
                    if point == last:  # edges can come flipped
                        point = edge.Vertexes[0].Point
                    output += "G1 X" + PathUtils.fmt(
                        point.x) + " Y" + PathUtils.fmt(
                            point.y) + " Z" + PathUtils.fmt(
                                obj.FinalDepth.Value)
                    output += " F " + PathUtils.fmt(self.horizFeed)
                    output += "\n"
                    last = point
            output += "G0 Z " + PathUtils.fmt(obj.SafeHeight.Value)
        return output