예제 #1
0
    def SetupOperation(self, itool):
        self.operation = self.activeOps[itool]
        try:
            self.tool = PathDressup.toolController(self.operation).Tool
        except Exception:
            self.tool = None

        if (self.tool is not None):
            if isinstance(self.tool, Path.Tool):
                # handle legacy tools
                toolProf = self.CreateToolProfile(
                    self.tool, Vector(0, 1, 0), Vector(0, 0, 0),
                    float(self.tool.Diameter) / 2.0)
                self.cutTool.Shape = Part.makeSolid(
                    toolProf.revolve(Vector(0, 0, 0), Vector(0, 0, 1)))
            else:
                # handle tool bits
                self.cutTool.Shape = self.tool.Shape

            if not self.cutTool.Shape.isValid() or self.cutTool.Shape.isNull():
                self.EndSimulation()
                raise RuntimeError(
                    "Path Simulation: Error in tool geometry - {}".format(
                        self.tool.Name))

            self.cutTool.ViewObject.show()
            self.voxSim.SetToolShape(self.cutTool.Shape, 0.05 * self.accuracy)
        self.icmd = 0
        self.curpos = FreeCAD.Placement(self.initialPos, self.stdrot)
        self.cutTool.Placement = self.curpos
        self.opCommands = self.operation.Path.Commands
예제 #2
0
    def setup(self, obj, initial):
        PathLog.info("Here we go ... ")
        if initial:
            if hasattr(obj.Base, "BoneBlacklist"):
                # dressing up a bone dressup
                obj.Side = obj.Base.Side
            else:
                # otherwise dogbones are opposite of the base path's side
                side = Side.Right
                if hasattr(obj.Base, 'Side') and obj.Base.Side == 'Inside':
                    side = Side.Left
                if hasattr(obj.Base,
                           'Directin') and obj.Base.Direction == 'CCW':
                    side = Side.oppositeOf(side)
                obj.Side = side

        self.toolRadius = 5
        tc = PathDressup.toolController(obj.Base)
        if tc is None or tc.ToolNumber == 0:
            self.toolRadius = 5
        else:
            tool = tc.Proxy.getTool(
                tc)  # PathUtils.getTool(obj, tc.ToolNumber)
            if not tool or tool.Diameter == 0:
                self.toolRadius = 5
            else:
                self.toolRadius = tool.Diameter / 2

        self.shapes = {}
        self.dbg = []
예제 #3
0
    def setup(self, obj, initial):
        PathLog.info("Here we go ... ")
        if initial:
            if hasattr(obj.Base, "BoneBlacklist"):
                # dressing up a bone dressup
                obj.Side = obj.Base.Side
            else:
                # otherwise dogbones are opposite of the base path's side
                side = Side.Right
                if hasattr(obj.Base, 'Side') and obj.Base.Side == 'Inside':
                    side = Side.Left
                if hasattr(obj.Base, 'Directin') and obj.Base.Direction == 'CCW':
                    side = Side.oppositeOf(side)
                obj.Side = side

        self.toolRadius = 5
        tc = PathDressup.toolController(obj.Base)
        if tc is None or tc.ToolNumber == 0:
            self.toolRadius = 5
        else:
            tool = tc.Proxy.getTool(tc)  # PathUtils.getTool(obj, tc.ToolNumber)
            if not tool or tool.Diameter == 0:
                self.toolRadius = 5
            else:
                self.toolRadius = tool.Diameter / 2

        self.shapes = {}
        self.dbg = []
예제 #4
0
    def setup(self, obj, generate=False):
        PathLog.debug("setup")
        self.obj = obj
        try:
            pathData = PathData(obj)
        except ValueError:
            PathLog.error(
                translate(
                    "Path_DressupTag",
                    "Cannot insert holding tags for this path - please select a Profile path"
                ) + "\n")
            #if sys.version_info.major < 3:
            #    traceback.print_exc(e)
            #else:
            #    traceback.print_exc()
            return None

        self.toolRadius = PathDressup.toolController(
            obj.Base).Tool.Diameter / 2
        self.pathData = pathData
        if generate:
            obj.Height = self.pathData.defaultTagHeight()
            obj.Width = self.pathData.defaultTagWidth()
            obj.Angle = self.pathData.defaultTagAngle()
            obj.Radius = self.pathData.defaultTagRadius()
            count = HoldingTagPreferences.defaultCount()
            self.generateTags(obj, count)
        return self.pathData
예제 #5
0
 def getDirectionOfPath(self, obj):
     op = PathDressup.baseOp(obj.Base)
     if hasattr(op, 'Side') and op.Side == 'Outside':
         if hasattr(op, 'Direction') and op.Direction == 'CW':
             return 'left'
         else:
             return 'right'
     else:
         if hasattr(op, 'Direction') and op.Direction == 'CW':
             return 'right'
     return 'left'
예제 #6
0
 def getLeadEnd(self, obj, queue, action):
     '''returns the  Gcode of LeadOut.'''
     global currLocation
     results = []
     horizFeed = PathDressup.toolController(obj.Base).HorizFeed.Value
     R = obj.Length.Value  # Radius of roll or length
     # set the correct twist command
     if self.getDirectionOfPath(obj) == 'right':
         arcdir = "G2"
     else:
         arcdir = "G3"
     if queue[1].Name == "G1":  # line
         p0 = queue[0].Placement.Base
         p1 = queue[1].Placement.Base
         v = self.normalize(p1.sub(p0))
     else:  # dealing with a circle
         p0 = queue[0].Placement.Base
         p1 = queue[1].Placement.Base
         v = self.normalize(p1.sub(p0))
     if self.getDirectionOfPath(obj) == 'right':
         off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0)
     else:
         off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0)
     offsetvector = FreeCAD.Vector(v.x * R, v.y * R, 0.0)
     if obj.RadiusCenter == 'Radius':
         leadend = (p1.add(off_v)).add(offsetvector)  # Rmode
     else:
         leadend = p1.add(off_v)  # Dmode
     IJ = off_v  # .negative()
     results.append(queue[1])
     if obj.StyleOff == 'Arc':
         arcmove = Path.Command(
             arcdir, {
                 "X": leadend.x,
                 "Y": leadend.y,
                 "I": IJ.x,
                 "J": IJ.y,
                 "F": horizFeed
             })  # add G2/G3 move
         results.append(arcmove)
     elif obj.StyleOff == 'Tangent':
         extendcommand = Path.Command(
             'G1', {
                 "X": leadend.x,
                 "Y": leadend.y,
                 "Z": currLocation["Z"],
                 "F": horizFeed
             })
         results.append(extendcommand)
     else:
         PathLog.notice(" CURRENT_IN Perp")
     if obj.UseMashineCRC:  # crc off
         results.append(Path.Command('G40', {}))
     return results
 def getDirectionOfPath(self, obj):
     op = PathDressup.baseOp(obj.Base)
     if hasattr(op, 'Side') and op.Side == 'Outside':
         if hasattr(op, 'Direction') and op.Direction == 'CW':
             return 'left'
         else:
             return 'right'
     else:
         if hasattr(op, 'Direction') and op.Direction == 'CW':
             return 'right'
     return 'left'
예제 #8
0
    def getDirectionOfPath(self, obj):
        op = PathDressup.baseOp(obj.Base)

        if hasattr(op, "Side") and op.Side == "Outside":
            if hasattr(op, "Direction") and op.Direction == "CW":
                return "left"
            else:
                return "right"
        else:
            if hasattr(op, "Direction") and op.Direction == "CW":
                return "right"
        return "left"
예제 #9
0
    def SetupOperation(self, itool):
        self.operation = self.activeOps[itool]
        try:
            self.tool = PathDressup.toolController(self.operation).Tool
        except:
            self.tool = None

        # if hasattr(self.operation, "ToolController"):
        #     self.tool = self.operation.ToolController.Tool
        if (self.tool is not None):
            toolProf = self.CreateToolProfile(self.tool, Vector(0, 1, 0), Vector(0, 0, 0), self.tool.Diameter / 2.0)
            self.cutTool.Shape = Part.makeSolid(toolProf.revolve(Vector(0, 0, 0), Vector(0, 0, 1)))
            self.cutTool.ViewObject.show()
            self.voxSim.SetCurrentTool(self.tool)
        self.icmd = 0
        self.curpos = FreeCAD.Placement(self.initialPos, self.stdrot)
        # self.cutTool.Placement = FreeCAD.Placement(self.curpos, self.stdrot)
        self.cutTool.Placement = self.curpos
예제 #10
0
    def SetupOperation(self, itool):
        self.operation = self.activeOps[itool]
        try:
            self.tool = PathDressup.toolController(self.operation).Tool
        except:
            self.tool = None

        # if hasattr(self.operation, "ToolController"):
        #     self.tool = self.operation.ToolController.Tool
        if (self.tool is not None):
            toolProf = self.CreateToolProfile(self.tool, Vector(0, 1, 0), Vector(0, 0, 0), self.tool.Diameter / 2.0)
            self.cutTool.Shape = Part.makeSolid(toolProf.revolve(Vector(0, 0, 0), Vector(0, 0, 1)))
            self.cutTool.ViewObject.show()
            self.voxSim.SetCurrentTool(self.tool)
        self.icmd = 0
        self.curpos = FreeCAD.Placement(self.initialPos, self.stdrot)
        # self.cutTool.Placement = FreeCAD.Placement(self.curpos, self.stdrot)
        self.cutTool.Placement = self.curpos
    def setup(self, obj, generate=False):
        PathLog.debug("setup")
        self.obj = obj
        try:
            pathData = PathData(obj)
        except ValueError:
            PathLog.error(translate("Path_DressupTag", "Cannot insert holding tags for this path - please select a Profile path")+"\n")
            return None

        self.toolRadius = PathDressup.toolController(obj.Base).Tool.Diameter / 2
        self.pathData = pathData
        if generate:
            obj.Height = self.pathData.defaultTagHeight()
            obj.Width = self.pathData.defaultTagWidth()
            obj.Angle = self.pathData.defaultTagAngle()
            obj.Radius = self.pathData.defaultTagRadius()
            count = HoldingTagPreferences.defaultCount()
            self.generateTags(obj, count)
        return self.pathData
 def getLeadEnd(self, obj, queue, action):
     '''returns the Gcode of LeadOut.'''
     global currLocation
     results = []
     horizFeed = PathDressup.toolController(obj.Base).HorizFeed.Value
     R = obj.Length.Value  # Radius of roll or length
     # set the correct twist command
     if self.getDirectionOfPath(obj) == 'right':
         arcdir = "G2"
     else:
         arcdir = "G3"
     if queue[1].Name == "G1":  # line
         p0 = queue[0].Placement.Base
         p1 = queue[1].Placement.Base
         v = self.normalize(p1.sub(p0))
     else:  # dealing with a circle
         p0 = queue[0].Placement.Base
         p1 = queue[1].Placement.Base
         v = self.normalize(p1.sub(p0))
     if self.getDirectionOfPath(obj) == 'right':
         off_v = FreeCAD.Vector(v.y*R, -v.x*R, 0.0)
     else:
         off_v = FreeCAD.Vector(-v.y*R, v.x*R, 0.0)
     offsetvector = FreeCAD.Vector(v.x*R, v.y*R, 0.0)
     if obj.RadiusCenter == 'Radius':
         leadend = (p1.add(off_v)).add(offsetvector)  # Rmode
     else:
         leadend = p1.add(off_v)  # Dmode
     IJ = off_v  # .negative()
     #results.append(queue[1])
     if obj.StyleOff == 'Arc':
         arcmove = Path.Command(arcdir, {"X": leadend.x, "Y": leadend.y, "I": IJ.x, "J": IJ.y, "F": horizFeed})  # add G2/G3 move
         results.append(arcmove)
     elif obj.StyleOff == 'Tangent':
         extendcommand = Path.Command('G1', {"X": leadend.x, "Y": leadend.y, "F": horizFeed})
         results.append(extendcommand)
     else:
         PathLog.notice(" CURRENT_IN Perp")
     if obj.UseMashineCRC:  # crc off
         results.append(Path.Command('G40', {}))
     return results
예제 #13
0
 def toolRadius(self):
     return float(PathDressup.toolController(
         self.obj.Base).Tool.Diameter) / 2.0
예제 #14
0
    def createPath(self, obj, pathData, tags):
        PathLog.track()
        commands = []
        lastEdge = 0
        lastTag = 0
        # sameTag = None
        t = 0
        # inters = None
        edge = None

        segm = 50
        if hasattr(obj, 'SegmentationFactor'):
            segm = obj.SegmentationFactor
            if segm <= 0:
                segm = 50
                obj.SegmentationFactor = 50

        self.mappers = []
        mapper = None

        while edge or lastEdge < len(pathData.edges):
            PathLog.debug("------- lastEdge = %d/%d.%d/%d" %
                          (lastEdge, lastTag, t, len(tags)))
            if not edge:
                edge = pathData.edges[lastEdge]
                debugEdge(
                    edge, "=======  new edge: %d/%d" %
                    (lastEdge, len(pathData.edges)))
                lastEdge += 1
                # sameTag = None

            if mapper:
                mapper.add(edge)
                if mapper.mappingComplete():
                    commands.extend(mapper.commands)
                    edge = mapper.tail
                    mapper = None
                else:
                    edge = None

            if edge:
                tIndex = (t + lastTag) % len(tags)
                t += 1
                i = tags[tIndex].intersects(edge, edge.FirstParameter)
                if i and self.isValidTagStartIntersection(edge, i):
                    mapper = MapWireToTag(edge, tags[tIndex], i, segm,
                                          pathData.maxZ)
                    self.mappers.append(mapper)
                    edge = mapper.tail

            if not mapper and t >= len(tags):
                # gone through all tags, consume edge and move on
                if edge:
                    debugEdge(edge, '++++++++')
                    if pathData.rapid.isRapid(edge):
                        v = edge.Vertexes[1]
                        if not commands and PathGeom.isRoughly(
                                0, v.X) and PathGeom.isRoughly(
                                    0, v.Y) and not PathGeom.isRoughly(0, v.Z):
                            # The very first move is just to move to ClearanceHeight
                            commands.append(Path.Command('G0', {'Z': v.Z}))
                        else:
                            commands.append(
                                Path.Command('G0', {
                                    'X': v.X,
                                    'Y': v.Y,
                                    'Z': v.Z
                                }))
                    else:
                        commands.extend(PathGeom.cmdsForEdge(edge, segm=segm))
                edge = None
                t = 0

        lastCmd = Path.Command('G0', {'X': 0.0, 'Y': 0.0, 'Z': 0.0})
        outCommands = []

        tc = PathDressup.toolController(obj.Base)
        horizFeed = tc.HorizFeed.Value
        vertFeed = tc.VertFeed.Value
        horizRapid = tc.HorizRapid.Value
        vertRapid = tc.VertRapid.Value

        for cmd in commands:
            params = cmd.Parameters
            zVal = params.get('Z', None)
            zVal2 = lastCmd.Parameters.get('Z', None)

            zVal = zVal and round(zVal, 8)
            zVal2 = zVal2 and round(zVal2, 8)

            if cmd.Name in ['G1', 'G2', 'G3', 'G01', 'G02', 'G03']:
                if False and zVal is not None and zVal2 != zVal:
                    params['F'] = vertFeed
                else:
                    params['F'] = horizFeed
                lastCmd = cmd

            elif cmd.Name in ['G0', 'G00']:
                if zVal is not None and zVal2 != zVal:
                    params['F'] = vertRapid
                else:
                    params['F'] = horizRapid
                lastCmd = cmd

            outCommands.append(Path.Command(cmd.Name, params))

        return Path.Path(outCommands)
예제 #15
0
    def createCommands(self, obj, edges):
        commands = []
        for edge in edges:
            israpid = False
            for redge in self.rapids:
                if PathGeom.edgesMatch(edge, redge):
                    israpid = True
            if israpid:
                v = edge.valueAt(edge.LastParameter)
                commands.append(Path.Command('G0', {'X': v.x, 'Y': v.y, 'Z': v.z}))
            else:
                commands.extend(PathGeom.cmdsForEdge(edge))

        lastCmd = Path.Command('G0', {'X': 0.0, 'Y': 0.0, 'Z': 0.0})

        outCommands = []

        tc = PathDressup.toolController(obj.Base)

        horizFeed = tc.HorizFeed.Value
        vertFeed = tc.VertFeed.Value
        if obj.RampFeedRate == "Horizontal Feed Rate":
            rampFeed = tc.HorizFeed.Value
        elif obj.RampFeedRate == "Vertical Feed Rate":
            rampFeed = tc.VertFeed.Value
        else:
            rampFeed = obj.CustomFeedRate.Value
        horizRapid = tc.HorizRapid.Value
        vertRapid = tc.VertRapid.Value

        for cmd in commands:
            params = cmd.Parameters
            zVal = params.get('Z', None)
            zVal2 = lastCmd.Parameters.get('Z', None)

            xVal = params.get('X', None)
            xVal2 = lastCmd.Parameters.get('X', None)

            yVal2 = lastCmd.Parameters.get('Y', None)
            yVal = params.get('Y', None)

            zVal = zVal and round(zVal, 8)
            zVal2 = zVal2 and round(zVal2, 8)

            if cmd.Name in ['G1', 'G2', 'G3', 'G01', 'G02', 'G03']:
                if zVal is not None and zVal2 != zVal:
                    if PathGeom.isRoughly(xVal, xVal2) and PathGeom.isRoughly(yVal, yVal2):
                        # this is a straight plunge
                        params['F'] = vertFeed
                    else:
                        # this is a ramp
                        params['F'] = rampFeed
                else:
                    params['F'] = horizFeed
                lastCmd = cmd

            elif cmd.Name in ['G0', 'G00']:
                if zVal is not None and zVal2 != zVal:
                    params['F'] = vertRapid
                else:
                    params['F'] = horizRapid
                lastCmd = cmd

            outCommands.append(Path.Command(cmd.Name, params))

        return Path.Path(outCommands)
예제 #16
0
 def setup(self, obj):
     obj.Angle = 60
     obj.Method = 2
     if PathDressup.baseOp(obj).StartDepth is not None:
         obj.DressupStartDepth = PathDressup.baseOp(obj).StartDepth
예제 #17
0
 def getLeadStart(self, obj, queue, action):
     '''returns Lead In G-code.'''
     global currLocation
     results = []
     # zdepth = currLocation["Z"]
     op = PathDressup.baseOp(obj.Base)
     tc = PathDressup.toolController(obj.Base)
     horizFeed = tc.HorizFeed.Value
     vertFeed = tc.VertFeed.Value
     toolnummer = tc.ToolNumber
     # set the correct twist command
     if self.getDirectionOfPath(obj) == 'left':
         arcdir = "G3"
     else:
         arcdir = "G2"
     R = obj.Length.Value  # Radius of roll or length
     if queue[1].Name == "G1":  # line
         p0 = queue[0].Placement.Base
         p1 = queue[1].Placement.Base
         v = self.normalize(p1.sub(p0))
         # PathLog.notice(" CURRENT_IN  : P0 Z:{} p1 Z:{}".format(p0.z,p1.z))
     else:
         p0 = queue[0].Placement.Base
         p1 = queue[1].Placement.Base
         # PathLog.notice(" CURRENT_IN ARC : P0 X:{} Y:{} P1 X:{} Y:{} ".format(p0.x,p0.y,p1.x,p1.y))
         v = self.normalize(p1.sub(p0))
     if self.getDirectionOfPath(obj) == 'right':
         off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0)
     else:
         off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0)
     offsetvector = FreeCAD.Vector(v.x * R, v.y * R, 0)  # IJ
     if obj.RadiusCenter == 'Radius':
         leadstart = (p0.add(off_v)).sub(offsetvector)  # Rmode
     else:
         leadstart = p0.add(off_v)  # Dmode
     if action == 'start':
         extendcommand = Path.Command('G0', {
             "X": 0.0,
             "Y": 0.0,
             "Z": op.ClearanceHeight.Value
         })
         results.append(extendcommand)
         extendcommand = Path.Command('G0', {
             "X": leadstart.x,
             "Y": leadstart.y,
             "Z": op.ClearanceHeight.Value
         })
         results.append(extendcommand)
         extendcommand = Path.Command('G0', {
             "X": leadstart.x,
             "Y": leadstart.y,
             "Z": op.SafeHeight.Value
         })
         results.append(extendcommand)
     if action == 'layer':
         if not obj.KeepToolDown:
             extendcommand = Path.Command('G0', {"Z": op.SafeHeight.Value})
             results.append(extendcommand)
         extendcommand = Path.Command('G0', {
             "X": leadstart.x,
             "Y": leadstart.y
         })
         results.append(extendcommand)
     extendcommand = Path.Command('G1', {
         "X": leadstart.x,
         "Y": leadstart.y,
         "Z": p1.z,
         "F": vertFeed
     })
     results.append(extendcommand)
     if obj.UseMashineCRC:
         if self.getDirectionOfPath(obj) == 'right':
             results.append(Path.Command('G42', {'D': toolnummer}))
         else:
             results.append(Path.Command('G41', {'D': toolnummer}))
     if obj.StyleOn == 'Arc':
         arcmove = Path.Command(
             arcdir, {
                 "X": p0.x,
                 "Y": p0.y,
                 "I": offsetvector.x,
                 "J": offsetvector.y,
                 "F": horizFeed
             })  # add G2/G3 move
         results.append(arcmove)
     elif obj.StyleOn == 'Tangent':
         extendcommand = Path.Command('G1', {
             "X": p0.x,
             "Y": p0.y,
             "F": horizFeed
         })
         results.append(extendcommand)
     else:
         PathLog.notice(" CURRENT_IN Perp")
     return results
예제 #18
0
    def createCommands(self, obj, edges):
        commands = []
        for edge in edges:
            israpid = False
            for redge in self.rapids:
                if PathGeom.edgesMatch(edge, redge):
                    israpid = True
            if israpid:
                v = edge.valueAt(edge.LastParameter)
                commands.append(
                    Path.Command("G0", {
                        "X": v.x,
                        "Y": v.y,
                        "Z": v.z
                    }))
            else:
                commands.extend(PathGeom.cmdsForEdge(edge))

        lastCmd = Path.Command("G0", {"X": 0.0, "Y": 0.0, "Z": 0.0})

        outCommands = []

        tc = PathDressup.toolController(obj.Base)

        horizFeed = tc.HorizFeed.Value
        vertFeed = tc.VertFeed.Value

        if obj.RampFeedRate == "Horizontal Feed Rate":
            rampFeed = tc.HorizFeed.Value
        elif obj.RampFeedRate == "Vertical Feed Rate":
            rampFeed = tc.VertFeed.Value
        elif obj.RampFeedRate == "Ramp Feed Rate":
            rampFeed = math.sqrt(
                pow(tc.VertFeed.Value, 2) + pow(tc.HorizFeed.Value, 2))
        else:
            rampFeed = obj.CustomFeedRate.Value

        horizRapid = tc.HorizRapid.Value
        vertRapid = tc.VertRapid.Value

        for cmd in commands:
            params = cmd.Parameters
            zVal = params.get("Z", None)
            zVal2 = lastCmd.Parameters.get("Z", None)

            xVal = params.get("X", None)
            xVal2 = lastCmd.Parameters.get("X", None)

            yVal2 = lastCmd.Parameters.get("Y", None)
            yVal = params.get("Y", None)

            zVal = zVal and round(zVal, 8)
            zVal2 = zVal2 and round(zVal2, 8)

            if cmd.Name in ["G1", "G2", "G3", "G01", "G02", "G03"]:
                if zVal is not None and zVal2 != zVal:
                    if PathGeom.isRoughly(xVal, xVal2) and PathGeom.isRoughly(
                            yVal, yVal2):
                        # this is a straight plunge
                        params["F"] = vertFeed
                    else:
                        # this is a ramp
                        params["F"] = rampFeed
                else:
                    params["F"] = horizFeed
                lastCmd = cmd

            elif cmd.Name in ["G0", "G00"]:
                if zVal is not None and zVal2 != zVal:
                    params["F"] = vertRapid
                else:
                    params["F"] = horizRapid
                lastCmd = cmd

            outCommands.append(Path.Command(cmd.Name, params))

        return Path.Path(outCommands)
 def setup(self, obj):
     obj.Angle = 60
     obj.Method = 2
     if PathDressup.baseOp(obj).StartDepth is not None:
         obj.DressupStartDepth = PathDressup.baseOp(obj).StartDepth
예제 #20
0
    def getLeadStart(self, obj, queue, action):
        '''returns Lead In G-code.'''
        results = []
        op = PathDressup.baseOp(obj.Base)
        tc = PathDressup.toolController(obj.Base)
        horizFeed = tc.HorizFeed.Value
        vertFeed = tc.VertFeed.Value
        toolnummer = tc.ToolNumber
        arcs_identical = False

        # Set the correct twist command
        if self.getDirectionOfPath(obj) == 'left':
            arcdir = "G3"
        else:
            arcdir = "G2"

        R = obj.Length.Value  # Radius of roll or length
        if queue[1].Name == "G1":  # line
            p0 = queue[0].Placement.Base
            p1 = queue[1].Placement.Base
            v = self.normalize(p1.sub(p0))
            # PathLog.debug(" CURRENT_IN : P0 Z:{} p1 Z:{}".format(p0.z,p1.z))
        else:
            p0 = queue[0].Placement.Base
            p1 = queue[1].Placement.Base
            v = self.normalize(p1.sub(p0))
            # PathLog.debug(" CURRENT_IN ARC : P0 X:{} Y:{} P1 X:{} Y:{} ".format(p0.x,p0.y,p1.x,p1.y))

        # Calculate offset vector (will be overwritten for arcs)
        if self.getDirectionOfPath(obj) == 'right':
            off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0)
        else:
            off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0)

        # Check if we enter at line or arc command
        if queue[1].Name in movecommands and queue[1].Name not in arccommands:
            # We have a line move
            vec = p1.sub(p0)
            vec_n = self.normalize(vec)
            vec_inv = self.invert(vec_n)
            vec_off = self.multiply(vec_inv, obj.ExtendLeadIn)
            #PathLog.debug("LineCMD: {}, Vxinv: {}, Vyinv: {}, Vxoff: {}, Vyoff: {}".format(queue[0].Name, vec_inv.x, vec_inv.y,  vec_off.x,  vec_off.y))
        else:
            # We have an arc move
            # Calculate coordinates for middle of circle
            pij = copy.deepcopy(p0)
            pij.x += queue[1].Parameters['I']
            pij.y += queue[1].Parameters['J']

            # Check if lead in and operation go in same direction (usually for inner circles)
            if arcdir == queue[1].Name:
                arcs_identical = True

            # Calculate vector circle start -> circle middle
            vec_circ = pij.sub(p0)

            # Rotate vector to get direction for lead in
            if arcdir == "G2":
                vec_rot = self.rotate(vec_circ, 90)
            else:
                vec_rot = self.rotate(vec_circ, -90)

            # Normalize and invert vector
            vec_n = self.normalize(vec_rot)

            v = self.invert(vec_n)

            # Calculate offset of lead in
            if arcdir == "G3":
                off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0)
            else:
                off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0)

            # Multiply offset by LeadIn length
            vec_off = self.multiply(vec_n, obj.ExtendLeadIn)

        offsetvector = FreeCAD.Vector(v.x * R - vec_off.x, v.y * R - vec_off.y,
                                      0)  # IJ

        if obj.RadiusCenter == 'Radius':
            leadstart = (p0.add(off_v)).sub(offsetvector)  # Rmode
            if arcs_identical:
                t = p0.sub(leadstart)
                t = p0.add(t)
                leadstart = t
                offsetvector = self.multiply(offsetvector, -1)
        else:
            leadstart = p0.add(off_v)  # Dmode

        if action == 'start':
            #extendcommand = Path.Command('G0', {"X": 0.0, "Y": 0.0, "Z": op.ClearanceHeight.Value})
            #results.append(extendcommand)
            extendcommand = Path.Command('G0', {
                "X": leadstart.x,
                "Y": leadstart.y,
                "Z": op.ClearanceHeight.Value
            })
            results.append(extendcommand)
            extendcommand = Path.Command('G0', {"Z": op.SafeHeight.Value})
            results.append(extendcommand)

        if action == 'layer':
            if not obj.KeepToolDown:
                extendcommand = Path.Command('G0', {"Z": op.SafeHeight.Value})
                results.append(extendcommand)

            extendcommand = Path.Command('G0', {
                "X": leadstart.x,
                "Y": leadstart.y
            })
            results.append(extendcommand)

        if not obj.RapidPlunge:
            extendcommand = Path.Command('G1', {
                "X": leadstart.x,
                "Y": leadstart.y,
                "Z": p1.z,
                "F": vertFeed
            })
        else:
            extendcommand = Path.Command('G0', {
                "X": leadstart.x,
                "Y": leadstart.y,
                "Z": p1.z,
            })
        results.append(extendcommand)

        if obj.UseMachineCRC:
            if self.getDirectionOfPath(obj) == 'right':
                results.append(Path.Command('G42', {'D': toolnummer}))
            else:
                results.append(Path.Command('G41', {'D': toolnummer}))

        if obj.StyleOn == 'Arc':
            arcmove = Path.Command(
                arcdir, {
                    "X": p0.x + vec_off.x,
                    "Y": p0.y + vec_off.y,
                    "I": offsetvector.x + vec_off.x,
                    "J": offsetvector.y + vec_off.y,
                    "F": horizFeed
                })  # add G2/G3 move
            results.append(arcmove)
            if obj.ExtendLeadIn != 0:
                extendcommand = Path.Command('G1', {
                    "X": p0.x,
                    "Y": p0.y,
                    "F": horizFeed
                })
                results.append(extendcommand)
        elif obj.StyleOn == 'Tangent':
            extendcommand = Path.Command('G1', {
                "X": p0.x,
                "Y": p0.y,
                "F": horizFeed
            })
            results.append(extendcommand)
        else:
            PathLog.debug(" CURRENT_IN Perp")

        currLocation.update(results[-1].Parameters)
        currLocation['Z'] = p1.z

        return results
예제 #21
0
    def createPath(self, obj, pathData, tags):
        PathLog.track()
        commands = []
        lastEdge = 0
        lastTag = 0
        # sameTag = None
        t = 0
        # inters = None
        edge = None

        segm = 50
        if hasattr(obj, 'SegmentationFactor'):
            segm = obj.SegmentationFactor
            if segm <= 0:
                segm = 50
                obj.SegmentationFactor = 50

        self.mappers = []
        mapper = None

        tc = PathDressup.toolController(obj.Base)
        horizFeed = tc.HorizFeed.Value
        vertFeed = tc.VertFeed.Value
        horizRapid = tc.HorizRapid.Value
        vertRapid = tc.VertRapid.Value

        while edge or lastEdge < len(pathData.edges):
            PathLog.debug("------- lastEdge = %d/%d.%d/%d" % (lastEdge, lastTag, t, len(tags)))
            if not edge:
                edge = pathData.edges[lastEdge]
                debugEdge(edge, "=======  new edge: %d/%d" % (lastEdge, len(pathData.edges)))
                lastEdge += 1
                # sameTag = None

            if mapper:
                mapper.add(edge)
                if mapper.mappingComplete():
                    commands.extend(mapper.commands)
                    edge = mapper.tail
                    mapper = None
                else:
                    edge = None

            if edge:
                tIndex = (t + lastTag) % len(tags)
                t += 1
                i = tags[tIndex].intersects(edge, edge.FirstParameter)
                if i and self.isValidTagStartIntersection(edge, i):
                    mapper = MapWireToTag(edge, tags[tIndex], i, segm, pathData.maxZ, hSpeed = horizFeed, vSpeed = vertFeed)
                    self.mappers.append(mapper)
                    edge = mapper.tail

            if not mapper and t >= len(tags):
                # gone through all tags, consume edge and move on
                if edge:
                    debugEdge(edge, '++++++++')
                    if pathData.rapid.isRapid(edge):
                        v = edge.Vertexes[1]
                        if not commands and PathGeom.isRoughly(0, v.X) and PathGeom.isRoughly(0, v.Y) and not PathGeom.isRoughly(0, v.Z):
                            # The very first move is just to move to ClearanceHeight
                            commands.append(Path.Command('G0', {'Z': v.Z, 'F': horizRapid}))
                        else:
                            commands.append(Path.Command('G0', {'X': v.X, 'Y': v.Y, 'Z': v.Z, 'F': vertRapid}))
                    else:
                        commands.extend(PathGeom.cmdsForEdge(edge, segm=segm, hSpeed = horizFeed, vSpeed = vertFeed))
                edge = None
                t = 0

        return Path.Path(commands)
 def getLeadStart(self, obj, queue, action):
     '''returns Lead In G-code.'''
     global currLocation
     results = []
     # zdepth = currLocation["Z"]
     op = PathDressup.baseOp(obj.Base)
     tc = PathDressup.toolController(obj.Base)
     horizFeed = tc.HorizFeed.Value
     vertFeed = tc.VertFeed.Value
     toolnummer = tc.ToolNumber
     # set the correct twist command
     if self.getDirectionOfPath(obj) == 'left':
         arcdir = "G3"
     else:
         arcdir = "G2"
     R = obj.Length.Value  # Radius of roll or length
     if queue[1].Name == "G1":  # line
         p0 = queue[0].Placement.Base
         p1 = queue[1].Placement.Base
         v = self.normalize(p1.sub(p0))
         # PathLog.notice(" CURRENT_IN  : P0 Z:{} p1 Z:{}".format(p0.z,p1.z))
     else:
         p0 = queue[0].Placement.Base
         p1 = queue[1].Placement.Base
         # PathLog.notice(" CURRENT_IN ARC : P0 X:{} Y:{} P1 X:{} Y:{} ".format(p0.x,p0.y,p1.x,p1.y))
         v = self.normalize(p1.sub(p0))
     if self.getDirectionOfPath(obj) == 'right':
         off_v = FreeCAD.Vector(v.y*R, -v.x*R, 0.0)
     else:
         off_v = FreeCAD.Vector(-v.y*R, v.x*R, 0.0)
     offsetvector = FreeCAD.Vector(v.x*R, v.y*R, 0)  # IJ
     if obj.RadiusCenter == 'Radius':
         leadstart = (p0.add(off_v)).sub(offsetvector)  # Rmode
     else:
         leadstart = p0.add(off_v)  # Dmode
     if action == 'start':
         extendcommand = Path.Command('G0', {"X": 0.0, "Y": 0.0, "Z": op.ClearanceHeight.Value})
         results.append(extendcommand)
         extendcommand = Path.Command('G0', {"X": leadstart.x, "Y": leadstart.y, "Z": op.ClearanceHeight.Value})
         results.append(extendcommand)
         extendcommand = Path.Command('G0', {"X": leadstart.x, "Y": leadstart.y, "Z": op.SafeHeight.Value})
         results.append(extendcommand)
     if action == 'layer':
         if not obj.KeepToolDown:
             extendcommand = Path.Command('G0', {"Z": op.SafeHeight.Value})
             results.append(extendcommand)
         extendcommand = Path.Command('G0', {"X": leadstart.x, "Y": leadstart.y})
         results.append(extendcommand)
     extendcommand = Path.Command('G1', {"X": leadstart.x, "Y": leadstart.y, "Z": p1.z, "F": vertFeed})
     results.append(extendcommand)
     if obj.UseMashineCRC:
             if self.getDirectionOfPath(obj) == 'right':
                 results.append(Path.Command('G42', {'D': toolnummer}))
             else:
                 results.append(Path.Command('G41', {'D': toolnummer}))
     if obj.StyleOn == 'Arc':
         arcmove = Path.Command(arcdir, {"X": p0.x, "Y": p0.y, "I": offsetvector.x, "J": offsetvector.y, "F": horizFeed})  # add G2/G3 move
         results.append(arcmove)
     elif obj.StyleOn == 'Tangent':
         extendcommand = Path.Command('G1', {"X": p0.x, "Y": p0.y, "F": horizFeed})
         results.append(extendcommand)
     else:
         PathLog.notice(" CURRENT_IN Perp")
     return results
    def execute(self, obj):
        if not obj.Base or not obj.Base.isDerivedFrom('Path::Feature') or not obj.Base.Path:
            return

        tc = PathDressup.toolController(obj.Base)

        if len(obj.Base.Path.Commands) > 0:
            self.safeHeight = float(PathUtil.opProperty(obj.Base, 'SafeHeight'))
            self.clearanceHeight = float(PathUtil.opProperty(obj.Base, 'ClearanceHeight'))

            boundary = obj.Stock.Shape
            cmd = obj.Base.Path.Commands[0]
            pos = cmd.Placement.Base
            commands = [cmd]
            lastExit = None
            for cmd in obj.Base.Path.Commands[1:]:
                if cmd.Name in PathGeom.CmdMoveAll:
                    edge = PathGeom.edgeForCmd(cmd, pos)
                    inside  = edge.common(boundary).Edges
                    outside = edge.cut(boundary).Edges
                    if not obj.Inside:
                        t = inside
                        inside = outside
                        outside = t
                    # it's really a shame that one cannot trust the sequence and/or
                    # orientation of edges
                    if 1 == len(inside) and 0 == len(outside):
                        PathLog.track(_vstr(pos), _vstr(lastExit), ' + ', cmd)
                        # cmd fully included by boundary
                        if lastExit:
                            commands.extend(self.boundaryCommands(obj, lastExit, pos, tc.VertFeed.Value))
                            lastExit = None
                        commands.append(cmd)
                        pos = PathGeom.commandEndPoint(cmd, pos)
                    elif 0 == len(inside) and 1 == len(outside):
                        PathLog.track(_vstr(pos), _vstr(lastExit), ' - ', cmd)
                        # cmd fully excluded by boundary
                        if not lastExit:
                            lastExit = pos
                        pos = PathGeom.commandEndPoint(cmd, pos)
                    else:
                        PathLog.track(_vstr(pos), _vstr(lastExit), len(inside), len(outside), cmd)
                        # cmd pierces boundary
                        while inside or outside:
                            ie = [e for e in inside if PathGeom.edgeConnectsTo(e, pos)]
                            PathLog.track(ie)
                            if ie:
                                e = ie[0]
                                ptL = e.valueAt(e.LastParameter)
                                flip = PathGeom.pointsCoincide(pos, ptL)
                                newPos = e.valueAt(e.FirstParameter) if flip else ptL
                                # inside edges are taken at this point (see swap of inside/outside
                                # above - so we can just connect the dots ...
                                if lastExit:
                                    commands.extend(self.boundaryCommands(obj, lastExit, pos, tc.VertFeed.Value))
                                    lastExit = None
                                PathLog.track(e, flip)
                                commands.extend(PathGeom.cmdsForEdge(e, flip, False))
                                inside.remove(e)
                                pos = newPos
                                lastExit = newPos
                            else:
                                oe = [e for e in outside if PathGeom.edgeConnectsTo(e, pos)]
                                PathLog.track(oe)
                                if oe:
                                    e = oe[0]
                                    ptL = e.valueAt(e.LastParameter)
                                    flip = PathGeom.pointsCoincide(pos, ptL)
                                    newPos = e.valueAt(e.FirstParameter) if flip else ptL
                                    # outside edges are never taken at this point (see swap of
                                    # inside/oustide above) - so just move along ...
                                    outside.remove(e)
                                    pos = newPos
                                else:
                                    PathLog.error('huh?')
                                    import Part
                                    Part.show(Part.Vertex(pos), 'pos')
                                    for e in inside:
                                        Part.show(e, 'ei')
                                    for e in outside:
                                        Part.show(e, 'eo')
                                    raise Exception('This is not supposed to happen')
                    #pos = PathGeom.commandEndPoint(cmd, pos)
                else:
                    PathLog.track('no-move', cmd)
                    commands.append(cmd)
            if lastExit:
                commands.extend(self.boundaryCommands(obj, lastExit, None, tc.VertFeed.Value))
                lastExit = None
        else:
            PathLog.warning("No Path Commands for %s" % obj.Base.Label)
            commands = []
        PathLog.track(commands)
        obj.Path = Path.Path(commands)
예제 #24
0
    def generateLeadInOutCurve(self, obj):
        global currLocation  # pylint: disable=global-statement
        firstmove = Path.Command("G0", {"X": 0, "Y": 0, "Z": 0})
        op = PathDressup.baseOp(obj.Base)
        currLocation.update(firstmove.Parameters)
        newpath = []
        queue = []
        action = 'start'
        prevCmd = ''
        layers = []

        # Read in all commands
        for curCommand in obj.Base.Path.Commands:
            #PathLog.debug("CurCMD: {}".format(curCommand))
            if curCommand.Name not in movecommands + rapidcommands:
                # Don't worry about non-move commands, just add to output
                newpath.append(curCommand)
                continue

            if curCommand.Name in rapidcommands:
                # We don't care about rapid moves
                prevCmd = curCommand
                currLocation.update(curCommand.Parameters)
                continue

            if curCommand.Name in movecommands:
                if prevCmd.Name in rapidcommands and curCommand.Name in movecommands and len(
                        queue) > 0:
                    # Layer changed: Save current layer cmds and prepare next layer
                    layers.append(queue)
                    queue = []
                if obj.IncludeLayers and curCommand.z < currLocation[
                        'Z'] and prevCmd.Name in movecommands:
                    # Layer change within move cmds
                    #PathLog.debug("Layer change in move: {}->{}".format(currLocation['Z'],  curCommand.z))
                    layers.append(queue)
                    queue = []

                # Save all move commands
                queue.append(curCommand)

            currLocation.update(curCommand.Parameters)
            prevCmd = curCommand

        # Add last layer
        if len(queue) > 0:
            layers.append(queue)
            queue = []

        # Go through each layer and add leadIn/Out
        idx = 0
        for layer in layers:
            #PathLog.debug("Layer {}".format(idx))

            if obj.LeadIn:
                temp = self.getLeadStart(obj, layer, action)
                newpath.extend(temp)

            for cmd in layer:
                #PathLog.debug("CurLoc: {}, NewCmd: {}".format(currLocation,  cmd))
                #if currLocation['X'] == cmd.x and currLocation['Y'] == cmd.y and currLocation['Z'] == cmd.z and cmd.Name in ['G1',  'G01']:
                #continue
                newpath.append(cmd)

            if obj.LeadOut:
                tmp = []
                tmp.append(layer[-2])
                tmp.append(layer[-1])
                temp = self.getLeadEnd(obj, tmp, action)
                newpath.extend(temp)

            if not obj.KeepToolDown or idx == len(layers) - 1:
                extendcommand = Path.Command('G0',
                                             {"Z": op.ClearanceHeight.Value})
                newpath.append(extendcommand)
            else:
                action = 'layer'

            idx += 1

        commands = newpath
        return Path.Path(commands)
예제 #25
0
    def getLeadEnd(self, obj, queue, action):
        '''returns the Gcode of LeadOut.'''
        # pylint: disable=unused-argument
        results = []
        horizFeed = PathDressup.toolController(obj.Base).HorizFeed.Value
        R = obj.Length.Value  # Radius of roll or length
        arcs_identical = False

        # Set the correct twist command
        if self.getDirectionOfPath(obj) == 'right':
            arcdir = "G2"
        else:
            arcdir = "G3"

        if queue[1].Name == "G1":  # line
            p0 = queue[0].Placement.Base
            p1 = queue[1].Placement.Base
            v = self.normalize(p1.sub(p0))
        else:  # dealing with a circle
            p0 = queue[0].Placement.Base
            p1 = queue[1].Placement.Base
            v = self.normalize(p1.sub(p0))

        if self.getDirectionOfPath(obj) == 'right':
            off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0)
        else:
            off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0)

        # Check if we leave at line or arc command
        if queue[1].Name in movecommands and queue[1].Name not in arccommands:
            # We have a line move
            vec = p1.sub(p0)
            vec_n = self.normalize(vec)
            vec_inv = self.invert(vec_n)
            vec_off = self.multiply(vec_inv, obj.ExtendLeadOut)
            #PathLog.debug("LineCMD: {}, Vxinv: {}, Vyinv: {}, Vxoff: {}, Vyoff: {}".format(queue[0].Name, vec_inv.x, vec_inv.y,  vec_off.x,  vec_off.y))
        else:
            # We have an arc move
            pij = copy.deepcopy(p0)
            pij.x += queue[1].Parameters['I']
            pij.y += queue[1].Parameters['J']
            ve = pij.sub(p1)

            if arcdir == queue[1].Name:
                arcs_identical = True

            if arcdir == "G2":
                vec_rot = self.rotate(ve, -90)
            else:
                vec_rot = self.rotate(ve, 90)

            vec_n = self.normalize(vec_rot)
            v = vec_n

            if arcdir == "G3":
                off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0)
            else:
                off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0)

            vec_inv = self.invert(vec_rot)

            vec_off = self.multiply(vec_inv, obj.ExtendLeadOut)

        offsetvector = FreeCAD.Vector(v.x * R - vec_off.x, v.y * R - vec_off.y,
                                      0.0)
        if obj.RadiusCenter == 'Radius':
            leadend = (p1.add(off_v)).add(offsetvector)  # Rmode
            if arcs_identical:
                t = p1.sub(leadend)
                t = p1.add(t)
                leadend = t
                off_v = self.multiply(off_v, -1)
        else:
            leadend = p1.add(off_v)  # Dmode

        IJ = off_v  # .negative()
        #results.append(queue[1])
        if obj.StyleOff == 'Arc':
            if obj.ExtendLeadOut != 0:
                extendcommand = Path.Command('G1', {
                    "X": p1.x - vec_off.x,
                    "Y": p1.y - vec_off.y,
                    "F": horizFeed
                })
                results.append(extendcommand)
            arcmove = Path.Command(
                arcdir, {
                    "X": leadend.x,
                    "Y": leadend.y,
                    "I": IJ.x,
                    "J": IJ.y,
                    "F": horizFeed
                })  # add G2/G3 move
            results.append(arcmove)
        elif obj.StyleOff == 'Tangent':
            extendcommand = Path.Command('G1', {
                "X": leadend.x,
                "Y": leadend.y,
                "F": horizFeed
            })
            results.append(extendcommand)
        else:
            PathLog.debug(" CURRENT_IN Perp")

        if obj.UseMachineCRC:  # crc off
            results.append(Path.Command('G40', {}))

        return results
    def createCommands(self, obj, edges):
        commands = []
        for edge in edges:
            israpid = False
            for redge in self.rapids:
                if PathGeom.edgesMatch(edge, redge):
                    israpid = True
            if israpid:
                v = edge.valueAt(edge.LastParameter)
                commands.append(Path.Command('G0', {'X': v.x, 'Y': v.y, 'Z': v.z}))
            else:
                commands.extend(PathGeom.cmdsForEdge(edge))

        lastCmd = Path.Command('G0', {'X': 0.0, 'Y': 0.0, 'Z': 0.0})

        outCommands = []

        tc = PathDressup.toolController(obj.Base)

        horizFeed = tc.HorizFeed.Value
        vertFeed = tc.VertFeed.Value
        if obj.RampFeedRate == "Horizontal Feed Rate":
            rampFeed = tc.HorizFeed.Value
        elif obj.RampFeedRate == "Vertical Feed Rate":
            rampFeed = tc.VertFeed.Value
        else:
            rampFeed = obj.CustomFeedRate.Value
        horizRapid = tc.HorizRapid.Value
        vertRapid = tc.VertRapid.Value

        for cmd in commands:
            params = cmd.Parameters
            zVal = params.get('Z', None)
            zVal2 = lastCmd.Parameters.get('Z', None)

            xVal = params.get('X', None)
            xVal2 = lastCmd.Parameters.get('X', None)

            yVal2 = lastCmd.Parameters.get('Y', None)
            yVal = params.get('Y', None)

            zVal = zVal and round(zVal, 8)
            zVal2 = zVal2 and round(zVal2, 8)

            if cmd.Name in ['G1', 'G2', 'G3', 'G01', 'G02', 'G03']:
                if zVal is not None and zVal2 != zVal:
                    if PathGeom.isRoughly(xVal, xVal2) and PathGeom.isRoughly(yVal, yVal2):
                        # this is a straight plunge
                        params['F'] = vertFeed
                    else:
                        # this is a ramp
                        params['F'] = rampFeed
                else:
                    params['F'] = horizFeed
                lastCmd = cmd

            elif cmd.Name in ['G0', 'G00']:
                if zVal is not None and zVal2 != zVal:
                    params['F'] = vertRapid
                else:
                    params['F'] = horizRapid
                lastCmd = cmd

            outCommands.append(Path.Command(cmd.Name, params))

        return Path.Path(outCommands)
예제 #27
0
    def createPath(self, obj, pathData, tags):
        PathLog.track()
        commands = []
        lastEdge = 0
        lastTag = 0
        # sameTag = None
        t = 0
        # inters = None
        edge = None

        segm = 50
        if hasattr(obj, 'SegmentationFactor'):
            segm = obj.SegmentationFactor
            if segm <= 0:
                segm = 50
                obj.SegmentationFactor = 50

        self.mappers = []
        mapper = None

        tc = PathDressup.toolController(obj.Base)
        horizFeed = tc.HorizFeed.Value
        vertFeed = tc.VertFeed.Value
        horizRapid = tc.HorizRapid.Value
        vertRapid = tc.VertRapid.Value

        while edge or lastEdge < len(pathData.edges):
            PathLog.debug("------- lastEdge = %d/%d.%d/%d" % (lastEdge, lastTag, t, len(tags)))
            if not edge:
                edge = pathData.edges[lastEdge]
                debugEdge(edge, "=======  new edge: %d/%d" % (lastEdge, len(pathData.edges)))
                lastEdge += 1
                # sameTag = None

            if mapper:
                mapper.add(edge)
                if mapper.mappingComplete():
                    commands.extend(mapper.commands)
                    edge = mapper.tail
                    mapper = None
                else:
                    edge = None

            if edge:
                tIndex = (t + lastTag) % len(tags)
                t += 1
                i = tags[tIndex].intersects(edge, edge.FirstParameter)
                if i and self.isValidTagStartIntersection(edge, i):
                    mapper = MapWireToTag(edge, tags[tIndex], i, segm, pathData.maxZ, hSpeed = horizFeed, vSpeed = vertFeed)
                    self.mappers.append(mapper)
                    edge = mapper.tail

            if not mapper and t >= len(tags):
                # gone through all tags, consume edge and move on
                if edge:
                    debugEdge(edge, '++++++++')
                    if pathData.rapid.isRapid(edge):
                        v = edge.Vertexes[1]
                        if not commands and PathGeom.isRoughly(0, v.X) and PathGeom.isRoughly(0, v.Y) and not PathGeom.isRoughly(0, v.Z):
                            # The very first move is just to move to ClearanceHeight
                            commands.append(Path.Command('G0', {'Z': v.Z, 'F': horizRapid}))
                        else:
                            commands.append(Path.Command('G0', {'X': v.X, 'Y': v.Y, 'Z': v.Z, 'F': vertRapid}))
                    else:
                        commands.extend(PathGeom.cmdsForEdge(edge, segm=segm, hSpeed = horizFeed, vSpeed = vertFeed))
                edge = None
                t = 0

        return Path.Path(commands)
 def IsActive(self):
     op = PathDressup.selection()
     if op:
         return not PathDressup.hasEntryMethod(op)
     return False
예제 #29
0
    def getSideOfPath(self, obj):
        op = PathDressup.baseOp(obj.Base)
        if hasattr(op, 'Side'):
            return op.Side

        return ''
예제 #30
0
    def getLeadStart(self, obj, queue, action):
        """returns Lead In G-code."""
        # Modified March 2022 by lcorley to support leadin extension
        results = []
        op = PathDressup.baseOp(obj.Base)
        tc = PathDressup.toolController(obj.Base)
        horizFeed = tc.HorizFeed.Value
        vertFeed = tc.VertFeed.Value
        toolnummer = tc.ToolNumber
        arcs_identical = False

        # Set the correct twist command
        if self.getDirectionOfPath(obj) == "left":
            arcdir = "G3"
        else:
            arcdir = "G2"

        R = obj.Length.Value  # Radius of roll or length
        if queue[1].Name == "G1":  # line
            p0 = queue[0].Placement.Base
            p1 = queue[1].Placement.Base
            v = self.normalize(p1.sub(p0))
            PathLog.debug(" CURRENT_IN Line : P0 Z:{} p1 Z:{}".format(
                p0.z, p1.z))
        else:
            p0 = queue[0].Placement.Base
            p1 = queue[1].Placement.Base
            v = self.normalize(p1.sub(p0))
            PathLog.debug(
                " CURRENT_IN ARC : P0 X:{} Y:{} P1 X:{} Y:{} ".format(
                    p0.x, p0.y, p1.x, p1.y))

        # Calculate offset vector (will be overwritten for arcs)
        if self.getDirectionOfPath(obj) == "right":
            off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0)
        else:
            off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0)

        # Check if we enter at line or arc command
        if queue[1].Name in movecommands and queue[1].Name not in arccommands:
            # We have a line move
            vec = p1.sub(p0)
            vec_n = self.normalize(vec)
            vec_inv = self.invert(vec_n)
            vec_off = self.multiply(vec_inv, obj.ExtendLeadIn)
            PathLog.debug(
                "LineCMD: {}, Vxinv: {}, Vyinv: {}, Vxoff: {}, Vyoff: {}".
                format(queue[0].Name, vec_inv.x, vec_inv.y, vec_off.x,
                       vec_off.y))
        else:
            # We have an arc move
            # Calculate coordinates for middle of circle
            pij = copy.deepcopy(p0)
            pij.x += queue[1].Parameters["I"]
            pij.y += queue[1].Parameters["J"]

            # Check if lead in and operation go in same direction (usually for inner circles)
            if arcdir == queue[1].Name:
                arcs_identical = True

            # Calculate vector circle start -> circle middle
            vec_circ = pij.sub(p0)

            # Rotate vector to get direction for lead in
            if arcdir == "G2":
                vec_rot = self.rotate(vec_circ, 90)
            else:
                vec_rot = self.rotate(vec_circ, -90)

            # Normalize and invert vector
            vec_n = self.normalize(vec_rot)

            v = self.invert(vec_n)

            # Calculate offset of lead in
            if arcdir == "G3":
                off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0)
            else:
                off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0)

        offsetvector = FreeCAD.Vector(v.x * R, v.y * R, 0)  # IJ

        if obj.RadiusCenter == "Radius":
            leadstart = (p0.add(off_v)).sub(offsetvector)  # Rmode
            if arcs_identical:
                t = p0.sub(leadstart)
                t = p0.add(t)
                leadstart = t
                offsetvector = self.multiply(offsetvector, -1)
        else:
            leadstart = p0.add(off_v)  # Dmode
        # At this point leadstart is the beginning of the leadin arc
        # and offsetvector points from leadstart to the center of the leadin arc
        # so the offsetvector is a radius of the leadin arc at its start
        # The extend line should be tangent to the leadin arc at this point, or perpendicular to the radius
        if arcdir == "G2":
            tangentvec = self.rotate(offsetvector, -90)
        else:
            tangentvec = self.rotate(offsetvector, 90)
        # Normalize the tangent vector
        tangentvecNorm = self.normalize(tangentvec)
        # Multiply tangentvecNorm by LeadIn length
        leadlinevec = self.multiply(tangentvecNorm, obj.ExtendLeadIn)
        # leadlinevec provides the offset from the beginning of the lead arc to the beginning of the extend line
        extendstart = leadstart.add(leadlinevec)

        if action == "start":
            if obj.ExtendLeadIn != 0:
                # Rapid move to beginning of extend line
                extendcommand = Path.Command(
                    "G0",
                    {
                        "X": extendstart.x,
                        "Y": extendstart.y,
                        "Z": op.ClearanceHeight.Value,
                    },
                )
            else:
                # Rapid move to beginning of leadin arc
                extendcommand = Path.Command(
                    "G0",
                    {
                        "X": extendstart.x,
                        "Y": extendstart.y,
                        "Z": op.ClearanceHeight.Value,
                    },
                )
            results.append(extendcommand)
            extendcommand = Path.Command("G0", {"Z": op.SafeHeight.Value})
            results.append(extendcommand)

        if action == "layer":
            if not obj.KeepToolDown:
                extendcommand = Path.Command("G0", {"Z": op.SafeHeight.Value})
                results.append(extendcommand)

            extendcommand = Path.Command("G0", {
                "X": extendstart.x,
                "Y": extendstart.y
            })
            results.append(extendcommand)

        if obj.RapidPlunge:
            extendcommand = Path.Command("G0", {"Z": p1.z})
        else:
            extendcommand = Path.Command("G1", {"Z": p1.z, "F": vertFeed})
        results.append(extendcommand)

        if obj.UseMachineCRC:
            if self.getDirectionOfPath(obj) == "right":
                results.append(Path.Command("G42", {"D": toolnummer}))
            else:
                results.append(Path.Command("G41", {"D": toolnummer}))

        if obj.StyleOn == "Arc":
            if obj.ExtendLeadIn != 0:
                # Insert move to beginning of leadin arc
                extendcommand = Path.Command("G1", {
                    "X": leadstart.x,
                    "Y": leadstart.y,
                    "F": horizFeed
                })
                results.append(extendcommand)
            arcmove = Path.Command(
                arcdir,
                {
                    "X": p0.x,
                    "Y": p0.y,
                    "Z": p0.z,
                    "I": offsetvector.x,
                    "J": offsetvector.y,
                    "K": offsetvector.z,
                    "F": horizFeed,
                },
            )  # add G2/G3 move
            results.append(arcmove)
        elif obj.StyleOn == "Tangent":
            extendcommand = Path.Command("G1", {
                "X": p0.x,
                "Y": p0.y,
                "F": horizFeed
            })
            results.append(extendcommand)
        else:
            PathLog.debug(" CURRENT_IN Perp")

        currLocation.update(results[-1].Parameters)
        currLocation["Z"] = p1.z

        return results
예제 #31
0
    def execute(self):
        if (
            not self.baseOp
            or not self.baseOp.isDerivedFrom("Path::Feature")
            or not self.baseOp.Path
        ):
            return None

        if len(self.baseOp.Path.Commands) == 0:
            PathLog.warning("No Path Commands for %s" % self.baseOp.Label)
            return []

        tc = PathDressup.toolController(self.baseOp)

        self.safeHeight = float(PathUtil.opProperty(self.baseOp, "SafeHeight"))
        self.clearanceHeight = float(
            PathUtil.opProperty(self.baseOp, "ClearanceHeight")
        )
        self.strG0ZsafeHeight = Path.Command(  # was a Feed rate with G1
            "G0", {"Z": self.safeHeight, "F": tc.VertRapid.Value}
        )
        self.strG0ZclearanceHeight = Path.Command("G0", {"Z": self.clearanceHeight})

        cmd = self.baseOp.Path.Commands[0]
        pos = cmd.Placement.Base  # bogus m/c position to create first edge
        bogusX = True
        bogusY = True
        commands = [cmd]
        lastExit = None
        for cmd in self.baseOp.Path.Commands[1:]:
            if cmd.Name in PathGeom.CmdMoveAll:
                if bogusX:
                    bogusX = "X" not in cmd.Parameters
                if bogusY:
                    bogusY = "Y" not in cmd.Parameters
                edge = PathGeom.edgeForCmd(cmd, pos)
                if edge:
                    inside = edge.common(self.boundary).Edges
                    outside = edge.cut(self.boundary).Edges
                    if not self.inside:  # UI "inside boundary" param
                        tmp = inside
                        inside = outside
                        outside = tmp
                    # it's really a shame that one cannot trust the sequence and/or
                    # orientation of edges
                    if 1 == len(inside) and 0 == len(outside):
                        PathLog.track(_vstr(pos), _vstr(lastExit), " + ", cmd)
                        # cmd fully included by boundary
                        if lastExit:
                            if not (
                                bogusX or bogusY
                            ):  # don't insert false paths based on bogus m/c position
                                commands.extend(
                                    self.boundaryCommands(
                                        lastExit, pos, tc.VertFeed.Value
                                    )
                                )
                            lastExit = None
                        commands.append(cmd)
                        pos = PathGeom.commandEndPoint(cmd, pos)
                    elif 0 == len(inside) and 1 == len(outside):
                        PathLog.track(_vstr(pos), _vstr(lastExit), " - ", cmd)
                        # cmd fully excluded by boundary
                        if not lastExit:
                            lastExit = pos
                        pos = PathGeom.commandEndPoint(cmd, pos)
                    else:
                        PathLog.track(
                            _vstr(pos), _vstr(lastExit), len(inside), len(outside), cmd
                        )
                        # cmd pierces boundary
                        while inside or outside:
                            ie = [e for e in inside if PathGeom.edgeConnectsTo(e, pos)]
                            PathLog.track(ie)
                            if ie:
                                e = ie[0]
                                LastPt = e.valueAt(e.LastParameter)
                                flip = PathGeom.pointsCoincide(pos, LastPt)
                                newPos = e.valueAt(e.FirstParameter) if flip else LastPt
                                # inside edges are taken at this point (see swap of inside/outside
                                # above - so we can just connect the dots ...
                                if lastExit:
                                    if not (bogusX or bogusY):
                                        commands.extend(
                                            self.boundaryCommands(
                                                lastExit, pos, tc.VertFeed.Value
                                            )
                                        )
                                    lastExit = None
                                PathLog.track(e, flip)
                                if not (
                                    bogusX or bogusY
                                ):  # don't insert false paths based on bogus m/c position
                                    commands.extend(
                                        PathGeom.cmdsForEdge(
                                            e,
                                            flip,
                                            False,
                                            50,
                                            tc.HorizFeed.Value,
                                            tc.VertFeed.Value,
                                        )
                                    )
                                inside.remove(e)
                                pos = newPos
                                lastExit = newPos
                            else:
                                oe = [
                                    e
                                    for e in outside
                                    if PathGeom.edgeConnectsTo(e, pos)
                                ]
                                PathLog.track(oe)
                                if oe:
                                    e = oe[0]
                                    ptL = e.valueAt(e.LastParameter)
                                    flip = PathGeom.pointsCoincide(pos, ptL)
                                    newPos = (
                                        e.valueAt(e.FirstParameter) if flip else ptL
                                    )
                                    # outside edges are never taken at this point (see swap of
                                    # inside/outside above) - so just move along ...
                                    outside.remove(e)
                                    pos = newPos
                                else:
                                    PathLog.error("huh?")
                                    import Part

                                    Part.show(Part.Vertex(pos), "pos")
                                    for e in inside:
                                        Part.show(e, "ei")
                                    for e in outside:
                                        Part.show(e, "eo")
                                    raise Exception("This is not supposed to happen")
                                # Eif
                            # Eif
                        # Ewhile
                    # Eif
                    # pos = PathGeom.commandEndPoint(cmd, pos)
                # Eif
            else:
                PathLog.track("no-move", cmd)
                commands.append(cmd)
        if lastExit:
            commands.extend(self.boundaryCommands(lastExit, None, tc.VertFeed.Value))
            lastExit = None

        PathLog.track(commands)
        return Path.Path(commands)
예제 #32
0
 def toolRadius(self):
     return PathDressup.toolController(self.obj.Base).Tool.Diameter / 2.0
    def createPath(self, obj, pathData, tags):
        PathLog.track()
        commands = []
        lastEdge = 0
        lastTag = 0
        # sameTag = None
        t = 0
        # inters = None
        edge = None

        segm = 50
        if hasattr(obj, 'SegmentationFactor'):
            segm = obj.SegmentationFactor
            if segm <= 0:
                segm = 50
                obj.SegmentationFactor = 50

        self.mappers = []
        mapper = None

        while edge or lastEdge < len(pathData.edges):
            PathLog.debug("------- lastEdge = %d/%d.%d/%d" % (lastEdge, lastTag, t, len(tags)))
            if not edge:
                edge = pathData.edges[lastEdge]
                debugEdge(edge, "=======  new edge: %d/%d" % (lastEdge, len(pathData.edges)))
                lastEdge += 1
                # sameTag = None

            if mapper:
                mapper.add(edge)
                if mapper.mappingComplete():
                    commands.extend(mapper.commands)
                    edge = mapper.tail
                    mapper = None
                else:
                    edge = None

            if edge:
                tIndex = (t + lastTag) % len(tags)
                t += 1
                i = tags[tIndex].intersects(edge, edge.FirstParameter)
                if i and self.isValidTagStartIntersection(edge, i):
                    mapper = MapWireToTag(edge, tags[tIndex], i, segm, pathData.maxZ)
                    self.mappers.append(mapper)
                    edge = mapper.tail

            if not mapper and t >= len(tags):
                # gone through all tags, consume edge and move on
                if edge:
                    debugEdge(edge, '++++++++')
                    if pathData.rapid.isRapid(edge):
                        v = edge.Vertexes[1]
                        if not commands and PathGeom.isRoughly(0, v.X) and PathGeom.isRoughly(0, v.Y) and not PathGeom.isRoughly(0, v.Z):
                            # The very first move is just to move to ClearanceHeight
                            commands.append(Path.Command('G0', {'Z': v.Z}))
                        else:
                            commands.append(Path.Command('G0', {'X': v.X, 'Y': v.Y, 'Z': v.Z}))
                    else:
                        commands.extend(PathGeom.cmdsForEdge(edge, segm=segm))
                edge = None
                t = 0

        lastCmd = Path.Command('G0', {'X': 0.0, 'Y': 0.0, 'Z': 0.0})
        outCommands = []

        tc = PathDressup.toolController(obj.Base)
        horizFeed = tc.HorizFeed.Value
        vertFeed = tc.VertFeed.Value
        horizRapid = tc.HorizRapid.Value
        vertRapid = tc.VertRapid.Value

        for cmd in commands:
            params = cmd.Parameters
            zVal = params.get('Z', None)
            zVal2 = lastCmd.Parameters.get('Z', None)

            zVal = zVal and round(zVal, 8)
            zVal2 = zVal2 and round(zVal2, 8)

            if cmd.Name in ['G1', 'G2', 'G3', 'G01', 'G02', 'G03']:
                if False and zVal is not None and zVal2 != zVal:
                    params['F'] = vertFeed
                else:
                    params['F'] = horizFeed
                lastCmd = cmd

            elif cmd.Name in ['G0', 'G00']:
                if zVal is not None and zVal2 != zVal:
                    params['F'] = vertRapid
                else:
                    params['F'] = horizRapid
                lastCmd = cmd

            outCommands.append(Path.Command(cmd.Name, params))

        return Path.Path(outCommands)
예제 #34
0
 def IsActive(self):
     op = PathDressup.selection()
     if op:
         return not PathDressup.hasEntryMethod(op)
     return False
예제 #35
0
    def getLeadEnd(self, obj, queue, action):
        """returns the Gcode of LeadOut."""
        results = []
        horizFeed = PathDressup.toolController(obj.Base).HorizFeed.Value
        R = obj.Length.Value  # Radius of roll or length
        arcs_identical = False

        # Set the correct twist command
        if self.getDirectionOfPath(obj) == "right":
            arcdir = "G2"
        else:
            arcdir = "G3"

        if queue[1].Name == "G1":  # line
            p0 = queue[0].Placement.Base
            p1 = queue[1].Placement.Base
            v = self.normalize(p1.sub(p0))
        else:  # dealing with a circle
            p0 = queue[0].Placement.Base
            p1 = queue[1].Placement.Base
            v = self.normalize(p1.sub(p0))

        if self.getDirectionOfPath(obj) == "right":
            off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0)
        else:
            off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0)

        # Check if we leave at line or arc command
        if queue[1].Name in movecommands and queue[1].Name not in arccommands:
            # We have a line move
            vec = p1.sub(p0)
            vec_n = self.normalize(vec)
            vec_inv = self.invert(vec_n)
            vec_off = self.multiply(vec_inv, obj.ExtendLeadOut)
            PathLog.debug(
                "LineCMD: {}, Vxinv: {}, Vyinv: {}, Vxoff: {}, Vyoff: {}".
                format(queue[0].Name, vec_inv.x, vec_inv.y, vec_off.x,
                       vec_off.y))
        else:
            # We have an arc move
            pij = copy.deepcopy(p0)
            pij.x += queue[1].Parameters["I"]
            pij.y += queue[1].Parameters["J"]
            ve = pij.sub(p1)

            if arcdir == queue[1].Name:
                arcs_identical = True

            if arcdir == "G2":
                vec_rot = self.rotate(ve, -90)
            else:
                vec_rot = self.rotate(ve, 90)

            vec_n = self.normalize(vec_rot)
            v = vec_n

            if arcdir == "G3":
                off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0)
            else:
                off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0)

            vec_inv = self.invert(vec_rot)

        offsetvector = FreeCAD.Vector(v.x * R, v.y * R, 0.0)
        if obj.RadiusCenter == "Radius":
            leadend = (p1.add(off_v)).add(offsetvector)  # Rmode
            if arcs_identical:
                t = p1.sub(leadend)
                t = p1.add(t)
                leadend = t
                off_v = self.multiply(off_v, -1)
        else:
            leadend = p1.add(off_v)  # Dmode

        IJ = off_v
        # At this point leadend is the location of the end of the leadout arc
        # IJ is an offset from the beginning of the leadout arc to its center.
        # It is parallel to a tangent line at the end of the leadout arc
        # Create the normalized tangent vector
        tangentvecNorm = self.normalize(IJ)
        leadlinevec = self.multiply(tangentvecNorm, obj.ExtendLeadOut)
        extendleadoutend = leadend.add(leadlinevec)

        if obj.StyleOff == "Arc":
            arcmove = Path.Command(
                arcdir,
                {
                    "X": leadend.x,
                    "Y": leadend.y,
                    "Z": leadend.z,
                    "I": IJ.x,
                    "J": IJ.y,
                    "K": IJ.z,
                    "F": horizFeed,
                },
            )  # add G2/G3 move
            results.append(arcmove)
            if obj.ExtendLeadOut != 0:
                extendcommand = Path.Command(
                    "G1",
                    {
                        "X": extendleadoutend.x,
                        "Y": extendleadoutend.y,
                        "F": horizFeed
                    },
                )
                results.append(extendcommand)
        elif obj.StyleOff == "Tangent":
            extendcommand = Path.Command("G1", {
                "X": leadend.x,
                "Y": leadend.y,
                "F": horizFeed
            })
            results.append(extendcommand)
        else:
            PathLog.debug(" CURRENT_IN Perp")

        if obj.UseMachineCRC:  # crc off
            results.append(Path.Command("G40", {}))

        return results