Jump to content

NetworkImage


julienmargelin

Recommended Posts

Hello everyone,

I'm trying to make a screenShot script with python that load my image in the network view

Well everything goes well until the end of the script:

editor = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor)
image = hou.NetworkImage()
image.setPath('$HFS/houdini/pic/Mandril.pic')
image.setRect(hou.BoundingRect(0, 0, 5, 5))
editor.setBackgroundImages([image])

I found this piece of code in the houdini documentation. The problem is when navigate from /obj/geo to /obj and go back to /obj/geo the image is gone.

is anybody has an idea ?

Thanks !

here is my full script:

def screenShot():
    """take a screen shot of the current viewport at the current frame"""
    help(screenShot)
    import hou
    import toolutils
    import os
    #selected node
    nodeSelect = hou.selectedNodes()
    path = hou.expandString("$HIP")
    frame = hou.expandString("$F")
    frame = int(frame)
    black=hou.Color((0,0,0))
    #name check there is a node selected
    if len(nodeSelect)<1:
        print ("!!!    error: select a node    !!!")
    else:
        for node in nodeSelect:
            name = node.name()
            node.setColor(black)
        #Get the current Desktop
        desktop = hou.ui.curDesktop()
        # Get the scene viewer
        scene= toolutils.sceneViewer()
        flipbook_options = scene.flipbookSettings().stash()
        # set frame range
        flipbook_options.frameRange((frame,frame))
        #set output path
        root ="{1}/{2}/{0}/".format(name,path,"screenShot")
        if os.path.exists(root):
            listPath = os.listdir(root)
            inc = len(listPath)
            inc = int(inc)   
            outputPath = "{}{}.{:04d}.jpg".format(root,name,inc)
        else:
            os.makedirs(root)
            inc = 0
            outputPath = "{}{}.{:04d}.jpg".format(root,name,inc)
        #set flipbook current path     
        flipbook_options.output(outputPath)
        #run flipbook
        scene.flipbook(scene.curViewport(),flipbook_options)
        # reload image
        print (outputPath)
        editor = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor)
        image = hou.NetworkImage()
        image.setPath(outputPath)
        image.setRect(hou.BoundingRect(0, 0, 5, 5))
        image.setRelativeToPath(node.path())
        editor.setBackgroundImages([image])

 

 

 

Link to comment
Share on other sites

  • 6 months later...

Afaik when you add a background image via their snippet, the .userDataDict() of the node is not being registered/saved (you can try adding a network bg image by hand and calling 

hou.node('/obj/mynode/').userDataDict()

You'll get something like:

{'___Version___': '16.0.736', 'backgroundimages': '[{"relativetopath": "volumevisualization24", "path": "/path/to/image.png", "rect": [-202.1, -265.1, 60.2, -85.3], "brightness": 0.54}]'}

Pretty sure this is a bug not a feature. Adding these values to the userDict works but if you screw up the formatting you can corrupt a node and houdini doesn't like it.

  • Like 1
Link to comment
Share on other sites

Sent a RFE and it's normal behaviour, if anyone googles the problem:

Quote

Our developers comment:
That is correct, setting the image on the network editor does not automatically save the change to the current network's userDataDict. On the other hand if you edit the network's userDataDict, the network editor should automatically update with the change. So you can either edit the userDataDict to make your desired changes, or you can use the nodegraphutils.saveBackgroundImages() method to save the backgroun image from the network editor into the network's userDataDict.

All the best,
Jenny.
(ID# 90646)

(i hope it's ok to post this. they are super responsive!)

  • Like 1
Link to comment
Share on other sites

  • 11 months later...

For anyone who googles out there I made a tool that I think matches what Julien wanted to do:

 

kuc1PnO.gif

 

https://berniebernie.fr/wiki/Houdini_Python#screenshot_to_background_image
 

Code as of 22/07/2019 if my website goes down:

 

import hou
import os
import subprocess
import nodegraphutils as utils
from time import gmtime, strftime

widthRatio = 4                      # change to make screenshot bigger or smaller, this is ~x4 node width

def takeScreenShot(savePath):
    '''change to your preferred capture app /!\ no error checking for now '''
    subprocess.check_call([r"C:\Users\me\MiniCap.exe","-captureregselect","-save",savePath,"-exit"])

def removeBackgroundImage(**kwargs):
    ''' erases bg image from tuples of backgroundImages() if it can find it, updates bg '''
    deletingNode = [x[1] for x in  kwargs.items()][0]
    image = deletingNode.parm('houdinipath').eval()
    editor = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor)
    backgroundImagesDic = editor.backgroundImages()
    backgroundImagesDic = tuple(x for x in backgroundImagesDic if x.path() != image)
    editor.setBackgroundImages(backgroundImagesDic)
    utils.saveBackgroundImages(editor.pwd(), backgroundImagesDic)

def changeBackgroundImageBrightness(event_type,**kwargs):
    ''' changes brightness/visibility if template or bypass flags are checked -- its poorly written/thought but i was tired'''
    nullNode = [x[1] for x in  kwargs.items()][0]
    image = nullNode.parm('houdinipath').eval()
    brightness = 1.0
    if nullNode.isBypassed():
        brightness = 0.0
    elif nullNode.isTemplateFlagSet():
        brightness = 0.5
    editor = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor)
    backgroundImagesDic = editor.backgroundImages()
    i = 0
    for item in backgroundImagesDic:
        if item.path() == image:
            backgroundImagesDic[i].setBrightness(brightness)
            break
        i = i + 1
    editor.setBackgroundImages(backgroundImagesDic)
    utils.saveBackgroundImages(editor.pwd(), backgroundImagesDic)
    
#generate unique(ish) path for screenshot
timestamp = strftime('%Y%m%d_%H%M%S', gmtime())
hipname = str(hou.getenv('HIPNAME'))
hippath = str(hou.getenv('HIP')) + '/screenshots'
screenshotName = hipname + '.' + timestamp + '.png'
systempath = hippath + '\\' + screenshotName
houdinipath = '$HIP/screenshots/'+screenshotName

#take screenshot with capture region
takeScreenShot(systempath)


#set up background image plane
editor = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor)
image = hou.NetworkImage()
image.setPath(houdinipath)
sel = hou.selectedNodes()
nullNode = ''

if sel:
    lastSel = sel[-1]
    nullNode = lastSel.parent().createNode('null','screenshot')
    if lastSel.outputConnections():
        nullNode.setInput(0,lastSel)                   

else:
    nullNode = editor.pwd().createNode('null','screenshot') 
    nullNode.moveToGoodPosition()
    lastSel = nullNode

#configure image plane placement
nullNode.setUserData('nodeshape','task')
nullNode.setPosition(lastSel.position())
nullNode.setColor(hou.Color(.3,.3,.3))
nullNode.move([lastSel.size()[0]*2,-lastSel.size()[1]*2])

rez = hou.imageResolution(systempath)
ratio = 1.0*rez[1]/rez[0]
rect = hou.BoundingRect(0,-lastSel.size()[1]*1.1,widthRatio,-widthRatio*ratio-lastSel.size()[1]*1.1)
image.setRelativeToPath(nullNode.path())
image.setRect(rect)

#following is adding a spare parm with image path to be able to know which node corresponds to which background image
#could have used a user attribute or relativeToPath() and smarter logic but it works and it helps me visualize filepath

hou_parm_template_group = hou.ParmTemplateGroup()
hou_parm_template = hou.LabelParmTemplate("houdinipath", "Label", column_labels=(['\\'+houdinipath]))
hou_parm_template.hideLabel(True)
hou_parm_template_group.append(hou_parm_template)
nullNode.setParmTemplateGroup(hou_parm_template_group)


#attach a function that deletes the background image plane if the corresponding node is deleted (faster than doing it by hand)
nullNode.addEventCallback((hou.nodeEventType.BeingDeleted,), removeBackgroundImage)

#attach a function to change visibility or opacity if corresponding node flags are changed
nullNode.addEventCallback((hou.nodeEventType.FlagChanged,), changeBackgroundImageBrightness)

#add image to network background
backgroundImagesDic = editor.backgroundImages()
backgroundImagesDic = backgroundImagesDic + (image,)
editor.setBackgroundImages(backgroundImagesDic)
utils.saveBackgroundImages(editor.pwd(), backgroundImagesDic)

 

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

I don't know if it is of any use but here is a linux version...

DISCLAIMER, I have ignored accounting for the outputConnections() as I don't really understand the purpose... also I have commented a bit further and expand strings to support variables vs absolute paths discrepancies... should work ok.

 

import hou
import os
import subprocess
import nodegraphutils as utils
from time import gmtime, strftime

widthRatio = 4           # change to make screenshot bigger or smaller, this is ~x4 node width


# --------------------------------------------------------------------------------------------    
# FUNCTIONS
# --------------------------------------------------------------------------------------------    

def createScreenshotFolder(saveFolder):
    '''create screenshot folder under $HIP folder '''
    
    # System call to create the necessary folder
    subprocess.check_call([r"mkdir", r"-p", saveFolder])

def takeScreenShot(savePath):
    '''change to your preferred capture app /!\ no error checking for now '''
    
    # System call using ImageMagik import command that requests an interactive region to operate
    subprocess.check_call([r"import", savePath])
    

def removeBackgroundImage(**kwargs):
    ''' erases bg image from tuples of backgroundImages() if it can find it, updates bg '''
    
    # find the node that is meant to be deleted
    deletingNode = [x[1] for x in  kwargs.items()][0]
    
    # find the image in the spare tab
    image = deletingNode.parm('houdinipath').eval()
    
    # find the network
    editor = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor)

    # collect the images stored in it
    backgroundImagesDic = editor.backgroundImages()
    
    # find the one image to be deleted
    backgroundImagesDic = tuple(x for x in backgroundImagesDic if hou.expandString(x.path()) != hou.expandString(image))
    
    # update the images
    editor.setBackgroundImages(backgroundImagesDic)
    utils.saveBackgroundImages(editor.pwd(), backgroundImagesDic)

    
def changeBackgroundImageBrightness(event_type,**kwargs):
    ''' changes brightness/visibility if template or bypass flags are checked -- its poorly written/thought but i was tired'''

    # find the null holding the image
    nullNode = [x[1] for x in  kwargs.items()][0]
    
    # find the image in the spare tab
    image = nullNode.parm('houdinipath').eval()

    # define color based on flags
    if nullNode.isBypassed():
        brightness = 0.0
    elif nullNode.isTemplateFlagSet():
        brightness = 0.5
    else:
        brightness = 1.0

    # find the network
    editor = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor)
    
    # collect the images stored in it
    backgroundImagesDic = editor.backgroundImages()
    
    # traverse all images, find the one we have actioned and set the brightness
    i = 0
    for item in backgroundImagesDic:
        if hou.expandString(item.path()) == hou.expandString(image):
            backgroundImagesDic[i].setBrightness(brightness)
            break
        i = i + 1

    # update the visibility values
    editor.setBackgroundImages(backgroundImagesDic)
    utils.saveBackgroundImages(editor.pwd(), backgroundImagesDic)

 

# --------------------------------------------------------------------------------------------    
# MAIN
# --------------------------------------------------------------------------------------------    

# generate unique(ish) path for screenshot
timestamp = strftime('%Y%m%d_%H%M%S', gmtime())
hipname = str(hou.getenv('HIPNAME'))
hippath = str(hou.getenv('HIP')) + '/screenshots'
screenshotName = hipname + '.' + timestamp + '.png'
systempath = hippath + '/' + screenshotName
houdinipath = '$HIP/screenshots/' + screenshotName


# take screenshot with capture region
createScreenshotFolder(hippath)
takeScreenShot(systempath)


# set up background image plane
editor = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor)
image = hou.NetworkImage()
image.setPath(houdinipath)
sel = hou.selectedNodes()
nullNode = ''

if sel:
    lastSel = sel[-1]
    nullNode = lastSel.parent().createNode('null','screenshot')

    nullNode.setInput(0,lastSel)
    #if lastSel.outputConnections():
    #    nullNode.setInput(0,lastSel)               

else:
    nullNode = editor.pwd().createNode('null','screenshot')
    nullNode.moveToGoodPosition()
    lastSel = nullNode
    

# configure image plane placement
nullNode.setUserData('nodeshape','task')
nullNode.setPosition(lastSel.position())
nullNode.setColor(hou.Color(.3,.3,.3))
nullNode.move([lastSel.size()[0]*2,-lastSel.size()[1]*2])

rez = hou.imageResolution(systempath)
ratio = 1.0*rez[1]/rez[0]
rect = hou.BoundingRect(0,-lastSel.size()[1]*1.1,widthRatio,-widthRatio*ratio-lastSel.size()[1]*1.1)
image.setRelativeToPath(nullNode.path())
image.setRect(rect)


# following is adding a spare parm with image path to be able to know which node corresponds to which background image
# could have used a user attribute or relativeToPath() and smarter logic but it works and it helps visualize filepath
hou_parm_template_group = hou.ParmTemplateGroup()
hou_parm_template = hou.LabelParmTemplate("houdinipath", "Label", column_labels=([houdinipath]))
hou_parm_template.hideLabel(True)
hou_parm_template_group.append(hou_parm_template)
nullNode.setParmTemplateGroup(hou_parm_template_group)


# attach a function that deletes the background image plane if the corresponding node is deleted (faster than doing it by hand)
nullNode.addEventCallback((hou.nodeEventType.BeingDeleted,), removeBackgroundImage)
# attach a function to change visibility or opacity if corresponding node flags are changed
nullNode.addEventCallback((hou.nodeEventType.FlagChanged,), changeBackgroundImageBrightness)


# add image to network background
backgroundImagesDic = editor.backgroundImages()
backgroundImagesDic = backgroundImagesDic + (image,)
editor.setBackgroundImages(backgroundImagesDic)
utils.saveBackgroundImages(editor.pwd(), backgroundImagesDic)

 

  

 

Edited by jordibares
  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Really useful script, thanks for sharing!

Got an error when bypassing the null using the Linux version, got it fixed by replacing line 77 with,

            backgroundImagesDic[i].setBrightness(brightness)

Seemed to just miss the

[i] 

 

Edited by AslakKS
missing [i]
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...