Skip to content

Instantly share code, notes, and snippets.

@johnfredcee
Created October 12, 2011 10:51
Show Gist options
  • Select an option

  • Save johnfredcee/1280912 to your computer and use it in GitHub Desktop.

Select an option

Save johnfredcee/1280912 to your computer and use it in GitHub Desktop.
Blender Sexp Exporter
bl_info = {
"name": "Dump Sexp (.lisp)",
"author": "John Connors (ZabaQ)",
"version": (0, 7),
"blender": (2, 5, 4),
"api": 33047,
"location": "File > Export",
"description": "Dump Blender Data To Sexp (.lisp)",
"warning": "",
"category": "Import-Export"}
import bpy
import mathutils
import types
# ExportHelper is a helper class, defines filename and
# invoke() function which calls the file selector.
from bpy_extras.io_utils import ExportHelper
from bpy.props import StringProperty, BoolProperty, EnumProperty
# transform python property to lisp keyword
def lispify(s):
if ((s == None) or (s[-1:]==']')):
return None
result = s.split('.')[-1:]
result = ":" + result[0].upper()
return result
def introspect_obj(o, txt, indent = 4):
global annotate_file
global outfile
type_o = type(o)
if (type_o in [ types.CodeType, types.BuiltinFunctionType, types.BuiltinMethodType, types.FunctionType, types.LambdaType ]):
return
if (txt != None):
lispname = lispify(txt)
if (lispname != None):
if annotate_file:
print("", file=outfile)
print(" " * indent, end='', file=outfile)
print ( "; " + txt, end = '', file=outfile)
print("", file=outfile)
print(" " * indent, end='', file=outfile)
print ( lispname + " ", end = '', file=outfile )
if (type_o == bool):
if (o == False):
print("NIL ", end = '', file=outfile)
else:
print("T ", end = '', file=outfile)
return
if (o == None):
print ("NIL ", end = '', file=outfile)
if (type_o in [ int, float ]):
print(o, " ", end='', file=outfile)
return
if (type(o) == str):
print ("\"" + o + "\" ", end='')
return
if txt == None:
return
# we do this explicitly to avoid the madness of swizzling (100s of members per vector!)
if (type_o == mathutils.Vector):
items = [ 'x', 'y', 'z', 'w' ]
print( " #(", end = '' , file=outfile)
for item in items:
newtxt = txt + '.' + item
val = getattr(o, item, None)
if (val != None):
print(" ", end='', file=outfile)
introspect_obj( val, newtxt, indent+4)
print( " ) ", end = '' , file=outfile)
return
# object members
try: __members__ = dir(o)
except: __members__ = []
# all kinds of stuff turns up in dir(), so filter it out
if (__members__ != []):
fields = []
for item in __members__:
if item.startswith("__"):
continue
if item in [ 'rna_type', 'bl_rna' ]:
continue
if item in txt:
continue
type_i = type(getattr(o, item, None))
if (type_i in [ types.CodeType, types.BuiltinFunctionType, types.BuiltinMethodType, types.FunctionType, types.LambdaType ]):
continue
fields += [ item ]
# if there's anything left, print it
if (len(fields) != 0):
print("", file=outfile)
print(" " * indent, end='', file=outfile)
print("(", end = '' , file=outfile)
itemindex = 0
for item in fields:
newtxt = txt + '.' + item
introspect_obj( getattr(o, item, None), newtxt, indent + 4)
itemindex=itemindex+1
print( " ) ", end='', file=outfile)
# now, try dict types
try: keys = o.keys()
except: keys = None
if keys:
print( "(", end = '' , file=outfile)
for k in keys:
print(" ", end='', file=outfile)
newtxt = txt + "." + k
introspect_obj(o.__getitem__(k), newtxt, indent+4)
print( ") ; keys", end='', file=outfile)
else:
# list/tuple
try: length = len( o )
except: length = 0
if (length != 0):
if ("__getitem__" in __members__):
# print(" " * indent, end='', file=outfile)
print( " #( ", end = '' , file=outfile)
# print(" " * indent, end='', file=outfile)
# print(txt)
for i in range(length):
print(" ", end='', file=outfile)
newtxt = txt + '[' + str(i) + ']'
introspect_obj(o[i], newtxt, indent+4)
print( " ) " , end = '', file=outfile)
else:
# sets/nonindexable
# print(" " * indent, end='', file=outfile)
print( " #( ", end = '' , file=outfile)
for i in o:
print(" ", end='', file=outfile)
introspect_obj(i, None, indent+4)
print( " ) ", end='', file=outfile)
return
def dump_sexp(fn, package, introspect, annotate):
global outfile
global annotate_file
outfile = open(fn, 'w+')
print ("(in-package :" + package + ")\n", file=outfile)
print ("'(", end='', file=outfile)
annotate_file = annotate
introspect_obj(eval(introspect, globals(), locals()), introspect)
print (")", file=outfile)
outfile.close()
class Export_sexp(bpy.types.Operator, ExportHelper):
'''Export secene as structured sexps'''
bl_idname = "export.sexp"
bl_label = "Export Sexp"
filename_ext = ".lisp"
filter_glob = StringProperty(default="*.lisp", options={'HIDDEN'})
filepath = StringProperty(name="File Path", description="Filepath used for exporting the lisp file", maxlen= 1024, default= "", subtype='FILE_PATH')
# check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True)
packageName = StringProperty(name="Package Name", description="Package the exported sexps will be placed in.", maxlen=256,default="photons")
introspectName = StringProperty(name="Data", description="Data to introspect", maxlen=256, default="bpy.context.active_object")
annotateFlag = BoolProperty(name="Annotate", description="Annotate file with comments (makes it large!)", default=False)
@classmethod
def poll(cls, context):
return context.active_object != None
def execute(self, context):
dump_sexp(self.filepath, self.packageName, self.introspectName, self.annotateFlag)
return {'FINISHED'}
### REGISTER ###
def menu_func(self, context):
self.layout.operator(Export_sexp.bl_idname, text="Sexp (.lisp)")
def register():
bpy.utils.register_class(Export_sexp)
bpy.types.INFO_MT_file_export.append(menu_func)
#bpy.types.VIEW3D_PT_tools_objectmode.prepend(menu_func)
def unregister():
bpy.utils.unregister_class(Export_sexp)
bpy.types.INFO_MT_file_export.remove(menu_func)
if __name__ == "__main__":
register()
# test call
bpy.ops.export.sexp('INVOKE_DEFAULT')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment