julienmargelin Posted January 26, 2018 Share Posted January 26, 2018 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]) Quote Link to comment Share on other sites More sharing options...
berniebernie Posted August 3, 2018 Share Posted August 3, 2018 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. 1 Quote Link to comment Share on other sites More sharing options...
berniebernie Posted August 8, 2018 Share Posted August 8, 2018 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!) 1 Quote Link to comment Share on other sites More sharing options...
berniebernie Posted July 22, 2019 Share Posted July 22, 2019 For anyone who googles out there I made a tool that I think matches what Julien wanted to do: 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) 2 1 Quote Link to comment Share on other sites More sharing options...
jordibares Posted July 22, 2019 Share Posted July 22, 2019 (edited) 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 July 25, 2019 by jordibares 2 1 Quote Link to comment Share on other sites More sharing options...
AslakKS Posted July 24, 2019 Share Posted July 24, 2019 (edited) 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 July 24, 2019 by AslakKS missing [i] Quote Link to comment Share on other sites More sharing options...
jordibares Posted July 25, 2019 Share Posted July 25, 2019 Fixed, the code snippet now incorporates your fix... I did have it on my text editor correctly but something went wrong on the copy I think... thanks once again. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.