Is this a bug? Macro works once then object has no attribute 'shape'

Need help, or want to share a macro? Post here!
CoderMusashi
Posts: 39
Joined: Mon Nov 19, 2018 8:26 pm

Is this a bug? Macro works once then object has no attribute 'shape'

Postby CoderMusashi » Mon Dec 30, 2019 10:34 pm

So I create a simple box sketch and I select one of the edges in the sketch that travels along the x axis. I then run this macro and get exactly what I expect a toolpath called my path. I select the opposite line going in the X direction and run the code and get an error saying the object now does not have an attribute 'Shape'. It sure seem to have had one just a second ago when I ran the code the first time. If i close the document create a new one with another sketch and select the other line it works but it only works once then gives me the object has not attribute 'Shape' error. What is going on why will it run once but errors after that?
Macrorun1.png
Macrorun1.png (136.67 KiB) Viewed 116 times

Code: Select all

from PySide import QtCore, QtGui
import Path

mainobj = App.ActiveDocument.ActiveObject.Shape.Edges

#create a simple input dialog box to get zdepth
zd, okPressed = QtGui.QInputDialog.getText(None, 'Z Cut Depth', '.1')

#create a simple input dialog box to get cuts per pass or step down amount
stepdown, okPressed = QtGui.QInputDialog.getText(None, 'Cut Depth per pass', 'Step down amount .015')

#create a simple input dialog box to get the tool diameter
td, okPressed = QtGui.QInputDialog.getText(None, 'Tool Diameter', '.375')

#create a simple input dialog box asking if tool comp is to the right or left side of the line
comp, okPressed = QtGui.QInputDialog.getText(None, 'Tool to left or right of line', 'Enter Left or Right')

#create a simple input dialog box to get the direction the tool is to travel like  climp or conventional milling
dir, okPressed = QtGui.QInputDialog.getText(None, 'Tool traveling in a clockwise or counter clockwise direction', 'Enter CW or CCW')


#get the selected object
selobj = Gui.Selection.getSelectionEx()[0]

#subn is a tuple
subn = selobj.SubElementNames

#subnstr is subn turned from a tuple to a string
subnstr = ''.join(subn)

#strip out Edge from sour subnstr varialbe
#turn it into a number and minus 1 from it to get its location
#in the mainobj list
indexnum =int(subnstr[4:10]) -1

#mainobj is a list and indexnum is the Edge we selected
selEdge = mainobj[indexnum]
p1 = selEdge.Vertexes[0]
p2 = selEdge.Vertexes[1]

toolcomp = float(td) / 2
if dir == "ccw":
    startx = p1.X
    #starty = p1.Y
    endx = p2.X
    #endy = p2.Y
    if comp == "left":
        starty = p1.Y - toolcomp
        endy = p2.Y - toolcomp
    elif comp == "right":
        starty = p1.Y + toolcomp
        endy = p2.Y + toolcomp
elif dir =="cw":
    startx = p2.X
    #starty = p2.Y
    endx = p1.X
    #endy = p1.Y
    if comp == "right":
        starty = p2.Y - toolcomp
        endy = p1.Y - toolcomp
    elif comp == "left":
        starty = p2.Y + toolcomp
        endy = p1.Y + toolcomp
#Create path
o = App.ActiveDocument.addObject("Path::Feature","myPath")
#set p to the hold myPaths Path
#Create GCode Header
p = Path.Command("G0 X{0:.3f} Y{1:.3f} \n".format(startx,starty))
o.Path.addCommands(p)
p = Path.Command("G0 Z.1")
o.Path.addCommands(p)

zdepth = float(zd)
stpdwn = float(stepdown)
numofpass, lastpass = divmod(zdepth,stpdwn)
numofpass = int(numofpass)
#loop for step down process
for i in range(numofpass):  
        curzdepth = (1+i) * stpdwn
        #p is our z current cut depth
        p = Path.Command("G0 Z-{0:.3f} \n".format(curzdepth))
        #add p to our path object
        o.Path.addCommands(p)
        #move to our x,y end point
        p = Path.Command("G01 X{0:.3f} Y{1:.3f} \n".format(endx,endy))
        #add the first path command to our new path object
        o.Path .addCommands(p)
        # retract in the z
        p = Path.Command("G0 Z.1")
        o.Path .addCommands(p)
        #return to strat of path
        p = Path.Command("G0 X{0:.3f} Y{1:.3f} \n".format(startx,starty))
        o.Path .addCommands(p)

p = Path.Command("G0 Z-{0:.3f} \n".format(zdepth))
o.Path .addCommands(p)
p = Path.Command("G01 X{0:.3f} Y{1:.3f} F20.\n".format(endx,endy))
o.Path .addCommands(p)
p = Path.Command("G0 Z.1 \n")
o.Path .addCommands(p)

If i change this line of code to reference my sketch it works every time with no errrors

Code: Select all

#mainobj = App.ActiveDocument.ActiveObject.Shape.Edges
mainobj = App.ActiveDocument.Sketch.Shape.Edges
Both my versions 18 and 19 on this machine

If i run this code in the python console it always points to 'myPath' no matter what object is actively selected.

Code: Select all

mainobj = App.ActiveDocument.ActiveObject.Name
print(mainobj)
seems 'myPath' stays active after i run the above macro code that generates myPath once.

OS: Windows 10 (10.0)
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19.18946 (Git)
Build type: Release
Branch: master
Hash: 0175008ceba01666449657086ca036fc59e0e6c7
Python version: 3.7.3
Qt version: 5.12.5
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: English/United States (en_US)
vocx
Posts: 3923
Joined: Thu Oct 18, 2018 9:18 pm

Re: Is this a bug? Macro works once then object has no attribute 'shape'

Postby vocx » Tue Dec 31, 2019 5:28 am

CoderMusashi wrote:
Mon Dec 30, 2019 10:34 pm
...
If i run this code in the python console it always points to 'myPath' no matter what object is actively selected.

Code: Select all

mainobj = App.ActiveDocument.ActiveObject.Name
print(mainobj)
seems 'myPath' stays active after i run the above macro code that generates myPath once.
I don't really understand the concept of "ActiveObject".

I feel it is something that was developed around 0.17, and it was supposed to be used with PartDesign Body and Std_Part to create assemblies. But it is not actually used.

So, using the actual object that you want, as in Sketch, is the way to go.

Maybe some of the other developers who were present at that time can shed some light on it.
Always add the important information to your posts if you need help.
To support the documentation effort, and code development, your donation is appreciated: paypal.