View Issue Details

IDProjectCategoryView StatusLast Update
0003293PathFeaturepublic2018-01-26 18:50
Reporteruser3807Assigned Tosliptonic  
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionfixed 
Product Version0.17 
Fixed in Version0.17 
Summary0003293: New Feather Path Dressup for getting a Roll on or foo to a path also for Using Mashine CRC insted off Compensation
Descriptionhi i made a new DRESSUP
to get a Toolpath for in and out on Profile operations
also the dressup is for PRO CNC as it respects mashine Cutter Radius Compensation
USE to get Mashine Tooltable doing the complete offset as G41/G42

its not perfect but it works
BESt is to get a better in and out of the path non tool breking
Steps To Reproduce
TagsPath
FreeCAD Information

Activities

user3807

2017-12-30 15:14

 

InitGui.py (10,188 bytes)   
# ***************************************************************************
# *   (c) Yorik van Havre (yorik@uncreated.net) 2014                        *
# *                                                                         *
# *   This file is part of the FreeCAD CAx development system.              *
# *                                                                         *
# *   This program is free software; you can redistribute it and/or modify  *
# *   it under the terms of the GNU Lesser General Public License (LGPL)    *
# *   as published by the Free Software Foundation; either version 2 of     *
# *   the License, or (at your option) any later version.                   *
# *   for detail see the LICENCE text file.                                 *
# *                                                                         *
# *   FreeCAD is distributed in the hope that it will be useful,            *
# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
# *   GNU Lesser General Public License for more details.                   *
# *                                                                         *
# *   You should have received a copy of the GNU Library General Public     *
# *   License along with FreeCAD; if not, write to the Free Software        *
# *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
# *   USA                                                                   *
# *                                                                         *
# ***************************************************************************/

class PathWorkbench (Workbench):
    "Path workbench"

    def __init__(self):
        self.__class__.Icon = FreeCAD.getResourceDir() + "Mod/Path/Resources/icons/PathWorkbench.svg"
        self.__class__.MenuText = "Path"
        self.__class__.ToolTip = "Path workbench"

    def Initialize(self):
        # Add preferences pages - before loading PathGui to properly order pages of Path group
        from PathScripts import PathPreferencesPathJob, PathPreferencesPathDressup
        FreeCADGui.addPreferencePage(PathPreferencesPathJob.JobPreferencesPage, "Path")
        FreeCADGui.addPreferencePage(PathPreferencesPathDressup.DressupPreferencesPage, "Path")

        # Check enablement of experimental features
        from PathScripts.PathPreferences import PathPreferences

        # load the builtin modules
        import Path
        import PathScripts
        import PathGui
        from PySide import QtGui
        FreeCADGui.addLanguagePath(":/translations")
        FreeCADGui.addIconPath(":/icons")
        # load python modules
        from PathScripts import PathArray
        from PathScripts import PathComment
        # from PathScripts import PathCompoundExtended
        from PathScripts import PathCustom
        from PathScripts import PathDressupDogbone
        from PathScripts import PathDressupDragknife
        from PathScripts import PathDressupRampEntry
        from PathScripts import PathDressupTagGui
        from PathScripts import PathDressupLeadInOut
        from PathScripts import PathDrillingGui
        from PathScripts import PathEngraveGui
        from PathScripts import PathFixture
        from PathScripts import PathHelixGui
        from PathScripts import PathHop
        from PathScripts import PathInspect
        from PathScripts import PathJobCmd
        from PathScripts import PathMillFaceGui
        from PathScripts import PathPlane
        from PathScripts import PathPocketGui
        from PathScripts import PathPocketShapeGui
        from PathScripts import PathPost
        from PathScripts import PathProfileContourGui
        from PathScripts import PathProfileEdgesGui
        from PathScripts import PathProfileFacesGui
        from PathScripts import PathSanity
        from PathScripts import PathSimpleCopy
        from PathScripts import PathStop
        from PathScripts import PathSurfaceGui
        from PathScripts import PathToolController
        from PathScripts import PathToolLenOffset
        from PathScripts import PathToolLibraryManager
        from PathScripts import PathSimulatorGui
        import PathCommands

        # build commands list
        projcmdlist = ["Path_Job", "Path_Post"]
        toolcmdlist = ["Path_Inspect", "Path_Simulator", "Path_ToolLibraryEdit", "Path_SelectLoop"]
        prepcmdlist = ["Path_Plane", "Path_Fixture", "Path_ToolLenOffset", "Path_Comment", "Path_Stop", "Path_Custom", "Path_Shape"]
        twodopcmdlist = ["Path_Contour", "Path_Profile_Faces", "Path_Profile_Edges", "Path_Pocket_Shape", "Path_Drilling", "Path_Engrave", "Path_MillFace", "Path_Helix"]
        threedopcmdlist = ["Path_Pocket_3D"]
        modcmdlist = ["Path_OperationCopy", "Path_Array", "Path_SimpleCopy" ]
        dressupcmdlist = ["PathDressup_Dogbone", "PathDressup_DragKnife", "PathDressup_Tag","PathDressup_LeadInOut", "PathDressup_RampEntry"]
        extracmdlist = []
        #modcmdmore = ["Path_Hop",]
        #remotecmdlist = ["Path_Remote"]

        # Add commands to menu and toolbar
        def QT_TRANSLATE_NOOP(scope, text):
            return text

        class ThreeDCommandGroup:
            def GetCommands(self):
                return tuple(threedopcmdlist)

            def GetResources(self):
                return { 'MenuText': QT_TRANSLATE_NOOP("Path",'3D Operations'),
                         'ToolTip': QT_TRANSLATE_NOOP("Path",'3D Operations')
                       }
            def IsActive(self):
                if FreeCAD.ActiveDocument is not None:
                    for o in FreeCAD.ActiveDocument.Objects:
                        if o.Name[:3] == "Job":
                                return True
                return False

        if PathPreferences.experimentalFeaturesEnabled():
            projcmdlist.append("Path_Sanity")
            threedopcmdlist.append("Path_Surface")
            extracmdlist.extend(["Path_Shape", "Path_Area", "Path_Area_Workplane"])
            FreeCADGui.addCommand('Path_3dTools', ThreeDCommandGroup())
            threedcmdgroup = ['Path_3dTools']
        else:
            threedcmdgroup = threedopcmdlist

        self.appendToolbar(QT_TRANSLATE_NOOP("Path", "Project Setup"), projcmdlist)
        self.appendToolbar(QT_TRANSLATE_NOOP("Path", "Tool Commands"), toolcmdlist)
        #self.appendToolbar(QT_TRANSLATE_NOOP("Path", "Partial Commands"), prepcmdlist)
        self.appendToolbar(QT_TRANSLATE_NOOP("Path", "New Operations"), twodopcmdlist+threedcmdgroup)
        self.appendToolbar(QT_TRANSLATE_NOOP("Path", "Path Modification"), modcmdlist)
        if extracmdlist:
            self.appendToolbar(QT_TRANSLATE_NOOP("Path", "Helpful Tools"), extracmdlist)

        self.appendMenu([QT_TRANSLATE_NOOP("Path", "&Path")], projcmdlist +["Path_ExportTemplate", "Separator"] + toolcmdlist +["Separator"] +twodopcmdlist +["Separator"] +threedopcmdlist +["Separator"])
        #self.appendMenu([QT_TRANSLATE_NOOP("Path", "Path"), QT_TRANSLATE_NOOP(
        #    "Path", "Tools")], toolcmdlist)
        self.appendMenu([QT_TRANSLATE_NOOP("Path", "&Path"), QT_TRANSLATE_NOOP(
            "Path", "Path Dressup")], dressupcmdlist)
        self.appendMenu([QT_TRANSLATE_NOOP("Path", "&Path"), QT_TRANSLATE_NOOP(
            "Path", "Partial Commands")], prepcmdlist)
        #self.appendMenu([QT_TRANSLATE_NOOP("Path", "Path"), QT_TRANSLATE_NOOP(
        #    "Path", "New Operations")], opcmdlist)
        self.appendMenu([QT_TRANSLATE_NOOP("Path", "&Path"), QT_TRANSLATE_NOOP(
            "Path", "Path Modification")], modcmdlist)
        #self.appendMenu([QT_TRANSLATE_NOOP("Path", "Path"), QT_TRANSLATE_NOOP(
        #    "Path", "Path Modification")], modcmdmore)
        # self.appendMenu([QT_TRANSLATE_NOOP("Path", "Path"), QT_TRANSLATE_NOOP(
        #     "Path", "Remote Operations")], remotecmdlist)
        if extracmdlist:
            self.appendMenu([QT_TRANSLATE_NOOP("Path", "&Path")], extracmdlist)

        self.dressupcmds = dressupcmdlist

        Path.Area.setDefaultParams(Accuracy = PathPreferences.defaultLibAreaCurveAccuracy())

        Log('Loading Path workbench... done\n')

    def GetClassName(self):
        return "Gui::PythonWorkbench"

    def Activated(self):
        # update the translation engine
        FreeCADGui.updateLocale()
        Msg("Path workbench activated\n")

    def Deactivated(self):
        Msg("Path workbench deactivated\n")

    def ContextMenu(self, recipient):
        import PathScripts
        if len(FreeCADGui.Selection.getSelection()) == 1:
            obj = FreeCADGui.Selection.getSelection()[0]
            if obj.isDerivedFrom("Path::Feature"):
                self.appendContextMenu("", "Separator")
                self.appendContextMenu("", ["Path_Inspect"])
                selectedName = obj.Name
                if "Remote" in selectedName:
                    self.appendContextMenu("", ["Refresh_Path"])
                if "Job" in selectedName:
                    self.appendContextMenu("", ["Path_ExportTemplate"])
            if isinstance (obj.Proxy, PathScripts.PathOp.ObjectOp):
                self.appendContextMenu("", ["Path_OperationCopy"])
            if obj.isDerivedFrom("Path::Feature"):
                if "Profile" in selectedName or "Contour" in selectedName or "Dressup" in selectedName:
                    self.appendContextMenu("", "Separator")
                    #self.appendContextMenu("", ["Set_StartPoint"])
                    #self.appendContextMenu("", ["Set_EndPoint"])
                    for cmd in self.dressupcmds:
                        self.appendContextMenu("", [cmd])

Gui.addWorkbench(PathWorkbench())

FreeCAD.addImportType(
    "GCode (*.nc *.gc *.ncc *.ngc *.cnc *.tap *.gcode)", "PathGui")
FreeCAD.addExportType(
    "GCode (*.nc *.gc *.ncc *.ngc *.cnc *.tap *.gcode)", "PathGui")

InitGui.py (10,188 bytes)   
PathDressupLeadInOut.py (17,085 bytes)   
#  -*- coding: utf-8 -*-

# ***************************************************************************
# *                                                                         *
# *   Copyright (c) 2017 LTS <SammelLothar@gmx.de> under LGPL               *
# *                                                                         *
# *   This program is free software; you can redistribute it and/or modify  *
# *   it under the terms of the GNU Lesser General Public License (LGPL)    *
# *   as published by the Free Software Foundation; either version 2 of     *
# *   the License, or (at your option) any later version.                   *
# *   for detail see the LICENCE text file.                                 *
# *                                                                         *
# *   This program is distributed in the hope that it will be useful,       *
# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
# *   GNU Library General Public License for more details.                  *
# *                                                                         *
# *   You should have received a copy of the GNU Library General Public     *
# *   License along with this program; if not, write to the Free Software   *
# *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
# *   USA                                                                   *
# *                                                                         *
# ***************************************************************************

from __future__ import print_function
import FreeCAD
import FreeCADGui
import Path
import Part
from PySide import QtCore, QtGui
import math
#import DraftVecUtils as D
import PathScripts.PathLog as PathLog
import PathScripts.PathUtils as PathUtils
from PathScripts.PathGeom import PathGeom

"""LeadInOut Dressup MASHIN-CRC USE ROLL-ON ROLL-OFF to profile"""

# Qt tanslation handling
def translate(text, context="PathDressup_LeadInOut", disambig=None):
    return QtCore.QCoreApplication.translate(context, text, disambig)

PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())

movecommands = ['G1', 'G01', 'G2', 'G02', 'G3', 'G03']
rapidcommands = ['G0', 'G00']
arccommands = ['G2', 'G3', 'G02', 'G03']
global currLocation
currLocation = {}


class ObjectDressup:

    def __init__(self, obj):
        self.obj = obj
        obj.addProperty("App::PropertyLink", "ToolController", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "The tool controller that will be used to calculate the path"))
        obj.addProperty("App::PropertyLink", "Base",  "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","The base path to modify"))
        obj.addProperty("App::PropertyBool", "LeadIn", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","Calculate roll-on to path"))
        obj.addProperty("App::PropertyBool", "LeadOut", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","Calculate roll-off from path"))
        obj.addProperty("App::PropertyBool", "KeepToolDown", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","Keep the Tool Down in Path"))
        obj.addProperty("App::PropertyBool", "UseMashineCRC", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","Use Mashine Cutter Radius Compensation /Tool Path Offset G41/G42"))
        obj.addProperty("App::PropertyDistance", "Length", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","Length or Radius of the approach"))
        obj.addProperty("App::PropertyEnumeration", "StyleOn", "Path", QtCore.QT_TRANSLATE_NOOP("PathDressup_LeadInOut", "The Style of LeadIn the Path"))
        obj.StyleOn = ["Arc", "Tangent", "Perpendicular"]
        obj.addProperty("App::PropertyEnumeration", "StyleOff", "Path", QtCore.QT_TRANSLATE_NOOP("PathDressup_LeadInOut", "The Style of LeadOut the Path"))
        obj.StyleOff = ["Arc", "Tangent", "Perpendicular"]
        obj.addProperty("App::PropertyEnumeration", "RadiusCenter", "Path", QtCore.QT_TRANSLATE_NOOP("PathDressup_LeadInOut", "The Mode of Point Radiusoffset or Center"))
        obj.RadiusCenter = ["Radius", "Center"]
        obj.Proxy = self

    def __getstate__(self):
        return None

    def __setstate__(self, state):
        return None
    def setup(self, obj):
        obj.Length = 5.0
        obj.LeadIn = True
        obj.LeadOut = True
        obj.KeepToolDown=False
        obj.UseMashineCRC=False
        obj.StyleOn = 'Arc'
        obj.StyleOff = 'Arc'
        obj.RadiusCenter = 'Radius'
        obj.ToolController = obj.Base.ToolController
 
    def execute(self, obj):
        if not obj.Base:
            return
        if not obj.Base.isDerivedFrom("Path::Feature"):
            return
        if not obj.Base.Path:
            return
        if obj.Length < 0:
            PathLog.error(translate("Length/Radius positiv not Null\n"))
            obj.Length = 0.1
        self.wire, self.rapids = PathGeom.wireForPath(obj.Base.Path)
        obj.Path = self.generateLeadInOutCurve(obj)

    def getDirectionOfPath(self,obj):
        if obj.Base.Side == 'Outside':
            if obj.Base.Direction =='CW':
                return 'left'
            else:
                return 'right'
        else: 
            if obj.Base.Direction =='CW':
                return 'right'
        return 'left' 

    def normalize(self, Vector):
        x=Vector.x
        y=Vector.y
        len = math.sqrt( x*x + y*y )
        if((math.fabs(len))> 0.0000000000001):
            vx = round(x / len,0)
            vy = round(y / len,0)  
        return FreeCAD.Base.Vector(vx,vy,0)

    def getLeadStart(self,obj, queue,action):
        '''returns Lead In G-code.'''
        global currLocation
        results = []
        zdepth = currLocation["Z"]
        horizFeed = obj.ToolController.HorizFeed.Value
        vertFeed = obj.ToolController.VertFeed.Value
        toolnummer = obj.Base.ToolController.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.Base.Vector(v.y*R,-v.x*R,0.0)
        else:
            off_v = FreeCAD.Base.Vector(-v.y*R,v.x*R,0.0)
        offsetvector = FreeCAD.Base.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": obj.Base.ClearanceHeight.Value})
            results.append(extendcommand)
            extendcommand = Path.Command('G0', {"X": leadstart.x, "Y": leadstart.y, "Z": obj.Base.ClearanceHeight.Value})
            results.append(extendcommand)
            extendcommand = Path.Command('G0', {"X": leadstart.x, "Y": leadstart.y, "Z": obj.Base.SafeHeight.Value})
            results.append(extendcommand)
        if action == 'layer':
            if not obj.KeepToolDown:
                extendcommand = Path.Command('G0', {"Z": obj.Base.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, "Z": p0.z, "F": horizFeed})
            results.append(extendcommand)
        else :
            PathLog.notice(" CURRENT_IN Perp")
        return results     

    def getLeadEnd(self,obj, queue,action):
        '''returns the  Gcode of LeadOut.'''
        global currLocation
        results = []
        horizFeed = obj.ToolController.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.Base.Vector(v.y*R,-v.x*R,0.0)
        else:
            off_v = FreeCAD.Base.Vector(-v.y*R,v.x*R,0.0)
        offsetvector = FreeCAD.Base.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 generateLeadInOutCurve(self, obj):
        global currLocation
        firstmove = Path.Command("G0", {"X": 0, "Y": 0, "Z": 0})
        currLocation.update(firstmove.Parameters)
        newpath = []
        queue = []
        num=0
        action= 'start'
        for curCommand in obj.Base.Path.Commands:
            replace = None
            # don't worry about non-move commands, just add to output
            if curCommand.Name not in movecommands + rapidcommands:
                newpath.append(curCommand)
                continue

            # rapid retract triggers exit move, else just add to output
            if curCommand.Name in rapidcommands:
                #detect start position
                if (curCommand.x != None) or (curCommand.y != None):
                    firstmove = curCommand
                currLocation.update(curCommand.Parameters)
                if action !='start':#done move out 
                    if obj.LeadOut:
                        temp = self.getLeadEnd(obj,queue,'end')
                        newpath.extend(temp)
                        newpath.append(curCommand) #Z clear DONE
 
            if curCommand.Name in movecommands:
                queue.append(curCommand)
                if action == 'start' and len(queue) <2:
                    continue
                if action == 'layer':
                    if len(queue) > 2: queue.pop(0)
                    if obj.LeadIn:
                        temp=self.getLeadStart(obj,queue,action)
                        newpath.extend(temp)
                        newpath.append(curCommand)
                        action='none'
                        currLocation.update(curCommand.Parameters)
                    else:
                        newpath.append(curCommand)
                if curCommand.z != currLocation["Z"] and action != 'start':# vertical feeding to depth
                    if obj.LeadOut:#fish cycle 
                        if len(queue) > 2: queue.pop(len(queue)-1)
                        temp = self.getLeadEnd(obj,queue,action)
                        newpath.extend(temp)
                        action = 'layer'
                        if len(queue) > 2: queue.pop(0)
                        continue
                    else:
                        newpath.append(curCommand)
                if len(queue) > 2: queue.pop(0)
                if obj.LeadIn and len(queue)>=2 and action == 'start':
                    temp=self.getLeadStart(obj,queue,action)
                    newpath.extend(temp)
                    newpath.append(curCommand)
                    action='none'
                    currLocation.update(curCommand.Parameters)
                else:
                    newpath.append(curCommand)
                currLocation.update(curCommand.Parameters)
        commands = newpath
        return Path.Path(commands)

class ViewProviderDressup:

    def __init__(self, vobj):
        vobj.Proxy = self

    def attach(self, vobj):
        self.obj = vobj.Object

    def claimChildren(self):
        if hasattr(self.obj.Base, "InList"):
            for i in self.obj.Base.InList:
                if hasattr(i, "Group"):
                    group = i.Group
                    for g in group:
                        if g.Name == self.obj.Base.Name:
                            group.remove(g)
                    i.Group = group
                    print(i.Group)
        # FreeCADGui.ActiveDocument.getObject(obj.Base.Name).Visibility = False
        return [self.obj.Base]

    def onDelete(self, arg1=None, arg2=None):
        PathLog.debug("Deleting Dressup")
        '''this makes sure that the base operation is added back to the project and visible'''
        FreeCADGui.ActiveDocument.getObject(arg1.Object.Base.Name).Visibility = True
        job = PathUtils.findParentJob(self.obj)
        job.Proxy.addOperation(arg1.Object.Base)
        arg1.Object.Base = None
        return True

    def __getstate__(self):
        return None

    def __setstate__(self, state):
        return None


class CommandPathDressupLeadInOut:

    def GetResources(self):
        return {'Pixmap': 'Path-Dressup',
                'MenuText': QtCore.QT_TRANSLATE_NOOP("PathDressup_LeadInOut", "LeadInOut Dressup"),
                'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathDressup_LeadInOut", "Creates a Cutter Radius Compensation G41/G42 Entry Dressup object from a selected path")}

    def IsActive(self):
        if FreeCAD.ActiveDocument is not None:
            for o in FreeCAD.ActiveDocument.Objects:
                if o.Name[:3] == "Job":
                        return True
        return False

    def Activated(self):

        # check that the selection contains exactly what we want
        selection = FreeCADGui.Selection.getSelection()
        if len(selection) != 1:
            PathLog.error(translate("Please select one path object\n"))
            return
        baseObject = selection[0]
        if not baseObject.isDerivedFrom("Path::Feature"):
            PathLog.error(translate("The selected object is not a path\n"))
            return
        if baseObject.isDerivedFrom("Path::FeatureCompoundPython"):
            PathLog.error(translate("Please select a Profile object"))
            return

        # everything ok!
        FreeCAD.ActiveDocument.openTransaction(translate("Create LeadInOut Dressup"))
        FreeCADGui.addModule("PathScripts.PathDressupLeadInOut")
        FreeCADGui.addModule("PathScripts.PathUtils")
        FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "LeadInOutDressup")')
        FreeCADGui.doCommand('dbo = PathScripts.PathDressupLeadInOut.ObjectDressup(obj)')
        FreeCADGui.doCommand('obj.Base = FreeCAD.ActiveDocument.' + selection[0].Name)
        FreeCADGui.doCommand('PathScripts.PathDressupLeadInOut.ViewProviderDressup(obj.ViewObject)')
        FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)')
        FreeCADGui.doCommand('Gui.ActiveDocument.getObject(obj.Base.Name).Visibility = False')
        FreeCADGui.doCommand('obj.ToolController = PathScripts.PathUtils.findToolController(obj)')
        FreeCADGui.doCommand('dbo.setup(obj)')
        FreeCAD.ActiveDocument.commitTransaction()
        FreeCAD.ActiveDocument.recompute()


if FreeCAD.GuiUp:
    # register the FreeCAD command
    FreeCADGui.addCommand('PathDressup_LeadInOut', CommandPathDressupLeadInOut())

PathLog.notice("Loading PathDressupLeadInOut... done\n")
PathDressupLeadInOut.py (17,085 bytes)   
lead.jpg (117,762 bytes)   
lead.jpg (117,762 bytes)   

Kunda1

2017-12-30 17:07

administrator   ~0010636

@maxcncmaho please open a forum thread to present this to the Path community. Also please follow the instructions on how to fill out a proper ticket: https://freecadweb.org/wiki/Tracker
This one is missing full version info and a forum thread

Kunda1

2017-12-31 00:50

administrator   ~0010641

@sliptonic care to weigh in ?

Kunda1

2018-01-02 12:47

administrator   ~0010660

@mlampert care to weigh in?

Kunda1

2018-01-26 14:14

administrator   ~0010861

@sliptonic ping

sliptonic

2018-01-26 18:21

manager   ~0010866

This has been implemented and merged. Issue can be closed

Kunda1

2018-01-26 18:50

administrator   ~0010867

Closing

Issue History

Date Modified Username Field Change
2017-12-30 15:14 user3807 New Issue
2017-12-30 15:14 user3807 File Added: InitGui.py
2017-12-30 15:14 user3807 File Added: PathDressupLeadInOut.py
2017-12-30 15:14 user3807 File Added: lead.jpg
2017-12-30 15:14 user3807 Tag Attached: Path
2017-12-30 17:07 Kunda1 Status new => feedback
2017-12-30 17:07 Kunda1 Note Added: 0010636
2017-12-30 17:07 Kunda1 Tag Attached: #post-to-forum
2017-12-31 00:50 Kunda1 Note Added: 0010641
2018-01-02 12:47 Kunda1 Note Added: 0010660
2018-01-26 14:14 Kunda1 Note Added: 0010861
2018-01-26 18:21 sliptonic Note Added: 0010866
2018-01-26 18:50 Kunda1 Assigned To => sliptonic
2018-01-26 18:50 Kunda1 Status feedback => closed
2018-01-26 18:50 Kunda1 Resolution open => fixed
2018-01-26 18:50 Kunda1 Fixed in Version => 0.17
2018-01-26 18:50 Kunda1 Note Added: 0010867
2018-01-26 18:50 Kunda1 Tag Detached: #post-to-forum