# lscriptreader.py
# One of 7 python scripts that implement a simple L system.
# Useage:
# database = lscriptreader.parse(fullpath_to_script.dat)
#
# The returned database is a dictionary of values read from the
# script.dat. See the sample script.dat files suppled with this
# module.
#
# Malcolm Kesson
# 18 Jan 2012, 26 Jan 2012
import os, copy
# A barebones default database
defaults = {
'title': 'untitled',
'axiom': '',
'rules': {}, # example { 'a': ['random','aba','bba',aab'] }
'generations': 1,
'angle': [45.0, 45.0],
'scale': [1.0, 1.0],
'move': [1.0, 1.0],
'port': 0,
'display': 'mel', # either mel or rib
'seed': 1,
'script_path': "unknown",
'curvewidth': [0.05], # renderman curves only
'rgb_delta': [0.0] # renderman incr/decr for rgb components
}
# Input: the full path to a script.dat file.
# Output: a list of lines of text
def read(path):
result = []
f = open(path, 'r')
lines = f.readlines()
for line in lines:
result.append(line.strip())
result.append('script_path "%s"' % path)
f.close()
return result
# Input: a list of lines of text and a dictionary
# Output: a customized version of the default dictionary.
def parse(text, in_database):
database = copy.deepcopy(in_database)
for line in text:
# Remove comments
index = line.find('#')
if index > -1:
line = line[:index]
if len(line.strip()) == 0:
continue
tokens = line.split()
name = tokens[0]
tokens = tokens[1:]
if name == 'rule':
char,subst = tokens
char = char.strip('"')
subst = subst.strip('"')
# A rule can be applied in ONE of three ways,
# rule "a" "aab" (normal substitution)
# rule "~a" "aab" (random substitution)
# rule "*a" "aab" (substitution on LAST rewrite only)
# rule "!a" "aab" (substitution NOT on last rewrite)
mode = 'normal'
if len(char) > 1:
if char[0] == '~': mode = 'random'
elif char[0] == '*': mode = 'last_gen_only'
elif char[0] == '!': mode = 'ignore_last_gen'
char = char[len(char)-1] # last character
# A new entry in the dictionary, create a list
# and initialize it with the mode.
if database['rules'].has_key(char) == False:
database['rules'][char] = []
database['rules'][char].append(mode) # a placeholder
database['rules'][char].append(subst)
database['rules'][char][0] = mode
#print database['rules'][char]
# Handle single string parameters
elif (name == 'axiom' or name == 'title' or
name == 'display' or name == 'script_path'):
database[name] = tokens[0].strip('"')
# Ditto single integer parameters
elif name == 'generations' or name == 'port' or name == 'seed':
database[name] = int(tokens[0])
# Other parameters are assigned to lists
else:
database[name] = []
for tok in tokens:
database[name].append(tok)
return database