Ejemplo n.º 1
0
    def setDefaultValues(self, obj):
        '''setDefaultValues(obj) ... base implementation.
        Do not overwrite, overwrite opSetDefaultValues() instead.'''
        job = PathUtils.addToJob(obj)

        obj.Active = True

        features = self.opFeatures(obj)

        if FeatureTool & features:
            if 1 < len(job.Operations.Group):
                obj.ToolController = PathUtil.toolControllerForOp(
                    job.Operations.Group[-2])
            else:
                obj.ToolController = PathUtils.findToolController(obj)
            if not obj.ToolController:
                return None
            obj.OpToolDiameter = obj.ToolController.Tool.Diameter

        if FeatureCoolant & features:
            obj.CoolantMode = job.SetupSheet.CoolantMode

        if FeatureDepths & features:
            if self.applyExpression(obj, 'StartDepth',
                                    job.SetupSheet.StartDepthExpression):
                obj.OpStartDepth = 1.0
            else:
                obj.StartDepth = 1.0
            if self.applyExpression(obj, 'FinalDepth',
                                    job.SetupSheet.FinalDepthExpression):
                obj.OpFinalDepth = 0.0
            else:
                obj.FinalDepth = 0.0
        else:
            obj.StartDepth = 1.0

        if FeatureStepDown & features:
            if not self.applyExpression(obj, 'StepDown',
                                        job.SetupSheet.StepDownExpression):
                obj.StepDown = '1 mm'

        if FeatureHeights & features:
            if job.SetupSheet.SafeHeightExpression:
                if not self.applyExpression(
                        obj, 'SafeHeight',
                        job.SetupSheet.SafeHeightExpression):
                    obj.SafeHeight = '3 mm'
            if job.SetupSheet.ClearanceHeightExpression:
                if not self.applyExpression(
                        obj, 'ClearanceHeight',
                        job.SetupSheet.ClearanceHeightExpression):
                    obj.ClearanceHeight = '5 mm'

        if FeatureStartPoint & features:
            obj.UseStartPoint = False

        self.opSetDefaultValues(obj, job)
        return job
Ejemplo n.º 2
0
    def executeUpload(self):
        '''Post process the current Path.Job and upload the resulting g-code into MK.
        Tag the uploaded g-code with the job and a hash so we can determine if the uploaded
        version is consistent with what is currently in FC.'''

        job = self.job
        if job:
            currTool = None
            postlist = []
            for obj in job.Operations.Group:
                tc = PathUtil.toolControllerForOp(obj)
                if tc is not None:
                    if tc.ToolNumber != currTool:
                        postlist.append(tc)
                        currTool = tc.ToolNumber
                postlist.append(obj)

            post = PathPost.CommandPathPost()
            fail, gcode = post.exportObjectsWith(postlist, job, False)
            if not fail:
                print("POST: ", fail)
                preamble = "(FreeCAD.Job: %s)\n(FreeCAD.File: %s)\n(FreeCAD.Signature: %d)\n" % (
                    job.Name, job.Document.FileName,
                    MKUtils.pathSignature(job.Path))
                buf = io.BytesIO((preamble + gcode).encode())
                endpoint = self.mk.instance.endpoint.get('file')
                if endpoint:
                    ftp = ftplib.FTP()
                    ftp.connect(endpoint.address(), endpoint.port())
                    ftp.login()
                    ftp.storbinary("STOR %s" % self.mk.RemoteFilename, buf)
                    ftp.quit()
                    sequence = MKUtils.taskModeMDI(self.mk)
                    for tc in job.ToolController:
                        t = tc.Tool
                        radius = float(t.Diameter) / 2 if hasattr(
                            t, 'Diameter') else 0.
                        offset = t.LengthOffset if hasattr(
                            t, 'LengthOffset') else 0.
                        sequence.append(
                            MKCommandTaskExecute(
                                "G10 L1 P%d R%g Z%g" %
                                (tc.ToolNumber, radius, offset)))
                    sequence.extend(MKUtils.taskModeAuto(self.mk))
                    sequence.append(MKCommandTaskReset(False))
                    sequence.extend([
                        MKCommandOpenFile(self.mk.remoteFilePath(), True),
                        MKCommandOpenFile(self.mk.remoteFilePath(), False)
                    ])
                    sequence.append(MKCommandTaskRun(True))
                    self.mk['command'].sendCommands(sequence)
                else:
                    PathLog.error('No endpoint found')
            else:
                PathLog.error('Post processing failed')
Ejemplo n.º 3
0
    def setDefaultValues(self, obj):
        '''setDefaultValues(obj) ... base implementation.
        Do not overwrite, overwrite opSetDefaultValues() instead.'''
        job = PathUtils.addToJob(obj)

        obj.Active = True

        features = self.opFeatures(obj)

        if FeatureTool & features:
            if 1 < len(job.Operations.Group):
                obj.ToolController = PathUtil.toolControllerForOp(job.Operations.Group[-2])
            else:
                obj.ToolController = PathUtils.findToolController(obj)
            if not obj.ToolController:
                return None
            obj.OpToolDiameter = obj.ToolController.Tool.Diameter

        if FeatureDepths & features:
            if self.applyExpression(obj, 'StartDepth', job.SetupSheet.StartDepthExpression):
                obj.OpStartDepth = 1.0
            else:
                obj.StartDepth = 1.0
            if self.applyExpression(obj, 'FinalDepth', job.SetupSheet.FinalDepthExpression):
                obj.OpFinalDepth = 0.0
            else:
                obj.FinalDepth = 0.0
        else:
            obj.StartDepth = 1.0

        if FeatureStepDown & features:
            if not self.applyExpression(obj, 'StepDown', job.SetupSheet.StepDownExpression):
                obj.StepDown = '1 mm'

        if FeatureHeights & features:
            if job.SetupSheet.SafeHeightExpression:
                if not self.applyExpression(obj, 'SafeHeight', job.SetupSheet.SafeHeightExpression):
                    obj.SafeHeight = '3 mm'
            if job.SetupSheet.ClearanceHeightExpression:
                if not self.applyExpression(obj, 'ClearanceHeight', job.SetupSheet.ClearanceHeightExpression):
                    obj.ClearanceHeight = '5 mm'

        if FeatureStartPoint & features:
            obj.UseStartPoint = False

        self.opSetDefaultValues(obj, job)
        return job
Ejemplo n.º 4
0
    def executeUpload(self):
        job = self.job
        if job:
            currTool = None
            postlist = []
            for obj in job.Operations.Group:
                tc = PathUtil.toolControllerForOp(obj)
                if tc is not None:
                    if tc.ToolNumber != currTool:
                        postlist.append(tc)
                        currTool = tc.ToolNumber
                postlist.append(obj)

            post = PathPost.CommandPathPost()
            fail, gcode = post.exportObjectsWith(postlist, job, False)
            if not fail:
                print("POST: ", fail)
                preamble = "(FreeCAD.Job: %s)\n(FreeCAD.File: %s)\n(FreeCAD.Signature: %d)\n" % (
                    job.Name, job.Document.FileName,
                    MKUtils.pathSignature(job.Path))
                buf = io.BytesIO((preamble + gcode).encode())
                endpoint = self.mk.instance.endpoint.get('file')
                if endpoint:
                    ftp = ftplib.FTP()
                    ftp.connect(endpoint.address(), endpoint.port())
                    ftp.login()
                    ftp.storbinary("STOR %s" % self.mk.RemoteFilename, buf)
                    ftp.quit()
                    sequence = MKUtils.taskModeMDI(self.mk)
                    for tc in job.ToolController:
                        t = tc.Tool
                        sequence.append(
                            MKCommandTaskExecute("G10 L1 P%d R%g Z%g" %
                                                 (tc.ToolNumber, t.Diameter /
                                                  2., t.LengthOffset)))
                    sequence.extend(MKUtils.taskModeAuto(self.mk))
                    sequence.append(MKCommandTaskReset(False))
                    sequence.append(
                        MKCommandOpenFile(self.mk.remoteFilePath(), False))
                    self.mk['command'].sendCommands(sequence)
                else:
                    PathLog.error('No endpoint found')
            else:
                PathLog.error('Post processing failed')
Ejemplo n.º 5
0
	def Activated(self):
		PathLog.track()
		FreeCAD.ActiveDocument.openTransaction(
			translate("Path_Post", "Post Process the Selected path(s)"))
		FreeCADGui.addModule("PathScripts.PathPost")

		# Attempt to figure out what the user wants to post-process
		# If a job is selected, post that.
		# If there's only one job in a document, post it.
		# If a user has selected a subobject of a job, post the job.
		# If multiple jobs and can't guess, ask them.

		selected = FreeCADGui.Selection.getSelectionEx()
		if len(selected) > 1:
			FreeCAD.Console.PrintError(
			"Please select a single job or other path object\n")
			return

		elif len(selected) == 1:
			sel = selected[0].Object
			if sel.Name[:3] == "Job":
				job = sel
			elif hasattr(sel, "Path"):
				try:
					job = PathUtils.findParentJob(sel)
				except Exception:  # pylint: disable=broad-except
					job = None
			else:
				job = None
		if job is None:
			targetlist = []
			for o in FreeCAD.ActiveDocument.Objects:
				if hasattr(o, "Proxy"):
					if isinstance(o.Proxy, PathJob.ObjectJob):
						targetlist.append(o.Label)
			PathLog.debug("Possible post objects: {}".format(targetlist))
			if len(targetlist) > 1:
				form = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobChooser.ui")
				form.cboProject.addItems(targetlist)
				r = form.exec_()
				if r is False:
					return
				else:
					jobname = form.cboProject.currentText()
			else:
				jobname = targetlist[0]
			job = FreeCAD.ActiveDocument.getObject(jobname)

		PathLog.debug("about to postprocess job: {}".format(job.Name))

		# Build up an ordered list of operations and tool changes.
		# Then post-the ordered list
		if hasattr(job, "Fixtures"):
			wcslist = job.Fixtures
		else:
			wcslist = ['G54']

		if hasattr(job, "OrderOutputBy"):
			orderby = job.OrderOutputBy
		else:
			orderby = "Operation"

		if hasattr(job, "SplitOutput"):
			split = job.SplitOutput
		else:
			split = False

		if hasattr(job, "OperatorSetupsheet"):
			ossheet = job.OperatorSetupsheet
		else:
			ossheet = False

		postlist = []

		if orderby == 'Fixture':
			PathLog.debug("Ordering by Fixture")
			# Order by fixture means all operations and tool changes will be completed in one
			# fixture before moving to the next.

			currTool = None
			for index, f in enumerate(wcslist):
				# create an object to serve as the fixture path
				fobj = _TempObject()
				c1 = Path.Command(f)
				fobj.Path = Path.Path([c1])
				if index != 0:
					c2 = Path.Command("G0 Z" + str(job.Stock.Shape.BoundBox.ZMax
					+ job.SetupSheet.ClearanceHeightOffset.Value))
					fobj.Path.addCommands(c2)
				fobj.InList.append(job)
				sublist = [fobj]

				# Now generate the gcode
				for obj in job.Operations.Group:
					tc = PathUtil.toolControllerForOp(obj)
					if tc is not None and PathUtil.opProperty(obj, 'Active'):
						if tc.ToolNumber != currTool:
							sublist.append(tc)
							PathLog.debug("Appending TC: {}".format(tc.Name))
							currTool = tc.ToolNumber
						sublist.append(obj)
					postlist.append(sublist)

		elif orderby == 'Tool':
			PathLog.debug("Ordering by Tool")
			# Order by tool means tool changes are minimized.
			# all operations with the current tool are processed in the current
			# fixture before moving to the next fixture.

			currTool = None
			fixturelist = []
			for f in wcslist:
				# create an object to serve as the fixture path
				fobj = _TempObject()
				c1 = Path.Command(f)
				c2 = Path.Command("G0 Z" + str(job.Stock.Shape.BoundBox.ZMax + job.SetupSheet.ClearanceHeightOffset.Value))

				fobj.Path = Path.Path([c1, c2])
				fobj.InList.append(job)
				fixturelist.append(fobj)

			# Now generate the gcode
			curlist = []  # list of ops for tool, will repeat for each fixture
			sublist = []  # list of ops for output splitting

			for idx, obj in enumerate(job.Operations.Group):

				# check if the operation is active
				active = PathUtil.opProperty(obj, 'Active')

				tc = PathUtil.toolControllerForOp(obj)
				if tc is None or tc.ToolNumber == currTool and active:
					curlist.append(obj)
				elif tc.ToolNumber != currTool and currTool is None and active:  # first TC
					sublist.append(tc)
					curlist.append(obj)
					currTool = tc.ToolNumber
				elif tc.ToolNumber != currTool and currTool is not None and active:  # TC
					for fixture in fixturelist:
						sublist.append(fixture)
						sublist.extend(curlist)
					postlist.append(sublist)
					sublist = [tc]
					curlist = [obj]
					currTool = tc.ToolNumber

				if idx == len(job.Operations.Group) - 1:  # Last operation.
					for fixture in fixturelist:
						sublist.append(fixture)
						sublist.extend(curlist)
					postlist.append(sublist)

		elif orderby == 'Operation':
			PathLog.debug("Ordering by Operation")
			# Order by operation means ops are done in each fixture in
			# sequence.
			currTool = None
			firstFixture = True

			# Now generate the gcode
			for obj in job.Operations.Group:
				if PathUtil.opProperty(obj, 'Active'):
					sublist = []
					PathLog.debug("obj: {}".format(obj.Name))
					for f in wcslist:
						fobj = _TempObject()
						c1 = Path.Command(f)
						fobj.Path = Path.Path([c1])
						if not firstFixture:
							c2 = Path.Command("G0 Z" + str(job.Stock.Shape.BoundBox.ZMax + job.SetupSheet.ClearanceHeightOffset.Value))
							fobj.Path.addCommands(c2)
						fobj.InList.append(job)
						sublist.append(fobj)
						firstFixture = False
						tc = PathUtil.toolControllerForOp(obj)
						if tc is not None:
							if tc.ToolNumber != currTool:
								sublist.append(tc)
								currTool = tc.ToolNumber
						sublist.append(obj)
					postlist.append(sublist)

		fail = True
		rc = '' # pylint: disable=unused-variable
		if split:
			for slist in postlist:
				(fail, rc) = self.exportObjectsWith(slist, job)
		else:
			finalpostlist = [item for slist in postlist for item in slist]
			(fail, rc) = self.exportObjectsWith(finalpostlist, job)

		self.subpart = 1

		if fail:
			FreeCAD.ActiveDocument.abortTransaction()
		else:
			FreeCAD.ActiveDocument.commitTransaction()

		if ossheet:
			FreeCAD.Console.PrintLog("Create OperatorSetupsheet\n")
		else:
			FreeCAD.Console.PrintLog("Do not create OperatorSetupsheet\n")

		FreeCAD.ActiveDocument.recompute()
Ejemplo n.º 6
0
def buildPostList(job):
    """Takes the job and determines the specific objects and order to
    postprocess  Returns a list of objects which can be passed to
    exportObjectsWith() for final posting."""
    wcslist = job.Fixtures
    orderby = job.OrderOutputBy

    postlist = []

    if orderby == "Fixture":
        PathLog.debug("Ordering by Fixture")
        # Order by fixture means all operations and tool changes will be
        # completed in one fixture before moving to the next.

        currTool = None
        for index, f in enumerate(wcslist):
            # create an object to serve as the fixture path
            fobj = _TempObject()
            c1 = Path.Command(f)
            fobj.Path = Path.Path([c1])
            if index != 0:
                c2 = Path.Command(
                    "G0 Z"
                    + str(
                        job.Stock.Shape.BoundBox.ZMax
                        + job.SetupSheet.ClearanceHeightOffset.Value
                    )
                )
                fobj.Path.addCommands(c2)
            fobj.InList.append(job)
            sublist = [fobj]

            # Now generate the gcode
            for obj in job.Operations.Group:
                tc = PathUtil.toolControllerForOp(obj)
                if tc is not None and PathUtil.opProperty(obj, "Active"):
                    if tc.ToolNumber != currTool:
                        sublist.append(tc)
                        PathLog.debug("Appending TC: {}".format(tc.Name))
                        currTool = tc.ToolNumber
                sublist.append(obj)
            postlist.append((f, sublist))

    elif orderby == "Tool":
        PathLog.debug("Ordering by Tool")
        # Order by tool means tool changes are minimized.
        # all operations with the current tool are processed in the current
        # fixture before moving to the next fixture.

        toolstring = "None"
        currTool = None

        # Build the fixture list
        fixturelist = []
        for f in wcslist:
            # create an object to serve as the fixture path
            fobj = _TempObject()
            c1 = Path.Command(f)
            c2 = Path.Command(
                "G0 Z"
                + str(
                    job.Stock.Shape.BoundBox.ZMax
                    + job.SetupSheet.ClearanceHeightOffset.Value
                )
            )
            fobj.Path = Path.Path([c1, c2])
            fobj.InList.append(job)
            fixturelist.append(fobj)

        # Now generate the gcode
        curlist = []  # list of ops for tool, will repeat for each fixture
        sublist = []  # list of ops for output splitting

        PathLog.track(job.PostProcessorOutputFile)
        for idx, obj in enumerate(job.Operations.Group):
            PathLog.track(obj.Label)

            # check if the operation is active
            if not getattr(obj, "Active", True):
                PathLog.track()
                continue

            # Determine the proper string for the Op's TC
            tc = PathUtil.toolControllerForOp(obj)
            if tc is None:
                tcstring = "None"
            elif "%T" in job.PostProcessorOutputFile:
                tcstring = f"{tc.ToolNumber}"
            else:
                tcstring = re.sub(r"[^\w\d-]", "_", tc.Label)
            PathLog.track(toolstring)

            if tc is None or tc.ToolNumber == currTool:
                curlist.append(obj)
            elif tc.ToolNumber != currTool and currTool is None:  # first TC
                sublist.append(tc)
                curlist.append(obj)
                currTool = tc.ToolNumber
                toolstring = tcstring

            elif tc.ToolNumber != currTool and currTool is not None:  # TC
                for fixture in fixturelist:
                    sublist.append(fixture)
                    sublist.extend(curlist)
                postlist.append((toolstring, sublist))
                sublist = [tc]
                curlist = [obj]
                currTool = tc.ToolNumber
                toolstring = tcstring

            if idx == len(job.Operations.Group) - 1:  # Last operation.
                for fixture in fixturelist:
                    sublist.append(fixture)
                    sublist.extend(curlist)

                postlist.append((toolstring, sublist))

    elif orderby == "Operation":
        PathLog.debug("Ordering by Operation")
        # Order by operation means ops are done in each fixture in
        # sequence.
        currTool = None
        firstFixture = True

        # Now generate the gcode
        for obj in job.Operations.Group:

            # check if the operation is active
            if not getattr(obj, "Active", True):
                continue

            sublist = []
            PathLog.debug("obj: {}".format(obj.Name))

            for f in wcslist:
                fobj = _TempObject()
                c1 = Path.Command(f)
                fobj.Path = Path.Path([c1])
                if not firstFixture:
                    c2 = Path.Command(
                        "G0 Z"
                        + str(
                            job.Stock.Shape.BoundBox.ZMax
                            + job.SetupSheet.ClearanceHeightOffset.Value
                        )
                    )
                    fobj.Path.addCommands(c2)
                fobj.InList.append(job)
                sublist.append(fobj)
                firstFixture = False
                tc = PathUtil.toolControllerForOp(obj)
                if tc is not None:
                    if job.SplitOutput or (tc.ToolNumber != currTool):
                        sublist.append(tc)
                        currTool = tc.ToolNumber
                sublist.append(obj)
            postlist.append((obj.Label, sublist))

    if job.SplitOutput:
        PathLog.track()
        return postlist
    else:
        PathLog.track()
        finalpostlist = [
            ("allitems", [item for slist in postlist for item in slist[1]])
        ]
        return finalpostlist
Ejemplo n.º 7
0
    def Activated(self):
        PathLog.track()
        FreeCAD.ActiveDocument.openTransaction(
            translate("Path_Post", "Post Process the Selected path(s)"))
        FreeCADGui.addModule("PathScripts.PathPost")

        # Attempt to figure out what the user wants to post-process
        # If a job is selected, post that.
        # If there's only one job in a document, post it.
        # If a user has selected a subobject of a job, post the job.
        # If multiple jobs and can't guess, ask them.

        selected = FreeCADGui.Selection.getSelectionEx()
        if len(selected) > 1:
            FreeCAD.Console.PrintError(
                "Please select a single job or other path object\n")
            return
        elif len(selected) == 1:
            sel = selected[0].Object
            if sel.Name[:3] == "Job":
                job = sel
            elif hasattr(sel, "Path"):
                try:
                    job = PathUtils.findParentJob(sel)
                except:
                    job = None
            else:
                job = None
        if job is None:
            targetlist = []
            for o in FreeCAD.ActiveDocument.Objects:
                if hasattr(o, "Proxy"):
                    if isinstance(o.Proxy, PathJob.ObjectJob):
                        targetlist.append(o.Label)
            PathLog.debug("Possible post objects: {}".format(targetlist))
            if len(targetlist) > 1:
                form = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobChooser.ui")
                form.cboProject.addItems(targetlist)
                r = form.exec_()
                if r is False:
                    return
                else:
                    jobname = form.cboProject.currentText()
            else:
                jobname = targetlist[0]
            job = FreeCAD.ActiveDocument.getObject(jobname)

        PathLog.debug("about to postprocess job: {}".format(job.Name))

        # Build up an ordered list of operations and tool changes.
        # Then post-the ordered list
        postlist = []
        currTool = None
        for obj in job.Operations.Group:
            PathLog.debug("obj: {}".format(obj.Name))
            tc = PathUtil.toolControllerForOp(obj)
            if tc is not None:
                if tc.ToolNumber != currTool:
                    postlist.append(tc)
                    currTool = tc.ToolNumber
            postlist.append(obj)

        fail = True
        rc = ''
        (fail, rc) = self.exportObjectsWith(postlist, job)

        if fail:
            FreeCAD.ActiveDocument.abortTransaction()
        else:
            FreeCAD.ActiveDocument.commitTransaction()
        FreeCAD.ActiveDocument.recompute()
Ejemplo n.º 8
0
    def Activated(self):
        PathLog.track()
        FreeCAD.ActiveDocument.openTransaction(
            translate("Path_Post", "Post Process the Selected path(s)"))
        FreeCADGui.addModule("PathScripts.PathPost")

        # Attempt to figure out what the user wants to post-process
        # If a job is selected, post that.
        # If there's only one job in a document, post it.
        # If a user has selected a subobject of a job, post the job.
        # If multiple jobs and can't guess, ask them.

        selected = FreeCADGui.Selection.getSelectionEx()
        if len(selected) > 1:
            FreeCAD.Console.PrintError("Please select a single job or other path object\n")
            return
        elif len(selected) == 1:
            sel = selected[0].Object
            if sel.Name[:3] == "Job":
                job = sel
            elif hasattr(sel, "Path"):
                try:
                    job = PathUtils.findParentJob(sel)
                except:
                    job = None
            else:
                job = None
        if job is None:
            targetlist = []
            for o in FreeCAD.ActiveDocument.Objects:
                if hasattr(o, "Proxy"):
                    if isinstance(o.Proxy, PathJob.ObjectJob):
                        targetlist.append(o.Label)
            PathLog.debug("Possible post objects: {}".format(targetlist))
            if len(targetlist) > 1:
                form = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobChooser.ui")
                form.cboProject.addItems(targetlist)
                r = form.exec_()
                if r is False:
                    return
                else:
                    jobname = form.cboProject.currentText()
            else:
                jobname = targetlist[0]
            job = FreeCAD.ActiveDocument.getObject(jobname)

        PathLog.debug("about to postprocess job: {}".format(job.Name))

        # Build up an ordered list of operations and tool changes.
        # Then post-the ordered list
        postlist = []
        currTool = None
        for obj in job.Operations.Group:
            PathLog.debug("obj: {}".format(obj.Name))
            tc = PathUtil.toolControllerForOp(obj)
            if tc is not None:
                if tc.ToolNumber != currTool:
                    postlist.append(tc)
            postlist.append(obj)

        fail = True
        rc = ''
        (fail, rc) = self.exportObjectsWith(postlist, job)

        if fail:
            FreeCAD.ActiveDocument.abortTransaction()
        else:
            FreeCAD.ActiveDocument.commitTransaction()
        FreeCAD.ActiveDocument.recompute()
Ejemplo n.º 9
0
    def Activated(self):
        PathLog.track()
        FreeCAD.ActiveDocument.openTransaction(
            "Post Process the Selected path(s)")
        FreeCADGui.addModule("PathScripts.PathPost")

        # Attempt to figure out what the user wants to post-process
        # If a job is selected, post that.
        # If there's only one job in a document, post it.
        # If a user has selected a subobject of a job, post the job.
        # If multiple jobs and can't guess, ask them.

        selected = FreeCADGui.Selection.getSelectionEx()
        if len(selected) > 1:
            FreeCAD.Console.PrintError(
                "Please select a single job or other path object\n")
            return
        elif len(selected) == 1:
            sel = selected[0].Object
            if sel.Name[:3] == "Job":
                job = sel
            elif hasattr(sel, "Path"):
                try:
                    job = PathUtils.findParentJob(sel)
                except Exception:
                    job = None
            else:
                job = None

        if job is None:
            targetlist = []
            for o in FreeCAD.ActiveDocument.Objects:
                if hasattr(o, "Proxy"):
                    if isinstance(o.Proxy, PathJob.ObjectJob):
                        targetlist.append(o.Label)
            PathLog.debug("Possible post objects: {}".format(targetlist))
            if len(targetlist) > 1:
                jobname, result = QtGui.QInputDialog.getItem(
                    None, translate("Path", "Choose a Path Job"), None,
                    targetlist)

                if result is False:
                    return
            else:
                jobname = targetlist[0]
            job = FreeCAD.ActiveDocument.getObject(jobname)

        PathLog.debug("about to postprocess job: {}".format(job.Name))

        wcslist = job.Fixtures
        orderby = job.OrderOutputBy
        split = job.SplitOutput

        postlist = []

        if orderby == "Fixture":
            PathLog.debug("Ordering by Fixture")
            # Order by fixture means all operations and tool changes will be completed in one
            # fixture before moving to the next.

            currTool = None
            for index, f in enumerate(wcslist):
                # create an object to serve as the fixture path
                fobj = _TempObject()
                c1 = Path.Command(f)
                fobj.Path = Path.Path([c1])
                if index != 0:
                    c2 = Path.Command(
                        "G0 Z" +
                        str(job.Stock.Shape.BoundBox.ZMax +
                            job.SetupSheet.ClearanceHeightOffset.Value))
                    fobj.Path.addCommands(c2)
                fobj.InList.append(job)
                sublist = [fobj]

                # Now generate the gcode
                for obj in job.Operations.Group:
                    tc = PathUtil.toolControllerForOp(obj)
                    if tc is not None and PathUtil.opProperty(obj, "Active"):
                        if tc.ToolNumber != currTool or split is True:
                            sublist.append(tc)
                            PathLog.debug("Appending TC: {}".format(tc.Name))
                            currTool = tc.ToolNumber
                    sublist.append(obj)
                postlist.append(sublist)

        elif orderby == "Tool":
            PathLog.debug("Ordering by Tool")
            # Order by tool means tool changes are minimized.
            # all operations with the current tool are processed in the current
            # fixture before moving to the next fixture.

            currTool = None
            fixturelist = []
            for f in wcslist:
                # create an object to serve as the fixture path
                fobj = _TempObject()
                c1 = Path.Command(f)
                c2 = Path.Command(
                    "G0 Z" + str(job.Stock.Shape.BoundBox.ZMax +
                                 job.SetupSheet.ClearanceHeightOffset.Value))
                fobj.Path = Path.Path([c1, c2])
                fobj.InList.append(job)
                fixturelist.append(fobj)

            # Now generate the gcode
            curlist = []  # list of ops for tool, will repeat for each fixture
            sublist = []  # list of ops for output splitting

            for idx, obj in enumerate(job.Operations.Group):

                # check if the operation is active
                active = PathUtil.opProperty(obj, "Active")

                tc = PathUtil.toolControllerForOp(obj)
                if tc is None or tc.ToolNumber == currTool and active:
                    curlist.append(obj)
                elif (tc.ToolNumber != currTool and currTool is None
                      and active):  # first TC
                    sublist.append(tc)
                    curlist.append(obj)
                    currTool = tc.ToolNumber
                elif (tc.ToolNumber != currTool and currTool is not None
                      and active):  # TC
                    for fixture in fixturelist:
                        sublist.append(fixture)
                        sublist.extend(curlist)
                    postlist.append(sublist)
                    sublist = [tc]
                    curlist = [obj]
                    currTool = tc.ToolNumber

                if idx == len(job.Operations.Group) - 1:  # Last operation.
                    for fixture in fixturelist:
                        sublist.append(fixture)
                        sublist.extend(curlist)
                    postlist.append(sublist)

        elif orderby == "Operation":
            PathLog.debug("Ordering by Operation")
            # Order by operation means ops are done in each fixture in
            # sequence.
            currTool = None
            firstFixture = True

            # Now generate the gcode
            for obj in job.Operations.Group:
                if PathUtil.opProperty(obj, "Active"):
                    sublist = []
                    PathLog.debug("obj: {}".format(obj.Name))
                    for f in wcslist:
                        fobj = _TempObject()
                        c1 = Path.Command(f)
                        fobj.Path = Path.Path([c1])
                        if not firstFixture:
                            c2 = Path.Command("G0 Z" + str(
                                job.Stock.Shape.BoundBox.ZMax +
                                job.SetupSheet.ClearanceHeightOffset.Value))
                            fobj.Path.addCommands(c2)
                        fobj.InList.append(job)
                        sublist.append(fobj)
                        firstFixture = False
                        tc = PathUtil.toolControllerForOp(obj)
                        if tc is not None:
                            if job.SplitOutput or (tc.ToolNumber != currTool):
                                sublist.append(tc)
                                currTool = tc.ToolNumber
                        sublist.append(obj)
                    postlist.append(sublist)

        fail = True
        rc = ""
        if split:
            for slist in postlist:
                (fail, rc, filename) = self.exportObjectsWith(slist, job)
                if fail:
                    break
        else:
            finalpostlist = [item for slist in postlist for item in slist]
            (fail, rc, filename) = self.exportObjectsWith(finalpostlist, job)

        self.subpart = 1

        if fail:
            FreeCAD.ActiveDocument.abortTransaction()
        else:
            if hasattr(job, "LastPostProcessDate"):
                job.LastPostProcessDate = str(datetime.now())
            if hasattr(job, "LastPostProcessOutput"):
                job.LastPostProcessOutput = filename
            FreeCAD.ActiveDocument.commitTransaction()

        FreeCAD.ActiveDocument.recompute()
Ejemplo n.º 10
0
    def buildPostList(self, job):
        """
        Parses the job and returns the list(s) of objects to be written by the post
        Postlist is a list of lists.  Each sublist is intended to be a separate file
        """
        orderby = job.OrderOutputBy

        fixturelist = []
        for f in job.Fixtures:
            # create an object to serve as the fixture path
            fobj = _TempObject()
            fobj.Label = f
            c1 = Path.Command(f)
            c2 = Path.Command("G0 Z" +
                              str(job.Stock.Shape.BoundBox.ZMax +
                                  job.SetupSheet.ClearanceHeightOffset.Value))
            fobj.Path = Path.Path([c1, c2])
            # fobj.InList.append(job)
            fixturelist.append(fobj)

        postlist = []

        if orderby == "Fixture":
            PathLog.debug("Ordering by Fixture")
            # Order by fixture means all operations and tool changes will be completed in one
            # fixture before moving to the next.

            for f in fixturelist:
                scratchpad = [(f, None)]

                # Now generate the gcode
                for obj in job.Operations.Group:
                    if not PathUtil.opProperty(obj, "Active"):
                        continue
                    tc = PathUtil.toolControllerForOp(obj)
                    scratchpad.append((obj, tc))

                sublist = []
                temptool = None
                for item in scratchpad:
                    if item[1] in [temptool, None]:
                        sublist.append(item[0])
                    else:
                        sublist.append(item[1])
                        temptool = item[1]
                        sublist.append(item[0])
                postlist.append(sublist)

        elif orderby == "Tool":
            PathLog.debug("Ordering by Tool")
            # Order by tool means tool changes are minimized.
            # all operations with the current tool are processed in the current
            # fixture before moving to the next fixture.

            currTool = None

            # Now generate the gcode
            curlist = []  # list of ops for tool, will repeat for each fixture
            # sublist = []  # list of ops for output splitting

            for idx, obj in enumerate(job.Operations.Group):

                # check if the operation is active
                active = PathUtil.opProperty(obj, "Active")

                tc = PathUtil.toolControllerForOp(obj)

                if not active:  # pass on any inactive ops
                    continue

                if tc is None:
                    curlist.append((obj, None))
                    continue

                if tc == currTool:
                    curlist.append((obj, tc))
                    continue

                if tc != currTool and currTool is None:  # first TC
                    currTool = tc
                    curlist.append((obj, tc))
                    continue

                if tc != currTool and currTool is not None:  # TC changed
                    if tc.ToolNumber == currTool.ToolNumber:  # Same tool /diff params
                        curlist.append((obj, tc))
                        currTool = tc
                    else:  # Actual Toolchange
                        # dump current state to postlist
                        sublist = []
                        t = None
                        for fixture in fixturelist:
                            sublist.append(fixture)
                            for item in curlist:
                                if item[1] == t:
                                    sublist.append(item[0])
                                else:
                                    sublist.append(item[1])
                                    t = item[1]
                                    sublist.append(item[0])

                        postlist.append(sublist)

                        # set up for next tool group
                        currTool = tc
                        curlist = [(obj, tc)]

            # flush remaining curlist to output
            sublist = []
            t = None
            for fixture in fixturelist:
                sublist.append(fixture)
                for item in curlist:
                    if item[1] == t:
                        sublist.append(item[0])
                    else:
                        sublist.append(item[1])
                        t = item[1]
                        sublist.append(item[0])
            postlist.append(sublist)

        elif orderby == "Operation":
            PathLog.debug("Ordering by Operation")
            # Order by operation means ops are done in each fixture in
            # sequence.
            currTool = None
            # firstFixture = True

            # Now generate the gcode
            for obj in job.Operations.Group:
                scratchpad = []
                tc = PathUtil.toolControllerForOp(obj)
                if not PathUtil.opProperty(obj, "Active"):
                    continue

                PathLog.debug("obj: {}".format(obj.Name))
                for f in fixturelist:

                    scratchpad.append((f, None))
                    scratchpad.append((obj, tc))

                sublist = []
                temptool = None
                for item in scratchpad:
                    if item[1] in [temptool, None]:
                        sublist.append(item[0])
                    else:
                        sublist.append(item[1])
                        temptool = item[1]
                        sublist.append(item[0])
                postlist.append(sublist)

        if job.SplitOutput:
            return postlist
        else:
            finalpostlist = [item for slist in postlist for item in slist]
            return [finalpostlist]
Ejemplo n.º 11
0
    def setDefaultValues(self, obj):
        """setDefaultValues(obj) ... base implementation.
        Do not overwrite, overwrite opSetDefaultValues() instead."""
        if self.job:
            job = self.job
        else:
            job = PathUtils.addToJob(obj)

        obj.Active = True

        features = self.opFeatures(obj)

        if FeatureTool & features:
            if 1 < len(job.Operations.Group):
                obj.ToolController = PathUtil.toolControllerForOp(
                    job.Operations.Group[-2])
            else:
                obj.ToolController = PathUtils.findToolController(obj, self)
            if not obj.ToolController:
                raise PathNoTCException()
            obj.OpToolDiameter = obj.ToolController.Tool.Diameter

        if FeatureCoolant & features:
            PathLog.track()
            PathLog.debug(obj.getEnumerationsOfProperty("CoolantMode"))
            obj.CoolantMode = job.SetupSheet.CoolantMode

        if FeatureDepths & features:
            if self.applyExpression(obj, "StartDepth",
                                    job.SetupSheet.StartDepthExpression):
                obj.OpStartDepth = 1.0
            else:
                obj.StartDepth = 1.0
            if self.applyExpression(obj, "FinalDepth",
                                    job.SetupSheet.FinalDepthExpression):
                obj.OpFinalDepth = 0.0
            else:
                obj.FinalDepth = 0.0
        else:
            obj.StartDepth = 1.0

        if FeatureStepDown & features:
            if not self.applyExpression(obj, "StepDown",
                                        job.SetupSheet.StepDownExpression):
                obj.StepDown = "1 mm"

        if FeatureHeights & features:
            if job.SetupSheet.SafeHeightExpression:
                if not self.applyExpression(
                        obj, "SafeHeight",
                        job.SetupSheet.SafeHeightExpression):
                    obj.SafeHeight = "3 mm"
            if job.SetupSheet.ClearanceHeightExpression:
                if not self.applyExpression(
                        obj, "ClearanceHeight",
                        job.SetupSheet.ClearanceHeightExpression):
                    obj.ClearanceHeight = "5 mm"

        if FeatureDiameters & features:
            obj.MinDiameter = "0 mm"
            obj.MaxDiameter = "0 mm"
            if job.Stock:
                obj.MaxDiameter = job.Stock.Shape.BoundBox.XLength

        if FeatureStartPoint & features:
            obj.UseStartPoint = False

        self.opSetDefaultValues(obj, job)
        return job