Import/export operator registration working. Written in python, it
authorArystanbek Dyussenov <arystan.d@gmail.com>
Fri, 12 Jun 2009 09:54:28 +0000 (09:54 +0000)
committerArystanbek Dyussenov <arystan.d@gmail.com>
Fri, 12 Jun 2009 09:54:28 +0000 (09:54 +0000)
traverses scripts in .blender/io extracting and registering Operator
subclasses, and binding to menu items under Scripts->Export in Scripts
Window.

release/io dir has to be copied to .blender manually for now.

release/io/export_obj.py [new file with mode: 0644]
release/ui/space_script.py

diff --git a/release/io/export_obj.py b/release/io/export_obj.py
new file mode 100644 (file)
index 0000000..37039bb
--- /dev/null
@@ -0,0 +1,28 @@
+import bpy
+
+class SCRIPT_OT_export_obj(bpy.types.Operator):
+       '''Operator documentation text, will be used for the operator tooltip and python docs.'''
+       __label__ = 'Export OBJ'
+       
+       # List of operator properties, the attributes will be assigned
+       # to the class instance from the operator settings before calling.
+       __props__ = [
+#              FloatProperty(attr="setting_1", name="Example 1", default=10.0, min=0, max=10, description="Add info here"),
+#              StringProperty(attr="filename")
+               ]
+
+       def debug(self, message):
+               print("{0}: {1}".format(self.__class__.__name__, message))
+
+       def exec(self, context):
+#              print(self.setting_1)
+               self.debug("exec")
+               return 'FINISHED'
+       
+       def invoke(self, context, event):
+               self.debug("invoke")
+               return self.exec(context)
+       
+       def poll(self, context): # poll isnt working yet
+               self.debug("poll")
+               return True
index ea6f4be311cef115739f3b7110d648c030bc60ac..0ab091e8fd511ea569d5ff1b7bc4fa9b854bd052 100644 (file)
@@ -1,5 +1,25 @@
+import sys
+import os
+import imp
+# import glob
 import bpy
 
+operators = []
+
+def register_op(opclass):
+    if (hasattr(bpy.ops, opclass.__name__)):
+        bpy.ops.remove(getattr(bpy.ops, opclass.__name__))
+
+    bpy.ops.add(opclass)
+
+    global operators
+    if opclass.__name__ not in operators:
+        operators.append(opclass.__name__)
+
+
+# hint for myself: for interface api documentation, see source/blender/editors/interface/interface_api.c
+# another hint: reloading ui scripts in scripts window is Shift + P
+
 class SCRIPT_HT_header(bpy.types.Header):
        __space_type__ = "SCRIPTS_WINDOW"
        __idname__ = "SCRIPT_HT_header"
@@ -14,23 +34,6 @@ class SCRIPT_HT_header(bpy.types.Header):
                        row = layout.row(align=True)
                        row.itemM(context, "SCRIPT_MT_scripts")
 
-        # draw menu item to reload scripts from
-        # release/io
-        #
-        # it should call operator or
-        # a func that will:
-        # for each .py file in the dir,
-        # import/reload module, in the module:
-        # find subclasses of bpy.types.Operator,
-        # for each subclass create menus under "Export"
-        # with (row.)itemO
-        #
-        # for interface api documentation, see
-        # see source/blender/editors/interface/interface_api.c
-        #
-        # hint: reloading ui scripts in scripts window is Shift+P
-
-
 class SCRIPT_MT_scripts(bpy.types.Menu):
     __space_type__ = "SCRIPTS_WINDOW"
     __label__ = "Scripts"
@@ -46,13 +49,69 @@ class SCRIPT_MT_export(bpy.types.Menu):
     __label__ = "Export"
 
     def draw(self, context):
-        pass
+        global operators
+
+        print("drawing {0} operators: {1}".format(len(operators), operators))
+
+        layout = self.layout
+        layout.column()
+        for opname in operators:
+            layout.itemO(opname)
 
 class SCRIPT_OT_reload_scripts(bpy.types.Operator):
     __label__ = 'Reload Scripts'
 
     def exec(self, context):
         print("SCRIPT_OT_reload_scripts: exec")
+
+        # add ../io to sys.path
+
+        # this module's absolute path
+        abspath = os.path.abspath(sys.modules[__name__].__file__)
+        print("Current abspath: {0}".format(abspath))
+
+        # ../io
+        io = os.path.normpath(os.path.dirname(abspath) + "/../io")
+        print("abspath = " + io)
+
+        if io not in sys.path:
+            sys.path.append(io)
+
+        # for each .py file in release/io,
+        # import/reload module, in the module:
+        # find subclasses of bpy.types.Operator,
+        # for each subclass create menus under "Export"
+        # with (row.)itemO
+
+        global operators
+        operators = []
+
+        # glob unavailable :(
+#         for path in glob.glob("../io/*.py"):
+        for path in os.listdir(io):
+            modname, ext = os.path.splitext(os.path.basename(path))
+
+            if ext != ".py":
+                continue
+
+            print("Found module {0}.".format(modname))
+
+            if modname in sys.modules:
+                mod = imp.reload(sys.modules[modname])
+                print("Reloaded it.")
+            else:
+                mod = __import__(modname)
+                print("Imported it.")
+
+            for attr in dir(mod):
+                cls = getattr(mod, attr)
+                
+                # XXX is there a better way to check that cls is a class?
+                if type(cls) == bpy.types.Operator.__class__ and issubclass(cls, bpy.types.Operator):
+                    print("Found class {0}.".format(cls.__name__))
+                    register_op(cls)
+                    print("Registered it.")
+
         return 'FINISHED'
 
     def invoke(self, context, event):
@@ -62,7 +121,6 @@ class SCRIPT_OT_reload_scripts(bpy.types.Operator):
     def poll(self, context):
         pass
 
-
 bpy.types.register(SCRIPT_HT_header)
 bpy.types.register(SCRIPT_MT_scripts)
 bpy.types.register(SCRIPT_MT_export)