# batch_rif.py
# Instanced by batch.render().
# Malcolm Kesson
# Edits: Aug 6 2018
import re
import os
import sys
import prman
import time
import inspect
import ast
class BatchRif():
def __init__(self, proj_path, ribs_dict, rifs):
self.proj_path = proj_path
self.ribs_dict = ribs_dict
self.rifs = rifs
self.logpath = proj_path
def applyRifs(self, format='ascii'):
# The user may have specified a rif by it's module eg. 'rif_it',
# but we need the "fully specified" version ie. 'rif_it.Rif()'
fully_specified_rifs = self.__getRifsFromList(self.rifs)[1:]
cameras = self.ribs_dict.keys()
for camera in cameras:
ribs = self.ribs_dict[camera]
self.__applyRifsToRibs(fully_specified_rifs, ribs, format)
#-------------------------------------------------
# __getRifsFromList [private]
#-------------------------------------------------
def __getRifsFromList(self, rifnames):
out = []
ri = prman.Ri()
out.append(ri)
for name in rifnames:
cls = self.__getModuleClassArgs(name.strip())
if cls == None:
continue
rifClass = cls[0]
if len(cls) == 1:
rifInst = rifClass(ri)
else:
rifArgs = cls[1]
args = ast.literal_eval(rifArgs)
if isinstance(args, tuple) == False:
args = [args]
rifInst = rifClass(ri, *args )
out.append(rifInst)
return out
#-------------------------------------------------
# __getModuleClassArgs [private]
#-------------------------------------------------
# mcStr might be 'rif_it' or 'rif_mesh2curves.Rif( 0.03, [1,0,0] )'
def __getModuleClassArgs(self, mcStr):
# parts might be ['rif_it'] or ['rif_mesh2curves', 'Rif( 0.03, [1,0,0] )']
parts = mcStr.split('.',1)
module_name = parts[0].strip()
if len(parts) == 1:
class_args = 'Rif()'
else:
class_args = parts[1]
args_begin = class_args.find('(')
args_end = class_args.rfind(')')
class_name = class_args[:args_begin]
args_str = class_args[args_begin + 1:args_end]
args_str = args_str.strip()
try:
m = __import__(module_name)
except:
print'%s' % ('-' * 70)
print('Error: Cannot import module named "%s".' % module_name)
print('It either does not exist or it has syntax errors.')
print'%s' % ('-' * 70)
return None
m = getattr(m, class_name)
out = [m]
if len(args_str):
out.append(args_str)
return out
#-------------------------------------------------
# __applyRifsToRibs
#-------------------------------------------------
def __applyRifsToRibs(self, rifs, ribs, format):
if len(rifs) == 0 or len(ribs) == 0:
return
# Get the instance of Ri used by any of the Rifs. There can only
# be a single instance of the 'ri' variable and it must be "shared"
# by the rifs so we pick the first Rif and use it to get an
# instance of 'm_ri'.
ri = rifs[0].m_ri
if format == 'ascii':
ri.Option("rib", {"string asciistyle": "indented"})
else:
ri.Option("rib", {"string format": "binary"})
prman.RifInit(rifs)
for ribin in ribs:
parent = os.path.dirname(ribin)
name = os.path.basename(ribin)
if name.endswith('.rib') == False:
continue
ribout = os.path.join(parent, 'tmp_' + name)
ri.Begin( ribout.encode('ascii', 'ignore') )
prman.ParseFile( ribin.encode('ascii', 'ignore') )
print('Info: BatchRif - filtered "%s"' % name)
ri.End()
os.remove(ribin)
os.rename(ribout,ribin)
prman.RifInit([]) # will crash without this !!
msg = 'Applied:\n'
for rif in rifs:
name = str(rif.__class__)
msg += ' %s\n' % name[8:len(name)-2]
msg += 'to filter:\n'
for rib in ribs:
msg += ' %s\n' % rib
self.__log('python_rif_log.txt', msg, 'a')
# Utility_____________________________________________
def __log(self, logname, logMsg, permission):
f = open(os.path.join(self.logpath,logname), permission)
if permission == 'w':
localtime = time.asctime( time.localtime(time.time()) )
f.write('Time %s.\n' % localtime)
f.write(logMsg)
f.close()