Beispiel #1
0
    def opExecute(self, obj, getsim=False):
        """opExecute(obj, getsim=False) ... implementation of Path.Area ops.
        determines the parameters for _buildPathArea().
        Do not overwrite, implement
            areaOpAreaParams(obj, isHole) ... op specific area param dictionary
            areaOpPathParams(obj, isHole) ... op specific path param dictionary
            areaOpShapes(obj)             ... the shape for path area to process
            areaOpUseProjection(obj)      ... return true if operation can use projection
        instead."""
        PathLog.track()

        # Instantiate class variables for operation reference
        self.endVector = None
        self.leadIn = 2.0

        # Initiate depthparams and calculate operation heights for operation
        self.depthparams = self._customDepthParams(obj, obj.StartDepth.Value,
                                                   obj.FinalDepth.Value)

        # Set start point
        if PathOp.FeatureStartPoint & self.opFeatures(
                obj) and obj.UseStartPoint:
            start = obj.StartPoint
        else:
            start = None

        aOS = self.areaOpShapes(obj)

        # Adjust tuples length received from other PathWB tools/operations
        shapes = []
        for shp in aOS:
            if len(shp) == 2:
                (fc, iH) = shp
                #     fc, iH,  sub or description
                tup = fc, iH, "otherOp"
                shapes.append(tup)
            else:
                shapes.append(shp)

        if len(shapes) > 1:
            locations = []
            for s in shapes:
                if s[2] == "OpenEdge":
                    shp = Part.makeCompound(s[0])
                else:
                    shp = s[0]
                locations.append({
                    "x": shp.BoundBox.XMax,
                    "y": shp.BoundBox.YMax,
                    "shape": s
                })

            locations = PathUtils.sort_locations(locations, ["x", "y"])

            shapes = [j["shape"] for j in locations]

        sims = []
        for shape, isHole, sub in shapes:
            profileEdgesIsOpen = False

            if sub == "OpenEdge":
                profileEdgesIsOpen = True
                if (PathOp.FeatureStartPoint & self.opFeatures(obj)
                        and obj.UseStartPoint):
                    osp = obj.StartPoint
                    self.commandlist.append(
                        Path.Command("G0", {
                            "X": osp.x,
                            "Y": osp.y,
                            "F": self.horizRapid
                        }))

            try:
                if profileEdgesIsOpen:
                    (pp, sim) = self._buildProfileOpenEdges(
                        obj, shape, isHole, start, getsim)
                else:
                    (pp, sim) = self._buildPathArea(obj, shape, isHole, start,
                                                    getsim)
            except Exception as e:
                FreeCAD.Console.PrintError(e)
                FreeCAD.Console.PrintError(
                    "Something unexpected happened. Check project and tool config."
                )
                raise e
            else:
                if profileEdgesIsOpen:
                    ppCmds = pp
                else:
                    ppCmds = pp.Commands

                # Save gcode commands to object command list
                self.commandlist.extend(ppCmds)
                sims.append(sim)
            # Eif

            if (self.areaOpRetractTool(obj) and self.endVector is not None
                    and len(self.commandlist) > 1):
                self.endVector[2] = obj.ClearanceHeight.Value
                self.commandlist.append(
                    Path.Command("G0", {
                        "Z": obj.ClearanceHeight.Value,
                        "F": self.vertRapid
                    }))

        PathLog.debug("obj.Name: " + str(obj.Name) + "\n\n")
        return sims
Beispiel #2
0
    def circularHoleExecute(self, obj, holes):
        """circularHoleExecute(obj, holes) ... generate drill operation for each hole in holes."""
        PathLog.track()
        machine = PathMachineState.MachineState()

        self.commandlist.append(Path.Command("(Begin Drilling)"))

        # rapid to clearance height
        command = Path.Command("G0", {"Z": obj.ClearanceHeight.Value})
        machine.addCommand(command)
        self.commandlist.append(command)

        self.commandlist.append(Path.Command("G90"))  # Absolute distance mode

        # Calculate offsets to add to target edge
        endoffset = 0.0
        if obj.ExtraOffset == "Drill Tip":
            endoffset = PathUtils.drillTipLength(self.tool)
        elif obj.ExtraOffset == "2x Drill Tip":
            endoffset = PathUtils.drillTipLength(self.tool) * 2

        # http://linuxcnc.org/docs/html/gcode/g-code.html#gcode:g98-g99
        self.commandlist.append(Path.Command(obj.ReturnLevel))

        holes = PathUtils.sort_locations(holes, ["x", "y"])

        # This section is technical debt. The computation of the
        # target shapes should be factored out for re-use.
        # This will likely mean refactoring upstream CircularHoleBase to pass
        # spotshapes instead of holes.

        startHeight = obj.StartDepth.Value + self.job.SetupSheet.SafeHeightOffset.Value

        edgelist = []
        for hole in holes:
            v1 = FreeCAD.Vector(hole["x"], hole["y"], obj.StartDepth.Value)
            v2 = FreeCAD.Vector(hole["x"], hole["y"],
                                obj.FinalDepth.Value - endoffset)
            edgelist.append(Part.makeLine(v1, v2))

        # iterate the edgelist and generate gcode
        for edge in edgelist:

            PathLog.debug(edge)

            # move to hole location

            startPoint = edge.Vertexes[0].Point

            command = Path.Command("G0", {
                "X": startPoint.x,
                "Y": startPoint.y
            })
            self.commandlist.append(command)
            machine.addCommand(command)

            command = Path.Command("G0", {"Z": startHeight})
            self.commandlist.append(command)
            machine.addCommand(command)

            # command = Path.Command("G1", {"Z": obj.StartDepth.Value})
            # self.commandlist.append(command)
            # machine.addCommand(command)

            # Technical Debt:  We are assuming the edges are aligned.
            # This assumption should be corrected and the necessary rotations
            # performed to align the edge with the Z axis for drilling

            # Perform drilling
            dwelltime = obj.DwellTime if obj.DwellEnabled else 0.0
            peckdepth = obj.PeckDepth.Value if obj.PeckEnabled else 0.0
            repeat = 1  # technical debt:  Add a repeat property for user control
            chipBreak = (obj.chipBreakEnabled and obj.PeckEnabled)

            try:
                drillcommands = generator.generate(edge,
                                                   dwelltime,
                                                   peckdepth,
                                                   repeat,
                                                   obj.RetractHeight.Value,
                                                   chipBreak=chipBreak)

            except ValueError as e:  # any targets that fail the generator are ignored
                PathLog.info(e)
                continue

            for command in drillcommands:
                self.commandlist.append(command)
                machine.addCommand(command)

        # Cancel canned drilling cycle
        self.commandlist.append(Path.Command("G80"))
        command = Path.Command("G0", {"Z": obj.SafeHeight.Value})
        self.commandlist.append(command)
        machine.addCommand(command)

        # Apply feedrates to commands
        PathFeedRate.setFeedRate(self.commandlist, obj.ToolController)