destroy in python sop

   6116   7   2
User Avatar
Member
79 posts
Joined: Feb. 2008
Offline
I need to write a Python script that goes through a list of points that contains asset information. For each point, it needs to load the referenced asset, extract some information and copy that info back onto a custom attribute on that point and then delete the asset before loading the next one. The assets are heavy, so that's why I need to load them one at a time and delete/destroy them before loading the next one.

Since my asset info are on a list of points, I figured I would use a Python SOP to do this, but I can't delete nodes/assets in a Python SOP. If you try and run this code:

obj = hou.node('/obj')
sub = obj.createNode('subnet')
sub.destroy()

You'll get this error message :

Error 
Python error: Traceback (most recent call last):
File "", line 3, in 
File "D:/PROGRA~1/SIDEEF~1/HOUDIN~1.348/houdini/python2.7libs\houpythonportion\ui.py", line 927, in decorator
return func(*args, **kwargs)
File "D:/PROGRA~1/SIDEEF~1/HOUDIN~1.348/houdini/python2.7libs\hou.py", line 10553, in destroy
return _hou.Node_destroy(*args, **kwargs)
OperationFailed: The attempted operation failed.
Cannot delete nodes while cooking


So instead I tried to use a pre-render script in a geometry ROP. That allows me to destroy my assets, but I can't create and copy the attributes I need on my point cloud as it gives me this error message:

Error 
Python error: Traceback (most recent call last):
File "", line 1, in 
File "opdef:/Sop/fetch_material_info?PythonModule", line 16, in fetchMaterials
File "D:/PROGRA~1/SIDEEF~1/HOUDIN~1.348/houdini/python2.7libs\houpythonportion\Geometry.py", line 67, in addAttrib
create_local_variable)
File "D:/PROGRA~1/SIDEEF~1/HOUDIN~1.348/houdini/python2.7libs\hou.py", line 29644, in addAttrib
return _hou.Geometry_addAttrib(*args)
GeometryPermissionError: Geometry is read-only.

So how can I write a Python script that will load and delete assets as it sets new data per point attribute? What's the proper way to do something like this?
User Avatar
Member
8583 posts
Joined: July 2007
Online
definitely not in Python SOP as that's for runtime processing and you seem to want something that runs just once

so HDA module, Shelf Tool, Pre-render script, all may work

to get around not being able to write to geo you can create geo in memory and then store it in any Data parameter for example in Stash node

so create Stash SOP and do this (in Python Shell for example for now):
geo = hou.Geometry()
geo.createPoint()

n = hou.node('/obj/geo1/stash1')
n.parm("stash").set(geo)

now the stash1 node will output that geo
Edited by tamte - June 11, 2020 21:17:39
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
79 posts
Joined: Feb. 2008
Offline
Mmmm… that's actually a great idea. Storing it in a Stash does make a lot of sense. I'll give this a shot. Thanks for the suggestion.
User Avatar
Member
679 posts
Joined: Feb. 2017
Offline
Hey everybody,

I hope someone can help me with this python question.
I`m trying to create a "quick stash" script. The purpose is to to create a stash node to the end of all selected nodes.
Populate/write the stash and then delete all the selected nodes. I have trouble figuring out the right syntax to populate the stash.
I`m stuck. Can anybody help?

import hou
import os.path

# put all currently selected nodes in a tuple
allnodes = hou.selectedNodes()

#find last node Position of selected nodes
lastNodePosition = len(allnodes)-1

# select last node
lastnode = allnodes[lastNodePosition]

# create curPath
lastnodePath = lastnode.path()
curPath = os.path.dirname(lastnodePath)

# make stash node
quickStash = hou.node(curPath).createNode('stash','quickStash')

# connect stash to last node
quickStash.setFirstInput (lastnode)

# set display/render/selection flag on stash node
quickStash.setDisplayFlag (True)
quickStash.setRenderFlag (True)
quickStash.setSelected(1,1)

# populate stash (not working... atm)
#quickStash.parm("stash").set(lastnode)
        

Cheers
CYTE
Edited by CYTE - July 2, 2021 15:13:20
User Avatar
Member
8583 posts
Joined: July 2007
Online
you can either connect it and press button on stash (all in code):
import hou

allnodes = hou.selectedNodes()
if allnodes:
    lastnode = allnodes[-1]
    
    quickStash = lastnode.parent().createNode('stash','quickStash')
    quickStash.setFirstInput (lastnode)
    quickStash.setDisplayFlag (True)
    quickStash.setRenderFlag (True)
    quickStash.setSelected(1,1)
    
    quickStash.parm("stashinput").pressButton()

or you dont even have to connect it and you can get geo of desired sop and set to stash:
import hou

allnodes = hou.selectedNodes()
if allnodes:
    lastnode = allnodes[-1]
    
    quickStash = lastnode.parent().createNode('stash','quickStash')
    quickStash.setDisplayFlag (True)
    quickStash.setRenderFlag (True)
    quickStash.setSelected(1,1)
    
    quickStash.parm("stash").set(lastnode.geometry())
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
679 posts
Joined: Feb. 2017
Offline
Hey Tomas,

Thank you for your help! Also, thank you for the two alternatives as it gives me more insight on how to work with Python in Houdini. As I‘m quite fresh with Python I stumbled against the next roadblock immediately. I can't destroy the selected nodes.
I tried:

#delete selected nodes
i = 0
for node in allnodes:
     currentnode = allnodes[i]
     
      currentnode.destroy()
      i = i + 1



edit:

ok found it:

for node in hou.selectedNodes():
    node.destroy()


Cheers
CYTE
Edited by CYTE - July 3, 2021 03:47:19
User Avatar
Member
385 posts
Joined: July 2018
Offline
how can i delete nodes in a locked hda from the python module? i am using a button with a callback script that runs a delete() function

for n in node.children(): n.destroy(True)


i get an error message that i don't have permissions.
User Avatar
Member
385 posts
Joined: July 2018
Offline
the solution was to put a subnet inside my hda and make it editable from the HDA Type Properties Node tab --> Editable Nodes.
The procedural graph creation takes place in there so the hda is locked but we have permissions to edit anything inside the subnet.

many thanks to Johannes Heintz for the tip

https://forums.odforce.net/topic/49591-python-module-createdelete-nodes-inside-locked-asset/ [forums.odforce.net]
  • Quick Links