Merge from trunk -r 23968:24181.
authorArystanbek Dyussenov <arystan.d@gmail.com>
Mon, 2 Nov 2009 16:41:57 +0000 (16:41 +0000)
committerArystanbek Dyussenov <arystan.d@gmail.com>
Mon, 2 Nov 2009 16:41:57 +0000 (16:41 +0000)
65 files changed:
CMake/macros.cmake
CMakeLists.txt
config/linux2-config.py
config/win32-vc-config.py
config/win64-vc-config.py
release/scripts/ui/space_info.py
release/ui/bpy_ops.py [new file with mode: 0644]
release/ui/buttons_data_armature.py [new file with mode: 0644]
release/ui/buttons_data_bone.py [new file with mode: 0644]
release/ui/buttons_data_camera.py [new file with mode: 0644]
release/ui/buttons_data_curve.py [new file with mode: 0644]
release/ui/buttons_data_empty.py [new file with mode: 0644]
release/ui/buttons_data_lamp.py [new file with mode: 0644]
release/ui/buttons_data_lattice.py [new file with mode: 0644]
release/ui/buttons_data_mesh.py [new file with mode: 0644]
release/ui/buttons_data_metaball.py [new file with mode: 0644]
release/ui/buttons_data_modifier.py [new file with mode: 0644]
release/ui/buttons_data_text.py [new file with mode: 0644]
release/ui/buttons_game.py [new file with mode: 0644]
release/ui/buttons_material.py [new file with mode: 0644]
release/ui/buttons_object.py [new file with mode: 0644]
release/ui/buttons_object_constraint.py [new file with mode: 0644]
release/ui/buttons_particle.py [new file with mode: 0644]
release/ui/buttons_physics_cloth.py [new file with mode: 0644]
release/ui/buttons_physics_field.py [new file with mode: 0644]
release/ui/buttons_physics_fluid.py [new file with mode: 0644]
release/ui/buttons_physics_smoke.py [new file with mode: 0644]
release/ui/buttons_physics_softbody.py [new file with mode: 0644]
release/ui/buttons_scene.py [new file with mode: 0644]
release/ui/buttons_texture.py [new file with mode: 0644]
release/ui/buttons_world.py [new file with mode: 0644]
release/ui/space_buttons.py [new file with mode: 0644]
release/ui/space_console.py [new file with mode: 0644]
release/ui/space_filebrowser.py [new file with mode: 0644]
release/ui/space_image.py [new file with mode: 0644]
release/ui/space_info.py [new file with mode: 0644]
release/ui/space_logic.py [new file with mode: 0644]
release/ui/space_node.py [new file with mode: 0644]
release/ui/space_outliner.py [new file with mode: 0644]
release/ui/space_sequencer.py [new file with mode: 0644]
release/ui/space_text.py [new file with mode: 0644]
release/ui/space_time.py [new file with mode: 0644]
release/ui/space_userpref.py [new file with mode: 0644]
release/ui/space_view3d.py [new file with mode: 0644]
release/ui/space_view3d_toolbar.py [new file with mode: 0644]
source/blender/CMakeLists.txt
source/blender/SConscript
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/intern/image.c
source/blender/collada/CMakeLists.txt [new file with mode: 0644]
source/blender/collada/DocumentExporter.cpp [new file with mode: 0644]
source/blender/collada/DocumentExporter.h [new file with mode: 0644]
source/blender/collada/DocumentImporter.cpp [new file with mode: 0644]
source/blender/collada/DocumentImporter.h [new file with mode: 0644]
source/blender/collada/SConscript [new file with mode: 0644]
source/blender/collada/collada.cpp [new file with mode: 0644]
source/blender/collada/collada.h [new file with mode: 0644]
source/blender/collada/collada_internal.h [new file with mode: 0644]
source/blender/editors/include/ED_object.h
source/blender/windowmanager/CMakeLists.txt
source/blender/windowmanager/SConscript
source/blender/windowmanager/intern/wm_operators.c
source/creator/CMakeLists.txt
tools/Blender.py
tools/btools.py

index 150bd55bfd7e06a2f10ef5d3cc8d62c526d4739b..de84b5f3372363b933bab623a8903c33de6b4a28 100644 (file)
@@ -67,6 +67,11 @@ MACRO(SETUP_LIBDIRS)
   IF(WITH_OPENAL)
     LINK_DIRECTORIES(${OPENAL_LIBPATH})
   ENDIF(WITH_OPENAL)
+  IF(WITH_OPENCOLLADA)
+    LINK_DIRECTORIES(${OPENCOLLADA_LIBPATH})
+    LINK_DIRECTORIES(${PCRE_LIBPATH})
+    LINK_DIRECTORIES(${EXPAT_LIBPATH})
+  ENDIF(WITH_OPENCOLLADA)
   IF(WITH_JACK)
     LINK_DIRECTORIES(${JACK_LIBPATH})
   ENDIF(WITH_JACK)
@@ -135,6 +140,11 @@ MACRO(SETUP_LIBLINKS
   IF(WITH_FFMPEG)
     TARGET_LINK_LIBRARIES(${target} ${FFMPEG_LIB})
   ENDIF(WITH_FFMPEG)
+  IF(WITH_OPENCOLLADA)
+    TARGET_LINK_LIBRARIES(${target} ${OPENCOLLADA_LIB})
+    TARGET_LINK_LIBRARIES(${target} ${PCRE_LIB})
+    TARGET_LINK_LIBRARIES(${target} ${EXPAT_LIB})
+  ENDIF(WITH_OPENCOLLADA)
   IF(WIN32)
     TARGET_LINK_LIBRARIES(${target} ${PTHREADS_LIB})
   ENDIF(WIN32)
index 963601dd94ac2a2722dcaf0807ee84eaf81d108c..a649a5e0a8df8d2df1f97d5ecc94d11f2c21d859 100644 (file)
@@ -80,6 +80,7 @@ OPTION(WITH_LZMA          "Enable best LZMA compression, used for pointcache" ON
 OPTION(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation" OFF)
 OPTION(WITH_BUILDINFO     "Include extra build details" ON)
 OPTION(WITH_INSTALL       "Install accompanying scripts and language files needed to run blender" ON)
+OPTION(WITH_OPENCOLLADA                "Enable OpenCollada Support (http://www.opencollada.org/)"      ON)
 
 IF (APPLE)
 OPTION(WITH_COCOA        "Use Cocoa framework instead of deprecated Carbon" ON)
@@ -90,6 +91,19 @@ IF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
        MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE")
 ENDIF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
 
+IF (WITH_OPENCOLLADA)
+SET(OPENCOLLADA /usr/local/opencollada CACHE FILEPATH "OpenCollada Directory")
+SET(OPENCOLLADA_LIBPATH ${OPENCOLLADA})
+SET(OPENCOLLADA_LIB OpenCollada)
+SET(PCRE /usr CACHE FILEPATH "PCRE Directory")
+SET(PCRE_LIBPATH ${PCRE}/lib)
+SET(PCRE_LIB pcre)
+SET(EXPAT /usr CACHE FILEPATH "Expat Directory")
+SET(EXPAT_LIBPATH ${EXPAT}/lib)
+SET(EXPAT_LIB expat)
+
+ENDIF (WITH_OPENCOLLADA)
+
 # For alternate Python locations the commandline can be used to override detected/default cache settings, e.g:
 # On Unix: 
 #   cmake -D PYTHON_LIB=/usr/local/lib/python2.3/config/libpython2.3.so -D PYTHON_INC=/usr/local/include/python2.3 -D PYTHON_BINARY=/usr/local/bin/python2.3 -G "Unix Makefiles" ../blender
index 026d0a200a5eb32ea8fab6daa0dd75a05af46b1f..536a3e0e327c585ad76d059649c9cbf09306209a 100644 (file)
@@ -151,6 +151,20 @@ BF_OPENGL_LIB = 'GL GLU X11 Xi'
 BF_OPENGL_LIBPATH = '/usr/X11R6/lib'
 BF_OPENGL_LIB_STATIC = '${BF_OPENGL_LIBPATH}/libGL.a ${BF_OPENGL_LIBPATH}/libGLU.a ${BF_OPENGL_LIBPATH}/libXxf86vm.a ${BF_OPENGL_LIBPATH}/libX11.a ${BF_OPENGL_LIBPATH}/libXi.a ${BF_OPENGL_LIBPATH}/libXext.a ${BF_OPENGL_LIBPATH}/libXxf86vm.a'
 
+WITH_BF_COLLADA = True
+BF_COLLADA = '#source/blender/collada'
+BF_COLLADA_INC = '${BF_COLLADA}'
+BF_COLLADA_LIB = 'bf_collada'
+BF_OPENCOLLADA = ''
+BF_OPENCOLLADA_LIB = 'OpenCollada'
+BF_OPENCOLLADA_LIBPATH = '/usr/lib'
+BF_PCRE = ''
+BF_PCRE_LIB = 'pcre'
+BF_PCRE_LIBPATH = '/usr/lib'
+BF_EXPAT = '/usr'
+BF_EXPAT_LIB = 'expat'
+BF_EXPAT_LIBPATH = '/usr/lib'
+
 ##
 CC = 'gcc'
 CXX = 'g++'
index 291aa023ec86410037f8e20043b55a909f5e93dd..73e6e39b7d1d3d25a0bbc061e37ad719da9ded06 100644 (file)
@@ -138,6 +138,16 @@ BF_FFTW3_LIBPATH = '${BF_FFTW3}/lib'
 WITH_BF_REDCODE = False  
 BF_REDCODE_INC = '#extern'
 
+WITH_BF_COLLADA = True
+BF_COLLADA = '#source/blender/collada'
+BF_COLLADA_INC = '${BF_COLLADA}'
+BF_COLLADA_LIB = 'bf_collada'
+
+BF_OPENCOLLADA = LIBDIR + '/opencollada'
+BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
+BF_OPENCOLLADA_LIB = 'opencollada'
+BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
+
 WITH_BF_STATICOPENGL = False
 BF_OPENGL_INC = '${BF_OPENGL}/include'
 BF_OPENGL_LIBINC = '${BF_OPENGL}/lib'
index 5f088489b34bb89e64500b4be1d06038731f3d96..64f023ef7be9ce012d3b1bf877a0d756e308fdfd 100644 (file)
@@ -151,6 +151,16 @@ BF_FFTW3_LIBPATH = '${BF_FFTW3}/lib'
 WITH_BF_REDCODE = False  
 BF_REDCODE_INC = '#extern'
 
+WITH_BF_COLLADA = True
+BF_COLLADA = '#source/blender/collada'
+BF_COLLADA_INC = '${BF_COLLADA}'
+BF_COLLADA_LIB = 'bf_collada'
+
+BF_OPENCOLLADA = LIBDIR + '/opencollada'
+BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
+BF_OPENCOLLADA_LIB = 'opencollada'
+BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
+
 WITH_BF_STATICOPENGL = False
 BF_OPENGL_INC = '${BF_OPENGL}/include'
 BF_OPENGL_LIBINC = '${BF_OPENGL}/lib'
index 083b6f07fbc6bd97bae67d57b1a270e65d3c7ba7..d4fcbbcdd4d498b5a9c0806f1468243733f0e920 100644 (file)
@@ -99,13 +99,13 @@ class INFO_MT_file_import(dynamic_menu.DynMenu):
        __label__ = "Import"
 
        def draw(self, context):
-               pass # dynamic menu
+               self.layout.itemO("WM_OT_collada_import", text="COLLADA (.dae)...")
 
 class INFO_MT_file_export(dynamic_menu.DynMenu):
        __label__ = "Export"
 
        def draw(self, context):
-               pass # dynamic menu
+               self.layout.itemO("WM_OT_collada_export", text="COLLADA (.dae)...")
 
 class INFO_MT_file_external_data(bpy.types.Menu):
        __label__ = "External Data"
diff --git a/release/ui/bpy_ops.py b/release/ui/bpy_ops.py
new file mode 100644 (file)
index 0000000..dff8125
--- /dev/null
@@ -0,0 +1,137 @@
+# for slightly faster access
+from bpy.__ops__ import add            as op_add
+from bpy.__ops__ import remove         as op_remove
+from bpy.__ops__ import dir            as op_dir
+from bpy.__ops__ import call           as op_call
+from bpy.__ops__ import get_rna        as op_get_rna
+
+# Keep in sync with WM_types.h
+context_dict = {
+       'INVOKE_DEFAULT':0,
+       'INVOKE_REGION_WIN':1,
+       'INVOKE_AREA':2,
+       'INVOKE_SCREEN':3,
+       'EXEC_DEFAULT':4,
+       'EXEC_REGION_WIN':5,
+       'EXEC_AREA':6,
+       'EXEC_SCREEN':7,
+}
+
+class bpy_ops(object):
+       '''
+       Fake module like class.
+       
+        bpy.ops
+       '''
+       def add(self, pyop):
+               op_add(pyop)
+       
+       def remove(self, pyop):
+               op_remove(pyop)
+       
+       def __getattr__(self, module):
+               '''
+               gets a bpy.ops submodule
+               '''
+               return bpy_ops_submodule(module)
+               
+       def __dir__(self):
+               
+               submodules = set()
+               
+               # add this classes functions
+               for id_name in dir(self.__class__):
+                       if not id_name.startswith('__'):
+                               submodules.add(id_name)
+               
+               for id_name in op_dir():
+                       id_split = id_name.split('_OT_', 1)
+                       
+                       if len(id_split) == 2:
+                               submodules.add(id_split[0].lower())
+                       else:
+                               submodules.add(id_split[0])
+               
+               return list(submodules)
+               
+       def __repr__(self):
+               return "<module like class 'bpy.ops'>"
+
+
+class bpy_ops_submodule(object):
+       '''
+       Utility class to fake submodules.
+       
+       eg. bpy.ops.object
+       '''
+       __keys__ = ('module',)
+       
+       def __init__(self, module):
+               self.module = module
+               
+       def __getattr__(self, func):
+               '''
+               gets a bpy.ops.submodule function
+               '''
+               return bpy_ops_submodule_op(self.module, func)
+               
+       def __dir__(self):
+               
+               functions = set()
+               
+               module_upper = self.module.upper()
+               
+               for id_name in op_dir():
+                       id_split = id_name.split('_OT_', 1)
+                       if len(id_split) == 2 and module_upper == id_split[0]:
+                               functions.add(id_split[1])
+               
+               return list(functions)
+       
+       def __repr__(self):
+               return "<module like class 'bpy.ops.%s'>" % self.module
+
+class bpy_ops_submodule_op(object):
+       '''
+       Utility class to fake submodule operators.
+       
+       eg. bpy.ops.object.somefunc
+       '''
+       __keys__ = ('module', 'func')
+       def __init__(self, module, func):
+               self.module = module
+               self.func = func
+       
+       def idname(self):
+               # submod.foo -> SUBMOD_OT_foo
+               return self.module.upper() + '_OT_' + self.func
+       
+       def __call__(self, *args, **kw):
+               
+               # Get the operator from blender
+               if len(args) > 1:
+                       raise ValueError("only one argument for the execution context is supported ")
+               
+               if args:
+                       try:
+                               context = context_dict[args[0]]
+                       except:
+                               raise ValueError("Expected a single context argument in: " + str(list(context_dict.keys())))
+                       
+                       return op_call(self.idname(), kw, context)
+               
+               else:
+                       return op_call(self.idname(), kw)
+       
+       def get_rna(self):
+               '''
+               currently only used for '__rna__'
+               '''
+               return op_get_rna(self.idname())
+                       
+       
+       def __repr__(self):
+               return "<function bpy.ops.%s.%s at 0x%x'>" % (self.module, self.func, id(self))
+
+import bpy
+bpy.ops = bpy_ops()
diff --git a/release/ui/buttons_data_armature.py b/release/ui/buttons_data_armature.py
new file mode 100644 (file)
index 0000000..5924a2e
--- /dev/null
@@ -0,0 +1,177 @@
+
+import bpy
+class DataButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "data"
+       
+       def poll(self, context):
+               return (context.armature)
+
+class DATA_PT_context_arm(DataButtonsPanel):
+       __show_header__ = False
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               arm = context.armature
+               space = context.space_data
+
+               split = layout.split(percentage=0.65)
+
+               if ob:
+                       split.template_ID(ob, "data")
+                       split.itemS()
+               elif arm:
+                       split.template_ID(space, "pin_id")
+                       split.itemS()
+
+class DATA_PT_skeleton(DataButtonsPanel):
+       __label__ = "Skeleton"
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               arm = context.armature
+               space = context.space_data
+
+               split = layout.split()
+
+               col = split.column()
+               col.itemL(text="Layers:")
+               col.itemR(arm, "layer", text="")
+               col.itemL(text="Protected Layers:")
+               col.itemR(arm, "layer_protection", text="")
+               col.itemL(text="Edit Options:")
+               col.itemR(arm, "x_axis_mirror")
+               col.itemR(arm, "auto_ik")
+               
+               col = split.column()
+               col.itemR(arm, "rest_position")
+               col.itemL(text="Deform:")
+               col.itemR(arm, "deform_vertexgroups", text="Vertex Groups")
+               col.itemR(arm, "deform_envelope", text="Envelopes")
+               col.itemR(arm, "deform_quaternion", text="Quaternion")
+               col.itemR(arm, "deform_bbone_rest", text="B-Bones Rest")
+               
+class DATA_PT_display(DataButtonsPanel):
+       __label__ = "Display"
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               arm = context.armature
+
+               layout.row().itemR(arm, "drawtype", expand=True)
+
+               flow = layout.column_flow()
+               flow.itemR(arm, "draw_names", text="Names")
+               flow.itemR(arm, "draw_axes", text="Axes")
+               flow.itemR(arm, "draw_custom_bone_shapes", text="Shapes")
+               flow.itemR(arm, "draw_group_colors", text="Colors")
+               flow.itemR(arm, "delay_deform", text="Delay Refresh")
+
+class DATA_PT_bone_groups(DataButtonsPanel):
+       __label__ = "Bone Groups"
+       
+       def poll(self, context):
+               return (context.object and context.object.type=='ARMATURE' and context.object.pose)
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               pose = ob.pose
+               
+               row = layout.row()
+               row.template_list(pose, "bone_groups", pose, "active_bone_group_index")
+               
+               col = row.column(align=True)
+               col.active = (ob.proxy == None)
+               col.itemO("pose.group_add", icon='ICON_ZOOMIN', text="")
+               col.itemO("pose.group_remove", icon='ICON_ZOOMOUT', text="")
+               
+               group = pose.active_bone_group
+               if group:
+                       col = layout.column()
+                       col.active= (ob.proxy == None)
+                       col.itemR(group, "name")
+                       
+                       split = layout.split(0.5)
+                       split.active= (ob.proxy == None)
+                       split.itemR(group, "color_set")
+                       if group.color_set:
+                               split.template_triColorSet(group, "colors")
+               
+               row = layout.row(align=True)
+               row.active = (ob.proxy == None)
+               
+               row.itemO("pose.group_assign", text="Assign")
+               row.itemO("pose.group_remove", text="Remove") #row.itemO("pose.bone_group_remove_from", text="Remove")
+               #row.itemO("object.bone_group_select", text="Select")
+               #row.itemO("object.bone_group_deselect", text="Deselect")
+
+class DATA_PT_paths(DataButtonsPanel):
+       __label__ = "Paths"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               arm = context.armature
+
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(arm, "paths_show_around_current_frame", text="Around Frame")
+               
+               sub = col.column(align=True)
+               if (arm.paths_show_around_current_frame):
+                       sub.itemR(arm, "path_before_current", text="Before")
+                       sub.itemR(arm, "path_after_current", text="After")
+               else:
+                       sub.itemR(arm, "path_start_frame", text="Start")
+                       sub.itemR(arm, "path_end_frame", text="End")
+
+               sub.itemR(arm, "path_size", text="Step")        
+               col.itemR(arm, "paths_calculate_head_positions", text="Head")
+               
+               col = split.column()
+               col.itemL(text="Show:")
+               col.itemR(arm, "paths_show_frame_numbers", text="Frame Numbers")
+               col.itemR(arm, "paths_highlight_keyframes", text="Keyframes")
+               col.itemR(arm, "paths_show_keyframe_numbers", text="Keyframe Numbers")
+
+class DATA_PT_ghost(DataButtonsPanel):
+       __label__ = "Ghost"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               arm = context.armature
+
+               split = layout.split()
+
+               col = split.column()
+               col.itemR(arm, "ghost_type", text="")
+
+               sub = col.column(align=True)
+               if arm.ghost_type == 'RANGE':
+                       sub.itemR(arm, "ghost_start_frame", text="Start")
+                       sub.itemR(arm, "ghost_end_frame", text="End")
+                       sub.itemR(arm, "ghost_size", text="Step")
+               elif arm.ghost_type == 'CURRENT_FRAME':
+                       sub.itemR(arm, "ghost_step", text="Range")
+                       sub.itemR(arm, "ghost_size", text="Step")
+
+               col = split.column()
+               col.itemR(arm, "ghost_only_selected", text="Selected Only")
+
+bpy.types.register(DATA_PT_context_arm)
+bpy.types.register(DATA_PT_skeleton)
+bpy.types.register(DATA_PT_display)
+bpy.types.register(DATA_PT_bone_groups)
+bpy.types.register(DATA_PT_paths)
+bpy.types.register(DATA_PT_ghost)
diff --git a/release/ui/buttons_data_bone.py b/release/ui/buttons_data_bone.py
new file mode 100644 (file)
index 0000000..a012182
--- /dev/null
@@ -0,0 +1,278 @@
+
+import bpy
+class BoneButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "bone"
+       
+       def poll(self, context):
+               return (context.bone or context.edit_bone)
+
+class BONE_PT_context_bone(BoneButtonsPanel):
+       __show_header__ = False
+
+       def draw(self, context):
+               layout = self.layout
+               
+               bone = context.bone
+               if not bone:
+                       bone = context.edit_bone
+               
+               row = layout.row()
+               row.itemL(text="", icon='ICON_BONE_DATA')
+               row.itemR(bone, "name", text="")
+
+class BONE_PT_transform(BoneButtonsPanel):
+       __label__ = "Transform"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               bone = context.bone
+               if not bone:
+                       bone = context.edit_bone
+
+                       row = layout.row()
+                       row.column().itemR(bone, "head")
+                       row.column().itemR(bone, "tail")
+
+                       col = row.column()
+                       sub = col.column(align=True)
+                       sub.itemL(text="Roll:")
+                       sub.itemR(bone, "roll", text="")
+                       sub.itemL()
+                       sub.itemR(bone, "locked")
+
+               else:
+                       pchan = ob.pose.pose_channels[context.bone.name]
+
+                       layout.itemR(pchan, "rotation_mode")
+
+                       row = layout.row()
+                       col = row.column()
+                       col.itemR(pchan, "location")
+                       col.active = not (bone.parent and bone.connected)
+
+                       col = row.column()
+                       if pchan.rotation_mode == 'QUATERNION':
+                               col.itemR(pchan, "rotation", text="Rotation")
+                       elif pchan.rotation_mode == 'AXIS_ANGLE':
+                               col.itemL(text="Rotation")
+                               col.itemR(pchan, "rotation_angle", text="Angle")
+                               col.itemR(pchan, "rotation_axis", text="Axis")
+                       else:
+                               col.itemR(pchan, "euler_rotation", text="Rotation")
+
+                       row.column().itemR(pchan, "scale")
+
+                       if pchan.rotation_mode == 'QUATERNION':
+                               col = layout.column(align=True)
+                               col.itemL(text="Euler:")
+                               col.row().itemR(pchan, "euler_rotation", text="")
+                               
+class BONE_PT_transform_locks(BoneButtonsPanel):
+       __label__ = "Transform Locks"
+       
+       def poll(self, context):
+               return context.bone
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               bone = context.bone
+               pchan = ob.pose.pose_channels[context.bone.name]
+               
+               row = layout.row()
+               col = row.column()
+               col.itemR(pchan, "lock_location")
+               col.active = not (bone.parent and bone.connected)
+               
+               col = row.column()
+               if pchan.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
+                       col.itemR(pchan, "lock_rotations_4d", text="Lock Rotation")
+                       if pchan.lock_rotations_4d:
+                               col.itemR(pchan, "lock_rotation_w", text="W")
+                       col.itemR(pchan, "lock_rotation", text="")
+               else:
+                       col.itemR(pchan, "lock_rotation", text="Rotation")
+               
+               row.column().itemR(pchan, "lock_scale")
+
+class BONE_PT_bone(BoneButtonsPanel):
+       __label__ = "Bone"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               bone = context.bone
+               arm = context.armature
+               
+               if not bone:
+                       bone = context.edit_bone
+                       pchan = None
+               else:
+                       pchan = ob.pose.pose_channels[context.bone.name]
+
+               split = layout.split()
+
+               col = split.column()
+               col.itemL(text="Parent:")
+               if context.bone:
+                       col.itemR(bone, "parent", text="")
+               else:
+                       col.item_pointerR(bone, "parent", arm, "edit_bones", text="")
+               
+               row = col.row()
+               row.active = bone.parent != None
+               row.itemR(bone, "connected")
+               
+               col.itemL(text="Layers:")
+               col.itemR(bone, "layer", text="")
+               
+               col = split.column()
+               col.itemL(text="Inherit:")
+               col.itemR(bone, "hinge", text="Rotation")
+               col.itemR(bone, "inherit_scale", text="Scale")
+               col.itemL(text="Display:")
+               col.itemR(bone, "draw_wire", text="Wireframe")
+               col.itemR(bone, "hidden", text="Hide")
+               
+               if ob and pchan:
+                       split = layout.split()
+                       
+                       col = split.column()
+                       col.itemL(text="Bone Group:")
+                       col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="")
+                       
+                       col = split.column()
+                       col.itemL(text="Custom Shape:")
+                       col.itemR(pchan, "custom_shape", text="")
+
+class BONE_PT_inverse_kinematics(BoneButtonsPanel):
+       __label__ = "Inverse Kinematics"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               ob = context.object
+               bone = context.bone
+
+               if ob and context.bone:
+                       pchan = ob.pose.pose_channels[context.bone.name]
+                       return pchan.has_ik
+               
+               return False
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               bone = context.bone
+               pchan = ob.pose.pose_channels[context.bone.name]
+
+               split = layout.split(percentage=0.25)
+               split.itemR(pchan, "ik_dof_x", text="X")
+               row = split.row()
+               row.itemR(pchan, "ik_stiffness_x", text="Stiffness")
+               row.active = pchan.ik_dof_x
+
+               split = layout.split(percentage=0.25)
+               row = split.row()
+               row.itemR(pchan, "ik_limit_x", text="Limit")
+               row.active = pchan.ik_dof_x
+               row = split.row(align=True)
+               row.itemR(pchan, "ik_min_x", text="")
+               row.itemR(pchan, "ik_max_x", text="")
+               row.active = pchan.ik_dof_x and pchan.ik_limit_x
+
+               split = layout.split(percentage=0.25)
+               split.itemR(pchan, "ik_dof_y", text="Y")
+               row = split.row()
+               row.itemR(pchan, "ik_stiffness_y", text="Stiffness")
+               row.active = pchan.ik_dof_y
+
+               split = layout.split(percentage=0.25)
+               row = split.row()
+               row.itemR(pchan, "ik_limit_y", text="Limit")
+               row.active = pchan.ik_dof_y
+               row = split.row(align=True)
+               row.itemR(pchan, "ik_min_y", text="")
+               row.itemR(pchan, "ik_max_y", text="")
+               row.active = pchan.ik_dof_y and pchan.ik_limit_y
+
+               split = layout.split(percentage=0.25)
+               split.itemR(pchan, "ik_dof_z", text="Z")
+               row = split.row()
+               row.itemR(pchan, "ik_stiffness_z", text="Stiffness")
+               row.active = pchan.ik_dof_z
+
+               split = layout.split(percentage=0.25)
+               row = split.row()
+               row.itemR(pchan, "ik_limit_z", text="Limit")
+               row.active = pchan.ik_dof_z
+               row = split.row(align=True)
+               row.itemR(pchan, "ik_min_z", text="")
+               row.itemR(pchan, "ik_max_z", text="")
+               row.active = pchan.ik_dof_z and pchan.ik_limit_z
+
+               split = layout.split()
+               split.itemR(pchan, "ik_stretch", text="Stretch")
+               split.itemL()
+
+class BONE_PT_deform(BoneButtonsPanel):
+       __label__ = "Deform"
+       __default_closed__ = True
+
+       def draw_header(self, context):
+               bone = context.bone
+               
+               if not bone:
+                       bone = context.edit_bone
+                       
+               self.layout.itemR(bone, "deform", text="")
+
+       def draw(self, context):
+               layout = self.layout
+               
+               bone = context.bone
+               
+               if not bone:
+                       bone = context.edit_bone
+       
+               layout.active = bone.deform
+                       
+               split = layout.split()
+
+               col = split.column()
+               col.itemL(text="Envelope:")
+               
+               sub = col.column(align=True)
+               sub.itemR(bone, "envelope_distance", text="Distance")
+               sub.itemR(bone, "envelope_weight", text="Weight")
+               col.itemR(bone, "multiply_vertexgroup_with_envelope", text="Multiply")
+
+               sub = col.column(align=True)
+               sub.itemL(text="Radius:")
+               sub.itemR(bone, "head_radius", text="Head")
+               sub.itemR(bone, "tail_radius", text="Tail")
+
+               col = split.column()
+               col.itemL(text="Curved Bones:")
+               
+               sub = col.column(align=True)
+               sub.itemR(bone, "bbone_segments", text="Segments")
+               sub.itemR(bone, "bbone_in", text="Ease In")
+               sub.itemR(bone, "bbone_out", text="Ease Out")
+               
+               col.itemL(text="Offset:")
+               col.itemR(bone, "cyclic_offset")
+
+bpy.types.register(BONE_PT_context_bone)
+bpy.types.register(BONE_PT_transform)
+bpy.types.register(BONE_PT_transform_locks)
+bpy.types.register(BONE_PT_bone)
+bpy.types.register(BONE_PT_deform)
+bpy.types.register(BONE_PT_inverse_kinematics)
diff --git a/release/ui/buttons_data_camera.py b/release/ui/buttons_data_camera.py
new file mode 100644 (file)
index 0000000..aa107d8
--- /dev/null
@@ -0,0 +1,97 @@
+
+import bpy
+
+class DataButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "data"
+
+       def poll(self, context):
+               return (context.camera)
+               
+class DATA_PT_context_camera(DataButtonsPanel):
+       __show_header__ = False
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               cam = context.camera
+               space = context.space_data
+
+               split = layout.split(percentage=0.65)
+
+               if ob:
+                       split.template_ID(ob, "data")
+                       split.itemS()
+               elif cam:
+                       split.template_ID(space, "pin_id")
+                       split.itemS()
+
+class DATA_PT_camera(DataButtonsPanel):
+       __label__ = "Lens"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               cam = context.camera
+
+               layout.itemR(cam, "type", expand=True)
+                       
+               row = layout.row(align=True)
+               if cam.type == 'PERSP':
+                       row.itemR(cam, "lens_unit", text="")
+                       if cam.lens_unit == 'MILLIMETERS':
+                               row.itemR(cam, "lens", text="Angle")
+                       elif cam.lens_unit == 'DEGREES':
+                               row.itemR(cam, "angle")
+
+               elif cam.type == 'ORTHO':
+                       row.itemR(cam, "ortho_scale")
+
+               layout.itemR(cam, "panorama")
+                               
+               split = layout.split()
+                       
+               col = split.column(align=True)
+               col.itemL(text="Shift:")
+               col.itemR(cam, "shift_x", text="X")
+               col.itemR(cam, "shift_y", text="Y")
+                       
+               col = split.column(align=True)
+               col.itemL(text="Clipping:")
+               col.itemR(cam, "clip_start", text="Start")
+               col.itemR(cam, "clip_end", text="End")
+                       
+               layout.itemL(text="Depth of Field:")
+               
+               row = layout.row()
+               row.itemR(cam, "dof_object", text="")
+               row.itemR(cam, "dof_distance", text="Distance")
+               
+class DATA_PT_camera_display(DataButtonsPanel):
+       __label__ = "Display"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               cam = context.camera
+
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(cam, "show_limits", text="Limits")
+               col.itemR(cam, "show_mist", text="Mist")
+               col.itemR(cam, "show_title_safe", text="Title Safe")
+               col.itemR(cam, "show_name", text="Name")
+                       
+               col = split.column()
+               col.itemR(cam, "show_passepartout", text="Passepartout")
+               sub = col.column()
+               sub.active = cam.show_passepartout
+               sub.itemR(cam, "passepartout_alpha", text="Alpha", slider=True)
+               col.itemR(cam, "draw_size", text="Size")
+               
+bpy.types.register(DATA_PT_context_camera)
+bpy.types.register(DATA_PT_camera)
+bpy.types.register(DATA_PT_camera_display)
diff --git a/release/ui/buttons_data_curve.py b/release/ui/buttons_data_curve.py
new file mode 100644 (file)
index 0000000..010acd1
--- /dev/null
@@ -0,0 +1,225 @@
+
+import bpy
+
+class DataButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "data"
+       
+       def poll(self, context):
+               return (context.object and context.object.type in ('CURVE', 'SURFACE') and context.curve)
+               
+class DataButtonsPanelCurve(DataButtonsPanel):
+       '''
+       Same as above but for curves only
+       '''
+       def poll(self, context):
+               return (context.object and context.object.type == 'CURVE' and context.curve)
+
+class DataButtonsPanelActive(DataButtonsPanel):
+       '''
+       Same as above but for curves only
+       '''
+       def poll(self, context):
+               curve = context.curve
+               return (curve and curve.active_spline)
+
+class DATA_PT_context_curve(DataButtonsPanel):
+       __show_header__ = False
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               curve = context.curve
+               space = context.space_data
+
+               split = layout.split(percentage=0.65)
+
+               if ob:
+                       split.template_ID(ob, "data")
+                       split.itemS()
+               elif curve:
+                       split.template_ID(space, "pin_id")
+                       split.itemS()
+
+class DATA_PT_shape_curve(DataButtonsPanel):
+       __label__ = "Shape"
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               curve = context.curve
+               space = context.space_data
+               is_surf = (ob.type == 'SURFACE')
+
+               if not is_surf:
+                       row = layout.row()
+                       row.itemR(curve, "curve_2d")
+               
+               split = layout.split()
+               
+               col = split.column()
+               
+               if not is_surf:
+                       sub = col.column()
+                       sub.active = curve.curve_2d
+                       sub.itemL(text="Caps:")
+                       row = sub.row()
+                       row.itemR(curve, "front")
+                       row.itemR(curve, "back")
+                       
+               col.itemL(text="Textures:")
+#              col.itemR(curve, "uv_orco")
+               col.itemR(curve, "auto_texspace")
+                       
+               col = split.column()    
+               col.itemL(text="Resolution:")
+               sub = col.column(align=True)
+               sub.itemR(curve, "resolution_u", text="Preview U")
+               sub.itemR(curve, "render_resolution_u", text="Render U")
+
+               if is_surf:
+                       sub = col.column(align=True)
+                       sub.itemR(curve, "resolution_v", text="Preview V")
+                       sub.itemR(curve, "render_resolution_v", text="Render V")
+               
+               # XXX - put somewhere nicer.
+               row= layout.row()
+               row.itemR(curve, "twist_mode")
+               row.itemR(curve, "twist_smooth") # XXX - may not be kept
+
+
+#              col.itemL(text="Display:")
+#              col.itemL(text="HANDLES")
+#              col.itemL(text="NORMALS")
+#              col.itemR(curve, "vertex_normal_flip")
+
+class DATA_PT_geometry_curve(DataButtonsPanelCurve):
+       __label__ = "Geometry "
+
+       def draw(self, context):
+               layout = self.layout
+               
+               curve = context.curve
+               
+               split = layout.split()
+       
+               col = split.column()
+               col.itemL(text="Modification:")
+               col.itemR(curve, "width")
+               col.itemR(curve, "extrude")
+               col.itemR(curve, "taper_object", icon='ICON_OUTLINER_OB_CURVE')
+               
+               col = split.column()
+               col.itemL(text="Bevel:")
+               col.itemR(curve, "bevel_depth", text="Depth")
+               col.itemR(curve, "bevel_resolution", text="Resolution")
+               col.itemR(curve, "bevel_object", icon='ICON_OUTLINER_OB_CURVE')
+
+       
+class DATA_PT_pathanim(DataButtonsPanelCurve):
+       __label__ = "Path Animation"
+       
+       def draw_header(self, context):
+               curve = context.curve
+
+               self.layout.itemR(curve, "use_path", text="")
+
+       def draw(self, context):
+               layout = self.layout
+               
+               curve = context.curve
+               
+               layout.active = curve.use_path  
+               
+               split = layout.split()          
+               
+               col = split.column()
+               col.itemR(curve, "path_length", text="Frames")
+               col.itemR(curve, "use_path_follow")
+
+               col = split.column()
+               col.itemR(curve, "use_stretch")
+               col.itemR(curve, "use_time_offset", text="Offset Children")
+       
+class DATA_PT_active_spline(DataButtonsPanelActive):
+       __label__ = "Active Spline"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               curve = context.curve
+               act_spline = curve.active_spline
+               is_surf = (ob.type == 'SURFACE')
+               is_poly = (act_spline.type == 'POLY')
+               
+               split = layout.split()
+               
+               if is_poly:
+                       # These settings are below but its easier to have 
+                       # poly's set aside since they use so few settings
+                       col = split.column()
+                       col.itemL(text="Cyclic:")
+                       col.itemR(act_spline, "smooth")
+                       col = split.column()
+                       col.itemR(act_spline, "cyclic_u", text="U")
+               
+               else:
+                       col = split.column()
+                       col.itemL(text="Cyclic:")
+                       if act_spline.type == 'NURBS':
+                               col.itemL(text="Bezier:")
+                               col.itemL(text="Endpoint:")
+                               col.itemL(text="Order:")
+                       
+                       col.itemL(text="Resolution:")
+                                       
+                       col = split.column()
+                       col.itemR(act_spline, "cyclic_u", text="U")
+                       
+                       if act_spline.type == 'NURBS':
+                               sub = col.column()
+                               # sub.active = (not act_spline.cyclic_u)
+                               sub.itemR(act_spline, "bezier_u", text="U")
+                               sub.itemR(act_spline, "endpoint_u", text="U")
+                               
+                               sub = col.column()
+                               sub.itemR(act_spline, "order_u", text="U")
+                       col.itemR(act_spline, "resolution_u", text="U")
+                       
+                       if is_surf:
+                               col = split.column()
+                               col.itemR(act_spline, "cyclic_v", text="V")
+                               
+                               # its a surface, assume its a nurb.
+                               sub = col.column()
+                               sub.active = (not act_spline.cyclic_v)
+                               sub.itemR(act_spline, "bezier_v", text="V")
+                               sub.itemR(act_spline, "endpoint_v", text="V")
+                               sub = col.column()
+                               sub.itemR(act_spline, "order_v", text="V")
+                               sub.itemR(act_spline, "resolution_v", text="V")
+
+                       
+                       if not is_surf:
+                               split = layout.split()
+                               col = split.column()
+                               col.active = (not curve.curve_2d)
+                               
+                               col.itemL(text="Interpolation:")
+                               col.itemR(act_spline, "tilt_interpolation", text="Tilt")
+                               col.itemR(act_spline, "radius_interpolation", text="Radius")
+                       
+                       split = layout.split()
+                       col = split.column()
+                       col.itemR(act_spline, "smooth")
+
+
+bpy.types.register(DATA_PT_context_curve)
+bpy.types.register(DATA_PT_shape_curve)
+bpy.types.register(DATA_PT_geometry_curve)
+bpy.types.register(DATA_PT_pathanim)
+bpy.types.register(DATA_PT_active_spline)
diff --git a/release/ui/buttons_data_empty.py b/release/ui/buttons_data_empty.py
new file mode 100644 (file)
index 0000000..c07f313
--- /dev/null
@@ -0,0 +1,23 @@
+
+import bpy
+
+class DataButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "data"
+       
+       def poll(self, context):
+               return (context.object and context.object.type == 'EMPTY')
+       
+class DATA_PT_empty(DataButtonsPanel):
+       __label__ = "Empty"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+
+               layout.itemR(ob, "empty_draw_type", text="Draw Type")
+               layout.itemR(ob, "empty_draw_size", text="Draw Size")
+               
+bpy.types.register(DATA_PT_empty)
diff --git a/release/ui/buttons_data_lamp.py b/release/ui/buttons_data_lamp.py
new file mode 100644 (file)
index 0000000..808a205
--- /dev/null
@@ -0,0 +1,313 @@
+
+import bpy
+
+class DataButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "data"
+       
+       def poll(self, context):
+               return (context.lamp)
+               
+class DATA_PT_preview(DataButtonsPanel):
+       __label__ = "Preview"
+
+       def draw(self, context):
+               self.layout.template_preview(context.lamp)
+       
+class DATA_PT_context_lamp(DataButtonsPanel):
+       __show_header__ = False
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               lamp = context.lamp
+               space = context.space_data
+
+               split = layout.split(percentage=0.65)
+
+               if ob:
+                       split.template_ID(ob, "data")
+                       split.itemS()
+               elif lamp:
+                       split.template_ID(space, "pin_id")
+                       split.itemS()
+
+class DATA_PT_lamp(DataButtonsPanel):
+       __label__ = "Lamp"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               lamp = context.lamp
+               
+               layout.itemR(lamp, "type", expand=True)
+               
+               split = layout.split()
+               
+               col = split.column()
+               sub = col.column()
+               sub.itemR(lamp, "color", text="")
+               sub.itemR(lamp, "energy")
+
+               if lamp.type in ('POINT', 'SPOT'):
+                       sub.itemL(text="Falloff:")
+                       sub.itemR(lamp, "falloff_type", text="")
+                       sub.itemR(lamp, "distance")
+
+                       if lamp.falloff_type == 'LINEAR_QUADRATIC_WEIGHTED':
+                               col.itemL(text="Attenuation Factors:")
+                               sub = col.column(align=True)
+                               sub.itemR(lamp, "linear_attenuation", slider=True, text="Linear")
+                               sub.itemR(lamp, "quadratic_attenuation", slider=True, text="Quadratic")
+                       
+                       col.itemR(lamp, "sphere")
+                       
+               if lamp.type == 'AREA':
+                       col.itemR(lamp, "distance")
+                       col.itemR(lamp, "gamma")
+       
+               col = split.column()
+               col.itemR(lamp, "negative")
+               col.itemR(lamp, "layer", text="This Layer Only")
+               col.itemR(lamp, "specular")
+               col.itemR(lamp, "diffuse")      
+
+class DATA_PT_sunsky(DataButtonsPanel):
+       __label__ = "Sun/Sky"
+       
+       def poll(self, context):
+               lamp = context.lamp
+               return (lamp and lamp.type == 'SUN')
+
+       def draw(self, context):
+               layout = self.layout
+               
+               lamp = context.lamp.sky
+
+               row = layout.row()
+               row.itemR(lamp, "sky")
+               row.itemR(lamp, "atmosphere")
+               
+               row = layout.row()
+               row.active = lamp.sky or lamp.atmosphere
+               row.itemR(lamp, "atmosphere_turbidity", text="Turbidity")
+                       
+               split = layout.split()
+               
+               col = split.column()
+               col.active = lamp.sky
+               col.itemL(text="Blend Mode:")
+               sub = col.column(align=True)
+               sub.itemR(lamp, "sky_blend_type", text="")
+               sub.itemR(lamp, "sky_blend", text="Factor")
+               
+               col.itemL(text="Color Space:")
+               sub = col.column(align=True)
+               sub.itemR(lamp, "sky_color_space", text="")
+               sub.itemR(lamp, "sky_exposure", text="Exposure")
+                       
+               col = split.column()
+               col.active = lamp.sky
+               col.itemL(text="Horizon:")
+               sub = col.column(align=True)
+               sub.itemR(lamp, "horizon_brightness", text="Brightness")
+               sub.itemR(lamp, "spread", text="Spread")
+               
+               col.itemL(text="Sun:")
+               sub = col.column(align=True)
+               sub.itemR(lamp, "sun_brightness", text="Brightness")
+               sub.itemR(lamp, "sun_size", text="Size")
+               sub.itemR(lamp, "backscattered_light", slider=True,text="Back Light")
+               
+               layout.itemS()
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.active = lamp.atmosphere
+               col.itemL(text="Sun:")
+               col.itemR(lamp, "sun_intensity", text="Intensity")
+               col.itemL(text="Scale Distance:")
+               col.itemR(lamp, "atmosphere_distance_factor", text="Distance")
+                       
+               col = split.column()
+               col.active = lamp.atmosphere
+               col.itemL(text="Scattering:")
+               sub = col.column(align=True)
+               sub.itemR(lamp, "atmosphere_inscattering", slider=True, text="Inscattering")
+               sub.itemR(lamp, "atmosphere_extinction", slider=True ,text="Extinction")
+               
+class DATA_PT_shadow(DataButtonsPanel):
+       __label__ = "Shadow"
+       
+       def poll(self, context):
+               lamp = context.lamp
+               return (lamp and lamp.type in ('POINT','SUN', 'SPOT', 'AREA'))
+
+       def draw(self, context):
+               layout = self.layout
+               
+               lamp = context.lamp
+
+               layout.itemR(lamp, "shadow_method", expand=True)
+               
+               if lamp.shadow_method != 'NOSHADOW':
+                       split = layout.split()
+                       
+                       col = split.column()
+                       col.itemR(lamp, "shadow_color", text="")
+                       
+                       col = split.column()
+                       col.itemR(lamp, "shadow_layer", text="This Layer Only")
+                       col.itemR(lamp, "only_shadow")
+               
+               if lamp.shadow_method == 'RAY_SHADOW':
+                       col = layout.column()
+                       col.itemL(text="Sampling:")
+                       col.row().itemR(lamp, "shadow_ray_sampling_method", expand=True)
+                               
+                       if lamp.type in ('POINT', 'SUN', 'SPOT'):
+                               split = layout.split()
+                               
+                               col = split.column()
+                               col.itemR(lamp, "shadow_soft_size", text="Soft Size")
+                               
+                               col.itemR(lamp, "shadow_ray_samples", text="Samples")
+                               if lamp.shadow_ray_sampling_method == 'ADAPTIVE_QMC':
+                                       col.itemR(lamp, "shadow_adaptive_threshold", text="Threshold")
+                               col = split.column()
+                                               
+                       elif lamp.type == 'AREA':
+                               split = layout.split()
+                               
+                               col = split.column()
+                               sub = split.column(align=True)
+                               if lamp.shape == 'SQUARE':
+                                       col.itemR(lamp, "shadow_ray_samples_x", text="Samples")
+                               elif lamp.shape == 'RECTANGLE':
+                                       col.itemR(lamp, "shadow_ray_samples_x", text="Samples X")
+                                       col.itemR(lamp, "shadow_ray_samples_y", text="Samples Y")
+                                       
+                               if lamp.shadow_ray_sampling_method == 'ADAPTIVE_QMC':
+                                       col.itemR(lamp, "shadow_adaptive_threshold", text="Threshold")
+                                       
+                               elif lamp.shadow_ray_sampling_method == 'CONSTANT_JITTERED':
+                                       sub.itemR(lamp, "umbra")
+                                       sub.itemR(lamp, "dither")
+                                       sub.itemR(lamp, "jitter")       
+
+               if lamp.shadow_method == 'BUFFER_SHADOW':
+                       col = layout.column()
+                       col.itemL(text="Buffer Type:")
+                       col.row().itemR(lamp, "shadow_buffer_type", expand=True)
+
+                       if lamp.shadow_buffer_type in ('REGULAR', 'HALFWAY'):
+                               split = layout.split()
+                               
+                               col = split.column()
+                               col.itemL(text="Filter Type:")
+                               col.itemR(lamp, "shadow_filter_type", text="")
+                               sub = col.column(align=True)
+                               sub.itemR(lamp, "shadow_buffer_soft", text="Soft")
+                               sub.itemR(lamp, "shadow_buffer_bias", text="Bias")
+                               
+                               col = split.column()
+                               col.itemL(text="Sample Buffers:")
+                               col.itemR(lamp, "shadow_sample_buffers", text="")
+                               sub = col.column(align=True)
+                               sub.itemR(lamp, "shadow_buffer_size", text="Size")
+                               sub.itemR(lamp, "shadow_buffer_samples", text="Samples")
+                               
+                       elif lamp.shadow_buffer_type == 'IRREGULAR':
+                               layout.itemR(lamp, "shadow_buffer_bias", text="Bias")
+                       
+                       row = layout.row()
+                       row.itemR(lamp, "auto_clip_start", text="Autoclip Start")
+                       sub = row.row()
+                       sub.active = not lamp.auto_clip_start
+                       sub.itemR(lamp, "shadow_buffer_clip_start", text="Clip Start")
+
+                       row = layout.row()
+                       row.itemR(lamp, "auto_clip_end", text="Autoclip End")
+                       sub = row.row()
+                       sub.active = not lamp.auto_clip_end
+                       sub.itemR(lamp, "shadow_buffer_clip_end", text=" Clip End")
+
+class DATA_PT_area(DataButtonsPanel):
+       __label__ = "Area Shape"
+       
+       def poll(self, context):
+               lamp = context.lamp
+               return (lamp and lamp.type == 'AREA')
+
+       def draw(self, context):
+               layout = self.layout
+               
+               lamp = context.lamp
+
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(lamp, "shape", text="")
+               
+               sub = col.column(align=True)
+               if (lamp.shape == 'SQUARE'):
+                       sub.itemR(lamp, "size")
+               elif (lamp.shape == 'RECTANGLE'):
+                       sub.itemR(lamp, "size", text="Size X")
+                       sub.itemR(lamp, "size_y", text="Size Y")
+               
+               col = split.column()
+
+class DATA_PT_spot(DataButtonsPanel):
+       __label__ = "Spot Shape"
+       
+       def poll(self, context):
+               lamp = context.lamp
+               return (lamp and lamp.type == 'SPOT')
+
+       def draw(self, context):
+               layout = self.layout
+               
+               lamp = context.lamp
+
+               split = layout.split()
+               
+               col = split.column()
+               sub = col.column(align=True)
+               sub.itemR(lamp, "spot_size", text="Size")
+               sub.itemR(lamp, "spot_blend", text="Blend")
+               col.itemR(lamp, "square")
+               
+               col = split.column()
+               col.itemR(lamp, "halo")
+               sub = col.column(align=True)
+               sub.active = lamp.halo
+               sub.itemR(lamp, "halo_intensity", text="Intensity")
+               if lamp.shadow_method == 'BUFFER_SHADOW':
+                       sub.itemR(lamp, "halo_step", text="Step")
+
+class DATA_PT_falloff_curve(DataButtonsPanel):
+       __label__ = "Falloff Curve"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               lamp = context.lamp
+
+               return (lamp and lamp.type in ('POINT', 'SPOT') and lamp.falloff_type == 'CUSTOM_CURVE')
+
+       def draw(self, context):
+               lamp = context.lamp
+
+               self.layout.template_curve_mapping(lamp.falloff_curve)
+
+bpy.types.register(DATA_PT_context_lamp)
+bpy.types.register(DATA_PT_preview)
+bpy.types.register(DATA_PT_lamp)
+bpy.types.register(DATA_PT_falloff_curve)
+bpy.types.register(DATA_PT_area)
+bpy.types.register(DATA_PT_spot)
+bpy.types.register(DATA_PT_shadow)
+bpy.types.register(DATA_PT_sunsky)
diff --git a/release/ui/buttons_data_lattice.py b/release/ui/buttons_data_lattice.py
new file mode 100644 (file)
index 0000000..895c1a6
--- /dev/null
@@ -0,0 +1,56 @@
+
+import bpy
+
+class DataButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "data"
+       
+       def poll(self, context):
+               return (context.lattice)
+       
+class DATA_PT_context_lattice(DataButtonsPanel):
+       __show_header__ = False
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               lat = context.lattice
+               space = context.space_data
+
+               split = layout.split(percentage=0.65)
+
+               if ob:
+                       split.template_ID(ob, "data")
+                       split.itemS()
+               elif lat:
+                       split.template_ID(space, "pin_id")
+                       split.itemS()
+
+class DATA_PT_lattice(DataButtonsPanel):
+       __label__ = "Lattice"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               lat = context.lattice
+
+               row = layout.row()
+               row.itemR(lat, "points_u")
+               row.itemR(lat, "interpolation_type_u", expand=True)
+                       
+               row = layout.row()
+               row.itemR(lat, "points_v")
+               row.itemR(lat, "interpolation_type_v", expand=True)
+                       
+               row = layout.row()
+               row.itemR(lat, "points_w")
+               row.itemR(lat, "interpolation_type_w", expand=True)
+                       
+               row = layout.row()
+               row.itemO("lattice.make_regular")
+               row.itemR(lat, "outside")
+
+bpy.types.register(DATA_PT_context_lattice)
+bpy.types.register(DATA_PT_lattice)
diff --git a/release/ui/buttons_data_mesh.py b/release/ui/buttons_data_mesh.py
new file mode 100644 (file)
index 0000000..33b3960
--- /dev/null
@@ -0,0 +1,203 @@
+
+import bpy
+
+class DataButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "data"
+       
+       def poll(self, context):
+               return (context.mesh)
+
+class DATA_PT_context_mesh(DataButtonsPanel):
+       __show_header__ = False
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               mesh = context.mesh
+               space = context.space_data
+
+               split = layout.split(percentage=0.65)
+
+               if ob:
+                       split.template_ID(ob, "data")
+                       split.itemS()
+               elif mesh:
+                       split.template_ID(space, "pin_id")
+                       split.itemS()
+
+class DATA_PT_normals(DataButtonsPanel):
+       __label__ = "Normals"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               mesh = context.mesh
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(mesh, "autosmooth")
+               sub = col.column()
+               sub.active = mesh.autosmooth
+               sub.itemR(mesh, "autosmooth_angle", text="Angle")
+               
+               col = split.column()
+               col.itemR(mesh, "vertex_normal_flip")
+               col.itemR(mesh, "double_sided")
+
+class DATA_PT_vertex_groups(DataButtonsPanel):
+       __label__ = "Vertex Groups"
+       
+       def poll(self, context):
+               return (context.object and context.object.type in ('MESH', 'LATTICE'))
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+
+               row = layout.row()
+               row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index")
+
+               col = row.column(align=True)
+               col.itemO("object.vertex_group_add", icon='ICON_ZOOMIN', text="")
+               col.itemO("object.vertex_group_remove", icon='ICON_ZOOMOUT', text="")
+
+               col.itemO("object.vertex_group_copy", icon='ICON_BLANK1', text="")
+               if ob.data.users > 1:
+                       col.itemO("object.vertex_group_copy_to_linked", icon='ICON_BLANK1', text="")
+
+               group = ob.active_vertex_group
+               if group:
+                       row = layout.row()
+                       row.itemR(group, "name")
+
+               if ob.mode == 'EDIT':
+                       row = layout.row()
+                       
+                       sub = row.row(align=True)
+                       sub.itemO("object.vertex_group_assign", text="Assign")
+                       sub.itemO("object.vertex_group_remove_from", text="Remove")
+                       
+                       sub = row.row(align=True)
+                       sub.itemO("object.vertex_group_select", text="Select")
+                       sub.itemO("object.vertex_group_deselect", text="Deselect")
+
+                       layout.itemR(context.tool_settings, "vertex_group_weight", text="Weight")
+
+class DATA_PT_shape_keys(DataButtonsPanel):
+       __label__ = "Shape Keys"
+       
+       def poll(self, context):
+               return (context.object and context.object.type in ('MESH', 'LATTICE'))
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               key = ob.data.shape_keys
+               kb = ob.active_shape_key
+
+               row = layout.row()
+               row.template_list(key, "keys", ob, "active_shape_key_index", rows=2)
+
+               col = row.column()
+
+               subcol = col.column(align=True)
+               subcol.itemO("object.shape_key_add", icon='ICON_ZOOMIN', text="")
+               subcol.itemO("object.shape_key_remove", icon='ICON_ZOOMOUT', text="")
+
+               if kb:
+                       col.itemS()
+
+                       subcol = col.column(align=True)
+                       subcol.itemR(ob, "shape_key_lock", icon='ICON_UNPINNED', text="")
+                       subcol.itemR(kb, "mute", icon='ICON_MUTE_IPO_ON', text="")
+
+                       if key.relative:
+                               row = layout.row()
+                               row.itemR(key, "relative")
+                               row.itemL()
+
+                               row = layout.row()
+                               row.itemR(kb, "name")
+
+                               if ob.active_shape_key_index != 0:
+                                       
+                                       row = layout.row()
+                                       row.enabled = ob.shape_key_lock == False
+                                       row.itemR(kb, "value", slider=True)
+                                       
+                                       split = layout.split()
+                                       sub = split.column(align=True)
+                                       sub.enabled = ob.shape_key_lock == False
+                                       sub.itemL(text="Range:")
+                                       sub.itemR(kb, "slider_min", text="Min")
+                                       sub.itemR(kb, "slider_max", text="Max")
+                                       
+                                       sub = split.column()
+                                       sub.itemL(text="Blend:")
+                                       sub.item_pointerR(kb, "vertex_group", ob, "vertex_groups", text="")
+                                       sub.item_pointerR(kb, "relative_key", key, "keys", text="")
+                                       
+                       else:
+                               row = layout.row()
+                               row.itemR(key, "relative")
+                               row.itemR(key, "slurph")
+
+                               layout.itemR(kb, "name")
+
+               if ob.mode == 'EDIT':
+                       layout.enabled = False
+
+class DATA_PT_uv_texture(DataButtonsPanel):
+       __label__ = "UV Texture"
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               me = context.mesh
+
+               row = layout.row()
+               col = row.column()
+               
+               col.template_list(me, "uv_textures", me, "active_uv_texture_index", rows=2)
+
+               col = row.column(align=True)
+               col.itemO("mesh.uv_texture_add", icon='ICON_ZOOMIN', text="")
+               col.itemO("mesh.uv_texture_remove", icon='ICON_ZOOMOUT', text="")
+
+               lay = me.active_uv_texture
+               if lay:
+                       layout.itemR(lay, "name")
+
+class DATA_PT_vertex_colors(DataButtonsPanel):
+       __label__ = "Vertex Colors"
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               me = context.mesh
+
+               row = layout.row()
+               col = row.column()
+
+               col.template_list(me, "vertex_colors", me, "active_vertex_color_index", rows=2)
+
+               col = row.column(align=True)
+               col.itemO("mesh.vertex_color_add", icon='ICON_ZOOMIN', text="")
+               col.itemO("mesh.vertex_color_remove", icon='ICON_ZOOMOUT', text="")
+
+               lay = me.active_vertex_color
+               if lay:
+                       layout.itemR(lay, "name")
+
+bpy.types.register(DATA_PT_context_mesh)
+bpy.types.register(DATA_PT_normals)
+bpy.types.register(DATA_PT_vertex_groups)
+bpy.types.register(DATA_PT_shape_keys)
+bpy.types.register(DATA_PT_uv_texture)
+bpy.types.register(DATA_PT_vertex_colors)
diff --git a/release/ui/buttons_data_metaball.py b/release/ui/buttons_data_metaball.py
new file mode 100644 (file)
index 0000000..88c0066
--- /dev/null
@@ -0,0 +1,112 @@
+import bpy
+
+class DataButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "data"
+       
+       def poll(self, context):
+               return (context.meta_ball)
+
+class DATA_PT_context_metaball(DataButtonsPanel):
+       __show_header__ = False
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               mball = context.meta_ball
+               space = context.space_data
+
+               split = layout.split(percentage=0.65)
+
+               if ob:
+                       split.template_ID(ob, "data")
+                       split.itemS()
+               elif mball:
+                       split.template_ID(space, "pin_id")
+                       split.itemS()
+
+class DATA_PT_metaball(DataButtonsPanel):
+       __label__ = "Metaball"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               mball = context.meta_ball
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Resolution:")
+               sub = col.column(align=True)
+               sub.itemR(mball, "wire_size", text="View")
+               sub.itemR(mball, "render_size", text="Render")  
+               
+               col = split.column()
+               col.itemL(text="Settings:")
+               col.itemR(mball, "threshold", text="Threshold")
+
+               layout.itemL(text="Update:")
+               layout.itemR(mball, "flag", expand=True)
+
+class DATA_PT_metaball_element(DataButtonsPanel):
+       __label__ = "Active Element"
+       
+       def poll(self, context):
+               return (context.meta_ball and context.meta_ball.active_element)
+
+       def draw(self, context):
+               layout = self.layout
+               
+               metaelem = context.meta_ball.active_element
+               
+               split = layout.split(percentage=0.3)
+               split.itemL(text="Type:")       
+               split.itemR(metaelem, "type", text="")
+               
+               split = layout.split()
+                       
+               col = split.column()
+               col.itemL(text="Settings:")
+               col.itemR(metaelem, "stiffness", text="Stiffness")
+               col.itemR(metaelem, "negative", text="Negative")
+               col.itemR(metaelem, "hide", text="Hide")
+               
+               if metaelem.type == 'BALL':
+               
+                       col = split.column(align=True)
+                       
+               elif metaelem.type == 'CUBE':
+               
+                       col = split.column(align=True)
+                       col.itemL(text="Size:") 
+                       col.itemR(metaelem, "size_x", text="X")
+                       col.itemR(metaelem, "size_y", text="Y")
+                       col.itemR(metaelem, "size_z", text="Z")
+                       
+               elif metaelem.type == 'TUBE':
+               
+                       col = split.column(align=True)
+                       col.itemL(text="Size:") 
+                       col.itemR(metaelem, "size_x", text="X")
+                       
+               elif metaelem.type == 'PLANE':
+                       
+                       col = split.column(align=True)
+                       col.itemL(text="Size:") 
+                       col.itemR(metaelem, "size_x", text="X")
+                       col.itemR(metaelem, "size_y", text="Y")
+                       
+               elif metaelem.type == 'ELLIPSOID':
+                       
+                       col = split.column(align=True)
+                       col.itemL(text="Size:") 
+                       col.itemR(metaelem, "size_x", text="X")
+                       col.itemR(metaelem, "size_y", text="Y")
+                       col.itemR(metaelem, "size_z", text="Z")
+               
+
+bpy.types.register(DATA_PT_context_metaball)
+bpy.types.register(DATA_PT_metaball)
+bpy.types.register(DATA_PT_metaball_element)
diff --git a/release/ui/buttons_data_modifier.py b/release/ui/buttons_data_modifier.py
new file mode 100644 (file)
index 0000000..754e8ce
--- /dev/null
@@ -0,0 +1,449 @@
+
+import bpy
+
+class DataButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "modifier"
+       
+class DATA_PT_modifiers(DataButtonsPanel):
+       __label__ = "Modifiers"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+
+               row = layout.row()
+               row.item_menu_enumO("object.modifier_add", "type")
+               row.itemL()
+
+               for md in ob.modifiers:
+                       box = layout.template_modifier(md)
+                       if box:
+                               # match enum type to our functions, avoids a lookup table.
+                               getattr(self, md.type)(box, ob, md)
+       
+       # the mt.type enum is (ab)used for a lookup on function names
+       # ...to avoid lengthy if statements
+       # so each type must have a function here.
+
+       def ARMATURE(self, layout, ob, md):
+               layout.itemR(md, "object")
+               
+               split = layout.split(percentage=0.5)
+               split.itemL(text="Vertex Group:")
+               sub = split.split(percentage=0.7)
+               sub.item_pointerR(md, "vertex_group", ob, "vertex_groups", text="")
+               subsub = sub.row()
+               subsub.active = md.vertex_group
+               subsub.itemR(md, "invert")
+               
+               layout.itemS()
+               
+               split = layout.split()
+
+               col = split.column()
+               col.itemL(text="Bind To:")
+               col.itemR(md, "use_vertex_groups", text="Vertex Groups")
+               col.itemR(md, "use_bone_envelopes", text="Bone Envelopes")
+               
+               col = split.column()
+               col.itemL(text="Deformation:")
+               col.itemR(md, "quaternion")
+               col.itemR(md, "multi_modifier")
+               
+       def ARRAY(self, layout, ob, md):
+               layout.itemR(md, "fit_type")
+               if md.fit_type == 'FIXED_COUNT':
+                       layout.itemR(md, "count")
+               elif md.fit_type == 'FIT_LENGTH':
+                       layout.itemR(md, "length")
+               elif md.fit_type == 'FIT_CURVE':
+                       layout.itemR(md, "curve")
+
+               layout.itemS()
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(md, "constant_offset")
+               sub = col.column()
+               sub.active = md.constant_offset
+               sub.itemR(md, "constant_offset_displacement", text="")
+
+               col.itemS()
+
+               col.itemR(md, "merge_adjacent_vertices", text="Merge")
+               sub = col.column()
+               sub.active = md.merge_adjacent_vertices
+               sub.itemR(md, "merge_end_vertices", text="First Last")
+               sub.itemR(md, "merge_distance", text="Distance")
+               
+               col = split.column()
+               col.itemR(md, "relative_offset")
+               sub = col.column()
+               sub.active = md.relative_offset
+               sub.itemR(md, "relative_offset_displacement", text="")
+
+               col.itemS()
+
+               col.itemR(md, "add_offset_object")
+               sub = col.column()
+               sub.active = md.add_offset_object
+               sub.itemR(md, "offset_object", text="")
+
+               layout.itemS()
+               
+               col = layout.column()
+               col.itemR(md, "start_cap")
+               col.itemR(md, "end_cap")
+       
+       def BEVEL(self, layout, ob, md):
+               row = layout.row()
+               row.itemR(md, "width")
+               row.itemR(md, "only_vertices")
+               
+               layout.itemL(text="Limit Method:")
+               layout.row().itemR(md, "limit_method", expand=True)
+               if md.limit_method == 'ANGLE':
+                       layout.itemR(md, "angle")
+               elif md.limit_method == 'WEIGHT':
+                       layout.row().itemR(md, "edge_weight_method", expand=True)
+                       
+       def BOOLEAN(self, layout, ob, md):
+               layout.itemR(md, "operation")
+               layout.itemR(md, "object")
+               
+       def BUILD(self, layout, ob, md):
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(md, "start")
+               col.itemR(md, "length")
+
+               col = split.column()
+               col.itemR(md, "randomize")
+               sub = col.column()
+               sub.active = md.randomize
+               sub.itemR(md, "seed")
+
+       def CAST(self, layout, ob, md):
+               layout.itemR(md, "cast_type")
+               layout.itemR(md, "object")
+               if md.object:
+                       layout.itemR(md, "use_transform")
+               
+               flow = layout.column_flow()
+               flow.itemR(md, "x")
+               flow.itemR(md, "y")
+               flow.itemR(md, "z")
+               flow.itemR(md, "factor")
+               flow.itemR(md, "radius")
+               flow.itemR(md, "size")
+
+               layout.itemR(md, "from_radius")
+               
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
+               
+       def CLOTH(self, layout, ob, md):
+               layout.itemL(text="See Cloth panel.")
+               
+       def COLLISION(self, layout, ob, md):
+               layout.itemL(text="See Collision panel.")
+               
+       def CURVE(self, layout, ob, md):
+               layout.itemR(md, "object")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
+               layout.itemR(md, "deform_axis")
+               
+       def DECIMATE(self, layout, ob, md):
+               layout.itemR(md, "ratio")
+               layout.itemR(md, "face_count")
+               
+       def DISPLACE(self, layout, ob, md):
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
+               layout.itemR(md, "texture")
+               layout.itemR(md, "midlevel")
+               layout.itemR(md, "strength")
+               layout.itemR(md, "direction")
+               layout.itemR(md, "texture_coordinates")
+               if md.texture_coordinates == 'OBJECT':
+                       layout.itemR(md, "texture_coordinate_object", text="Object")
+               elif md.texture_coordinates == 'UV' and ob.type == 'MESH':
+                       layout.item_pointerR(md, "uv_layer", ob.data, "uv_textures")
+       
+       def EDGE_SPLIT(self, layout, ob, md):
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(md, "use_edge_angle", text="Edge Angle")
+               sub = col.column()
+               sub.active = md.use_edge_angle
+               sub.itemR(md, "split_angle")
+               
+               col = split.column()
+               col.itemR(md, "use_sharp", text="Sharp Edges")
+               
+       def EXPLODE(self, layout, ob, md):
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
+               layout.itemR(md, "protect")
+
+               flow = layout.column_flow(2)
+               flow.itemR(md, "split_edges")
+               flow.itemR(md, "unborn")
+               flow.itemR(md, "alive")
+               flow.itemR(md, "dead")
+
+               layout.itemO("object.explode_refresh", text="Refresh");
+               
+       def FLUID_SIMULATION(self, layout, ob, md):
+               layout.itemL(text="See Fluid panel.")
+               
+       def HOOK(self, layout, ob, md):
+               col = layout.column()
+               col.itemR(md, "object")
+               if md.object and md.object.type == 'ARMATURE':
+                       layout.item_pointerR(md, "subtarget", md.object.data, "bones", text="Bone")
+               
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
+
+               split = layout.split()
+               split.itemR(md, "falloff")
+               split.itemR(md, "force", slider=True)
+
+               layout.itemS()
+
+               row = layout.row()
+               row.itemO("object.hook_reset", text="Reset")
+               row.itemO("object.hook_recenter", text="Recenter")
+
+               if ob.mode == 'EDIT':
+                       row = layout.row()
+                       row.itemO("object.hook_select", text="Select")
+                       row.itemO("object.hook_assign", text="Assign")
+               
+       def LATTICE(self, layout, ob, md):
+               layout.itemR(md, "object")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
+               
+       def MASK(self, layout, ob, md):
+               layout.itemR(md, "mode")
+               if md.mode == 'ARMATURE':
+                       layout.itemR(md, "armature")
+               elif md.mode == 'VERTEX_GROUP':
+                       layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
+               layout.itemR(md, "inverse")
+               
+       def MESH_DEFORM(self, layout, ob, md):
+               layout.itemR(md, "object")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
+               layout.itemR(md, "invert")
+
+               layout.itemS()
+               
+               if md.is_bound:
+                       layout.itemO("object.meshdeform_bind", text="Unbind")
+               else:
+                       layout.itemO("object.meshdeform_bind", text="Bind")
+                       row = layout.row()
+                       row.itemR(md, "precision")
+                       row.itemR(md, "dynamic")
+               
+       def MIRROR(self, layout, ob, md):
+               layout.itemR(md, "merge_limit")
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(md, "x")
+               col.itemR(md, "y")
+               col.itemR(md, "z")
+               
+               col = split.column()
+               col.itemL(text="Textures:")
+               col.itemR(md, "mirror_u")
+               col.itemR(md, "mirror_v")
+               
+               col = split.column()
+               col.itemR(md, "clip", text="Do Clipping")
+               col.itemR(md, "mirror_vertex_groups", text="Vertex Group")
+               
+               layout.itemR(md, "mirror_object")
+               
+       def MULTIRES(self, layout, ob, md):
+               layout.itemR(md, "subdivision_type")
+               
+               row = layout.row()
+               row.itemO("object.multires_subdivide", text="Subdivide")
+               row.itemO("object.multires_higher_levels_delete", text="Delete Higher")
+
+               layout.itemR(md, "level")
+       
+       def PARTICLE_INSTANCE(self, layout, ob, md):
+               layout.itemR(md, "object")
+               layout.itemR(md, "particle_system_number")
+               
+               flow = layout.column_flow()
+               flow.itemR(md, "normal")
+               flow.itemR(md, "children")
+               flow.itemR(md, "size")
+               flow.itemR(md, "path")
+               if md.path:
+                       flow.itemR(md, "keep_shape")
+               flow.itemR(md, "unborn")
+               flow.itemR(md, "alive")
+               flow.itemR(md, "dead")
+               flow.itemL(md, "")
+               if md.path:
+                       flow.itemR(md, "axis", text="")
+               
+               if md.path:
+                       row = layout.row()
+                       row.itemR(md, "position", slider=True)
+                       row.itemR(md, "random_position", text = "Random", slider=True)
+               
+       def PARTICLE_SYSTEM(self, layout, ob, md):
+               layout.itemL(text="See Particle panel.")
+               
+       def SHRINKWRAP(self, layout, ob, md):
+               layout.itemR(md, "target")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
+               layout.itemR(md, "offset")
+               layout.itemR(md, "subsurf_levels")
+               layout.itemR(md, "mode")
+               if md.mode == 'PROJECT':
+                       layout.itemR(md, "subsurf_levels")
+                       layout.itemR(md, "auxiliary_target")
+               
+                       row = layout.row()
+                       row.itemR(md, "x")
+                       row.itemR(md, "y")
+                       row.itemR(md, "z")
+               
+                       flow = layout.column_flow()
+                       flow.itemR(md, "negative")
+                       flow.itemR(md, "positive")
+                       flow.itemR(md, "cull_front_faces")
+                       flow.itemR(md, "cull_back_faces")
+               elif md.mode == 'NEAREST_SURFACEPOINT':
+                       layout.itemR(md, "keep_above_surface")
+               
+       def SIMPLE_DEFORM(self, layout, ob, md):
+               layout.itemR(md, "mode")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
+               layout.itemR(md, "origin")
+               layout.itemR(md, "relative")
+               layout.itemR(md, "factor")
+               layout.itemR(md, "limits")
+               if md.mode in ('TAPER', 'STRETCH'):
+                       layout.itemR(md, "lock_x_axis")
+                       layout.itemR(md, "lock_y_axis")
+                       
+       def SMOKE(self, layout, ob, md):
+               layout.itemL(text="See Smoke panel.")
+       
+       def SMOOTH(self, layout, ob, md):
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(md, "x")
+               col.itemR(md, "y")
+               col.itemR(md, "z")
+               
+               col = split.column()
+               col.itemR(md, "factor")
+               col.itemR(md, "repeat")
+               
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
+               
+       def SOFT_BODY(self, layout, ob, md):
+               layout.itemL(text="See Soft Body panel.")
+       
+       def SUBSURF(self, layout, ob, md):
+               layout.row().itemR(md, "subdivision_type", expand=True)
+               
+               flow = layout.column_flow()
+               flow.itemR(md, "levels", text="Preview")
+               flow.itemR(md, "render_levels", text="Render")
+               flow.itemR(md, "optimal_draw", text="Optimal Display")
+               flow.itemR(md, "subsurf_uv")
+
+       def SURFACE(self, layout, ob, md):
+               layout.itemL(text="See Fields panel.")
+       
+       def UV_PROJECT(self, layout, ob, md):
+               if ob.type == 'MESH':
+                       layout.item_pointerR(md, "uv_layer", ob.data, "uv_textures")
+                       layout.itemR(md, "image")
+                       layout.itemR(md, "override_image")
+
+                       split = layout.split()
+
+                       col = split.column()
+                       col.itemL(text="Aspect Ratio:")
+
+                       sub = col.column(align=True)
+                       sub.itemR(md, "horizontal_aspect_ratio", text="Horizontal")
+                       sub.itemR(md, "vertical_aspect_ratio", text="Vertical")
+
+                       col = split.column()
+                       col.itemL(text="Projectors:")
+
+                       sub = col.column(align=True)
+                       sub.itemR(md, "num_projectors", text="Number")
+                       for proj in md.projectors:
+                               sub.itemR(proj, "object", text="")
+               
+       def WAVE(self, layout, ob, md):
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Motion:")
+               col.itemR(md, "x")
+               col.itemR(md, "y")
+               col.itemR(md, "cyclic")
+               
+               col = split.column()
+               col.itemR(md, "normals")
+               sub = col.column()
+               sub.active = md.normals
+               sub.itemR(md, "x_normal", text="X")
+               sub.itemR(md, "y_normal", text="Y")
+               sub.itemR(md, "z_normal", text="Z")
+               
+               split = layout.split()
+
+               col = split.column()
+               col.itemL(text="Time:")
+               sub = col.column(align=True)
+               sub.itemR(md, "time_offset", text="Offset")
+               sub.itemR(md, "lifetime", text="Life")
+               col.itemR(md, "damping_time", text="Damping")
+               
+               col = split.column()
+               col.itemL(text="Position:")
+               sub = col.column(align=True)
+               sub.itemR(md, "start_position_x", text="X")
+               sub.itemR(md, "start_position_y", text="Y")
+               col.itemR(md, "falloff_radius", text="Falloff")
+               
+               layout.itemS()
+               
+               layout.itemR(md, "start_position_object")
+               layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
+               layout.itemR(md, "texture")
+               layout.itemR(md, "texture_coordinates")
+               if md.texture_coordinates == 'MAP_UV' and ob.type == 'MESH':
+                       layout.item_pointerR(md, "uv_layer", ob.data, "uv_textures")
+               elif md.texture_coordinates == 'OBJECT':
+                       layout.itemR(md, "texture_coordinates_object")
+               
+               layout.itemS()
+               
+               flow = layout.column_flow()
+               flow.itemR(md, "speed", slider=True)
+               flow.itemR(md, "height", slider=True)
+               flow.itemR(md, "width", slider=True)
+               flow.itemR(md, "narrowness", slider=True)
+
+bpy.types.register(DATA_PT_modifiers)
diff --git a/release/ui/buttons_data_text.py b/release/ui/buttons_data_text.py
new file mode 100644 (file)
index 0000000..d0e7ea0
--- /dev/null
@@ -0,0 +1,183 @@
+
+import bpy
+
+class DataButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "data"
+       
+       def poll(self, context):
+               return (context.object and context.object.type == 'TEXT' and context.curve)
+
+class DATA_PT_context_text(DataButtonsPanel):
+       __show_header__ = False
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               curve = context.curve
+               space = context.space_data
+
+               split = layout.split(percentage=0.65)
+
+               if ob:
+                       split.template_ID(ob, "data")
+                       split.itemS()
+               elif curve:
+                       split.template_ID(space, "pin_id")
+                       split.itemS()
+
+class DATA_PT_shape_text(DataButtonsPanel):
+       __label__ = "Shape Text"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               curve = context.curve
+               space = context.space_data
+
+               layout.itemR(curve, "curve_2d")                 
+                                                       
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Caps:")
+               row = col.row()
+               row .itemR(curve, "front")
+               row .itemR(curve, "back")
+               # col = split.column()
+               col.itemL(text="Textures:")
+               col.itemR(curve, "uv_orco")
+               col.itemR(curve, "auto_texspace")
+                       
+               col = split.column()    
+               col.itemL(text="Resolution:")
+               sub = col.column(align=True)
+               sub.itemR(curve, "resolution_u", text="Preview U")
+               sub.itemR(curve, "render_resolution_u", text="Render U")
+               
+               # resolution_v is not used for text
+               
+               sub = col.column(align=True)
+               col.itemL(text="Display:")
+               col.itemR(curve, "fast", text="Fast Editing")
+
+class DATA_PT_geometry_text(DataButtonsPanel):
+       __label__ = "Geometry"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               curve = context.curve
+
+               split = layout.split()
+       
+               col = split.column()
+               col.itemL(text="Modification:")
+               col.itemR(curve, "width")
+               col.itemR(curve, "extrude")
+               col.itemL(text="Taper Object:")
+               col.itemR(curve, "taper_object", text="")
+               
+               col = split.column()
+               col.itemL(text="Bevel:")
+               col.itemR(curve, "bevel_depth", text="Depth")
+               col.itemR(curve, "bevel_resolution", text="Resolution")
+               col.itemL(text="Bevel Object:")
+               col.itemR(curve, "bevel_object", text="")
+
+class DATA_PT_font(DataButtonsPanel):
+       __label__ = "Font"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               text = context.curve
+               char = context.curve.edit_format
+
+               layout.itemR(text, "font")
+               
+               row = layout.row()
+               row.itemR(text, "text_size", text="Size")       
+               row.itemR(text, "shear")
+               
+               split = layout.split()
+               
+               col = split.column()    
+               col.itemL(text="Object Font:")
+               col.itemR(text, "family", text="")
+
+               col = split.column()
+               col.itemL(text="Text on Curve:")
+               col.itemR(text, "text_on_curve", text="")
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Character:")
+               col.itemR(char, "bold")
+               col.itemR(char, "italic")
+               col.itemR(char, "underline")
+#              col.itemR(char, "style")
+#              col.itemR(char, "wrap")
+
+               col = split.column(align=True)
+               col.itemL(text="Underline:")
+               col.itemR(text, "ul_position", text="Position")
+               col.itemR(text, "ul_height", text="Thickness")
+               
+
+class DATA_PT_paragraph(DataButtonsPanel):
+       __label__ = "Paragraph"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               text = context.curve
+
+               layout.itemL(text="Align:")
+               layout.itemR(text, "spacemode", expand=True)
+
+               split = layout.split()
+               
+               col = split.column(align=True)  
+               col.itemL(text="Spacing:")
+               col.itemR(text, "spacing", text="Character")
+               col.itemR(text, "word_spacing", text="Word")
+               col.itemR(text, "line_dist", text="Line")
+
+               col = split.column(align=True)
+               col.itemL(text="Offset:")
+               col.itemR(text, "offset_x", text="X")
+               col.itemR(text, "offset_y", text="Y")
+
+
+class DATA_PT_textboxes(DataButtonsPanel):
+       __label__ = "Text Boxes"
+
+       def draw(self, context):
+               layout = self.layout
+                       
+               text = context.curve
+               
+               for box in text.textboxes:
+                       split = layout.box().split()
+                       
+                       col = split.column(align=True)
+                       col.itemL(text="Dimensions:")
+                       col.itemR(box, "width", text="Width")
+                       col.itemR(box, "height", text="Height")
+               
+                       col = split.column(align=True)  
+                       col.itemL(text="Offset:")
+                       col.itemR(box, "x", text="X")
+                       col.itemR(box, "y", text="Y")
+
+bpy.types.register(DATA_PT_context_text)       
+bpy.types.register(DATA_PT_shape_text) 
+bpy.types.register(DATA_PT_geometry_text)
+bpy.types.register(DATA_PT_font)
+bpy.types.register(DATA_PT_paragraph)
+bpy.types.register(DATA_PT_textboxes)
diff --git a/release/ui/buttons_game.py b/release/ui/buttons_game.py
new file mode 100644 (file)
index 0000000..73ba566
--- /dev/null
@@ -0,0 +1,407 @@
+
+import bpy
+class PhysicsButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "physics"
+
+       def poll(self, context):
+               ob = context.active_object
+               rd = context.scene.render_data
+               return ob and ob.game and (rd.engine == 'BLENDER_GAME')
+
+class PHYSICS_PT_game_physics(PhysicsButtonsPanel):
+       __label__ = "Physics"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.active_object
+               game = ob.game
+               soft = ob.game.soft_body
+
+               layout.itemR(game, "physics_type")
+               layout.itemS()
+               
+               #if game.physics_type == 'DYNAMIC':
+               if game.physics_type in ('DYNAMIC', 'RIGID_BODY'):
+
+                       split = layout.split()
+                       
+                       col = split.column()
+                       col.itemR(game, "actor")
+                       col.itemR(game, "ghost")
+                       col.itemR(ob, "restrict_render", text="Invisible") # out of place but useful
+                       
+                       col = split.column()
+                       col.itemR(game, "material_physics")
+                       col.itemR(game, "rotate_from_normal")
+                       col.itemR(game, "no_sleeping")
+                       
+                       layout.itemS()
+                       
+                       split = layout.split()
+                       
+                       col = split.column()
+                       col.itemL(text="Attributes:")
+                       col.itemR(game, "mass")
+                       col.itemR(game, "radius")
+                       col.itemR(game, "form_factor")
+                       
+                       col = split.column()
+                       sub = col.column()
+                       sub.active = (game.physics_type == 'RIGID_BODY')
+                       sub.itemR(game, "anisotropic_friction")
+                       subsub = sub.column()
+                       subsub.active = game.anisotropic_friction
+                       subsub.itemR(game, "friction_coefficients", text="", slider=True)
+                       
+                       split = layout.split()
+                       
+                       col = split.column()
+                       col.itemL(text="Velocity:")
+                       sub = col.column(align=True)
+                       sub.itemR(game, "minimum_velocity", text="Minimum")
+                       sub.itemR(game, "maximum_velocity", text="Maximum")
+                       
+                       col = split.column()
+                       col.itemL(text="Damping:")
+                       sub = col.column(align=True)
+                       sub.itemR(game, "damping", text="Translation", slider=True)
+                       sub.itemR(game, "rotation_damping", text="Rotation", slider=True)
+                       
+                       layout.itemS()
+                       
+                       split = layout.split()
+                       
+                       col = split.column()
+                       col.itemL(text="Lock Translation:")
+                       col.itemR(game, "lock_x_axis", text="X")
+                       col.itemR(game, "lock_y_axis", text="Y")
+                       col.itemR(game, "lock_z_axis", text="Z")
+                       
+                       col = split.column()
+                       col.itemL(text="Lock Rotation:")
+                       col.itemR(game, "lock_x_rot_axis", text="X")
+                       col.itemR(game, "lock_y_rot_axis", text="Y")
+                       col.itemR(game, "lock_z_rot_axis", text="Z")
+               
+               elif game.physics_type == 'SOFT_BODY':
+
+                       col = layout.column()
+                       col.itemR(game, "actor")
+                       col.itemR(game, "ghost")
+                       col.itemR(ob, "restrict_render", text="Invisible")
+                       
+                       layout.itemS()
+                       
+                       split = layout.split()
+                       
+                       col = split.column()
+                       col.itemL(text="Attributes:")
+                       col.itemR(game, "mass")
+                       col.itemR(soft, "welding")
+                       col.itemR(soft, "position_iterations")
+                       col.itemR(soft, "linstiff", slider=True)
+                       col.itemR(soft, "dynamic_friction", slider=True)
+                       col.itemR(soft, "margin", slider=True)
+                       col.itemR(soft, "bending_const", text="Bending Constraints")
+
+                       col = split.column()
+                       col.itemR(soft, "shape_match")
+                       sub = col.column()
+                       sub.active = soft.shape_match
+                       sub.itemR(soft, "threshold", slider=True)
+                       
+                       col.itemS()
+                       
+                       col.itemL(text="Cluster Collision:")
+                       col.itemR(soft, "cluster_rigid_to_softbody")
+                       col.itemR(soft, "cluster_soft_to_softbody")
+                       sub  = col.column()
+                       sub.active = (soft.cluster_rigid_to_softbody or soft.cluster_soft_to_softbody)
+                       sub.itemR(soft, "cluster_iterations", text="Iterations")
+               
+               elif game.physics_type == 'STATIC':
+                       
+                       col = layout.column()
+                       col.itemR(game, "actor")
+                       col.itemR(game, "ghost")
+                       col.itemR(ob, "restrict_render", text="Invisible")
+                       
+               elif game.physics_type in ('SENSOR', 'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'):
+                       
+                       layout.itemR(ob, "restrict_render", text="Invisible")
+                       
+class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel):
+       __label__ = "Collision Bounds"
+
+       def poll(self, context):
+               game = context.object.game
+               rd = context.scene.render_data
+               return (game.physics_type in ('DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC')) and (rd.engine == 'BLENDER_GAME')
+
+       def draw_header(self, context):
+               game = context.active_object.game
+
+               self.layout.itemR(game, "use_collision_bounds", text="")
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               game = context.active_object.game
+
+               layout.active = game.use_collision_bounds
+               layout.itemR(game, "collision_bounds", text="Bounds")
+               
+               row = layout.row()
+               row.itemR(game, "collision_compound", text="Compound")
+               row.itemR(game, "collision_margin", text="Margin", slider=True)
+
+bpy.types.register(PHYSICS_PT_game_physics)
+bpy.types.register(PHYSICS_PT_game_collision_bounds)
+
+class SceneButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "scene"
+
+       def poll(self, context):
+               rd = context.scene.render_data
+               return (rd.engine == 'BLENDER_GAME')
+
+class SCENE_PT_game(SceneButtonsPanel):
+       __label__ = "Game"
+
+       def draw(self, context):
+               layout = self.layout
+
+               row = layout.row()
+               row.itemO("view3d.game_start", text="Start")
+               row.itemL()
+
+class SCENE_PT_game_player(SceneButtonsPanel):
+       __label__ = "Standalone Player"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               gs = context.scene.game_data
+               
+               layout.itemR(gs, "fullscreen")
+
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Resolution:")
+               sub = col.column(align=True)
+               sub.itemR(gs, "resolution_x", slider=False, text="X")
+               sub.itemR(gs, "resolution_y", slider=False, text="Y")
+
+               col = split.column()
+               col.itemL(text="Quality:")
+               sub = col.column(align=True)
+               sub.itemR(gs, "depth", text="Bit Depth", slider=False)
+               sub.itemR(gs, "frequency", text="FPS", slider=False)
+
+               # framing:
+               col = layout.column()
+               col.itemL(text="Framing:")
+               col.row().itemR(gs, "framing_type", expand=True)
+               if gs.framing_type == 'LETTERBOX':
+                       col.itemR(gs, "framing_color", text="")
+
+class SCENE_PT_game_stereo(SceneButtonsPanel):
+       __label__ = "Stereo"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               gs = context.scene.game_data
+               stereo_mode = gs.stereo
+
+               # stereo options:
+               layout.itemR(gs, "stereo", expand=True)
+               # stereo:
+               if stereo_mode == 'STEREO':
+                       layout.itemR(gs, "stereo_mode")
+                       layout.itemL(text="To do: Focal Length")
+                       layout.itemL(text="To do: Eye Separation")
+
+               # dome:
+               elif stereo_mode == 'DOME':
+                       layout.itemR(gs, "dome_mode", text="Dome Type")
+
+                       dome_type = gs.dome_mode
+
+                       split=layout.split()
+
+                       if dome_type == 'FISHEYE' or \
+                          dome_type == 'TRUNCATED_REAR' or \
+                          dome_type == 'TRUNCATED_FRONT':
+                               
+                               col=split.column()
+                               col.itemR(gs, "dome_angle", slider=True)
+                               col.itemR(gs, "dome_tilt")
+
+                               col=split.column()
+                               col.itemR(gs, "dome_tesselation", text="Tesselation")
+                               col.itemR(gs, "dome_buffer_resolution", text="Resolution", slider=True)
+
+                       elif dome_type == 'PANORAM_SPH':
+                               col=split.column()
+                               col.itemR(gs, "dome_tesselation", text="Tesselation")
+                               col.itemR(gs, "dome_buffer_resolution", text="Resolution", slider=True)
+
+                       else: # cube map
+                               col=split.column()
+                               col.itemR(gs, "dome_buffer_resolution", text="Resolution", slider=True)
+               
+                       layout.itemR(gs, "dome_text")
+
+class SCENE_PT_game_shading(SceneButtonsPanel):
+       __label__ = "Shading"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               gs = context.scene.game_data
+               layout.itemR(gs, "material_mode", expand=True)
+               if gs.material_mode == 'GLSL':
+                       split = layout.split()
+
+                       col = split.column()
+                       col.itemR(gs, "glsl_lights", text="Lights")
+                       col.itemR(gs, "glsl_shaders", text="Shaders")
+                       col.itemR(gs, "glsl_shadows", text="Shadows")
+
+                       col = split.column()
+                       col.itemR(gs, "glsl_ramps", text="Ramps")
+                       col.itemR(gs, "glsl_nodes", text="Nodes")
+                       col.itemR(gs, "glsl_extra_textures", text="Extra Textures")
+
+class SCENE_PT_game_performance(SceneButtonsPanel):
+       __label__ = "Performance"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               gs = context.scene.game_data
+
+               split = layout.split()
+
+               col = split.column()
+               col.itemL(text="Show:")
+               col.itemR(gs, "show_debug_properties", text="Debug Properties")
+               col.itemR(gs, "show_framerate_profile", text="Framerate and Profile")
+               col.itemR(gs, "show_physics_visualization", text="Physics Visualization")
+               col.itemR(gs, "deprecation_warnings")
+               col = split.column()
+               col.itemL(text="Render:")
+               col.itemR(gs, "all_frames")
+               col.itemR(gs, "display_lists")
+
+bpy.types.register(SCENE_PT_game)
+bpy.types.register(SCENE_PT_game_player)
+bpy.types.register(SCENE_PT_game_stereo)
+bpy.types.register(SCENE_PT_game_shading)
+bpy.types.register(SCENE_PT_game_performance)
+
+class WorldButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "world"
+
+       def poll(self, context):
+               rd = context.scene.render_data
+               return (rd.engine == 'BLENDER_GAME')
+
+class WORLD_PT_game_context_world(WorldButtonsPanel):
+       __show_header__ = False
+
+       def poll(self, context):
+               rd = context.scene.render_data
+               return (context.scene) and (rd.use_game_engine)
+
+       def draw(self, context):
+               layout = self.layout
+               
+               scene = context.scene
+               world = context.world
+               space = context.space_data
+
+               split = layout.split(percentage=0.65)
+
+               if scene:
+                       split.template_ID(scene, "world", new="world.new")
+               elif world:
+                       split.template_ID(space, "pin_id")
+
+class WORLD_PT_game_world(WorldButtonsPanel):
+       __label__ = "World"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               world = context.world
+
+               row = layout.row()
+               row.column().itemR(world, "horizon_color")
+               row.column().itemR(world, "ambient_color")
+
+               layout.itemR(world.mist, "enabled", text="Mist")
+
+               row = layout.column_flow()
+               row.active = world.mist.enabled
+               row.itemR(world.mist, "start")
+               row.itemR(world.mist, "depth")
+
+class WORLD_PT_game_physics(WorldButtonsPanel):
+       __label__ = "Physics"
+       def draw(self, context):
+               layout = self.layout
+               
+               gs = context.scene.game_data
+               
+               layout.itemR(gs, "physics_engine")
+               if gs.physics_engine != 'NONE':
+                       layout.itemR(gs, "physics_gravity", text="Gravity")
+                       split = layout.split()
+                       
+                       col = split.column()
+                       col.itemL(text="Physics Steps:")
+                       sub = col.column(align=True)
+                       sub.itemR(gs, "physics_step_max", text="Max")
+                       sub.itemR(gs, "physics_step_sub", text="Substeps")
+                       col.itemR(gs, "fps", text="FPS")
+                       
+                       col = split.column()
+                       col.itemL(text="Logic Steps:")
+                       col.itemR(gs, "logic_step_max", text="Max")
+                       
+                       col = layout.column()
+                       col.itemR(gs, "use_occlusion_culling", text="Occlusion Culling")
+                       sub = col.column()
+                       sub.active = gs.use_occlusion_culling
+                       sub.itemR(gs, "occlusion_culling_resolution", text="Resolution")
+
+               else:
+                       split = layout.split()
+                       
+                       col = split.column()
+                       col.itemL(text="Physics Steps:")
+                       col.itemR(gs, "fps", text="FPS")
+                       
+                       col = split.column()
+                       col.itemL(text="Logic Steps:")
+                       col.itemR(gs, "logic_step_max", text="Max")
+
+bpy.types.register(WORLD_PT_game_context_world)
+bpy.types.register(WORLD_PT_game_world)
+bpy.types.register(WORLD_PT_game_physics)
diff --git a/release/ui/buttons_material.py b/release/ui/buttons_material.py
new file mode 100644 (file)
index 0000000..dc11731
--- /dev/null
@@ -0,0 +1,713 @@
+       
+import bpy
+
+class MaterialButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "material"
+       # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
+
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (engine in self.COMPAT_ENGINES)
+
+class MATERIAL_PT_preview(MaterialButtonsPanel):
+       __label__ = "Preview"
+       COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
+
+       def draw(self, context):
+               self.layout.template_preview(context.material)
+               
+class MATERIAL_PT_context_material(MaterialButtonsPanel):
+       __show_header__ = False
+       COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
+
+       def poll(self, context):
+               # An exception, dont call the parent poll func because
+               # this manages materials for all engine types
+               
+               engine = context.scene.render_data.engine
+               return (context.object) and (engine in self.COMPAT_ENGINES)
+
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               ob = context.object
+               slot = context.material_slot
+               space = context.space_data
+
+               if ob:
+                       row = layout.row()
+
+                       row.template_list(ob, "materials", ob, "active_material_index", rows=2)
+
+                       col = row.column(align=True)
+                       col.itemO("object.material_slot_add", icon='ICON_ZOOMIN', text="")
+                       col.itemO("object.material_slot_remove", icon='ICON_ZOOMOUT', text="")
+
+                       if ob.mode == 'EDIT':
+                               row = layout.row(align=True)
+                               row.itemO("object.material_slot_assign", text="Assign")
+                               row.itemO("object.material_slot_select", text="Select")
+                               row.itemO("object.material_slot_deselect", text="Deselect")
+
+               split = layout.split(percentage=0.65)
+
+               if ob:
+                       split.template_ID(ob, "active_material", new="material.new")
+                       row = split.row()
+                       if slot:
+                               row.itemR(slot, "link", text="")
+                       else:
+                               row.itemL()
+               elif mat:
+                       split.template_ID(space, "pin_id")
+                       split.itemS()
+
+               layout.itemR(mat, "type", expand=True)
+       
+class MATERIAL_PT_shading(MaterialButtonsPanel):
+       __label__ = "Shading"
+       COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
+
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES)
+
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+
+               if mat.type in ('SURFACE', 'WIRE'):
+                       split = layout.split()
+       
+                       col = split.column()
+                       sub = col.column()
+                       sub.active = not mat.shadeless
+                       sub.itemR(mat, "emit")
+                       sub.itemR(mat, "ambient")
+                       sub = col.column()
+                       sub.itemR(mat, "translucency")
+                               
+                       col = split.column()
+                       col.itemR(mat, "shadeless")     
+                       sub = col.column()
+                       sub.active = not mat.shadeless
+                       sub.itemR(mat, "tangent_shading")
+                       sub.itemR(mat, "cubic")
+                               
+               elif mat.type == 'HALO':
+                       layout.itemR(mat, "alpha")
+                       
+class MATERIAL_PT_strand(MaterialButtonsPanel):
+       __label__ = "Strand"
+       __default_closed__ = True
+       COMPAT_ENGINES = set(['BLENDER_RENDER'])
+
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES)
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               tan = mat.strand
+               
+               split = layout.split()
+               
+               col = split.column(align=True)
+               col.itemL(text="Size:")
+               col.itemR(tan, "root_size", text="Root")
+               col.itemR(tan, "tip_size", text="Tip")
+               col.itemR(tan, "min_size", text="Minimum")
+               col.itemR(tan, "blender_units")
+               sub = col.column()
+               sub.active = (not mat.shadeless)
+               sub.itemR(tan, "tangent_shading")
+               col.itemR(tan, "shape")
+               
+               col = split.column()
+               col.itemL(text="Shading:")
+               col.itemR(tan, "width_fade")
+               col.itemR(tan, "uv_layer")
+               col.itemS()
+               sub = col.column()
+               sub.active = (not mat.shadeless)
+               sub.itemR(tan, "surface_diffuse")
+               sub = col.column()
+               sub.active = tan.surface_diffuse
+               sub.itemR(tan, "blend_distance", text="Distance")
+               
+class MATERIAL_PT_physics(MaterialButtonsPanel):
+       __label__ = "Physics"
+       COMPAT_ENGINES = set(['BLENDER_GAME'])
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               phys = context.material.physics
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(phys, "distance")
+               col.itemR(phys, "friction")
+               col.itemR(phys, "align_to_normal")
+               
+               col = split.column()
+               col.itemR(phys, "force", slider=True)
+               col.itemR(phys, "elasticity", slider=True)
+               col.itemR(phys, "damp", slider=True)
+               
+class MATERIAL_PT_options(MaterialButtonsPanel):
+       __label__ = "Options"
+       COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
+
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES)
+
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(mat, "traceable")
+               col.itemR(mat, "full_oversampling")
+               col.itemR(mat, "sky")
+               col.itemR(mat, "exclude_mist")
+               col.itemR(mat, "invert_z")
+               sub = col.column(align=True)
+               sub.itemL(text="Light Group:")
+               sub.itemR(mat, "light_group", text="")
+               row = sub.row()
+               row.active = mat.light_group
+               row.itemR(mat, "light_group_exclusive", text="Exclusive")
+
+               col = split.column()
+               col.itemR(mat, "face_texture")
+               sub = col.column()
+               sub.active = mat.face_texture
+               sub.itemR(mat, "face_texture_alpha")
+               col.itemS()
+               col.itemR(mat, "vertex_color_paint")
+               col.itemR(mat, "vertex_color_light")
+               col.itemR(mat, "object_color")
+
+class MATERIAL_PT_shadow(MaterialButtonsPanel):
+       __label__ = "Shadow"
+       __default_closed__ = True
+       COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
+       
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
+
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(mat, "shadows", text="Receive")
+               col.itemR(mat, "receive_transparent_shadows", text="Receive Transparent")
+               col.itemR(mat, "only_shadow", text="Shadows Only")
+               col.itemR(mat, "cast_shadows_only", text="Cast Only")
+               col.itemR(mat, "shadow_casting_alpha", text="Casting Alpha")
+               
+               col = split.column()
+               col.itemR(mat, "cast_buffer_shadows")
+               sub = col.column()
+               sub.active = mat.cast_buffer_shadows
+               sub.itemR(mat, "shadow_buffer_bias", text="Buffer Bias")
+               col.itemR(mat, "ray_shadow_bias", text="Auto Ray Bias")
+               sub = col.column()
+               sub.active = (not mat.ray_shadow_bias)
+               sub.itemR(mat, "shadow_ray_bias", text="Ray Bias")
+
+class MATERIAL_PT_diffuse(MaterialButtonsPanel):
+       __label__ = "Diffuse"
+       COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
+
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
+
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material  
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(mat, "diffuse_color", text="")
+               sub = col.column()
+               sub.active = (not mat.shadeless)
+               sub.itemR(mat, "diffuse_intensity", text="Intensity")
+               
+               col = split.column()
+               col.active = (not mat.shadeless)
+               col.itemR(mat, "diffuse_shader", text="")
+               col.itemR(mat, "use_diffuse_ramp", text="Ramp")
+               
+               col = layout.column()
+               col.active = (not mat.shadeless)
+               if mat.diffuse_shader == 'OREN_NAYAR':
+                       col.itemR(mat, "roughness")
+               elif mat.diffuse_shader == 'MINNAERT':
+                       col.itemR(mat, "darkness")
+               elif mat.diffuse_shader == 'TOON':
+                       row = col.row()
+                       row.itemR(mat, "diffuse_toon_size", text="Size")
+                       row.itemR(mat, "diffuse_toon_smooth", text="Smooth")
+               elif mat.diffuse_shader == 'FRESNEL':
+                       row = col.row()
+                       row.itemR(mat, "diffuse_fresnel", text="Fresnel")
+                       row.itemR(mat, "diffuse_fresnel_factor", text="Factor")
+                       
+               if mat.use_diffuse_ramp:
+                       layout.itemS()
+                       layout.template_color_ramp(mat.diffuse_ramp, expand=True)
+                       layout.itemS()
+                       row = layout.row()
+                       split = row.split(percentage=0.3)
+                       split.itemL(text="Input:")
+                       split.itemR(mat, "diffuse_ramp_input", text="")
+                       split = row.split(percentage=0.3)
+                       split.itemL(text="Blend:")
+                       split.itemR(mat, "diffuse_ramp_blend", text="")
+
+class MATERIAL_PT_specular(MaterialButtonsPanel):
+       __label__ = "Specular"
+       COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
+
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
+
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               
+               layout.active = (not mat.shadeless)
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(mat, "specular_color", text="")
+               col.itemR(mat, "specular_intensity", text="Intensity")
+
+               col = split.column()
+               col.itemR(mat, "specular_shader", text="")
+               col.itemR(mat, "use_specular_ramp", text="Ramp")
+
+               col = layout.column()
+               if mat.specular_shader in ('COOKTORR', 'PHONG'):
+                       col.itemR(mat, "specular_hardness", text="Hardness")
+               elif mat.specular_shader == 'BLINN':
+                       row = col.row()
+                       row.itemR(mat, "specular_hardness", text="Hardness")
+                       row.itemR(mat, "specular_ior", text="IOR")
+               elif mat.specular_shader == 'WARDISO':
+                       col.itemR(mat, "specular_slope", text="Slope")
+               elif mat.specular_shader == 'TOON':
+                       row = col.row()
+                       row.itemR(mat, "specular_toon_size", text="Size")
+                       row.itemR(mat, "specular_toon_smooth", text="Smooth")
+               
+               if mat.use_specular_ramp:
+                       layout.itemS()
+                       layout.template_color_ramp(mat.specular_ramp, expand=True)
+                       layout.itemS()
+                       row = layout.row()
+                       split = row.split(percentage=0.3)
+                       split.itemL(text="Input:")
+                       split.itemR(mat, "specular_ramp_input", text="")
+                       split = row.split(percentage=0.3)
+                       split.itemL(text="Blend:")
+                       split.itemR(mat, "specular_ramp_blend", text="")
+               
+class MATERIAL_PT_sss(MaterialButtonsPanel):
+       __label__ = "Subsurface Scattering"
+       __default_closed__ = True
+       COMPAT_ENGINES = set(['BLENDER_RENDER'])
+       
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
+
+       def draw_header(self, context):
+               sss = context.material.subsurface_scattering
+               mat = context.material
+               
+               self.layout.active = (not mat.shadeless)
+               self.layout.itemR(sss, "enabled", text="")
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               sss = context.material.subsurface_scattering
+
+               layout.active = sss.enabled     
+               
+               split = layout.split()
+               split.active = (not mat.shadeless)
+               
+               col = split.column()
+               col.itemR(sss, "ior")
+               col.itemR(sss, "scale")
+               col.itemR(sss, "color", text="")
+               col.itemR(sss, "radius", text="RGB Radius")
+               
+               col = split.column()
+               sub = col.column(align=True)
+               sub.itemL(text="Blend:")
+               sub.itemR(sss, "color_factor", text="Color")
+               sub.itemR(sss, "texture_factor", text="Texture")
+               sub.itemL(text="Scattering Weight:")
+               sub.itemR(sss, "front")
+               sub.itemR(sss, "back")
+               col.itemS()
+               col.itemR(sss, "error_tolerance", text="Error")
+
+class MATERIAL_PT_mirror(MaterialButtonsPanel):
+       __label__ = "Mirror"
+       __default_closed__ = True
+       COMPAT_ENGINES = set(['BLENDER_RENDER'])
+       
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
+       
+       def draw_header(self, context): 
+               raym = context.material.raytrace_mirror
+
+               self.layout.itemR(raym, "enabled", text="")
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               raym = context.material.raytrace_mirror
+               
+               layout.active = raym.enabled
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(raym, "reflect_factor")
+               col.itemR(mat, "mirror_color", text="")
+
+               col = split.column()
+               col.itemR(raym, "fresnel")
+               sub = col.column()
+               sub.active = raym.fresnel > 0
+               sub.itemR(raym, "fresnel_factor", text="Blend")
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemS()
+               col.itemR(raym, "distance", text="Max Dist")
+               col.itemR(raym, "depth")
+               col.itemS()
+               sub = col.split(percentage=0.4)
+               sub.itemL(text="Fade To:")
+               sub.itemR(raym, "fade_to", text="")
+               
+               col = split.column()
+               col.itemL(text="Gloss:")
+               col.itemR(raym, "gloss_factor", text="Amount")
+               sub = col.column()
+               sub.active = raym.gloss_factor < 1.0
+               sub.itemR(raym, "gloss_threshold", text="Threshold")
+               sub.itemR(raym, "gloss_samples", text="Samples")
+               sub.itemR(raym, "gloss_anisotropic", text="Anisotropic")
+
+class MATERIAL_PT_transp(MaterialButtonsPanel):
+       __label__= "Transparency"
+       __default_closed__ = True
+       COMPAT_ENGINES = set(['BLENDER_RENDER'])
+               
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
+
+       def draw_header(self, context): 
+               mat = context.material
+               self.layout.itemR(mat, "transparency", text="")
+
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               rayt = context.material.raytrace_transparency
+               
+               row = layout.row()
+               row.active = mat.transparency and (not mat.shadeless)
+               row.itemR(mat, "transparency_method", expand=True)
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(mat, "alpha")
+               row = col.row()
+               row.active = mat.transparency and (not mat.shadeless)
+               row.itemR(mat, "specular_alpha", text="Specular")
+
+               col = split.column()
+               col.active = (not mat.shadeless)
+               col.itemR(rayt, "fresnel")
+               sub = col.column()
+               sub.active = rayt.fresnel > 0
+               sub.itemR(rayt, "fresnel_factor", text="Blend")
+
+               if mat.transparency_method == 'RAYTRACE':
+                       layout.itemS()
+                       split = layout.split()
+                       split.active = mat.transparency
+
+                       col = split.column()
+                       col.itemR(rayt, "ior")
+                       col.itemR(rayt, "filter")
+                       col.itemR(rayt, "falloff")
+                       col.itemR(rayt, "limit")
+                       col.itemR(rayt, "depth")
+                       
+                       col = split.column()
+                       col.itemL(text="Gloss:")
+                       col.itemR(rayt, "gloss_factor", text="Amount")
+                       sub = col.column()
+                       sub.active = rayt.gloss_factor < 1.0
+                       sub.itemR(rayt, "gloss_threshold", text="Threshold")
+                       sub.itemR(rayt, "gloss_samples", text="Samples")
+
+class MATERIAL_PT_halo(MaterialButtonsPanel):
+       __label__= "Halo"
+       COMPAT_ENGINES = set(['BLENDER_RENDER'])
+       
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (mat.type == 'HALO') and (engine in self.COMPAT_ENGINES)
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               halo = mat.halo
+
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(mat, "diffuse_color", text="")
+               col.itemR(halo, "size")
+               col.itemR(halo, "hardness")
+               col.itemR(halo, "add")
+               col.itemL(text="Options:")
+               col.itemR(halo, "texture")
+               col.itemR(halo, "vertex_normal")
+               col.itemR(halo, "xalpha")
+               col.itemR(halo, "shaded")
+               col.itemR(halo, "soft")
+
+               col = split.column()
+               col.itemR(halo, "ring")
+               sub = col.column()
+               sub.active = halo.ring
+               sub.itemR(halo, "rings")
+               sub.itemR(mat, "mirror_color", text="")
+               col.itemS()
+               col.itemR(halo, "lines")
+               sub = col.column()
+               sub.active = halo.lines
+               sub.itemR(halo, "line_number", text="Lines")
+               sub.itemR(mat, "specular_color", text="")
+               col.itemS()
+               col.itemR(halo, "star")
+               sub = col.column()
+               sub.active = halo.star
+               sub.itemR(halo, "star_tips")
+               
+class MATERIAL_PT_flare(MaterialButtonsPanel):
+       __label__= "Flare"
+       COMPAT_ENGINES = set(['BLENDER_RENDER'])
+       
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (mat.type == 'HALO') and (engine in self.COMPAT_ENGINES)
+       
+       def draw_header(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               halo = mat.halo
+               layout.itemR(halo, "flare_mode", text="")
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               halo = mat.halo
+
+               layout.active = halo.flare_mode
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(halo, "flare_size", text="Size")
+               col.itemR(halo, "flare_boost", text="Boost")
+               col.itemR(halo, "flare_seed", text="Seed")
+               col = split.column()
+               col.itemR(halo, "flares_sub", text="Subflares")
+               col.itemR(halo, "flare_subsize", text="Subsize")
+               
+bpy.types.register(MATERIAL_PT_context_material)
+bpy.types.register(MATERIAL_PT_preview)
+bpy.types.register(MATERIAL_PT_diffuse)
+bpy.types.register(MATERIAL_PT_specular)
+bpy.types.register(MATERIAL_PT_shading)
+bpy.types.register(MATERIAL_PT_transp)
+bpy.types.register(MATERIAL_PT_mirror)
+bpy.types.register(MATERIAL_PT_sss)
+bpy.types.register(MATERIAL_PT_halo)
+bpy.types.register(MATERIAL_PT_flare)
+bpy.types.register(MATERIAL_PT_physics)
+bpy.types.register(MATERIAL_PT_strand)
+bpy.types.register(MATERIAL_PT_options)
+bpy.types.register(MATERIAL_PT_shadow)
+
+# Volumetrics
+class VolumeButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "material"
+
+       def poll(self, context):
+               mat = context.material
+               engine = context.scene.render_data.engine
+               return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES)
+               
+class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
+       __label__ = "Shading"
+       __default_closed__ = False
+       COMPAT_ENGINES = set(['BLENDER_RENDER'])
+
+       def draw(self, context):
+               layout = self.layout
+
+               mat = context.material
+               vol = context.material.volume
+               
+               row = layout.row()
+               row.itemR(vol, "density")
+               row.itemR(vol, "scattering")
+
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(vol, "absorption")
+               col.itemR(vol, "absorption_color", text="")
+
+               col = split.column()
+               col.itemR(vol, "emission")
+               col.itemR(vol, "emission_color", text="")
+
+class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
+       __label__ = "Scattering"
+       __default_closed__ = False
+       COMPAT_ENGINES = set(['BLENDER_RENDER'])
+
+       def draw(self, context):
+               layout = self.layout
+               
+               vol = context.material.volume
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(vol, "scattering_mode", text="")
+               if vol.scattering_mode == 'SINGLE_SCATTERING':
+                       col.itemR(vol, "light_cache")
+                       sub = col.column()
+                       sub.active = vol.light_cache
+                       sub.itemR(vol, "cache_resolution")
+               elif vol.scattering_mode in ('MULTIPLE_SCATTERING', 'SINGLE_PLUS_MULTIPLE_SCATTERING'):
+                       col.itemR(vol, "cache_resolution")
+                       
+                       col = col.column(align=True)
+                       col.itemR(vol, "ms_diffusion")
+                       col.itemR(vol, "ms_spread")
+                       col.itemR(vol, "ms_intensity")
+               
+               col = split.column()
+               # col.itemL(text="Anisotropic Scattering:")
+               col.itemR(vol, "phase_function", text="")
+               if vol.phase_function in ('SCHLICK', 'HENYEY-GREENSTEIN'):
+                       col.itemR(vol, "asymmetry")
+
+class MATERIAL_PT_volume_transp(VolumeButtonsPanel):
+       __label__= "Transparency"
+       COMPAT_ENGINES = set(['BLENDER_RENDER'])
+
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               rayt = context.material.raytrace_transparency
+               
+               row= layout.row()
+               row.itemR(mat, "transparency_method", expand=True)
+               row.active = mat.transparency and (not mat.shadeless)
+               
+class MATERIAL_PT_volume_integration(VolumeButtonsPanel):
+       __label__ = "Integration"
+       __default_closed__ = False
+       COMPAT_ENGINES = set(['BLENDER_RENDER'])
+
+       def draw(self, context):
+               layout = self.layout
+               
+               mat = context.material
+               vol = context.material.volume
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Step Calculation:")
+               col.itemR(vol, "step_calculation", text="")
+               col = col.column(align=True)
+               col.itemR(vol, "step_size")
+               col.itemR(vol, "shading_step_size")
+               
+               col = split.column()
+               col.itemL()
+               col.itemR(vol, "depth_cutoff")
+               col.itemR(vol, "density_scale")
+
+bpy.types.register(MATERIAL_PT_volume_shading)
+bpy.types.register(MATERIAL_PT_volume_scattering)
+bpy.types.register(MATERIAL_PT_volume_transp)
+bpy.types.register(MATERIAL_PT_volume_integration)
diff --git a/release/ui/buttons_object.py b/release/ui/buttons_object.py
new file mode 100644 (file)
index 0000000..af2c7cf
--- /dev/null
@@ -0,0 +1,181 @@
+
+import bpy
+
+class ObjectButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "object"
+
+class OBJECT_PT_context_object(ObjectButtonsPanel):
+       __show_header__ = False
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               
+               row = layout.row()
+               row.itemL(text="", icon='ICON_OBJECT_DATA')
+               row.itemR(ob, "name", text="")
+
+class OBJECT_PT_transform(ObjectButtonsPanel):
+       __label__ = "Transform"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+
+               row = layout.row()
+               row.column().itemR(ob, "location")
+               row.column().itemR(ob, "rotation")
+               row.column().itemR(ob, "scale")
+
+class OBJECT_PT_relations(ObjectButtonsPanel):
+       __label__ = "Relations"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(ob, "layers")
+               col.itemS()
+               col.itemR(ob, "pass_index")
+
+               col = split.column()
+               col.itemL(text="Parent:")
+               col.itemR(ob, "parent", text="")
+
+               sub = col.column()
+               split = sub.split(percentage=0.3)
+               split.itemL(text="Type:")
+               split.itemR(ob, "parent_type", text="")
+               parent = ob.parent
+               if parent and ob.parent_type == 'BONE' and parent.type == 'ARMATURE':
+                       sub.item_pointerR(ob, "parent_bone", parent.data, "bones", text="")
+               sub.active = parent != None
+
+class OBJECT_PT_groups(ObjectButtonsPanel):
+       __label__ = "Groups"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+
+               split = layout.split()
+               split.item_menu_enumO("object.group_add", "group", text="Add to Group")
+               split.itemL()
+
+               for group in bpy.data.groups:
+                       if ob.name in group.objects:
+                               col = layout.column(align=True)
+
+                               col.set_context_pointer("group", group)
+
+                               row = col.box().row()
+                               row.itemR(group, "name", text="")
+                               row.itemO("object.group_remove", text="", icon='VICON_X')
+
+                               split = col.box().split()
+                               split.column().itemR(group, "layer", text="Dupli")
+                               split.column().itemR(group, "dupli_offset", text="")
+
+class OBJECT_PT_display(ObjectButtonsPanel):
+       __label__ = "Display"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+                       
+               row = layout.row()
+               row.itemR(ob, "max_draw_type", text="Type")
+               row.itemR(ob, "draw_bounds_type", text="Bounds")
+
+               flow = layout.column_flow()
+               flow.itemR(ob, "draw_name", text="Name")
+               flow.itemR(ob, "draw_axis", text="Axis")
+               flow.itemR(ob, "draw_wire", text="Wire")
+               flow.itemR(ob, "draw_texture_space", text="Texture Space")
+               flow.itemR(ob, "x_ray", text="X-Ray")
+               flow.itemR(ob, "draw_transparent", text="Transparency")
+
+class OBJECT_PT_duplication(ObjectButtonsPanel):
+       __label__ = "Duplication"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+
+               layout.itemR(ob, "dupli_type", expand=True)
+
+               if ob.dupli_type == 'FRAMES':
+                       split = layout.split()
+                       
+                       col = split.column(align=True)
+                       col.itemR(ob, "dupli_frames_start", text="Start")
+                       col.itemR(ob, "dupli_frames_end", text="End")
+                       
+                       col = split.column(align=True)
+                       col.itemR(ob, "dupli_frames_on", text="On")
+                       col.itemR(ob, "dupli_frames_off", text="Off")
+                       
+                       layout.itemR(ob, "dupli_frames_no_speed", text="No Speed")
+
+               elif ob.dupli_type == 'VERTS':
+                       layout.itemR(ob, "dupli_verts_rotation", text="Rotation")
+
+               elif ob.dupli_type == 'FACES':
+                       row = layout.row()
+                       row.itemR(ob, "dupli_faces_scale", text="Scale")
+                       row.itemR(ob, "dupli_faces_inherit_scale", text="Inherit Scale")
+
+               elif ob.dupli_type == 'GROUP':
+                       layout.itemR(ob, "dupli_group", text="Group")
+
+class OBJECT_PT_animation(ObjectButtonsPanel):
+       __label__ = "Animation"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Time Offset:")
+               col.itemR(ob, "time_offset_edit", text="Edit")
+               row = col.row()
+               row.itemR(ob, "time_offset_particle", text="Particle")
+               row.active = len(ob.particle_systems) != 0
+               row = col.row()
+               row.itemR(ob, "time_offset_parent", text="Parent")
+               row.active = ob.parent != None
+               row = col.row()
+               row.itemR(ob, "slow_parent")
+               row.active = ob.parent != None
+               col.itemR(ob, "time_offset", text="Offset")
+
+               col = split.column()
+               col.itemL(text="Track:")
+               col.itemR(ob, "track", text="")
+               col.itemR(ob, "track_axis", text="Axis")
+               col.itemR(ob, "up_axis", text="Up Axis")
+               row = col.row()
+               row.itemR(ob, "track_override_parent", text="Override Parent")
+               row.active = ob.parent != None
+
+bpy.types.register(OBJECT_PT_context_object)
+bpy.types.register(OBJECT_PT_transform)
+bpy.types.register(OBJECT_PT_relations)
+bpy.types.register(OBJECT_PT_groups)
+bpy.types.register(OBJECT_PT_display)
+bpy.types.register(OBJECT_PT_duplication)
+bpy.types.register(OBJECT_PT_animation)
diff --git a/release/ui/buttons_object_constraint.py b/release/ui/buttons_object_constraint.py
new file mode 100644 (file)
index 0000000..ff3231a
--- /dev/null
@@ -0,0 +1,535 @@
+
+import bpy
+
+class ConstraintButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "constraint"
+
+       def draw_constraint(self, con):
+               layout = self.layout
+               
+               box = layout.template_constraint(con)
+
+               if box:
+                       # match enum type to our functions, avoids a lookup table.
+                       getattr(self, con.type)(box, con)
+       
+                       # show/key buttons here are most likely obsolete now, with
+                       # keyframing functionality being part of every button
+                       if con.type not in ('RIGID_BODY_JOINT', 'NULL'):
+                               box.itemR(con, "influence")
+       
+       def space_template(self, layout, con, target=True, owner=True):
+               if target or owner:
+                       row = layout.row()
+
+                       row.itemL(text="Convert:")
+
+                       if target:
+                               row.itemR(con, "target_space", text="")
+
+                       if target and owner:
+                               row.itemL(icon='ICON_ARROW_LEFTRIGHT')
+
+                       if owner:
+                               row.itemR(con, "owner_space", text="")
+                       
+       def target_template(self, layout, con, subtargets=True):
+               layout.itemR(con, "target") # XXX limiting settings for only 'curves' or some type of object
+               
+               if con.target and subtargets:
+                       if con.target.type == 'ARMATURE':
+                               layout.item_pointerR(con, "subtarget", con.target.data, "bones", text="Bone")
+                               
+                               if con.type == 'COPY_LOCATION':
+                                       row = layout.row()
+                                       row.itemL(text="Head/Tail:")
+                                       row.itemR(con, "head_tail", text="")
+                       elif con.target.type in ('MESH', 'LATTICE'):
+                               layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
+       
+       def CHILD_OF(self, layout, con):
+               self.target_template(layout, con)
+
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Location:")
+               col.itemR(con, "locationx", text="X")
+               col.itemR(con, "locationy", text="Y")
+               col.itemR(con, "locationz", text="Z")
+               
+               col = split.column()
+               col.itemL(text="Rotation:")
+               col.itemR(con, "rotationx", text="X")
+               col.itemR(con, "rotationy", text="Y")
+               col.itemR(con, "rotationz", text="Z")
+               
+               col = split.column()
+               col.itemL(text="Scale:")
+               col.itemR(con, "sizex", text="X")
+               col.itemR(con, "sizey", text="Y")
+               col.itemR(con, "sizez", text="Z")
+               
+               row = layout.row()
+               row.itemO("constraint.childof_set_inverse")
+               row.itemO("constraint.childof_clear_inverse")
+               
+       def TRACK_TO(self, layout, con):
+               self.target_template(layout, con)
+               
+               row = layout.row()
+               row.itemL(text="To:")
+               row.itemR(con, "track", expand=True)
+               
+               row = layout.row()
+               #row.itemR(con, "up", text="Up", expand=True) # XXX: up and expand don't play nice together
+               row.itemR(con, "up", text="Up")
+               row.itemR(con, "target_z")
+               
+               self.space_template(layout, con)
+               
+       def IK(self, layout, con):
+               self.target_template(layout, con)
+               
+               layout.itemR(con, "pole_target")
+       
+               if con.pole_target and con.pole_target.type == 'ARMATURE':
+                       layout.item_pointerR(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
+               
+               split = layout.split()
+       
+               col = split.column()
+               col.itemR(con, "iterations")
+               col.itemR(con, "chain_length")
+               sub = col.column()
+               sub.active = con.pole_target
+               sub.itemR(con, "pole_angle")
+               col.itemL(text="Weight:")
+               col.itemR(con, "weight", text="Position", slider=True)
+               sub = col.column()
+               sub.active = con.rotation
+               sub.itemR(con, "orient_weight", text="Rotation", slider=True)
+               
+               col = split.column()
+               col.itemR(con, "tail")
+               col.itemR(con, "rotation")
+               col.itemR(con, "targetless")
+               col.itemR(con, "stretch")
+               
+       def FOLLOW_PATH(self, layout, con):
+               self.target_template(layout, con)
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(con, "curve_follow")
+               
+               col = split.column()
+               col.itemR(con, "fixed_position")
+               if con.fixed_position:
+                       col.itemR(con, "offset_percentage", text="Offset")
+               else:
+                       col.itemR(con, "offset")
+               
+               row = layout.row()
+               row.itemL(text="Forward:")
+               row.itemR(con, "forward", expand=True)
+               
+               row = layout.row()
+               row.itemR(con, "up", text="Up")
+               row.itemL()
+               
+       def LIMIT_ROTATION(self, layout, con):
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(con, "use_limit_x")
+               sub = col.column()
+               sub.active = con.use_limit_x
+               sub.itemR(con, "minimum_x", text="Min")
+               sub.itemR(con, "maximum_x", text="Max")
+               
+               col = split.column()
+               col.itemR(con, "use_limit_y")
+               sub = col.column()
+               sub.active = con.use_limit_y
+               sub.itemR(con, "minimum_y", text="Min")
+               sub.itemR(con, "maximum_y", text="Max")
+               
+               col = split.column()
+               col.itemR(con, "use_limit_z")
+               sub = col.column()
+               sub.active = con.use_limit_z
+               sub.itemR(con, "minimum_z", text="Min")
+               sub.itemR(con, "maximum_z", text="Max")
+               
+               row = layout.row()
+               row.itemR(con, "limit_transform")
+               row.itemL()
+               
+               row = layout.row()
+               row.itemL(text="Convert:")
+               row.itemR(con, "owner_space", text="")
+               
+       def LIMIT_LOCATION(self, layout, con):
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(con, "use_minimum_x")
+               sub = col.column()
+               sub.active = con.use_minimum_x
+               sub.itemR(con, "minimum_x", text="")
+               col.itemR(con, "use_maximum_x")
+               sub = col.column()
+               sub.active = con.use_maximum_x
+               sub.itemR(con, "maximum_x", text="")
+               
+               col = split.column()
+               col.itemR(con, "use_minimum_y")
+               sub = col.column()
+               sub.active = con.use_minimum_y
+               sub.itemR(con, "minimum_y", text="")
+               col.itemR(con, "use_maximum_y")
+               sub = col.column()
+               sub.active = con.use_maximum_y
+               sub.itemR(con, "maximum_y", text="")
+               
+               col = split.column()
+               col.itemR(con, "use_minimum_z")
+               sub = col.column()
+               sub.active = con.use_minimum_z
+               sub.itemR(con, "minimum_z", text="")
+               col.itemR(con, "use_maximum_z")
+               sub = col.column()
+               sub.active = con.use_maximum_z
+               sub.itemR(con, "maximum_z", text="")
+       
+               row = layout.row()
+               row.itemR(con, "limit_transform")
+               row.itemL()
+               
+               row = layout.row()
+               row.itemL(text="Convert:")
+               row.itemR(con, "owner_space", text="")
+               
+       def LIMIT_SCALE(self, layout, con):
+               split = layout.split()
+
+               col = split.column()
+               col.itemR(con, "use_minimum_x")
+               sub = col.column()
+               sub.active = con.use_minimum_x
+               sub.itemR(con, "minimum_x", text="")
+               col.itemR(con, "use_maximum_x")
+               sub = col.column()
+               sub.active = con.use_maximum_x
+               sub.itemR(con, "maximum_x", text="")
+               
+               col = split.column()
+               col.itemR(con, "use_minimum_y")
+               sub = col.column()
+               sub.active = con.use_minimum_y
+               sub.itemR(con, "minimum_y", text="")
+               col.itemR(con, "use_maximum_y")
+               sub = col.column()
+               sub.active = con.use_maximum_y
+               sub.itemR(con, "maximum_y", text="")
+               
+               col = split.column()
+               col.itemR(con, "use_minimum_z")
+               sub = col.column()
+               sub.active = con.use_minimum_z
+               sub.itemR(con, "minimum_z", text="")
+               col.itemR(con, "use_maximum_z")
+               sub = col.column()
+               sub.active = con.use_maximum_z
+               sub.itemR(con, "maximum_z", text="")
+               
+               row = layout.row()
+               row.itemR(con, "limit_transform")
+               row.itemL()
+               
+               row = layout.row()
+               row.itemL(text="Convert:")
+               row.itemR(con, "owner_space", text="")
+       
+       def COPY_ROTATION(self, layout, con):
+               self.target_template(layout, con)
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(con, "rotate_like_x", text="X")
+               sub = col.column()
+               sub.active = con.rotate_like_x
+               sub.itemR(con, "invert_x", text="Invert")
+               
+               col = split.column()
+               col.itemR(con, "rotate_like_y", text="Y")
+               sub = col.column()
+               sub.active = con.rotate_like_y
+               sub.itemR(con, "invert_y", text="Invert")
+               
+               col = split.column()
+               col.itemR(con, "rotate_like_z", text="Z")
+               sub = col.column()
+               sub.active = con.rotate_like_z
+               sub.itemR(con, "invert_z", text="Invert")
+
+               layout.itemR(con, "offset")
+               
+               self.space_template(layout, con)
+               
+       def COPY_LOCATION(self, layout, con):
+               self.target_template(layout, con)
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(con, "locate_like_x", text="X")
+               sub = col.column()
+               sub.active = con.locate_like_x
+               sub.itemR(con, "invert_x", text="Invert")
+               
+               col = split.column()
+               col.itemR(con, "locate_like_y", text="Y")
+               sub = col.column()
+               sub.active = con.locate_like_y
+               sub.itemR(con, "invert_y", text="Invert")
+               
+               col = split.column()
+               col.itemR(con, "locate_like_z", text="Z")
+               sub = col.column()
+               sub.active = con.locate_like_z
+               sub.itemR(con, "invert_z", text="Invert")
+
+               layout.itemR(con, "offset")
+                       
+               self.space_template(layout, con)
+               
+       def COPY_SCALE(self, layout, con):
+               self.target_template(layout, con)
+               
+               row = layout.row(align=True)
+               row.itemR(con, "size_like_x", text="X")
+               row.itemR(con, "size_like_y", text="Y")
+               row.itemR(con, "size_like_z", text="Z")
+
+               layout.itemR(con, "offset")
+               
+               self.space_template(layout, con)
+               
+       #def SCRIPT(self, layout, con):
+       
+       def ACTION(self, layout, con):
+               self.target_template(layout, con)
+               
+               layout.itemR(con, "action")
+               layout.itemR(con, "transform_channel")
+
+               split = layout.split()
+       
+               col = split.column(align=True)
+               col.itemR(con, "start_frame", text="Start")
+               col.itemR(con, "end_frame", text="End")
+               
+               col = split.column(align=True)
+               col.itemR(con, "minimum", text="Min")
+               col.itemR(con, "maximum", text="Max")
+               
+               row = layout.row()
+               row.itemL(text="Convert:")
+               row.itemR(con, "owner_space", text="")
+       
+       def LOCKED_TRACK(self, layout, con):
+               self.target_template(layout, con)
+               
+               row = layout.row()
+               row.itemL(text="To:")
+               row.itemR(con, "track", expand=True)
+               
+               row = layout.row()
+               row.itemL(text="Lock:")
+               row.itemR(con, "locked", expand=True)
+               
+       def LIMIT_DISTANCE(self, layout, con):
+               self.target_template(layout, con)
+               
+               col = layout.column(align=True);
+               col.itemR(con, "distance")
+               col.itemO("constraint.limitdistance_reset")
+               
+               row = layout.row()
+               row.itemL(text="Clamp Region:")
+               row.itemR(con, "limit_mode", text="")
+               
+       def STRETCH_TO(self, layout, con):
+               self.target_template(layout, con)
+               
+               row = layout.row()
+               row.itemR(con, "original_length", text="Rest Length")
+               row.itemO("constraint.stretchto_reset", text="Reset")
+               
+               col = layout.column()
+               col.itemR(con, "bulge", text="Volume Variation")
+               
+               row = layout.row()
+               row.itemL(text="Volume:")
+               row.itemR(con, "volume", expand=True)
+               row.itemL(text="Plane:")
+               row.itemR(con, "keep_axis", expand=True)
+               
+       def FLOOR(self, layout, con):
+               self.target_template(layout, con)
+               
+               row = layout.row()
+               row.itemR(con, "sticky")
+               row.itemR(con, "use_rotation")
+               
+               layout.itemR(con, "offset")
+               
+               row = layout.row()
+               row.itemL(text="Min/Max:")
+               row.itemR(con, "floor_location", expand=True)
+               
+       def RIGID_BODY_JOINT(self, layout, con):
+               self.target_template(layout, con)
+               
+               layout.itemR(con, "pivot_type")
+               layout.itemR(con, "child")
+               
+               row = layout.row()
+               row.itemR(con, "disable_linked_collision", text="No Collision")
+               row.itemR(con, "draw_pivot", text="Display Pivot")
+               
+               split = layout.split()
+               
+               col = split.column(align=True)
+               col.itemL(text="Pivot:")
+               col.itemR(con, "pivot_x", text="X")
+               col.itemR(con, "pivot_y", text="Y")
+               col.itemR(con, "pivot_z", text="Z")
+               
+               col = split.column(align=True)
+               col.itemL(text="Axis:")
+               col.itemR(con, "axis_x", text="X")
+               col.itemR(con, "axis_y", text="Y")
+               col.itemR(con, "axis_z", text="Z")
+               
+               #Missing: Limit arrays (not wrapped in RNA yet) 
+       
+       def CLAMP_TO(self, layout, con):
+               self.target_template(layout, con)
+               
+               row = layout.row()
+               row.itemL(text="Main Axis:")
+               row.itemR(con, "main_axis", expand=True)
+               
+               row = layout.row()
+               row.itemR(con, "cyclic")
+               
+       def TRANSFORM(self, layout, con):
+               self.target_template(layout, con)
+               
+               layout.itemR(con, "extrapolate_motion", text="Extrapolate")
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Source:")
+               col.row().itemR(con, "map_from", expand=True)
+               
+               sub = col.row(align=True)
+               sub.itemL(text="X:")
+               sub.itemR(con, "from_min_x", text="")
+               sub.itemR(con, "from_max_x", text="")
+               
+               sub = col.row(align=True)
+               sub.itemL(text="Y:")
+               sub.itemR(con, "from_min_y", text="")
+               sub.itemR(con, "from_max_y", text="")
+               
+               sub = col.row(align=True)
+               sub.itemL(text="Z:")
+               sub.itemR(con, "from_min_z", text="")
+               sub.itemR(con, "from_max_z", text="")
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Destination:")
+               col.row().itemR(con, "map_to", expand=True)
+
+               sub = col.row(align=True)
+               sub.itemR(con, "map_to_x_from", text="")
+               sub.itemR(con, "to_min_x", text="")
+               sub.itemR(con, "to_max_x", text="")
+               
+               sub = col.row(align=True)
+               sub.itemR(con, "map_to_y_from", text="")
+               sub.itemR(con, "to_min_y", text="")
+               sub.itemR(con, "to_max_y", text="")
+               
+               sub = col.row(align=True)
+               sub.itemR(con, "map_to_z_from", text="")
+               sub.itemR(con, "to_min_z", text="")
+               sub.itemR(con, "to_max_z", text="")
+               
+               self.space_template(layout, con)
+               
+       def SHRINKWRAP (self, layout, con):
+               self.target_template(layout, con)
+               
+               layout.itemR(con, "distance")
+               layout.itemR(con, "shrinkwrap_type")
+               
+               if con.shrinkwrap_type == 'PROJECT':
+                       row = layout.row(align=True)
+                       row.itemR(con, "axis_x")
+                       row.itemR(con, "axis_y")
+                       row.itemR(con, "axis_z")
+               
+class OBJECT_PT_constraints(ConstraintButtonsPanel):
+       __label__ = "Constraints"
+       __context__ = "constraint"
+
+       def poll(self, context):
+               return (context.object)
+               
+       def draw(self, context):
+               layout = self.layout
+               ob = context.object
+
+               row = layout.row()
+               row.item_menu_enumO("object.constraint_add", "type")
+               row.itemL();
+
+               for con in ob.constraints:
+                       self.draw_constraint(con)
+
+class BONE_PT_constraints(ConstraintButtonsPanel):
+       __label__ = "Constraints"
+       __context__ = "bone"
+
+       def poll(self, context):
+               ob = context.object
+               return (ob and ob.type == 'ARMATURE' and context.bone)
+               
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               pchan = ob.pose.pose_channels[context.bone.name]
+
+               row = layout.row()
+               row.item_menu_enumO("pose.constraint_add", "type")
+               row.itemL();
+
+               for con in pchan.constraints:
+                       self.draw_constraint(con)
+
+bpy.types.register(OBJECT_PT_constraints)
+bpy.types.register(BONE_PT_constraints)
diff --git a/release/ui/buttons_particle.py b/release/ui/buttons_particle.py
new file mode 100644 (file)
index 0000000..1d496e1
--- /dev/null
@@ -0,0 +1,959 @@
+
+import bpy
+
+def particle_panel_enabled(psys):
+       return psys.point_cache.baked==False and psys.edited==False
+       
+def particle_panel_poll(context):
+       psys = context.particle_system
+       if psys==None:  return False
+       if psys.settings==None:  return False
+       return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR')
+       
+def point_cache_ui(self, cache, enabled, particles, smoke):
+       layout = self.layout
+       layout.set_context_pointer("PointCache", cache)
+       
+       row = layout.row()
+       row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 )
+       col = row.column(align=True)
+       col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="")
+       col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="")
+       
+       row = layout.row()
+       row.itemL(text="File Name:")
+       if particles:
+               row.itemR(cache, "external")
+       
+       if cache.external:
+               split = layout.split(percentage=0.80)
+               split.itemR(cache, "name", text="")
+               split.itemR(cache, "index", text="")
+               
+               layout.itemL(text="File Path:")
+               layout.itemR(cache, "filepath", text="")
+               
+               layout.itemL(text=cache.info)
+       else:
+               layout.itemR(cache, "name", text="")
+               
+               if not particles:
+                       row = layout.row()
+                       row.enabled = enabled
+                       row.itemR(cache, "start_frame")
+                       row.itemR(cache, "end_frame")
+               
+               row = layout.row()
+       
+               if cache.baked == True:
+                       row.itemO("ptcache.free_bake", text="Free Bake")
+               else:
+                       row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
+       
+               sub = row.row()
+               sub.enabled = (cache.frames_skipped or cache.outdated) and enabled
+               sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
+               
+               row = layout.row()
+               row.enabled = enabled
+               row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
+               row.itemR(cache, "step");
+       
+               if not smoke:
+                       row = layout.row()
+                       sub = row.row()
+                       sub.enabled = enabled
+                       sub.itemR(cache, "quick_cache")
+                       row.itemR(cache, "disk_cache")
+       
+               layout.itemL(text=cache.info)
+               
+               layout.itemS()
+               
+               row = layout.row()
+               row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
+               row.itemO("ptcache.free_bake_all", text="Free All Bakes")
+               layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
+       
+
+class ParticleButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "particle"
+
+       def poll(self, context):
+               return particle_panel_poll(context)
+
+class PARTICLE_PT_particles(ParticleButtonsPanel):
+       __show_header__ = False
+
+       def poll(self, context):
+               return (context.particle_system or context.object)
+
+       def draw(self, context):
+               layout = self.layout
+               ob = context.object
+               psys = context.particle_system
+
+               if ob:
+                       row = layout.row()
+
+                       row.template_list(ob, "particle_systems", ob, "active_particle_system_index", rows=2)
+
+                       col = row.column(align=True)
+                       col.itemO("object.particle_system_add", icon='ICON_ZOOMIN', text="")
+                       col.itemO("object.particle_system_remove", icon='ICON_ZOOMOUT', text="")
+
+               if psys and not psys.settings:
+                       split = layout.split(percentage=0.32)
+                       col = split.column()
+                       col.itemL(text="Name:")
+                       col.itemL(text="Settings:")
+                       
+                       col = split.column()
+                       col.itemR(psys, "name", text="")
+                       col.template_ID(psys, "settings", new="particle.new")
+               elif psys:
+                       part = psys.settings
+                       
+                       split = layout.split(percentage=0.32)
+                       col = split.column()
+                       col.itemL(text="Name:")
+                       if part.type in ('EMITTER', 'REACTOR', 'HAIR'):
+                               col.itemL(text="Settings:")
+                               col.itemL(text="Type:")
+                       
+                       col = split.column()
+                       col.itemR(psys, "name", text="")
+                       if part.type in ('EMITTER', 'REACTOR', 'HAIR'):
+                               col.template_ID(psys, "settings", new="particle.new")
+                       
+                       #row = layout.row()
+                       #row.itemL(text="Viewport")
+                       #row.itemL(text="Render")
+                       
+                       if part:
+                               if part.type not in ('EMITTER', 'REACTOR', 'HAIR'):
+                                       layout.itemL(text="No settings for fluid particles")
+                                       return
+                               
+                               row=col.row()
+                               row.enabled = particle_panel_enabled(psys)
+                               row.itemR(part, "type", text="")
+                               row.itemR(psys, "seed")
+                               
+                               split = layout.split(percentage=0.65)
+                               if part.type=='HAIR':
+                                       if psys.edited==True:
+                                               split.itemO("particle.edited_clear", text="Free Edit")
+                                       else:
+                                               split.itemL(text="")
+                                       row = split.row()
+                                       row.enabled = particle_panel_enabled(psys)
+                                       row.itemR(part, "hair_step")
+                                       if psys.edited==True:
+                                               if psys.global_hair:
+                                                       layout.itemO("particle.connect_hair")
+                                                       layout.itemL(text="Hair is disconnected.")
+                                               else:
+                                                       layout.itemO("particle.disconnect_hair")
+                                                       layout.itemL(text="")
+                               elif part.type=='REACTOR':
+                                       split.enabled = particle_panel_enabled(psys)
+                                       split.itemR(psys, "reactor_target_object")
+                                       split.itemR(psys, "reactor_target_particle_system", text="Particle System")
+               
+class PARTICLE_PT_emission(ParticleButtonsPanel):
+       __label__ = "Emission"
+       
+       def poll(self, context):
+               if particle_panel_poll(context):
+                       return not context.particle_system.point_cache.external
+               else:
+                       return False
+       
+       def draw(self, context):
+               layout = self.layout
+
+               psys = context.particle_system
+               part = psys.settings
+               
+               layout.enabled = particle_panel_enabled(psys) and not psys.multiple_caches
+               
+               row = layout.row()
+               row.itemR(part, "amount")
+               
+               split = layout.split()
+               
+               col = split.column(align=True)
+               col.itemR(part, "start")
+               col.itemR(part, "end")
+
+               col = split.column(align=True)
+               col.itemR(part, "lifetime")
+               col.itemR(part, "random_lifetime", slider=True)
+               
+               layout.row().itemL(text="Emit From:")
+               
+               row = layout.row()
+               row.itemR(part, "emit_from", expand=True)
+               row = layout.row()
+               row.itemR(part, "trand")
+               if part.distribution!='GRID':
+                       row.itemR(part, "even_distribution")
+               
+               if part.emit_from=='FACE' or part.emit_from=='VOLUME':
+                       row = layout.row()
+                       row.itemR(part, "distribution", expand=True)
+                       
+                       row = layout.row()
+
+                       if part.distribution=='JIT':
+                               row.itemR(part, "userjit", text="Particles/Face")
+                               row.itemR(part, "jitter_factor", text="Jittering Amount", slider=True)
+                       elif part.distribution=='GRID':
+                               row.itemR(part, "grid_resolution")
+
+class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel):
+       __label__ = "Hair dynamics"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               psys = context.particle_system
+               if psys==None:  return False
+               if psys.settings==None:  return False
+               return psys.settings.type == 'HAIR'
+               
+       def draw_header(self, context):
+               #cloth = context.cloth.collision_settings
+               
+               #self.layout.active = cloth_panel_enabled(context.cloth)
+               #self.layout.itemR(cloth, "enable_collision", text="")
+               psys = context.particle_system
+               self.layout.itemR(psys, "hair_dynamics", text="")
+               
+       def draw(self, context):
+               layout = self.layout
+
+               psys = context.particle_system
+               part = psys.settings
+               cloth = psys.cloth.settings
+               
+               layout.enabled = psys.hair_dynamics
+               
+               split = layout.split()
+                       
+               col = split.column()
+               col.itemL(text="Quality:")
+               col.itemR(cloth, "quality", text="Steps",slider=True)
+               col.itemL(text="Gravity:")
+               col.itemR(cloth, "gravity", text="")
+               
+               col = split.column()
+               col.itemL(text="Material:")
+               sub = col.column(align=True)
+               sub.itemR(cloth, "pin_stiffness", text="Stiffness")
+               sub.itemR(cloth, "mass")
+               col.itemL(text="Damping:")
+               sub = col.column(align=True)
+               sub.itemR(cloth, "spring_damping", text="Spring")
+               sub.itemR(cloth, "air_damping", text="Air")
+               
+               layout.itemR(cloth, "internal_friction", slider="True")
+                               
+class PARTICLE_PT_cache(ParticleButtonsPanel):
+       __label__ = "Cache"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               psys = context.particle_system
+               if psys==None:  return False
+               if psys.settings==None:  return False
+               phystype = psys.settings.physics_type
+               if phystype == 'NO' or phystype == 'KEYED':
+                       return False
+               return psys.settings.type in ('EMITTER', 'REACTOR') or (psys.settings.type == 'HAIR' and psys.hair_dynamics)
+
+       def draw(self, context):
+               layout = self.layout
+
+               psys = context.particle_system
+               
+               point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), not psys.hair_dynamics, 0)
+
+class PARTICLE_PT_initial(ParticleButtonsPanel):
+       __label__ = "Velocity"
+       
+       def poll(self, context):
+               if particle_panel_poll(context):
+                       psys = context.particle_system
+                       return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external
+               else:
+                       return False
+
+       def draw(self, context):
+               layout = self.layout
+
+               psys = context.particle_system
+               part = psys.settings
+               
+               layout.enabled = particle_panel_enabled(psys)
+                               
+               layout.row().itemL(text="Direction:")
+       
+               split = layout.split()
+                       
+               sub = split.column()
+               sub.itemR(part, "normal_factor")
+               if part.emit_from=='PARTICLE':
+                       sub.itemR(part, "particle_factor")
+               else:
+                       sub.itemR(part, "object_factor", slider=True)
+               sub.itemR(part, "random_factor")
+               sub.itemR(part, "tangent_factor")
+               sub.itemR(part, "tangent_phase", slider=True)
+               
+               sub = split.column()
+               sub.itemL(text="TODO:")
+               sub.itemL(text="Object aligned")
+               sub.itemL(text="direction: X, Y, Z")
+               
+               if part.type=='REACTOR':
+                       sub.itemR(part, "reactor_factor")
+                       sub.itemR(part, "reaction_shape", slider=True)
+               else:
+                       sub.itemL(text="")
+               
+               layout.row().itemL(text="Rotation:")
+               split = layout.split()
+                       
+               sub = split.column()
+               
+               sub.itemR(part, "rotation_mode", text="Axis")
+               split = layout.split()
+                       
+               sub = split.column()
+               sub.itemR(part, "rotation_dynamic")
+               sub.itemR(part, "random_rotation_factor", slider=True)
+               sub = split.column()
+               sub.itemR(part, "phase_factor", slider=True)
+               sub.itemR(part, "random_phase_factor", text="Random", slider=True)
+
+               layout.row().itemL(text="Angular velocity:")
+               layout.row().itemR(part, "angular_velocity_mode", expand=True)
+               split = layout.split()
+                       
+               sub = split.column()
+               
+               sub.itemR(part, "angular_velocity_factor", text="")
+               
+class PARTICLE_PT_physics(ParticleButtonsPanel):
+       __label__ = "Physics"
+       
+       def poll(self, context):
+               if particle_panel_poll(context):
+                       return not context.particle_system.point_cache.external
+               else:
+                       return False
+
+       def draw(self, context):
+               layout = self.layout
+
+               psys = context.particle_system
+               part = psys.settings
+               
+               layout.enabled = particle_panel_enabled(psys)
+
+               row = layout.row()
+               row.itemR(part, "physics_type", expand=True)
+               if part.physics_type != 'NO':
+                       row = layout.row()
+                       col = row.column(align=True)
+                       col.itemR(part, "particle_size")
+                       col.itemR(part, "random_size", slider=True)
+                       col = row.column(align=True)
+                       col.itemR(part, "mass")
+                       col.itemR(part, "sizemass", text="Multiply mass with size")
+                       
+               if part.physics_type == 'NEWTON':
+                       split = layout.split()
+                       sub = split.column()
+                       
+                       sub.itemL(text="Forces:")
+                       sub.itemR(part, "brownian_factor")
+                       sub.itemR(part, "drag_factor", slider=True)
+                       sub.itemR(part, "damp_factor", slider=True)
+                       sub.itemR(part, "integrator")
+                       sub = split.column()
+                       sub.itemR(part, "acceleration")
+                       
+               elif part.physics_type == 'KEYED':
+                       split = layout.split()
+                       sub = split.column()
+                       
+                       row = layout.row()
+                       col = row.column()
+                       col.active = not psys.keyed_timing
+                       col.itemR(part, "keyed_loops", text="Loops")
+                       row.itemR(psys, "keyed_timing", text="Use Timing")
+                       
+                       layout.itemL(text="Keys:")
+               elif part.physics_type=='BOIDS':
+                       boids = part.boids
+                       
+
+                       row = layout.row()
+                       row.itemR(boids, "allow_flight")
+                       row.itemR(boids, "allow_land")
+                       row.itemR(boids, "allow_climb")
+                       
+                       split = layout.split()
+                       
+                       sub = split.column()
+                       col = sub.column(align=True)
+                       col.active = boids.allow_flight
+                       col.itemR(boids, "air_max_speed")
+                       col.itemR(boids, "air_min_speed", slider="True")
+                       col.itemR(boids, "air_max_acc", slider="True")
+                       col.itemR(boids, "air_max_ave", slider="True")
+                       col.itemR(boids, "air_personal_space")
+                       row = col.row()
+                       row.active = (boids.allow_land or boids.allow_climb) and boids.allow_flight
+                       row.itemR(boids, "landing_smoothness")
+                       
+                       sub = split.column()
+                       col = sub.column(align=True)
+                       col.active = boids.allow_land or boids.allow_climb
+                       col.itemR(boids, "land_max_speed")
+                       col.itemR(boids, "land_jump_speed")
+                       col.itemR(boids, "land_max_acc", slider="True")
+                       col.itemR(boids, "land_max_ave", slider="True")
+                       col.itemR(boids, "land_personal_space")
+                       col.itemR(boids, "land_stick_force")
+                       
+                       row = layout.row()
+                       
+                       col = row.column(align=True)
+                       col.itemL(text="Battle:")
+                       col.itemR(boids, "health")
+                       col.itemR(boids, "strength")
+                       col.itemR(boids, "aggression")
+                       col.itemR(boids, "accuracy")
+                       col.itemR(boids, "range")
+                       
+                       col = row.column()
+                       col.itemL(text="Misc:")
+                       col.itemR(part, "gravity")
+                       col.itemR(boids, "banking", slider=True)
+                       col.itemR(boids, "height", slider=True)
+                       
+               if part.physics_type=='NEWTON':
+                       sub.itemR(part, "size_deflect")
+                       sub.itemR(part, "die_on_collision")
+               elif part.physics_type=='KEYED' or part.physics_type=='BOIDS':
+                       if part.physics_type=='BOIDS':
+                               layout.itemL(text="Relations:")
+                       
+                       row = layout.row()
+                       row.template_list(psys, "targets", psys, "active_particle_target_index")
+                       
+                       col = row.column()
+                       subrow = col.row()
+                       subcol = subrow.column(align=True)
+                       subcol.itemO("particle.new_target", icon='ICON_ZOOMIN', text="")
+                       subcol.itemO("particle.remove_target", icon='ICON_ZOOMOUT', text="")
+                       subrow = col.row()
+                       subcol = subrow.column(align=True)
+                       subcol.itemO("particle.target_move_up", icon='VICON_MOVE_UP', text="")
+                       subcol.itemO("particle.target_move_down", icon='VICON_MOVE_DOWN', text="")
+                       
+                       key = psys.active_particle_target
+                       if key:
+                               row = layout.row()
+                               if part.physics_type=='KEYED':
+                                       col = row.column()
+                                       #doesn't work yet
+                                       #col.red_alert = key.valid
+                                       col.itemR(key, "object", text="")
+                                       col.itemR(key, "system", text="System")
+                                       col = row.column();
+                                       col.active = psys.keyed_timing
+                                       col.itemR(key, "time")
+                                       col.itemR(key, "duration")
+                               else:
+                                       subrow = row.row()
+                                       #doesn't work yet
+                                       #subrow.red_alert = key.valid
+                                       subrow.itemR(key, "object", text="")
+                                       subrow.itemR(key, "system", text="System")
+                                       
+                                       layout.itemR(key, "mode", expand=True)
+
+class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
+       __label__ = "Boid Brain"
+
+       def poll(self, context):
+               psys = context.particle_system
+               if psys==None:  return False
+               if psys.settings==None:  return False
+               if psys.point_cache.external: return False
+               return psys.settings.physics_type=='BOIDS'
+       
+       def draw(self, context):
+               boids = context.particle_system.settings.boids
+               layout = self.layout
+               
+               layout.enabled = particle_panel_enabled(psys)
+               
+               # Currently boids can only use the first state so these are commented out for now.
+               #row = layout.row()
+               #row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
+               #col = row.row()
+               #subrow = col.row(align=True)
+               #subrow.itemO("boid.boidstate_add", icon='ICON_ZOOMIN', text="")
+               #subrow.itemO("boid.boidstate_del", icon='ICON_ZOOMOUT', text="")
+               #subrow = row.row(align=True)
+               #subrow.itemO("boid.boidstate_move_up", icon='VICON_MOVE_UP', text="")
+               #subrow.itemO("boid.boidstate_move_down", icon='VICON_MOVE_DOWN', text="")
+               
+               state = boids.active_boid_state
+               
+               #layout.itemR(state, "name", text="State name")
+               
+               row = layout.row()
+               row.itemR(state, "ruleset_type")
+               if state.ruleset_type=='FUZZY':
+                       row.itemR(state, "rule_fuzziness", slider=True)
+               else:
+                       row.itemL(text="")
+               
+               row = layout.row()
+               row.template_list(state, "rules", state, "active_boid_rule_index")
+               
+               col = row.column()
+               subrow = col.row()
+               subcol = subrow.column(align=True)
+               subcol.item_menu_enumO("boid.boidrule_add", "type", icon='ICON_ZOOMIN', text="")
+               subcol.itemO("boid.boidrule_del", icon='ICON_ZOOMOUT', text="")
+               subrow = col.row()
+               subcol = subrow.column(align=True)
+               subcol.itemO("boid.boidrule_move_up", icon='VICON_MOVE_UP', text="")
+               subcol.itemO("boid.boidrule_move_down", icon='VICON_MOVE_DOWN', text="")
+               
+               rule = state.active_boid_rule
+               
+               if rule:
+                       row = layout.row()
+                       row.itemR(rule, "name", text="")
+                       #somebody make nice icons for boids here please! -jahka
+                       row.itemR(rule, "in_air", icon='VICON_MOVE_UP', text="")
+                       row.itemR(rule, "on_land", icon='VICON_MOVE_DOWN', text="")
+                       
+                       row = layout.row()
+
+                       if rule.type == 'GOAL':
+                               row.itemR(rule, "object")
+                               row = layout.row()
+                               row.itemR(rule, "predict")
+                       elif rule.type == 'AVOID':
+                               row.itemR(rule, "object")
+                               row = layout.row()
+                               row.itemR(rule, "predict")
+                               row.itemR(rule, "fear_factor")
+                       elif rule.type == 'FOLLOW_PATH':
+                               row.itemL(text="Not yet functional.")
+                       elif rule.type == 'AVOID_COLLISION':
+                               row.itemR(rule, "boids")
+                               row.itemR(rule, "deflectors")
+                               row.itemR(rule, "look_ahead")
+                       elif rule.type == 'FOLLOW_LEADER':
+                               row.itemR(rule, "object", text="")
+                               row.itemR(rule, "distance")
+                               row = layout.row()
+                               row.itemR(rule, "line")
+                               subrow = row.row()
+                               subrow.active = rule.line
+                               subrow.itemR(rule, "queue_size")
+                       elif rule.type == 'AVERAGE_SPEED':
+                               row.itemR(rule, "speed", slider=True)
+                               row.itemR(rule, "wander", slider=True)
+                               row.itemR(rule, "level", slider=True)
+                       elif rule.type == 'FIGHT':
+                               row.itemR(rule, "distance")
+                               row.itemR(rule, "flee_distance")
+               
+
+class PARTICLE_PT_render(ParticleButtonsPanel):
+       __label__ = "Render"
+       
+       def poll(self, context):
+               psys = context.particle_system
+               if psys==None: return False
+               if psys.settings==None: return False
+               return True;
+               
+       def draw(self, context):
+               layout = self.layout
+
+               psys = context.particle_system
+               part = psys.settings
+
+               row = layout.row()
+               row.itemR(part, "material")
+               row.itemR(psys, "parent");
+               
+               split = layout.split()
+                       
+               sub = split.column()
+               sub.itemR(part, "emitter");
+               sub.itemR(part, "parent");
+               sub = split.column()
+               sub.itemR(part, "unborn");
+               sub.itemR(part, "died");
+               
+               row = layout.row()
+               row.itemR(part, "ren_as", expand=True)
+               
+               split = layout.split()
+                       
+               sub = split.column()
+               
+               if part.ren_as == 'LINE':
+                       sub.itemR(part, "line_length_tail")
+                       sub.itemR(part, "line_length_head")
+                       sub = split.column()
+                       sub.itemR(part, "velocity_length")
+               elif part.ren_as == 'PATH':
+               
+                       if (part.type!='HAIR' and part.physics_type!='KEYED' and psys.point_cache.baked==False):
+                               box = layout.box()
+                               box.itemL(text="Baked or keyed particles needed for correct rendering.")
+                               return
+                               
+                       sub.itemR(part, "render_strand")
+                       colsub = sub.column()
+                       colsub.active = part.render_strand == False
+                       colsub.itemR(part, "render_adaptive")
+                       colsub = sub.column()
+                       colsub.active = part.render_adaptive or part.render_strand == True
+                       colsub.itemR(part, "adaptive_angle")
+                       colsub = sub.column()
+                       colsub.active = part.render_adaptive == True and part.render_strand == False
+                       colsub.itemR(part, "adaptive_pix")
+                       sub.itemR(part, "hair_bspline")
+                       sub.itemR(part, "render_step", text="Steps")
+                       sub = split.column()    
+
+                       sub.itemL(text="Timing:")
+                       sub.itemR(part, "abs_path_time")
+                       sub.itemR(part, "path_start", text="Start", slider= not part.abs_path_time)
+                       sub.itemR(part, "path_end", text="End", slider= not part.abs_path_time)         
+                       sub.itemR(part, "random_length", text="Random", slider=True)
+                       
+                       row = layout.row()
+                       col = row.column()
+                       
+                       if part.type=='HAIR' and part.render_strand==True and part.child_type=='FACES':
+                               layout.itemR(part, "enable_simplify")
+                               if part.enable_simplify==True:
+                                       row = layout.row()
+                                       row.itemR(part, "simplify_refsize")
+                                       row.itemR(part, "simplify_rate")
+                                       row.itemR(part, "simplify_transition")
+                                       row = layout.row()
+                                       row.itemR(part, "viewport")
+                                       subrow = row.row()
+                                       subrow.active = part.viewport==True
+                                       subrow.itemR(part, "simplify_viewport")
+                       
+
+               elif part.ren_as == 'OBJECT':
+                       sub.itemR(part, "dupli_object")
+               elif part.ren_as == 'GROUP':
+                       sub.itemR(part, "dupli_group")
+                       split = layout.split()
+                       sub = split.column()
+                       sub.itemR(part, "whole_group")
+                       sub = split.column()
+                       colsub = sub.column()
+                       colsub.active = part.whole_group == False
+                       colsub.itemR(part, "rand_group")
+                       
+               elif part.ren_as == 'BILLBOARD':
+                       sub.itemL(text="Align:")
+                       
+                       row = layout.row()
+                       row.itemR(part, "billboard_align", expand=True)
+                       row.itemR(part, "billboard_lock", text="Lock")
+                       row = layout.row()
+                       row.itemR(part, "billboard_object")
+               
+                       row = layout.row()
+                       col = row.column(align=True)
+                       col.itemL(text="Tilt:")
+                       col.itemR(part, "billboard_tilt", text="Angle", slider=True)
+                       col.itemR(part, "billboard_random_tilt", slider=True)
+                       col = row.column()
+                       col.itemR(part, "billboard_offset")
+                       
+                       row = layout.row()
+                       row.itemR(psys, "billboard_normal_uv")
+                       row = layout.row()
+                       row.itemR(psys, "billboard_time_index_uv")
+                       
+                       row = layout.row()
+                       row.itemL(text="Split uv's:")
+                       row.itemR(part, "billboard_uv_split", text="Number of splits")
+                       row = layout.row()
+                       row.itemR(psys, "billboard_split_uv")
+                       row = layout.row()
+                       row.itemL(text="Animate:")
+                       row.itemR(part, "billboard_animation", expand=True)
+                       row.itemL(text="Offset:")
+                       row.itemR(part, "billboard_split_offset", expand=True)
+               if part.ren_as == 'HALO' or part.ren_as == 'LINE' or part.ren_as=='BILLBOARD':
+                       row = layout.row()
+                       col = row.column()
+                       col.itemR(part, "trail_count")
+                       if part.trail_count > 1:
+                               col.itemR(part, "abs_path_time", text="Length in frames")
+                               col = row.column()
+                               col.itemR(part, "path_end", text="Length", slider=not part.abs_path_time)
+                               col.itemR(part, "random_length", text="Random", slider=True)
+                       else:
+                               col = row.column()
+                               col.itemL(text="")
+                               
+class PARTICLE_PT_draw(ParticleButtonsPanel):
+       __label__ = "Display"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               psys = context.particle_system
+               if psys==None: return False
+               if psys.settings==None: return False
+               return True;
+       
+       def draw(self, context):
+               layout = self.layout
+
+               psys = context.particle_system
+               part = psys.settings
+               
+               row = layout.row()
+               row.itemR(part, "draw_as", expand=True)
+               
+               if part.draw_as=='NONE' or (part.ren_as=='NONE' and part.draw_as=='RENDER'):
+                       return
+                       
+               path = (part.ren_as=='PATH' and part.draw_as=='RENDER') or part.draw_as=='PATH'
+                       
+               if path and part.type!='HAIR' and part.physics_type!='KEYED' and psys.point_cache.baked==False:
+                       box = layout.box()
+                       box.itemL(text="Baked or keyed particles needed for correct drawing.")
+                       return
+               
+               row = layout.row()
+               row.itemR(part, "display", slider=True)
+               if part.draw_as!='RENDER' or part.ren_as=='HALO':
+                       row.itemR(part, "draw_size")
+               else:
+                       row.itemL(text="")
+               
+               row = layout.row()
+               col = row.column()
+               col.itemR(part, "show_size")
+               col.itemR(part, "velocity")
+               col.itemR(part, "num")
+               if part.physics_type == 'BOIDS':
+                       col.itemR(part, "draw_health")
+               
+               col = row.column()
+               col.itemR(part, "material_color", text="Use material color")
+               
+               if (path):                      
+                       col.itemR(part, "draw_step")
+               else:
+                       subcol = col.column()
+                       subcol.active = part.material_color==False
+                       #subcol.itemL(text="color")
+                       #subcol.itemL(text="Override material color")
+
+class PARTICLE_PT_children(ParticleButtonsPanel):
+       __label__ = "Children"
+       __default_closed__ = True
+
+       def draw(self, context):
+               layout = self.layout
+
+               psys = context.particle_system
+               part = psys.settings
+               
+               layout.row().itemR(part, "child_type", expand=True)
+               
+               if part.child_type=='NONE':
+                       return
+               
+               row = layout.row()
+               
+               col = row.column(align=True)
+               col.itemR(part, "child_nbr", text="Display")
+               col.itemR(part, "rendered_child_nbr", text="Render")
+               
+               col = row.column(align=True)
+               
+               if part.child_type=='FACES':
+                       col.itemR(part, "virtual_parents", slider=True)
+               else:
+                       col.itemR(part, "child_radius", text="Radius")
+                       col.itemR(part, "child_roundness", text="Roundness", slider=True)
+               
+                       col = row.column(align=True)
+                       col.itemR(part, "child_size", text="Size")
+                       col.itemR(part, "child_random_size", text="Random")
+               
+               layout.row().itemL(text="Effects:")
+               
+               row = layout.row()
+               
+               col = row.column(align=True)
+               col.itemR(part, "clump_factor", slider=True)
+               col.itemR(part, "clumppow", slider=True)
+               
+               col = row.column(align=True)
+               col.itemR(part, "rough_endpoint")
+               col.itemR(part, "rough_end_shape")
+
+               row = layout.row()
+               
+               col = row.column(align=True)
+               col.itemR(part, "rough1")
+               col.itemR(part, "rough1_size")
+
+               col = row.column(align=True)
+               col.itemR(part, "rough2")
+               col.itemR(part, "rough2_size")
+               col.itemR(part, "rough2_thres", slider=True)
+               
+               row = layout.row()
+               col = row.column(align=True)
+               col.itemR(part, "child_length", slider=True)
+               col.itemR(part, "child_length_thres", slider=True)
+               
+               col = row.column(align=True)
+               col.itemL(text="Space reserved for")
+               col.itemL(text="hair parting controls")
+               
+               layout.row().itemL(text="Kink:")
+               layout.row().itemR(part, "kink", expand=True)
+               
+               split = layout.split()
+               
+               sub = split.column()
+               sub.itemR(part, "kink_amplitude")
+               sub.itemR(part, "kink_frequency")
+               sub = split.column()
+               sub.itemR(part, "kink_shape", slider=True)
+
+class PARTICLE_PT_effectors(ParticleButtonsPanel):
+       __label__ = "Effectors"
+       __default_closed__ = True
+       
+       def draw(self, context):
+               layout = self.layout
+
+               psys = context.particle_system
+               part = psys.settings
+               
+               layout.itemR(part, "effector_group")
+               
+               layout.itemR(part, "eweight_all", slider=True)
+               
+               layout.itemS()
+               layout.itemR(part, "eweight_spherical", slider=True)
+               layout.itemR(part, "eweight_vortex", slider=True)
+               layout.itemR(part, "eweight_magnetic", slider=True)
+               layout.itemR(part, "eweight_wind", slider=True)
+               layout.itemR(part, "eweight_curveguide", slider=True)
+               layout.itemR(part, "eweight_texture", slider=True)
+               layout.itemR(part, "eweight_harmonic", slider=True)
+               layout.itemR(part, "eweight_charge", slider=True)
+               layout.itemR(part, "eweight_lennardjones", slider=True)
+               
+class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
+       __label__ = "Vertexgroups"
+       __default_closed__ = True
+
+       def draw(self, context):
+               layout = self.layout
+
+               psys = context.particle_system
+               part = psys.settings
+               
+               layout.itemL(text="Nothing here yet.")
+
+               #row = layout.row()
+               #row.itemL(text="Vertex Group")
+               #row.itemL(text="Negate")
+
+               
+               #row = layout.row()
+               #row.itemR(psys, "vertex_group_density")
+               #row.itemR(psys, "vertex_group_density_negate", text="")
+               
+               #row = layout.row()
+               #row.itemR(psys, "vertex_group_velocity")
+               #row.itemR(psys, "vertex_group_velocity_negate", text="")
+               
+               #row = layout.row()
+               #row.itemR(psys, "vertex_group_length")
+               #row.itemR(psys, "vertex_group_length_negate", text="")
+               
+               #row = layout.row()
+               #row.itemR(psys, "vertex_group_clump")
+               #row.itemR(psys, "vertex_group_clump_negate", text="")
+               
+               #row = layout.row()
+               #row.itemR(psys, "vertex_group_kink")
+               #row.itemR(psys, "vertex_group_kink_negate", text="")
+               
+               #row = layout.row()
+               #row.itemR(psys, "vertex_group_roughness1")
+               #row.itemR(psys, "vertex_group_roughness1_negate", text="")
+               
+               #row = layout.row()
+               #row.itemR(psys, "vertex_group_roughness2")
+               #row.itemR(psys, "vertex_group_roughness2_negate", text="")
+               
+               #row = layout.row()
+               #row.itemR(psys, "vertex_group_roughness_end")
+               #row.itemR(psys, "vertex_group_roughness_end_negate", text="")
+
+               #row = layout.row()
+               #row.itemR(psys, "vertex_group_size")
+               #row.itemR(psys, "vertex_group_size_negate", text="")
+               
+               #row = layout.row()
+               #row.itemR(psys, "vertex_group_tangent")
+               #row.itemR(psys, "vertex_group_tangent_negate", text="")
+               
+               #row = layout.row()
+               #row.itemR(psys, "vertex_group_rotation")
+               #row.itemR(psys, "vertex_group_rotation_negate", text="")
+               
+               #row = layout.row()
+               #row.itemR(psys, "vertex_group_field")
+               #row.itemR(psys, "vertex_group_field_negate", text="")
+               
+bpy.types.register(PARTICLE_PT_particles)
+bpy.types.register(PARTICLE_PT_hair_dynamics)
+bpy.types.register(PARTICLE_PT_cache)
+bpy.types.register(PARTICLE_PT_emission)
+bpy.types.register(PARTICLE_PT_initial)
+bpy.types.register(PARTICLE_PT_physics)
+bpy.types.register(PARTICLE_PT_boidbrain)
+bpy.types.register(PARTICLE_PT_render)
+bpy.types.register(PARTICLE_PT_draw)
+bpy.types.register(PARTICLE_PT_children)
+bpy.types.register(PARTICLE_PT_effectors)
+bpy.types.register(PARTICLE_PT_vertexgroups)
diff --git a/release/ui/buttons_physics_cloth.py b/release/ui/buttons_physics_cloth.py
new file mode 100644 (file)
index 0000000..5cdca3c
--- /dev/null
@@ -0,0 +1,172 @@
+
+import bpy
+
+from buttons_particle import point_cache_ui
+
+def cloth_panel_enabled(md):
+       return md.point_cache.baked==False
+
+class PhysicButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "physics"
+
+       def poll(self, context):
+               ob = context.object
+               rd = context.scene.render_data
+               return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
+               
+class PHYSICS_PT_cloth(PhysicButtonsPanel):
+       __label__ = "Cloth"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               md = context.cloth
+               ob = context.object
+
+               split = layout.split()
+               split.operator_context = 'EXEC_DEFAULT'
+
+               if md:
+                       # remove modifier + settings
+                       split.set_context_pointer("modifier", md)
+                       split.itemO("object.modifier_remove", text="Remove")
+
+                       row = split.row(align=True)
+                       row.itemR(md, "render", text="")
+                       row.itemR(md, "realtime", text="")
+               else:
+                       # add modifier
+                       split.item_enumO("object.modifier_add", "type", 'CLOTH', text="Add")
+                       split.itemL()
+
+               if md:
+                       cloth = md.settings
+                       
+                       layout.active = cloth_panel_enabled(md)
+
+                       split = layout.split()
+                       
+                       col = split.column()
+                       col.itemL(text="Quality:")
+                       col.itemR(cloth, "quality", text="Steps",slider=True)
+                       col.itemL(text="Gravity:")
+                       col.itemR(cloth, "gravity", text="")
+
+                       col.itemR(cloth, "pin_cloth", text="Pin")
+                       sub = col.column(align=True)
+                       sub.active = cloth.pin_cloth
+                       sub.itemR(cloth, "pin_stiffness", text="Stiffness")
+                       sub.item_pointerR(cloth, "mass_vertex_group", ob, "vertex_groups", text="")
+                       
+                       col = split.column()
+                       col.itemL(text="Presets...")
+                       col.itemL(text="TODO!")
+                       col.itemL(text="Material:")
+                       sub = col.column(align=True)
+                       sub.itemR(cloth, "mass")
+                       sub.itemR(cloth, "structural_stiffness", text="Structural")
+                       sub.itemR(cloth, "bending_stiffness", text="Bending")
+                       col.itemL(text="Damping:")
+                       sub = col.column(align=True)
+                       sub.itemR(cloth, "spring_damping", text="Spring")
+                       sub.itemR(cloth, "air_damping", text="Air")
+                       
+                       # Disabled for now
+                       """
+                       if cloth.mass_vertex_group:
+                               layout.itemL(text="Goal:")
+                       
+                               col = layout.column_flow()
+                               col.itemR(cloth, "goal_default", text="Default")
+                               col.itemR(cloth, "goal_spring", text="Stiffness")
+                               col.itemR(cloth, "goal_friction", text="Friction")
+                       """
+
+class PHYSICS_PT_cloth_cache(PhysicButtonsPanel):
+       __label__ = "Cloth Cache"
+       __default_closed__ = True
+
+       def poll(self, context):
+               return (context.cloth)
+
+       def draw(self, context):
+               md = context.cloth
+               point_cache_ui(self, md.point_cache, cloth_panel_enabled(md), 0, 0)
+               
+class PHYSICS_PT_cloth_collision(PhysicButtonsPanel):
+       __label__ = "Cloth Collision"
+       __default_closed__ = True
+
+       def poll(self, context):
+               return (context.cloth)
+       
+       def draw_header(self, context):
+               cloth = context.cloth.collision_settings
+               
+               self.layout.active = cloth_panel_enabled(context.cloth)
+               self.layout.itemR(cloth, "enable_collision", text="")
+
+       def draw(self, context):
+               layout = self.layout
+               
+               cloth = context.cloth.collision_settings
+               md = context.cloth
+               
+               layout.active = cloth.enable_collision and cloth_panel_enabled(md)
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemR(cloth, "collision_quality", slider=True, text="Quality")
+               col.itemR(cloth, "min_distance", slider=True, text="Distance")
+               col.itemR(cloth, "friction")
+               
+               col = split.column()
+               col.itemR(cloth, "enable_self_collision", text="Self Collision")
+               sub = col.column()
+               sub.active = cloth.enable_self_collision
+               sub.itemR(cloth, "self_collision_quality", slider=True, text="Quality")
+               sub.itemR(cloth, "self_min_distance", slider=True, text="Distance")
+
+class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel):
+       __label__ = "Cloth Stiffness Scaling"
+       __default_closed__ = True
+
+       def poll(self, context):
+               return (context.cloth != None)
+       
+       def draw_header(self, context):
+               cloth = context.cloth.settings
+       
+               self.layout.active = cloth_panel_enabled(context.cloth)
+               self.layout.itemR(cloth, "stiffness_scaling", text="")
+
+       def draw(self, context):
+               layout = self.layout
+               
+               md = context.cloth
+               ob = context.object
+               cloth = context.cloth.settings
+               
+               layout.active = cloth.stiffness_scaling and cloth_panel_enabled(md)
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Structural Stiffness:")
+               sub = col.column(align=True)
+               sub.itemR(cloth, "structural_stiffness_max", text="Max")
+               sub.item_pointerR(cloth, "structural_stiffness_vertex_group", ob, "vertex_groups", text="")
+               
+               col = split.column()
+               col.itemL(text="Bending Stiffness:")
+               sub = col.column(align=True)
+               sub.itemR(cloth, "bending_stiffness_max", text="Max")
+               sub.item_pointerR(cloth, "bending_vertex_group", ob, "vertex_groups", text="")
+               
+bpy.types.register(PHYSICS_PT_cloth)
+bpy.types.register(PHYSICS_PT_cloth_cache)
+bpy.types.register(PHYSICS_PT_cloth_collision)
+bpy.types.register(PHYSICS_PT_cloth_stiffness)
diff --git a/release/ui/buttons_physics_field.py b/release/ui/buttons_physics_field.py
new file mode 100644 (file)
index 0000000..58033d2
--- /dev/null
@@ -0,0 +1,230 @@
+
+import bpy
+
+class PhysicButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "physics"
+
+       def poll(self, context):
+               rd = context.scene.render_data
+               return (context.object) and (not rd.use_game_engine)
+               
+class PHYSICS_PT_field(PhysicButtonsPanel):
+       __label__ = "Force Fields"
+       __default_closed__ = True
+
+       def draw(self, context):
+               layout = self.layout
+               
+               ob = context.object
+               field = ob.field
+
+               #layout.active = field.enabled
+               
+               split = layout.split(percentage=0.2)
+               
+               split.itemL(text="Type:")
+               split.itemR(field, "type",text="")
+                       
+               split = layout.split()
+               
+               if field.type == 'GUIDE':
+                       layout.itemR(field, "guide_path_add")
+                       
+               elif field.type == 'WIND':
+                       split.itemR(field, "strength")
+                       
+                       col = split.column()
+                       col.itemR(field, "noise")
+                       col.itemR(field, "seed")
+
+               elif field.type == 'VORTEX':
+                       split.itemR(field, "strength")
+                       split.itemL()
+                       
+               elif field.type in ('SPHERICAL', 'CHARGE', 'LENNARDJ'):
+                       split.itemR(field, "strength")
+                       
+                       col = split.column()
+                       col.itemR(field, "planar")
+                       col.itemR(field, "surface")
+                       
+               elif field.type == 'BOID':
+                       split.itemR(field, "strength")
+                       split.itemR(field, "surface")
+                       
+               elif field.type == 'MAGNET':
+                       split.itemR(field, "strength")
+                       split.itemR(field, "planar")
+                       
+               elif field.type == 'HARMONIC':
+                       col = split.column()
+                       col.itemR(field, "strength")
+                       col.itemR(field, "harmonic_damping", text="Damping")
+                       
+                       col = split.column()
+                       col.itemR(field, "planar")
+                       col.itemR(field, "surface")
+                       
+               elif field.type == 'TEXTURE':
+                       col = split.column()
+                       col.itemR(field, "strength")
+                       col.itemR(field, "texture", text="")
+                       col.itemR(field, "texture_mode", text="")
+                       col.itemR(field, "texture_nabla")
+                       
+                       col = split.column()
+                       col.itemR(field, "use_coordinates")
+                       col.itemR(field, "root_coordinates")
+                       col.itemR(field, "force_2d")
+                       
+               if field.type in ('HARMONIC', 'SPHERICAL', 'CHARGE', 'WIND', 'VORTEX', 'TEXTURE', 'MAGNET', 'BOID'):
+                       
+                       layout.itemL(text="Falloff:")
+                       layout.itemR(field, "falloff_type", expand=True)
+
+                       split = layout.split(percentage=0.35)
+                       
+                       col = split.column()
+                       col.itemR(field, "positive_z", text="Positive Z")
+                       col.itemR(field, "use_min_distance", text="Use Minimum")
+                       col.itemR(field, "use_max_distance", text="Use Maximum")
+
+                       col = split.column()
+                       col.itemR(field, "falloff_power", text="Power")
+                       
+                       sub = col.column()
+                       sub.active = field.use_min_distance
+                       sub.itemR(field, "minimum_distance", text="Distance")
+                       
+                       sub = col.column()
+                       sub.active = field.use_max_distance
+                       sub.itemR(field, "maximum_distance", text="Distance")
+                       
+                       if field.falloff_type == 'CONE':
+                               
+                               layout.itemS()
+                               
+                               split = layout.split(percentage=0.35)
+                               
+                               col = split.column()
+                               col.itemL(text="Angular:")
+                               col.itemR(field, "use_radial_min", text="Use Minimum")  
+                               col.itemR(field, "use_radial_max", text="Use Maximum")
+                               
+                               col = split.column()
+                               col.itemR(field, "radial_falloff", text="Power")
+                               
+                               sub = col.column()
+                               sub.active = field.use_radial_min
+                               sub.itemR(field, "radial_minimum", text="Angle")
+                               
+                               sub = col.column()
+                               sub.active = field.use_radial_max
+                               sub.itemR(field, "radial_maximum", text="Angle")
+                               
+                       elif field.falloff_type == 'TUBE':
+                               
+                               layout.itemS()
+                               
+                               split = layout.split(percentage=0.35)
+                                       
+                               col = split.column()
+                               col.itemL(text="Radial:")       
+                               col.itemR(field, "use_radial_min", text="Use Minimum")  
+                               col.itemR(field, "use_radial_max", text="Use Maximum")
+                               
+                               col = split.column()
+                               col.itemR(field, "radial_falloff", text="Power")
+                               
+                               sub = col.column()
+                               sub.active = field.use_radial_min
+                               sub.itemR(field, "radial_minimum", text="Distance")
+                               
+                               sub = col.column()
+                               sub.active = field.use_radial_max
+                               sub.itemR(field, "radial_maximum", text="Distance")
+                               
+               #if ob.type in 'CURVE':
+                       #if field.type == 'GUIDE':
+                               #colsub = col.column(align=True)
+                       
+               #if field.type != 'NONE':
+                       #layout.itemR(field, "strength")
+
+               #if field.type in ('HARMONIC', 'SPHERICAL', 'CHARGE', "LENNARDj"):
+                       #if ob.type in ('MESH', 'SURFACE', 'FONT', 'CURVE'):
+                               #layout.itemR(field, "surface")
+
+class PHYSICS_PT_collision(PhysicButtonsPanel):
+       __label__ = "Collision"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               ob = context.object
+               rd = context.scene.render_data
+               return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               md = context.collision
+
+               split = layout.split()
+               split.operator_context = 'EXEC_DEFAULT'
+
+               if md:
+                       # remove modifier + settings
+                       split.set_context_pointer("modifier", md)
+                       split.itemO("object.modifier_remove", text="Remove")
+                       col = split.column()
+                       
+                       #row = split.row(align=True)
+                       #row.itemR(md, "render", text="")
+                       #row.itemR(md, "realtime", text="")
+                       
+                       coll = md.settings
+                       
+               else:
+                       # add modifier
+                       split.item_enumO("object.modifier_add", "type", 'COLLISION', text="Add")
+                       split.itemL()
+                       
+                       coll = None
+               
+               if coll:
+                       settings = context.object.collision
+
+                       layout.active = settings.enabled
+               
+                       split = layout.split()
+               
+                       col = split.column()
+                       col.itemL(text="Particle:")
+                       col.itemR(settings, "permeability", slider=True)
+                       col.itemL(text="Particle Damping:")
+                       sub = col.column(align=True)
+                       sub.itemR(settings, "damping_factor", text="Factor", slider=True)
+                       sub.itemR(settings, "random_damping", text="Random", slider=True)
+               
+                       col.itemL(text="Soft Body and Cloth:")
+                       sub = col.column(align=True)
+                       sub.itemR(settings, "outer_thickness", text="Outer", slider=True)
+                       sub.itemR(settings, "inner_thickness", text="Inner", slider=True)
+               
+                       layout.itemL(text="Force Fields:")
+                       layout.itemR(md, "absorption", text="Absorption")
+               
+                       col = split.column()
+                       col.itemL(text="")
+                       col.itemR(settings, "kill_particles")
+                       col.itemL(text="Particle Friction:")
+                       sub = col.column(align=True)
+                       sub.itemR(settings, "friction_factor", text="Factor", slider=True)
+                       sub.itemR(settings, "random_friction", text="Random", slider=True)
+                       col.itemL(text="Soft Body Damping:")
+                       col.itemR(settings, "damping", text="Factor", slider=True)
+               
+bpy.types.register(PHYSICS_PT_field)
+bpy.types.register(PHYSICS_PT_collision)
diff --git a/release/ui/buttons_physics_fluid.py b/release/ui/buttons_physics_fluid.py
new file mode 100644 (file)
index 0000000..6f7a97f
--- /dev/null
@@ -0,0 +1,260 @@
+
+import bpy
+
+class PhysicButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "physics"
+
+       def poll(self, context):
+               ob = context.object
+               rd = context.scene.render_data
+               return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
+               
+class PHYSICS_PT_fluid(PhysicButtonsPanel):
+       __label__ = "Fluid"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               md = context.fluid
+               ob = context.object
+
+               split = layout.split()
+               split.operator_context = 'EXEC_DEFAULT'
+
+               if md:
+                       # remove modifier + settings
+                       split.set_context_pointer("modifier", md)
+                       split.itemO("object.modifier_remove", text="Remove")
+
+                       row = split.row(align=True)
+                       row.itemR(md, "render", text="")
+                       row.itemR(md, "realtime", text="")
+                       
+                       fluid = md.settings
+                       
+               else:
+                       # add modifier
+                       split.item_enumO("object.modifier_add", "type", 'FLUID_SIMULATION', text="Add")
+                       split.itemL()
+                       
+                       fluid = None
+               
+               
+               if fluid:
+                       layout.itemR(fluid, "type")
+
+                       if fluid.type == 'DOMAIN':
+                               layout.itemO("fluid.bake", text="Bake Fluid Simulation", icon='ICON_MOD_FLUIDSIM')
+                               split = layout.split()
+                               
+                               col = split.column()
+                               col.itemL(text="Resolution:")
+                               col.itemR(fluid, "resolution", text="Final")
+                               col.itemL(text="Render Display:")
+                               col.itemR(fluid, "render_display_mode", text="")
+                               col.itemL(text="Time:")
+                               sub = col.column(align=True)
+                               sub.itemR(fluid, "start_time", text="Start")
+                               sub.itemR(fluid, "end_time", text="End")
+                               
+                               col = split.column()
+                               col.itemL(text="Required Memory: " + fluid.memory_estimate)
+                               col.itemR(fluid, "preview_resolution", text="Preview")
+                               col.itemL(text="Viewport Display:")
+                               col.itemR(fluid, "viewport_display_mode", text="")
+                               col.itemL()
+                               col.itemR(fluid, "generate_speed_vectors")
+                               col.itemR(fluid, "reverse_frames")
+                               
+                               layout.itemR(fluid, "path", text="")
+                               
+                       elif fluid.type == 'FLUID':
+                               split = layout.split()
+                               
+                               col = split.column()
+                               col.itemL(text="Volume Initialization:")
+                               col.itemR(fluid, "volume_initialization", text="")
+                               col.itemR(fluid, "export_animated_mesh")
+                               
+                               col = split.column()
+                               col.itemL(text="Initial Velocity:")
+                               col.itemR(fluid, "initial_velocity", text="")
+                               
+                       elif fluid.type == 'OBSTACLE':
+                               split = layout.split()
+                               
+                               col = split.column()
+                               col.itemL(text="Volume Initialization:")
+                               col.itemR(fluid, "volume_initialization", text="")
+                               col.itemR(fluid, "export_animated_mesh")
+                               
+                               col = split.column()
+                               col.itemL(text="Slip Type:")
+                               col.itemR(fluid, "slip_type", text="")
+                               if fluid.slip_type == 'PARTIALSLIP':
+                                       col.itemR(fluid, "partial_slip_factor", slider=True, text="Amount")
+                                       
+                               col.itemL(text="Impact:")
+                               col.itemR(fluid, "impact_factor", text="Factor")
+                               
+                       elif fluid.type == 'INFLOW':
+                               split = layout.split()
+                               
+                               col = split.column()
+                               col.itemL(text="Volume Initialization:")
+                               col.itemR(fluid, "volume_initialization", text="")
+                               col.itemR(fluid, "export_animated_mesh")
+                               col.itemR(fluid, "local_coordinates")
+                               
+                               col = split.column()
+                               col.itemL(text="Inflow Velocity:")
+                               col.itemR(fluid, "inflow_velocity", text="")
+                               
+                       elif fluid.type == 'OUTFLOW':
+                               split = layout.split()
+                               
+                               col = split.column()
+                               col.itemL(text="Volume Initialization:")
+                               col.itemR(fluid, "volume_initialization", text="")
+                               col.itemR(fluid, "export_animated_mesh")
+                               
+                               split.column()
+                               
+                       elif fluid.type == 'PARTICLE':
+                               split = layout.split(percentage=0.5)
+                               
+                               col = split.column()
+                               col.itemL(text="Influence:")
+                               col.itemR(fluid, "particle_influence", text="Size")
+                               col.itemR(fluid, "alpha_influence", text="Alpha")
+                               
+                               col = split.column()
+                               col.itemL(text="Type:")
+                               col.itemR(fluid, "drops")
+                               col.itemR(fluid, "floats")
+                               col = split.column()
+                               col.itemL()
+                               col.itemR(fluid, "tracer")
+                               
+                               layout.itemR(fluid, "path", text="")
+                               
+                       elif fluid.type == 'CONTROL':
+                               split = layout.split()
+                               
+                               col = split.column()
+                               col.itemL(text="")
+                               col.itemR(fluid, "quality", slider=True)
+                               col.itemR(fluid, "reverse_frames")
+                               
+                               col = split.column()
+                               col.itemL(text="Time:")
+                               sub = col.column(align=True)
+                               sub.itemR(fluid, "start_time", text="Start")
+                               sub.itemR(fluid, "end_time", text="End")
+                               
+                               split = layout.split()
+                               
+                               col = split.column()
+                               col.itemL(text="Attraction Force:")
+                               sub = col.column(align=True)
+                               sub.itemR(fluid, "attraction_strength", text="Strength")
+                               sub.itemR(fluid, "attraction_radius", text="Radius")
+                               
+                               col = split.column()
+                               col.itemL(text="Velocity Force:")
+                               sub = col.column(align=True)
+                               sub.itemR(fluid, "velocity_strength", text="Strength")
+                               sub.itemR(fluid, "velocity_radius", text="Radius")
+
+class PHYSICS_PT_domain_gravity(PhysicButtonsPanel):
+       __label__ = "Domain World"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               md = context.fluid
+               if md:
+                       return (md.settings.type == 'DOMAIN')
+
+       def draw(self, context):
+               layout = self.layout
+               
+               fluid = context.fluid.settings
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Gravity:")
+               col.itemR(fluid, "gravity", text="")
+               col.itemL(text="Real World Size:")
+               col.itemR(fluid, "real_world_size", text="Metres")
+               
+               col = split.column()
+               col.itemL(text="Viscosity Presets:")
+               sub = col.column(align=True)
+               sub.itemR(fluid, "viscosity_preset", text="")
+               
+               if fluid.viscosity_preset == 'MANUAL':
+                       sub.itemR(fluid, "viscosity_base", text="Base")
+                       sub.itemR(fluid, "viscosity_exponent", text="Exponent", slider=True)
+               else:
+                       sub.itemL()
+                       sub.itemL()
+                       
+               col.itemL(text="Optimization:")
+               sub = col.column(align=True)
+               sub.itemR(fluid, "grid_levels", slider=True)
+               sub.itemR(fluid, "compressibility", slider=True)
+       
+class PHYSICS_PT_domain_boundary(PhysicButtonsPanel):
+       __label__ = "Domain Boundary"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               md = context.fluid
+               if md:
+                       return (md.settings.type == 'DOMAIN')
+
+       def draw(self, context):
+               layout = self.layout
+               
+               fluid = context.fluid.settings
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Slip Type:")
+               sub = col.column(align=True)
+               sub.itemR(fluid, "slip_type", text="")
+               if fluid.slip_type == 'PARTIALSLIP':
+                       sub.itemR(fluid, "partial_slip_factor", slider=True, text="Amount")
+
+               col = split.column()
+               col.itemL(text="Surface:")
+               sub = col.column(align=True)
+               sub.itemR(fluid, "surface_smoothing", text="Smoothing")
+               sub.itemR(fluid, "surface_subdivisions", text="Subdivisions")   
+               
+class PHYSICS_PT_domain_particles(PhysicButtonsPanel):
+       __label__ = "Domain Particles"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               md = context.fluid
+               if md:
+                       return (md.settings.type == 'DOMAIN')
+                       
+       def draw(self, context):
+               layout = self.layout
+               
+               fluid = context.fluid.settings
+               
+               col = layout.column(align=True)
+               col.itemR(fluid, "tracer_particles")
+               col.itemR(fluid, "generate_particles")
+
+bpy.types.register(PHYSICS_PT_fluid)
+bpy.types.register(PHYSICS_PT_domain_gravity)
+bpy.types.register(PHYSICS_PT_domain_boundary)
+bpy.types.register(PHYSICS_PT_domain_particles)
diff --git a/release/ui/buttons_physics_smoke.py b/release/ui/buttons_physics_smoke.py
new file mode 100644 (file)
index 0000000..6aee152
--- /dev/null
@@ -0,0 +1,182 @@
+
+import bpy
+
+from buttons_particle import point_cache_ui
+
+class PhysicButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "physics"
+
+       def poll(self, context):
+               ob = context.object
+               rd = context.scene.render_data
+               return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
+               
+class PHYSICS_PT_smoke(PhysicButtonsPanel):
+       __label__ = "Smoke"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               md = context.smoke
+               ob = context.object
+
+               split = layout.split()
+               split.operator_context = 'EXEC_DEFAULT'
+
+               if md:
+                       # remove modifier + settings
+                       split.set_context_pointer("modifier", md)
+                       split.itemO("object.modifier_remove", text="Remove")
+
+                       row = split.row(align=True)
+                       row.itemR(md, "render", text="")
+                       row.itemR(md, "realtime", text="")
+                       
+               else:
+                       # add modifier
+                       split.item_enumO("object.modifier_add", "type", 'SMOKE', text="Add")
+                       split.itemL()
+
+               if md:
+                       layout.itemR(md, "smoke_type", expand=True)
+               
+                       if md.smoke_type == 'TYPE_DOMAIN':
+                               
+                               domain = md.domain_settings
+                               
+                               split = layout.split()
+                               
+                               col = split.column()
+                               col.itemL(text="Resolution:")
+                               col.itemR(domain, "maxres", text="Divisions")
+                               
+                               col = split.column()
+                               col.itemL(text="Behavior:")
+                               col.itemR(domain, "alpha")
+                               col.itemR(domain, "beta")
+                               col.itemR(domain, "dissolve_smoke", text="Dissolve")
+                               sub = col.column()
+                               sub.active = domain.dissolve_smoke
+                               sub.itemR(domain, "dissolve_speed", text="Time")
+                               sub.itemR(domain, "dissolve_smoke_log", text="Slow")
+                               
+                       elif md.smoke_type == 'TYPE_FLOW':
+                               
+                               flow = md.flow_settings
+                               
+                               split = layout.split()
+                               
+                               col = split.column()
+                               col.itemR(flow, "outflow")
+                               col.itemL(text="Particle System:")
+                               col.item_pointerR(flow, "psys", ob, "particle_systems", text="")
+                               
+                               if md.flow_settings.outflow:                            
+                                       col = split.column()
+                               else:
+                                       col = split.column()
+                                       col.itemL(text="Behavior:")
+                                       col.itemR(flow, "temperature")
+                                       col.itemR(flow, "density")
+                                       
+                       #elif md.smoke_type == 'TYPE_COLL':
+                       #       layout.itemS()
+
+class PHYSICS_PT_smoke_groups(PhysicButtonsPanel):
+       __label__ = "Smoke Groups"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               md = context.smoke
+               if md:
+                               return (md.smoke_type == 'TYPE_DOMAIN')
+               
+               return False
+
+       def draw(self, context):
+               layout = self.layout
+               
+               group = context.smoke.domain_settings
+               
+               split = layout.split()
+               
+               col = split.column()
+               col.itemL(text="Flow Group:")
+               col.itemR(group, "fluid_group", text="")
+                               
+               #col.itemL(text="Effector Group:")
+               #col.itemR(group, "eff_group", text="")
+                               
+               col = split.column()
+               col.itemL(text="Collision Group:")
+               col.itemR(group, "coll_group", text="")
+
+class PHYSICS_PT_smoke_cache(PhysicButtonsPanel):
+       __label__ = "Smoke Cache"
+       __default_closed__ = True
+
+       def poll(self, context):
+               md = context.smoke
+               return md and (md.smoke_type == 'TYPE_DOMAIN')
+
+       def draw(self, context):
+               layout = self.layout
+
+               md = context.smoke.domain_settings
+               cache = md.point_cache_low
+                       
+               point_cache_ui(self, cache, cache.baked==False, 0, 1)
+                                       
+class PHYSICS_PT_smoke_highres(PhysicButtonsPanel):
+       __label__ = "Smoke High Resolution"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               md = context.smoke
+               return md and (md.smoke_type == 'TYPE_DOMAIN')
+
+       def draw_header(self, context): 
+               high = context.smoke.domain_settings
+       
+               self.layout.itemR(high, "highres", text="")
+               
+       def draw(self, context):
+               layout = self.layout
+               
+               md = context.smoke.domain_settings
+
+               split = layout.split()
+                       
+               col = split.column()
+               col.itemL(text="Resolution:")
+               col.itemR(md, "amplify", text="Divisions")
+                       
+               col = split.column()
+               col.itemL(text="Noise Method:")
+               col.row().itemR(md, "noise_type", text="")
+               col.itemR(md, "strength")
+               col.itemR(md, "viewhighres")
+               
+class PHYSICS_PT_smoke_cache_highres(PhysicButtonsPanel):
+       __label__ = "Smoke High Resolution Cache"
+       __default_closed__ = True
+
+       def poll(self, context):
+               md = context.smoke
+               return md and (md.smoke_type == 'TYPE_DOMAIN') and md.domain_settings.highres
+
+       def draw(self, context):
+               layout = self.layout
+
+               md = context.smoke.domain_settings
+               cache = md.point_cache_high
+                       
+               point_cache_ui(self, cache, cache.baked==False, 0, 1)
+                                       
+bpy.types.register(PHYSICS_PT_smoke)
+bpy.types.register(PHYSICS_PT_smoke_cache)
+bpy.types.register(PHYSICS_PT_smoke_highres)
+bpy.types.register(PHYSICS_PT_smoke_groups)
+bpy.types.register(PHYSICS_PT_smoke_cache_highres)
diff --git a/release/ui/buttons_physics_softbody.py b/release/ui/buttons_physics_softbody.py
new file mode 100644 (file)
index 0000000..703977a
--- /dev/null
@@ -0,0 +1,231 @@
+
+import bpy
+
+from buttons_particle import point_cache_ui
+
+def softbody_panel_enabled(md):
+       return md.point_cache.baked==False
+
+class PhysicButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "physics"
+
+       def poll(self, context):
+               ob = context.object
+               rd = context.scene.render_data
+               return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
+               
+class PHYSICS_PT_softbody(PhysicButtonsPanel):
+       __label__ = "Soft Body"
+
+       def draw(self, context):
+               layout = self.layout
+               
+               md = context.soft_body
+               ob = context.object
+
+               split = layout.split()
+               split.operator_context = "EXEC_DEFAULT"
+
+               if md:
+                       # remove modifier + settings
+                       split.set_context_pointer("modifier", md)
+                       split.itemO("object.modifier_remove", text="Remove")
+
+                       row = split.row(align=True)
+                       row.itemR(md, "render", text="")
+                       row.itemR(md, "realtime", text="")
+               else:
+                       # add modifier
+                       split.item_enumO("object.modifier_add", "type", 'SOFT_BODY', text="Add")
+                       split.itemL("")
+                       
+               if md:
+                       softbody = md.settings
+
+                       # General
+                       split = layout.split()
+                       split.enabled = softbody_panel_enabled(md)
+                       
+                       col = split.column()
+                       col.itemL(text="Object:")
+                       col.itemR(softbody, "mass")
+                       col.itemR(softbody, "friction")
+
+                       col = split.column()
+                       col.itemL(text="Simulation:")
+                       col.itemR(softbody, "gravity")
+                       col.itemR(softbody, "speed")
+                       
+class PHYSICS_PT_softbody_cache(PhysicButtonsPanel):
+       __label__ = "Soft Body Cache"
+       __default_closed__ = True
+
+       def poll(self, context):
+               return (context.soft_body)
+
+       def draw(self, context):
+               md = context.soft_body
+               point_cache_ui(self, md.point_cache, softbody_panel_enabled(md), 0, 0)
+                       
+class PHYSICS_PT_softbody_goal(PhysicButtonsPanel):
+       __label__ = "Soft Body Goal"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               return (context.soft_body)
+               
+       def draw_header(self, context):
+               softbody = context.soft_body.settings
+       
+               self.layout.active = softbody_panel_enabled(context.soft_body)
+               self.layout.itemR(softbody, "use_goal", text="")
+               
+       def draw(self, context):
+               layout = self.layout
+               
+               md = context.soft_body
+               softbody = md.settings
+               ob = context.object
+               
+               layout.active = softbody.use_goal and softbody_panel_enabled(md)
+
+               split = layout.split()
+
+               # Goal 
+               split = layout.split()
+
+               col = split.column()
+               col.itemL(text="Goal Strengths:")
+               col.itemR(softbody, "goal_default", text="Default")
+               sub = col.column(align=True)
+               sub.itemR(softbody, "goal_min", text="Minimum")
+               sub.itemR(softbody, "goal_max", text="Maximum")
+                       
+               col = split.column()
+               col.itemL(text="Goal Settings:")
+               col.itemR(softbody, "goal_spring", text="Stiffness")
+               col.itemR(softbody, "goal_friction", text="Damping")
+                       
+               layout.item_pointerR(softbody, "goal_vertex_group", ob, "vertex_groups", text="Vertex Group")
+
+class PHYSICS_PT_softbody_edge(PhysicButtonsPanel):
+       __label__ = "Soft Body Edges"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               return (context.soft_body)
+               
+       def draw_header(self, context):
+               softbody = context.soft_body.settings
+       
+               self.layout.active = softbody_panel_enabled(context.soft_body)
+               self.layout.itemR(softbody, "use_edges", text="")
+               
+       def draw(self, context):
+               layout = self.layout
+               
+               md = context.soft_body
+               softbody = md.settings
+               ob = context.object
+
+               layout.active = softbody.use_edges and softbody_panel_enabled(md)
+                       
+               split = layout.split()
+                       
+               col = split.column()
+               col.itemL(text="Springs:")
+               col.itemR(softbody, "pull")
+               col.itemR(softbody, "push")
+               col.itemR(softbody, "damp")
+               col.itemR(softbody, "plastic")
+               col.itemR(softbody, "bending")
+               col.itemR(softbody, "spring_length", text="Length")
+                       
+               col = split.column()
+               col.itemR(softbody, "stiff_quads")
+               sub = col.column()
+               sub.active = softbody.stiff_quads
+               sub.itemR(softbody, "shear")
+                       
+               col.itemR(softbody, "new_aero", text="Aero")
+               sub = col.column()
+               sub.enabled = softbody.new_aero
+               sub.itemR(softbody, "aero", text="Factor")
+
+               col.itemL(text="Collision:")
+               col.itemR(softbody, "edge_collision", text="Edge")
+               col.itemR(softbody, "face_collision", text="Face")
+                       
+class PHYSICS_PT_softbody_collision(PhysicButtonsPanel):
+       __label__ = "Soft Body Collision"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               return (context.soft_body)
+               
+       def draw_header(self, context):
+               softbody = context.soft_body.settings
+       
+               self.layout.active = softbody_panel_enabled(context.soft_body)
+               self.layout.itemR(softbody, "self_collision", text="")
+               
+       def draw(self, context):
+               layout = self.layout
+               
+               md = context.soft_body
+               softbody = md.settings
+               ob = context.object
+
+               layout.active = softbody.self_collision and softbody_panel_enabled(md)
+                       
+               layout.itemL(text="Collision Type:")
+               layout.itemR(softbody, "collision_type", expand=True)
+                       
+               col = layout.column(align=True)
+               col.itemL(text="Ball:")
+               col.itemR(softbody, "ball_size", text="Size")
+               col.itemR(softbody, "ball_stiff", text="Stiffness")
+               col.itemR(softbody, "ball_damp", text="Dampening")
+
+class PHYSICS_PT_softbody_solver(PhysicButtonsPanel):
+       __label__ = "Soft Body Solver"
+       __default_closed__ = True
+       
+       def poll(self, context):
+               return (context.soft_body)
+               
+       def draw(self, context):
+               layout = self.layout
+               
+               md = context.soft_body
+               softbody = md.settings
+               ob = context.object
+
+               layout.active = softbody_panel_enabled(md)
+
+               # Solver
+               split = layout.split()
+                       
+               col = split.column(align=True)
+               col.itemL(text="Step Size:")
+               col.itemR(softbody, "minstep")
+               col.itemR(softbody, "maxstep")
+               col.itemR(softbody, "auto_step", text="Auto-Step")
+                       
+               col = split.column()
+               col.itemR(softbody, "error_limit")
+               col.itemL(text="Helpers:")
+               col.itemR(softbody, "choke")
+               col.itemR(softbody, "fuzzy")
+                       
+               layout.itemL(text="Diagnostics:")
+               layout.itemR(softbody, "diagnose")
+       
+bpy.types.register(PHYSICS_PT_softbody)
+bpy.types.register(PHYSICS_PT_softbody_cache)
+bpy.types.register(PHYSICS_PT_softbody_goal)
+bpy.types.register(PHYSICS_PT_softbody_edge)
+bpy.types.register(PHYSICS_PT_softbody_collision)
+bpy.types.register(PHYSICS_PT_softbody_solver)
diff --git a/release/ui/buttons_scene.py b/release/ui/buttons_scene.py
new file mode 100644 (file)
index 0000000..3c321f1
--- /dev/null
@@ -0,0 +1,463 @@
+
+import bpy
+
+class RenderButtonsPanel(bpy.types.Panel):
+       __space_type__ = 'PROPERTIES'
+       __region_type__ = 'WINDOW'
+       __context__ = "scene"
+       # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
+       
+       def poll(self, context):
+               rd = context.scene.render_data
+               return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES)
+
+class SCENE_PT_render(RenderButtonsPanel):
+       __label__ = "Render"
+       COMPAT_ENGINES = set(['BLENDER_RENDER'])
+       
+       def draw(self, context):
+               layout = self.layout
+               
+               rd = context.scene.render_data
+
+               row = layout.row()
+               row.itemO("screen.render", text="Image", icon='ICON_RENDER_RESULT')
+               row.item_booleanO("screen.render", "animation", True, text="Animation", icon='ICON_RENDER_ANIMATION')
+
+               layout.itemR(rd, "display_mode", text="Display")
+
+class SCENE_PT_layers(RenderButtonsPanel):
+       __label__ = "Layers"
+       __default_closed__ = True
+       COMPAT_ENGINES = set(['BLENDER_RENDER'])
+       
+       def draw(self, co