Forum: Poser Python Scripting


Subject: RenderCacheLocation?

FVerbaas opened this issue on Dec 20, 2020 ยท 9 posts


FVerbaas posted Sun, 20 December 2020 at 3:23 PM Forum Coordinator

We have poser.PrefsLocation, poser.TempLocation, and a few more.

i was not able to find a simple definition of the RendersLocation and, while we're at it, the present selected 'front' render.

Background: Did make way to export the current selected render to Krita or PaintshopPro. Now calling Krita from Poser to get the .exr's into postwork. It works now with hard coded path to the cache and simply latest .exr bu would be nice to send the curent selected render.
Would be fun to have it


adp001 posted Sun, 20 December 2020 at 3:57 PM

Screemshot.png




adp001 posted Sun, 20 December 2020 at 4:06 PM

Or did you mean the last rendered image? Yes, this would be nice to have.




FVerbaas posted Sun, 20 December 2020 at 4:13 PM Forum Coordinator

That's the renderende (FF, SF, preview, sketch')

What I am looking for is the folder where the finished .exr render results go. On my system this is somewhere in the documents folder. Guess I specified that once. So must be written somewhere. Question is how to read this info in Python.


structure posted Sun, 20 December 2020 at 8:33 PM Forum Coordinator

the rendercache was moved to the users documents folder.

it used to be in poser.PrefsLocation():rendercache

this is a routine I used to find it on the current computer

    def get_rendercache( self, event = None ):
        poserprefs = poser.PrefsLocation()
        docsOld = os.path.join( poserprefs, "RenderCache" )
        if os.path.exists( docsOld ):
            return docsOld
        docsNew = os.path.join("Documents", "Poser", "RenderCache")
        available_drives = [('%s:' + os.path.sep) %d for d in string.ascii_uppercase if os.path.exists( '%s:' %d )] 
        os.environ[ "DOCS" ] = os.path.join(os.environ['USERPROFILE'], docsNew )
        docs = os.environ[ "DOCS" ]
        if not os.path.exists( docs )  :
            for drive_letter in available_drives:
                docs = docs.replace( docs[0:3], drive_letter )
                if os.path.exists( docs ):
                    return docs
                else:
                    docs = os.path.join( drive_letter, docsNew )
                    if os.path.exists( docs ):
                        return docs
                    else:
                        continue

this is the windows version - you will need to edit

available_drives = [('%s:' + os.path.sep) %d for d in string.ascii_uppercase if os.path.exists( '%s:' %d )] 

for macOS

Locked Out


FVerbaas posted Mon, 21 December 2020 at 12:41 AM Forum Coordinator

Many thanks!

Would be a lot easier to have a poser.RenderCacheLocation() though.


structure posted Mon, 21 December 2020 at 5:46 AM Forum Coordinator

for the "front" render ( I assume you mean the latest ):

I found this, which should help.

http://stackoverflow.com/a/39501288/1709587

import os
import platform

def creation_date(path_to_file):
    """
    Try to get the date that a file was created, falling back to when it was
    last modified if that isn't possible.
    See http://stackoverflow.com/a/39501288/1709587 for explanation.
    """
    if platform.system() == 'Windows':
        return os.path.getctime(path_to_file)
    else:
        stat = os.stat(path_to_file)
        try:
            return stat.st_birthtime
        except AttributeError:
            # We're probably on Linux. No easy way to get creation dates here,
            # so we'll settle for when its content was last modified.
            return stat.st_mtime

example of usage:

lof = os.listdir( get_rendercache() )
olddate, oldfile= 0, ""
if lof:
    for f in lof:
        f = os.path.join( rendercache, f )
        creation = creation_date( f )
        if creation > olddate:
            olddate = creation
            oldfile = f 
    print( oldfile )

Locked Out


FVerbaas posted Mon, 21 December 2020 at 10:08 AM Forum Coordinator

Thank you for the snippets.

I was implementing this and then I realized that there may be issues with localizations of Poser and non-English versions of operating systems. I therefore for now will simply ask the user for the folder.

The latest file I find using glob:

import os
import glob

list_of_files = glob.glob(rendercachefolderfulladdress+'/*.exr') 
imagepath = max(list_of_files, key=os.path.getctime)

Didn't dream this up myself, of course, but it works like a charm. ;-)


FVerbaas posted Mon, 21 December 2020 at 1:58 PM Forum Coordinator

OK, here is the end?? product. Let's see if dev team gives us the pointers to the files. Krita accepts Poser's .exr files and supports editing the 16 bit float per channel.

#
# Script to kick off a session with a .exr image processing program (Krita for example) with the last image from the RenderCache. . 
#
# This script reads the location where the image processing app can be found and launches the app with the file  
# location of rendercache and favorite app is written in small 'cookie' text files in poser.PrefsLocation in oreder to be re-used
# (mental note: need some prefsManagement system)
#
# note: Not written for Mac yet. I have no Mac so could not test. 
#
# F. Verbaas, 21-Dec-2020

import os, sys
import subprocess
import platform
from datetime import datetime
import glob

#
# breaks a path into a list of its components
# from: https://www.oreilly.com/library/view/python-cookbook/0596001673/ch04s16.html
def splitall(path):
    allparts = []
    while 1:
        parts = os.path.split(path)
        if parts[0] == path:  # sentinel for absolute paths
            allparts.insert(0, parts[0])
            break
        elif parts[1] == path: # sentinel for relative paths
            allparts.insert(0, parts[1])
            break
        else:
            path = parts[0]
            allparts.insert(0, parts[1])
    return allparts

scene = poser.Scene()
good = True

#
#-------------------------------------------------------------------
# Check out if preferred executable was saved, if not ask and set up
#-------------------------------------------------------------------
AppPathpointer  = os.path.join(poser.PrefsLocation(), 'ImgAppsLocations.txt')
if not os.access(AppPathpointer, os.R_OK):
    # make default location
    osflavor = platform.system()
    if osflavor in 'Windows': 
        AppPathproposal = 'C:/Program Files'
        AppLocationChooser = poser.DialogFileChooser(poser.kDialogFileChooserOpen, None, "Select Imsage Editing Application", AppPathproposal , ".exe")
        AppLocationChooser.Show()

        if '.exe'in AppLocationChooser.Path():
            app = open(AppPathpointer, 'w')
            AppPath = app.write(AppLocationChooser.Path())
            app.close
        else:
            poser.DialogSimple.MessageBox('Selected path ' + AppLocationChooser.Path() + 'does not lead to an executable file')
            good = False

    elif osflavor in 'Darwin': 
        poser.DialogSimple.MessageBox( 'Sorry No Mac support yet.')
        good = False

if not os.access(AppPathpointer, os.R_OK):
    poser.DialogSimple.MessageBox('Link to app was not set correctly.n Please re-run script.n If problem persists check manual.')
    good = False
else:
    with open(AppPathpointer, 'r') as app:
        AppPath = app.read()

#
#--------------------------------------------------------------------
# check if location of cache was saved already, if not ask and set up
# use PrefsLocation as a cunning way to get the User's name  
#--------------------------------------------------------------------
CachePathpointer  = os.path.join(poser.PrefsLocation(), 'RenderCacheLocation.txt')
if not os.access(CachePathpointer, os.R_OK):
    # make default location
    osflavor = platform.system()
    if osflavor in 'Windows': 
        parts = splitall(CachePathpointer)
        CachePathProposal = os.path.join(parts[0],parts[1],parts[2])   # we guess the first three parts of the path are C:users
        CachePathChooser = poser.DialogDirChooser(None, "Select location  of RenderCache", CachePathProposal)
        CachePathChooser.Show()
        CachePath = CachePathChooser.Path()
        if len(CachePath)> 0 :
            cache = open(CachePathpointer, 'w')
            cache.write(CachePath)
            cache.close()
        else:
            poser.DialogSimple.MessageBox('Selected folder not correct')
            good = False
    elif osflavor in 'Darwin': 
        poser.DialogSimple.MessageBox( 'Sorry No Mac support yet.')
        good = False

# 
#-------------------------------------------------
# should now have both app and folder
# Double-check and read final value of Cachepath
#-----------------------------------------------
if not os.access(CachePathpointer, os.R_OK):
    poser.DialogSimple.MessageBox('Link to cache was not set correctly.n Please re-run script.n If problem persists check manual.')
    good = False
else:
    with open(CachePathpointer, 'r') as cache:
        CachePath = cache.read()

#
#-------------------------------------------------
# finally all should be known. Process! 
#-------------------------------------------------
if good:
    #
    #------------------------------------------------
    # Get latest rendered image 
    # would need a parameter in Poser of course
    #------------------------------------------------
    list_of_files = glob.glob(os.path.join(CachePath,'*.exr'))
    if len(list_of_files) > 0: # user may have flushed the cache
        imagepath = max(list_of_files, key=os.path.getctime)
        if len(imagepath)>0: # who knows what else may have happened
            subprocess.call([AppPath, imagepath])

enjoy and thank you all who helped me thru.