2
0
Эх сурвалжийг харах

Fixed bugs in exporter, check for uuvs, textures, added files for anki material panel

akal 9 жил өмнө
parent
commit
6f6cbb39ab

+ 12 - 2
tools/anki_scene_exporter/__init__.py

@@ -22,14 +22,22 @@ if "bpy" in locals():
 
 	importlib.reload(ops.environment)
 	importlib.reload(ops.export)
+	importlib.reload(ops.gui)
+	importlib.reload(ops.material)
+	importlib.reload(ops.text)
 	importlib.reload(props.export_props)
 	importlib.reload(ui.gui)
+	importlib.reload(ui.panel_prop_dynamic)
 
 else:
 	from .ops import environment
 	from .ops import export
+	from .ops import gui
+	from .ops import material
+	from .ops import text
 	from .props import export_props
 	from .ui import gui
+	from .ui import panel_prop_dynamic
 
 import bpy, os
 from bpy.types import AddonPreferences
@@ -137,13 +145,15 @@ class SCENE_anki_scene_exporter(AddonPreferences):
 
 		layout.operator("scene.anki_preference_set", text="Set Preferences")
 
+from .props import material
+
 def register():
 	bpy.utils.register_module(__name__)
-
+	bpy.types.Material.ANKI = bpy.props.PointerProperty(type=material.ANKI_Properties)
 
 def unregister():
 	bpy.utils.unregister_module(__name__)
-
+	del bpy.types.Material.ANKI
 
 if __name__ == "__main__":
 	register()

+ 27 - 1
tools/anki_scene_exporter/lib/gui.py

@@ -5,15 +5,41 @@
 # keep methods in alphabetical order
 
 # blender imports
+import os
+
 import bpy
+import bpy.utils.previews
+from bpy.props import StringProperty
 
 bl_info = {"author": "A. A. Kalugin Jr."}
 
 def get_region3d(context):
+	"""
+	Gets the first region 3d viewport.
+	"""
+	view = get_view_3d(context)
+	if view:
+		return view.spaces[0].region_3d
+	return None
+
+def get_view_3d(context):
 	"""
 	Gets the first region 3d viewport.
 	"""
 	for view in context.window.screen.areas:
 		if view.type == 'VIEW_3D':
-			return view.spaces[0].region_3d
+			return view
 	return None
+
+def image_filter_glob():
+	return StringProperty(
+						   default="*.bmp;*.sgi;*.rgb;*.bw;*.png;*.jpg;*.jpeg;*.exr;*.hdr;*.jp2;*.j2c;*.tga",
+						   options={'HIDDEN'}
+						 )
+
+def image_file_path():
+	return StringProperty(
+						  name="File Path",
+						  description="File path use",
+						  maxlen= 1024, default= ""
+						 )

+ 12 - 2
tools/anki_scene_exporter/lib/material.py

@@ -18,7 +18,17 @@ def get_texture_images_nodes():
 	for mat in mats:
 		for slot in mat.texture_slots:
 			if slot:
-				if (slot.texture.image != None):
-					bl_images.append(slot.texture.image)
+				if slot.texture.type == 'IMAGE':
+					if (slot.texture.image != None):
+						bl_images.append(slot.texture.image)
+
 	return bl_images
 
+	def check_material(self, material):
+		if material is not None:
+			if material.use_nodes:
+				if material.active_node_material is not None:
+					return True
+				return False
+			return True
+		return False

+ 185 - 0
tools/anki_scene_exporter/lib/mesh.py

@@ -0,0 +1,185 @@
+import bpy
+from bpy import context
+
+def add_uv_channel(obj):
+	scn = bpy.context.scene
+	scn.objects.active = obj
+	bpy.ops.mesh.uv_texture_add()
+
+def get_textures(obj):
+	#build a list of images, one per material
+	images = []
+	#get the textures from the mats
+	for slot in obj.material_slots:
+		if slot.material is None:
+			continue
+		has_image = False
+		textures = zip(slot.material.texture_slots, slot.material.use_textures)
+		for tex_slot, enabled in textures:
+			if enabled and tex_slot is not None:
+				tex = tex_slot.texture
+				if tex.type == 'IMAGE':
+					images.append(tex.image)
+					has_image = True
+					break
+
+		if not has_image:
+			print('not an image in', slot.name)
+			images.append(None)
+	return images
+
+def get_uv_channel(mesh):
+	r"""add uvs if none exist"""
+	print (mesh)
+	if len(mesh.uv_textures) == 0:
+		return False
+	return True
+
+def set_textured(obj, draw_texture = True):
+	images = get_textures(obj)
+	mesh = obj.data
+
+	uv_channel = get_uv_channel(mesh)
+	if len(images) > 0 and not uv_channel:
+		add_uv_channel(obj)
+
+	if len(images):
+		if obj.active_material != None:
+			for t in  mesh.uv_textures:
+				if t.active:
+					uvtex = t.data
+					for f in mesh.polygons:
+						if draw_texture:
+							#check that material had an image!
+							if images[f.material_index] is not None:
+								uvtex[f.index].image = images[f.material_index]
+							else:
+								uvtex[f.index].image = None
+						else:
+							uvtex[f.index].image = None
+		mesh.update()
+
+
+class MeshUtilities(object):
+	# obj = bpy.context.object
+	def __init__(self):
+		self.cntx = bpy.context
+
+	def get_selection_mode(self):
+		settings = bpy.context.tool_settings
+		if bpy.context.mode == 'EDIT_MESH':
+			sub_mod = settings.mesh_select_mode
+			if sub_mod[0] == True: #Verts
+				return "VERT"
+			if sub_mod[1] == True: #Edge
+				return "EDGE"
+			if sub_mod[2] == True: #Face
+				return "FACE"
+		return "OBJECT"
+
+	def get_sub_selection(self, mesh_node):
+		r''' Assumed that obj.type == MESH '''
+		mesh_node.update_from_editmode() # Loads edit-mode data into ect data
+		mode = self.get_selection_mode()
+		if self.get_selection_mode() == "FACE":
+			return [p for p in mesh_node.data.polygons if p.select]
+		if self.get_selection_mode() == "EDGE":
+			return [e for e in mesh_node.data.edges if e.select]
+		if self.get_selection_mode() == "VERTEX":
+			return [v for v in mesh_node.data.vertices if v.select]
+		return []
+
+	def get_modifier(self, obj, mod_type):
+		r''' Returns a modifier of type '''
+		for mod in obj.modifiers:
+			if mod.type == mod_type:
+				return mod
+		return False
+
+	def set_origin_to_selected(self, obj):
+		obj.update_from_editmode()
+		if bpy.context.mode == 'EDIT_MESH':
+			saved_location = bpy.context.scene.cursor_location.copy()
+			bpy.ops.view3d.snap_cursor_to_selected()
+			bpy.ops.object.mode_set(mode = 'OBJECT')
+			bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
+			bpy.context.scene.cursor_location = saved_location
+			bpy.ops.object.mode_set(mode = 'EDIT')
+			return True
+		if bpy.context.mode == 'OBJECT':
+			bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
+			return True
+		return False
+
+	def set_modifier(self, obj, name):
+		r''' '''
+		return obj.modifiers.new("bsi-subsurf", name)
+
+	def is_editable(self, ob):
+		editable = ['MESH','CURVE']
+		if bpy.context.active_object.type in editable:
+			return True
+		return False
+
+	def get_textures(self, obj):
+		#build a list of images, one per material
+		images = []
+		#get the textures from the mats
+		for slot in obj.material_slots:
+			if slot.material is None:
+				continue
+			has_image = False
+			textures = zip(slot.material.texture_slots, slot.material.use_textures)
+			for tex_slot, enabled in textures:
+				if enabled and tex_slot is not None:
+					tex = tex_slot.texture
+					if tex.type == 'IMAGE':
+						images.append(tex.image)
+						has_image = True
+						break
+
+			if not has_image:
+				print('not an image in', slot.name)
+				images.append(None)
+		return images
+
+	def get_uv_channel(self, mesh):
+		r"""add uvs if none exist"""
+		print (mesh)
+		if len(mesh.uv_textures) == 0:
+			return False
+		return True
+
+	def add_uv_channel(self, obj):
+		scn = bpy.context.scene
+		scn.objects.active = obj
+		bpy.ops.mesh.uv_texture_add()
+
+	def set_textured(self, obj, draw_texture = True):
+		images = self.get_textures(obj)
+		mesh = obj.data
+
+		uv_channel = self.get_uv_channel(mesh)
+		if len(images) > 0 and not uv_channel:
+			self.add_uv_channel(obj)
+
+		if len(images):
+			if obj.active_material != None:
+				for t in  mesh.uv_textures:
+					if t.active:
+						uvtex = t.data
+						for f in mesh.polygons:
+							if draw_texture:
+								#check that material had an image!
+								if images[f.material_index] is not None:
+									uvtex[f.index].image = images[f.material_index]
+								else:
+									uvtex[f.index].image = None
+							else:
+								uvtex[f.index].image = None
+			mesh.update()
+
+	def set_objects_textured(self, draw_texture = True):
+		for ob in bpy.data.objects:
+			if ob.type == 'MESH':
+				self.set_textured(ob, draw_texture)

+ 11 - 1
tools/anki_scene_exporter/lib/objects.py

@@ -22,4 +22,14 @@ def get_camera():
 	cam = getter()
 	if cam == None:
 		bpy.ops.object.camera_add()
-	return getter()
+	return getter()
+
+def get_objects_wuith_no_uvs():
+	no_uvs = []
+	obs = bpy.data.objects
+	for ob in obs:
+		if ob.type == 'MESH':
+			_id = (ob.data.uv_layers.active_index)
+			if _id == -1:
+				no_uvs.append(ob)
+	return no_uvs

+ 0 - 38
tools/anki_scene_exporter/ops/environment.py

@@ -1,38 +0,0 @@
-# Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
-# All rights reserved.
-# Code licensed under the BSD License.
-# http://www.anki3d.org/LICENSE
-# keep methods in alphabetical order
-
-# blender imports
-import bpy
-import mathutils
-from bpy.types import Operator
-from bpy.props import StringProperty
-
-# local imports
-from ..lib import environment as ENV
-from ..lib import preferences as PREF
-
-bl_info = {"author": "A. A. Kalugin Jr."}
-
-class OBJECT_OT_anki_preference_set(Operator):
-	"""Set anki preferences operator """
-	bl_idname = "scene.anki_preference_set"
-	bl_label = "Anki Preferences Setter"
-	bl_options = {'REGISTER', 'UNDO'}
-
-	def execute(self, context):
-		#get the environment variables
-		addon_prefs = PREF.get_anki_exporter_preferences(context)
-		ENV.ENVIRO = addon_prefs.anki_environment
-		env_dct, export_dct, tools_dct = ENV.get_environment()
-		ENV.set_environment(env_dct, tools_dct)
-
-		# Set project paths
-		addon_prefs.tools_path = tools_dct['tools_path']
-		addon_prefs.export_path = export_dct['export_src_data']
-		addon_prefs.map_path = export_dct['export_map_path']
-		addon_prefs.texture_path = export_dct['export_texture_path']
-
-		return {'FINISHED'}

+ 103 - 81
tools/anki_scene_exporter/ops/export.py

@@ -19,7 +19,9 @@ from ..lib import objects as OBJ
 from ..lib import material as MAT
 from ..lib import math as MTH
 from ..lib import preferences as PREF
-
+from ..lib.images import *
+# for k, v in locals().items():
+# 	print(k,v)
 bl_info = {"author": "A. A. Kalugin Jr."}
 
 class OBJECT_OT_anki_export_material(Operator):
@@ -36,33 +38,43 @@ class OBJECT_OT_anki_export_material(Operator):
 			py_image_converter = addon_prefs.tool_py_texture
 			export_path        = addon_prefs.export_texture_path
 			textures           = MAT.get_texture_images_nodes()
+			cmd_string         = "{0} -i {1} -o {2}"
 
 			# Process the blender texture slot nodes.
 			for texture in textures:
 				src_path = texture.filepath
 				src_file_name = os.path.basename(src_path)
 
+				dst_path = ("{0}/{1}.ankitex".format(export_path, os.path.splitext(src_file_name)[0] ))
 				# Check if the resolution of the image is power of twos
 				res_x = (texture.size[0])
 				res_y = (texture.size[1])
-				if not MTH.is_power_of_two(res_x) and not MTH.is_power_of_two(res_y):
+				if not MTH.is_power_of_two(res_x) or not MTH.is_power_of_two(res_y):
 					msg = "Image {0} resolution not power of 2. x {1} y {2}"
+					src_path = d_lib_images["not_powers_of_two"]
+					cmd = cmd_string.format(py_image_converter, src_path, dst_path)
+
 					error = msg.format(texture.filepath, res_x, res_y)
 					error_log.append(error)
+					commands.append(cmd)
 					continue
 
 				# Set up the command for texture export.
-				dst_path = ("{0}/{1}.ankitex".format(export_path, os.path.splitext(src_file_name)[0] ))
-				cmd = "{0} -i {1} -o {2}".format(py_image_converter, texture.filepath, dst_path)
-				Popen(cmd, shell=True)
+				cmd = cmd_string.format(py_image_converter, texture.filepath, dst_path)
+				# Popen(cmd, shell=True)
 				src_time = os.path.getatime(src_path)
+				if not os.path.exists(dst_path):
+					commands.append(cmd)
+					continue
+
 				dst_time = os.path.getatime(dst_path)
 				if src_time > dst_time:
 					export = "Running command: {0}".format(cmd)
 					exported_log.append(export)
 					commands.append(cmd)
 
-			# Process the commands
+			# # Process the commands
+			print (commands)
 			if len(commands) > 0:
 				for cmd in commands:
 					print ("Running command: {0}".format(cmd))
@@ -79,80 +91,90 @@ class OBJECT_OT_anki_export_scene(Operator):
 		bl_options = {'REGISTER'}
 
 		def execute(self, context):
-				scn = context.scene
-
-				addon_prefs = PREF.get_anki_exporter_preferences(context)
-
-				temp_dea =  addon_prefs.temp_dea
-
-				view_mtx = None
-				cam = None
-				if scn.UseViewport:
-						# Get camera matrix to viewport projection matrix
-						cam = OBJ.get_camera()
-						view_mtx = mathutils.Matrix(cam.matrix_world)
-						r3d = GUI.get_region3d(context)
-						cam.matrix_world = r3d.view_matrix.inverted()
-						print ("Set camera to view projection matrix.")
-
-				# Export the collada file to temp.dea
-				bpy.ops.wm.collada_export(filepath=temp_dea,
-													check_existing=True,
-													filter_blender=False,
-													filter_backup=False,
-													filter_image=False,
-													filter_movie=False,
-													filter_python=False,
-													filter_font=False,
-													filter_sound=False,
-													filter_text=False,
-													filter_btx=False,
-													filter_collada=True,
-													filter_folder=True,
-													filter_blenlib=False,
-													filemode=8,
-													display_type='DEFAULT',
-													sort_method='FILE_SORT_ALPHA',
-													apply_modifiers=False,
-													export_mesh_type=0,
-													export_mesh_type_selection='view',
-													selected=False,
-													include_children=False,
-													include_armatures=False,
-													include_shapekeys=True,
-													deform_bones_only=False,
-													active_uv_only=False,
-													include_uv_textures=False,
-													include_material_textures=True,
-													use_texture_copies=False,
-													triangulate=True,
-													use_object_instantiation=True,
-													sort_by_name=False,
-													export_transformation_type=0,
-													export_transformation_type_selection='matrix',
-													open_sim=False)
-				print ("Exported to:", temp_dea)
-
-				# Restore Camera
-				if scn.UseViewport:
-						cam.matrix_world = view_mtx
-						print ("Restored camera to original projection matrix.")
-
-				# Format the command and convert the exported collada
-				rel_map_path = (addon_prefs.export_map_path.replace(addon_prefs.anki_project_path, ""))
-				rel_texture_path = (addon_prefs.export_texture_path.replace(addon_prefs.anki_project_path, ""))
-				cmd_str = "ankisceneimp {0} {1} -rpath {2} -texrpath {3} -flipyz"
-				cmd  = cmd_str.format(temp_dea,
-									  addon_prefs.export_map_path,
-									  rel_map_path,
-									  rel_texture_path)
-
-				subprocess.call(cmd, shell=True)
-
-				# Run the level in the game
-				bled_app = ("{0}/build/bled/bled".format(addon_prefs.anki_project_path))
-
-				subprocess.call(bled_app, shell=True)
-
+			scn = context.scene
+			no_uvs_objs        = OBJ.get_objects_wuith_no_uvs()
+			if no_uvs_objs:
+				msg = ""
+				for ob in  no_uvs_objs:
+					msg += "Object: {0},".format(ob.name)
+				self.report({'INFO'}, "NO UVS on bjects! {0}".format(msg))
 				return {'FINISHED'}
 
+			addon_prefs = PREF.get_anki_exporter_preferences(context)
+			temp_dea =  addon_prefs.temp_dea
+
+			view_mtx = None
+			cam = None
+			if scn.UseViewport:
+					# Get camera matrix to viewport projection matrix
+					cam = OBJ.get_camera()
+					view_mtx = mathutils.Matrix(cam.matrix_world)
+					r3d = GUI.get_region3d(context)
+					cam.matrix_world = r3d.view_matrix.inverted()
+					print ("Set camera to view projection matrix.")
+
+			# Export the collada file to temp.dea
+			bpy.ops.wm.collada_export(filepath=temp_dea,
+												check_existing=True,
+												filter_blender=False,
+												filter_backup=False,
+												filter_image=False,
+												filter_movie=False,
+												filter_python=False,
+												filter_font=False,
+												filter_sound=False,
+												filter_text=False,
+												filter_btx=False,
+												filter_collada=True,
+												filter_folder=True,
+												filter_blenlib=False,
+												filemode=8,
+												display_type='DEFAULT',
+												sort_method='FILE_SORT_ALPHA',
+												apply_modifiers=False,
+												export_mesh_type=0,
+												export_mesh_type_selection='view',
+												selected=False,
+												include_children=False,
+												include_armatures=False,
+												include_shapekeys=True,
+												deform_bones_only=False,
+												active_uv_only=False,
+												include_uv_textures=False,
+												include_material_textures=True,
+												use_texture_copies=False,
+												triangulate=True,
+												use_object_instantiation=True,
+												sort_by_name=False,
+												export_transformation_type=0,
+												export_transformation_type_selection='matrix',
+												open_sim=False)
+			print ("Exported to:", temp_dea)
+
+			# Restore Camera
+			if scn.UseViewport:
+					cam.matrix_world = view_mtx
+					print ("Restored camera to original projection matrix.")
+
+			# Format the command and convert the exported collada
+			rel_map_path = (addon_prefs.export_map_path.replace(addon_prefs.anki_project_path, ""))
+			print(rel_map_path)
+			rel_texture_path = (addon_prefs.export_texture_path.replace(addon_prefs.anki_project_path, ""))
+			print(rel_texture_path)
+			cmd_str = "ankisceneimp {0} {1} -rpath {2} -texrpath {3} -flipyz"
+			print (cmd_str)
+			cmd  = cmd_str.format(temp_dea,
+								  addon_prefs.export_map_path,
+								  rel_map_path,
+								  rel_texture_path)
+			print (cmd)
+			subprocess.call(cmd, shell=True)
+
+			# Run the level in the game
+			bled_app = ("{0}/build/bled/bled".format(addon_prefs.anki_project_path))
+			print (bled_app)
+
+			subprocess.call(bled_app, shell=True)
+
+			return {'FINISHED'}
+

+ 103 - 0
tools/anki_scene_exporter/ops/gui.py

@@ -0,0 +1,103 @@
+import bpy
+from bpy.types import Operator
+
+class BSI_PP_home_op(Operator):
+	"""BL Mesh Edit"""
+	bl_idname = "bsi.pp_home_op"
+	bl_label = "BSI Home Panel"
+	bl_options = {'REGISTER'}
+
+	def execute(self, context):
+		bpy.ops.bsi.view3d_dynamic_prop_panel(panel = "BSI_PP_home")
+		return {'FINISHED'}
+
+class BSI_PP_motiontracking(Operator):
+	"""BSI Motiontracking Panel Op"""
+	bl_idname = "bsi.panel_motiontracking"
+	bl_label = "Motiontracking Panel"
+	bl_options = {'REGISTER'}
+
+	def execute(self, context):
+		bpy.ops.bsi.view3d_dynamic_prop_panel(panel = "VIEW3D_PP_motiontracking")
+		return {'FINISHED'}
+
+class BSI_PP_viewproperties(Operator):
+	"""BSI View Properties Panel"""
+	bl_idname = "bsi.panel_viewproperties"
+	bl_label = "View Properties Panel"
+	bl_options = {'REGISTER'}
+
+	def execute(self, context):
+		bpy.ops.bsi.view3d_dynamic_prop_panel(panel = "VIEW3D_PP_viewproperties")
+		return {'FINISHED'}
+
+class VIEW3D_PP_meshproperties(Operator):
+	"""BSI Mesh Properties Panel"""
+	bl_idname = "bsi.panel_meshproperties"
+	bl_label = "Mesh Properties Panel"
+	bl_options = {'REGISTER'}
+
+	def execute(self, context):
+		bpy.ops.bsi.view3d_dynamic_prop_panel(panel = "VIEW3D_PP_meshproperties")
+		return {'FINISHED'}
+
+class BSI_TP_meshedit_op(Operator):
+	"""BL Mesh Edit"""
+	bl_idname = "bsi.panel_meshedit"
+	bl_label = "Mesh Edit Panel"
+	bl_options = {'REGISTER'}
+
+	def execute(self, context):
+		bpy.ops.bsi.view3d_dynamic_tool_panel(panel = "VIEW3D_TP_meshedit")
+		return {'FINISHED'}
+
+class BSI_TP_greasepencil_op(Operator):
+	"""BL Gease Pencil Panel"""
+	bl_idname = "bsi.panel_greasepencil"
+	bl_label = "Grease Pencil Panel"
+	bl_options = {'REGISTER'}
+
+	def execute(self, context):
+		bpy.ops.bsi.view3d_dynamic_tool_panel(panel = "VIEW3D_TP_greasepencil")
+		return {'FINISHED'}
+
+class BSI_TP_rigidbody_op(Operator):
+	"""BL Rigid Body Panel"""
+	bl_idname = "bsi.panel_rigidbody"
+	bl_label = "Rigid Body Panel"
+	bl_options = {'REGISTER'}
+
+	def execute(self, context):
+		bpy.ops.bsi.view3d_dynamic_tool_panel(panel = "VIEW3D_TP_rigidbody")
+		return {'FINISHED'}
+
+class BSI_TP_animation_op(Operator):
+	"""BL Animation Panel"""
+	bl_idname = "bsi.panel_animation"
+	bl_label = "Animation Panel"
+	bl_options = {'REGISTER'}
+
+	def execute(self, context):
+		bpy.ops.bsi.view3d_dynamic_tool_panel(panel = "VIEW3D_TP_animation")
+		return {'FINISHED'}
+
+class BSI_TP_relation_op(Operator):
+	"""BL Relation Panel"""
+	bl_idname = "bsi.panel_relation"
+	bl_label = "Relation Panel"
+	bl_options = {'REGISTER'}
+
+	def execute(self, context):
+		bpy.ops.bsi.view3d_dynamic_tool_panel(panel = "VIEW3D_TP_relation")
+		return {'FINISHED'}
+
+class VIEW3D_TP_addobject(Operator):
+	"""BL Add Object Panel"""
+	bl_idname = "bsi.panel_addobject"
+	bl_label = "Add Object Panel"
+	bl_options = {'REGISTER'}
+
+	def execute(self, context):
+		bpy.ops.bsi.view3d_dynamic_tool_panel(panel = "VIEW3D_TP_addobject")
+		return {'FINISHED'}
+

+ 69 - 0
tools/anki_scene_exporter/ops/material.py

@@ -0,0 +1,69 @@
+# Blender imports
+import bpy
+from bpy.types import Operator
+from bpy.props import StringProperty
+from bpy_extras.io_utils import ImportHelper
+
+# Local imports
+from ..lib import gui as GUI
+from ..lib import material as MAT
+from ..lib import mesh as MESH
+
+
+class ANKI_MATERIAL_clear_slot(Operator):
+	"""Clears a given material stol"""
+	bl_idname	= "anki.clear_texture_slot"
+	bl_label	= "Clear Slot by ID"
+	bl_options	= {'REGISTER', 'UNDO'}
+	port_type 	= bpy.props.StringProperty(default = "diffuse")
+
+	def execute(self, context):
+		mat = context.active_object.active_material
+		MAT.clear_texture_slot(mat, self.port_type)
+		return {'FINISHED'}
+
+class ANKI_MATERIAL_apply_image(Operator, ImportHelper):
+	bl_idname 		= "anki.apply_texture_image"
+	bl_label 		= "Apply Material Image"
+	bl_options		= {'REGISTER', 'UNDO'}
+	# filename_ext 	= ".jpg"
+	filter_glob 	= GUI.image_filter_glob()
+	filepath 		= GUI.image_file_path()
+	mat_port_type 	= bpy.props.StringProperty(default ="diffuse")
+
+	@classmethod
+	def poll(cls, context):
+		material = context.active_object.active_material
+		return MAT.check_material(material)
+
+	def execute(self, context):
+		material = context.active_object.active_material
+		img = MAT.get_image_node( self.filepath)
+		texture_node = MAT.get_texture_node(self.filepath)
+		texture_node.image = img
+
+		texture_slot = MAT.get_texture_slot( material, self.mat_port_type)
+
+		if self.mat_port_type == "diffuse":
+			context.active_object.active_material.ANKI.diff_path = self.filepath
+			MAT.set_diffuse_texture_attr(texture_slot, texture_node)
+
+		if self.mat_port_type == "roughness":
+			context.active_object.active_material.ANKI.spec_path = self.filepath
+			texture_slot.texture = texture_node
+			# texture_slot.use_map_specular = True
+			# texture_slot.use_map_specular = 1.0
+
+			texture_slot.use_map_color_diffuse = False
+			texture_slot.use_map_hardness      = True
+			# texture_slot.use_map_hardness      = 1.0
+
+		MESH.set_textured(context.active_object, draw_texture = True)
+		MAT.set_uv_texture_attr(texture_slot)
+
+		return {'FINISHED'}
+
+	def invoke(self, context, event):
+		context.window_manager.fileselect_add(self)
+
+		return {'RUNNING_MODAL'}

+ 19 - 0
tools/anki_scene_exporter/ops/text.py

@@ -0,0 +1,19 @@
+# Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+# All rights reserved.
+# Code licensed under the BSD License.
+# http://www.anki3d.org/LICENSE
+# keep in alphabetical order
+
+import bpy
+from bpy.types import Operator
+
+class ANKI_TEXT_reload_run(Operator):
+    """ANKI reload and run text"""
+    bl_idname = "anki.reload_build"
+    bl_label = "Reload Run Text"
+    bl_options = {'REGISTER'}
+
+    def execute(self, context):
+        bpy.ops.text.reload()
+        bpy.ops.text.run_script()
+        return {'FINISHED'}

+ 56 - 0
tools/anki_scene_exporter/props/material.py

@@ -0,0 +1,56 @@
+# Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+# All rights reserved.
+# Code licensed under the BSD License.
+# http://www.anki3d.org/LICENSE
+# keep methods in alphabetical order
+
+
+import bpy
+from bpy.types import PropertyGroup
+from bpy.props import FloatVectorProperty, BoolProperty, StringProperty
+
+class ANKI_Properties(PropertyGroup):
+	shader_stand 		= BoolProperty(default=False)
+	indirect_illum 		= BoolProperty(default=False)
+	shader_rendering	= BoolProperty(default=False)
+	shader_shadow		= BoolProperty(default=False)
+	shader_sss 			= BoolProperty(default=False)
+	shader_transparency	= BoolProperty(default=False)
+	shader_reflection	= BoolProperty(default=False)
+	shader_strand		= BoolProperty(default=False)
+
+	diff_shader 		= BoolProperty(default=False)
+	diff_image 			= BoolProperty(default=False)
+	diff_path			= StringProperty()
+	diff_uvs			= BoolProperty(default=False)
+	diff_sampling		= BoolProperty(default=False)
+	diff_influence 		= BoolProperty(default=False)
+	diff_ramp 			= BoolProperty(default=False)
+	diff_img_display	= BoolProperty(default=False)
+
+	spec_shader 		= BoolProperty(default=False)
+	spec_image 			= BoolProperty(default=False)
+	spec_path			= StringProperty()
+	spec_uvs			= BoolProperty(default=False)
+	spec_sampling		= BoolProperty(default=False)
+	spec_influence 		= BoolProperty(default=False)
+	spec_ramp 			= BoolProperty(default=False)
+	spec_img_display	= BoolProperty(default=False)
+
+	tran_shader 		= BoolProperty(default=False)
+	tran_image 			= BoolProperty(default=False)
+	tran_path			= StringProperty()
+	tran_uvs			= BoolProperty(default=False)
+	tran_influence 		= BoolProperty(default=False)
+
+	norm_shader 		= BoolProperty(default=False)
+	norm_image 			= BoolProperty(default=False)
+	norm_path			= StringProperty()
+	norm_uvs			= BoolProperty(default=False)
+	norm_influence 		= BoolProperty(default=False)
+
+	refl_shader 		= BoolProperty(default=False)
+	refl_image 			= BoolProperty(default=False)
+	refl_path			= StringProperty()
+	refl_uvs			= BoolProperty(default=False)
+	refl_influence 		= BoolProperty(default=False)

+ 1480 - 0
tools/anki_scene_exporter/ui/panel_layouts.py

@@ -0,0 +1,1480 @@
+# Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+# All rights reserved.
+# Code licensed under the BSD License.
+# http://www.anki3d.org/LICENSE
+# keep methods in alphabetical order
+
+
+import bpy, os
+from bpy import context
+from bpy.app.translations import contexts as i18n_contexts
+# from ..libs import material_utilities
+# from ..libs import mesh_utilities
+# from ..libs import gui_utilities
+
+############################### CONSTANTS ###############################
+# MAT = material_utilities.MaterialUtilities()
+# GUI = gui_utilities.GuiUtilities()
+# MESH = mesh_utilities.MeshUtilities()
+# ico_path = "%s/../libs/ico" % os.path.dirname(os.path.realpath(__file__))
+# ico = gui_utilities.get_icons(ico_path)
+############################### CONSTANTS ###############################
+
+def bsi_empty_panel(layout, context):
+	pass
+
+def VIEW3D_PP_meshproperties(layout, context):
+	use_freestyle = bpy.app.build_options.freestyle
+	mesh = context.active_object.data
+	scene = context.scene
+
+	if (context.active_object and (context.mode == 'EDIT_MESH')):
+		box = layout.box()
+		split = box.split()
+		col = split.column()
+		col.label(text="Overlays:")
+		col.prop(mesh, "show_faces", text="Faces")
+		col.prop(mesh, "show_edges", text="Edges")
+		col.prop(mesh, "show_edge_crease", text="Creases")
+		if use_freestyle:
+			col.prop(mesh, "show_edge_seams", text="Seams")
+
+		box.prop(mesh, "show_weight")
+
+		col = split.column()
+		col.label()
+		if not use_freestyle:
+			col.prop(mesh, "show_edge_seams", text="Seams")
+		col.prop(mesh, "show_edge_sharp", text="Sharp", text_ctxt=i18n_contexts.plural)
+		col.prop(mesh, "show_edge_bevel_weight", text="Bevel")
+		if use_freestyle:
+			col.prop(mesh, "show_freestyle_edge_marks", text="Edge Marks")
+			col.prop(mesh, "show_freestyle_face_marks", text="Face Marks")
+
+		box = layout.box()
+
+		box.label(text="Normals:")
+		row = box.row(align=True)
+
+		row.prop(mesh, "show_normal_vertex", text="", icon='VERTEXSEL')
+		row.prop(mesh, "show_normal_loop", text="", icon='LOOPSEL')
+		row.prop(mesh, "show_normal_face", text="", icon='FACESEL')
+
+		sub = row.row(align=True)
+		sub.active = mesh.show_normal_vertex or mesh.show_normal_face or mesh.show_normal_loop
+		sub.prop(scene.tool_settings, "normal_size", text="Size")
+
+		box = layout.box()
+		split = box.split()
+		col = split.column()
+		col.label(text="Edge Info:")
+		col.prop(mesh, "show_extra_edge_length", text="Length")
+		col.prop(mesh, "show_extra_edge_angle", text="Angle")
+		col = split.column()
+		col.label(text="Face Info:")
+		col.prop(mesh, "show_extra_face_area", text="Area")
+		col.prop(mesh, "show_extra_face_angle", text="Angle")
+		if bpy.app.debug:
+			layout.prop(mesh, "show_extra_indices")
+
+		statvis = context.tool_settings.statvis
+		box = layout.box()
+		box.prop(mesh, "show_statvis", text="Mesh Analysis")
+		if mesh.show_statvis:
+			box.prop(statvis, "type")
+			if statvis.type == 'OVERHANG':
+				row = box.row(align=True)
+				row.prop(statvis, "overhang_min", text="")
+				row.prop(statvis, "overhang_max", text="")
+				row = box.row(align=True)
+				row.prop(statvis, "overhang_axis", expand=True)
+			elif statvis.type == 'THICKNESS':
+				row = box.row(align=True)
+				row.prop(statvis, "thickness_min", text="")
+				row.prop(statvis, "thickness_max", text="")
+				row = box.row(align=True)
+				rowt.prop(statvis, "thickness_samples")
+			elif statvis_type == 'INTERSECT':
+				pass
+			elif statvis.type == 'DISTORT':
+				row = box.row(align=True)
+				row.prop(statvis, "distort_min", text="")
+				row.prop(statvis, "distort_max", text="")
+			elif statvis.type == 'SHARP':
+				row = box.row(align=True)
+				row.prop(statvis, "sharp_min", text="")
+				row.prop(statvis, "sharp_max", text="")
+
+
+def VIEW3D_PP_viewproperties(layout, context):
+	v3d = GUI.get_screen_area(type = "VIEW_3D")
+	col = layout.column()
+	col.active = bool(v3d.region_3d.view_perspective != 'CAMERA' or v3d.region_quadviews)
+	col.prop(v3d, "lens")
+	col.label(text="Lock to Object:")
+	col.prop(v3d, "lock_object", text="")
+	lock_object = v3d.lock_object
+	if lock_object:
+		if lock_object.type == 'ARMATURE':
+			col.prop_search(v3d, "lock_bone", lock_object.data,
+							"edit_bones" if lock_object.mode == 'EDIT'
+							else "bones",
+							text="")
+	else:
+		col.prop(v3d, "lock_cursor", text="Lock to Cursor")
+
+	col = layout.column()
+	col.prop(v3d, "lock_camera")
+
+	col = layout.column(align=True)
+	col.label(text="Clip:")
+	col.prop(v3d, "clip_start", text="Start")
+	col.prop(v3d, "clip_end", text="End")
+
+	subcol = col.column(align=True)
+	subcol.enabled = not v3d.lock_camera_and_layers
+	subcol.label(text="Local Camera:")
+	subcol.prop(v3d, "camera", text="")
+
+	col = layout.column(align=True)
+	col.prop(view, "use_render_border")
+	col.active = v3d.region_3d.view_perspective != 'CAMERA'
+
+
+def VIEW3D_TP_addobject(layout, context):
+	col = layout.column(align=True)
+
+	col.label(text="Primitives:")
+	row = col.row(align=True)
+	row.operator("mesh.primitive_plane_add", text=" ", icon='MESH_PLANE')
+	row.operator("mesh.primitive_cube_add", text=" ", icon='MESH_CUBE')
+	row.operator("mesh.primitive_circle_add", text=" ", icon='MESH_CIRCLE')
+	row.operator("mesh.primitive_uv_sphere_add", text=" ", icon='MESH_UVSPHERE')
+	row.operator("mesh.primitive_ico_sphere_add", text=" ", icon='MESH_ICOSPHERE')
+	row = col.row(align=True)
+	row.operator("mesh.primitive_cylinder_add", text=" ", icon='MESH_CYLINDER')
+	row.operator("mesh.primitive_cone_add", text=" ", icon='MESH_CONE')
+	row.operator("mesh.primitive_torus_add", text=" ", icon='MESH_TORUS')
+	row.operator("mesh.primitive_grid_add", text=" ", icon='MESH_GRID')
+	row.operator("mesh.primitive_monkey_add", text=" ", icon='MESH_MONKEY')
+
+	col = layout.column(align=True)
+	col.label(text="Misc:")
+	row = col.row(align=True)
+	row.operator("object.text_add", text=" ", icon='OUTLINER_OB_FONT')
+	row.operator("object.armature_add", text=" ", icon='OUTLINER_OB_ARMATURE')
+	row.operator("object.add", text=" ", icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
+	row = col.row(align=True)
+	row.operator("object.empty_add", text=" ", icon='OUTLINER_OB_EMPTY').type = 'PLAIN_AXES'
+	row.operator("object.speaker_add", text=" ", icon='OUTLINER_OB_SPEAKER')
+	row.operator("object.camera_add", text=" ", icon='OUTLINER_OB_CAMERA')
+
+	col = layout.column(align=True)
+	col.label(text="Bezier:")
+	row = col.row(align=True)
+	row.operator("curve.primitive_bezier_curve_add", text="Bezier", icon='CURVE_BEZCURVE')
+	row.operator("curve.primitive_bezier_circle_add", text="Circle", icon='CURVE_BEZCIRCLE')
+
+
+	col.label(text="Nurbs and Surfaces:")
+	row = col.row(align=True)
+	row.operator("curve.primitive_nurbs_curve_add", text=" ", icon='CURVE_NCURVE')
+	row.operator("curve.primitive_nurbs_circle_add", text=" ", icon='CURVE_NCIRCLE')
+	row.operator("curve.primitive_nurbs_path_add", text=" ", icon='CURVE_PATH')
+
+	#col = layout.column(align=True)
+	#col.label(text="Surface:  ")
+	row = col.row(align=True)
+	row.operator("surface.primitive_nurbs_surface_curve_add", text=" ", icon='SURFACE_NCURVE')
+	row.operator("surface.primitive_nurbs_surface_circle_add", text=" ", icon='SURFACE_NCIRCLE')
+	row.operator("surface.primitive_nurbs_surface_surface_add", text=" ", icon='SURFACE_NSURFACE')
+	row = col.row(align=True)
+	row.operator("surface.primitive_nurbs_surface_cylinder_add", text=" ", icon='SURFACE_NCYLINDER')
+	row.operator("surface.primitive_nurbs_surface_sphere_add", text=" ", icon='SURFACE_NSPHERE')
+	row.operator("surface.primitive_nurbs_surface_torus_add", text=" ", icon='SURFACE_NTORUS')
+
+	col = layout.column(align=True)
+	row = col.row(align=True)
+	# row.operator_enum("object.metaball_add","type")
+	row.operator_menu_enum("object.metaball_add", "type",
+							text="Metaball",
+							icon='OUTLINER_OB_META'
+							)
+	row.operator_menu_enum("object.lamp_add", "type",
+							text="Lamp",
+							icon='OUTLINER_OB_LAMP'
+							)
+
+def VIEW3D_TP_rigidbody(layout, context):
+	col = layout.column(align=True)
+	col.label(text="Add/Remove:")
+	row = col.row(align=True)
+	row.operator("rigidbody.objects_add", text="Add Active").type = 'ACTIVE'
+	row.operator("rigidbody.objects_add", text="Add Passive").type = 'PASSIVE'
+	row = col.row(align=True)
+	row.operator("rigidbody.objects_remove", text="Remove")
+
+	col = layout.column(align=True)
+	col.label(text="Object Tools:")
+	col.operator("rigidbody.shape_change", text="Change Shape")
+	col.operator("rigidbody.mass_calculate", text="Calculate Mass")
+	col.operator("rigidbody.object_settings_copy", text="Copy from Active")
+	col.operator("object.visual_transform_apply", text="Apply Transformation")
+	col.operator("rigidbody.bake_to_keyframes", text="Bake To Keyframes")
+	col.label(text="Constraints:")
+	col.operator("rigidbody.connect", text="Connect")
+
+def VIEW3D_TP_relation(layout, context):
+	col = layout.column(align=True)
+
+	col.label(text="Group:")
+	col.operator("group.create", text="New Group")
+	col.operator("group.objects_add_active", text="Add to Active")
+	col.operator("group.objects_remove", text="Remove from Group")
+
+	col.separator()
+
+	col.label(text="Parent:")
+	row = col.row(align=True)
+	row.operator("object.parent_set", text="Set")
+	row.operator("object.parent_clear", text="Clear")
+
+	col.separator()
+
+	col.label(text="Object Data:")
+	col.operator("object.make_links_data")
+	col.operator("object.make_single_user")
+
+	col.separator()
+
+	col.label(text="Linked Objects:")
+	col.operator("object.make_local")
+	col.operator("object.proxy_make")
+
+def draw_keyframing_tools(context, layout):
+	col = layout.column(align=True)
+	col.label(text="Keyframes:")
+	row = col.row(align=True)
+	row.operator("anim.keyframe_insert_menu", text="Insert")
+	row.operator("anim.keyframe_delete_v3d", text="Remove")
+
+def VIEW3D_TP_animation(layout, context):
+	draw_keyframing_tools(context, layout)
+	col = layout.column(align=True)
+	col.label(text="Motion Paths:")
+	row = col.row(align=True)
+	row.operator("object.paths_calculate", text="Calculate")
+	row.operator("object.paths_clear", text="Clear")
+
+	col.separator()
+
+	col.label(text="Action:")
+	col.operator("nla.bake", text="Bake Action")
+
+def gpencil_stroke_placement_settings(context, layout, gpd):
+	col = layout.column(align=True)
+
+	col.label(text="Stroke Placement:")
+
+	row = col.row(align=True)
+	row.prop_enum(gpd, "draw_mode", 'VIEW')
+	row.prop_enum(gpd, "draw_mode", 'CURSOR')
+
+	if context.space_data.type == 'VIEW_3D':
+		row = col.row(align=True)
+		row.prop_enum(gpd, "draw_mode", 'SURFACE')
+		row.prop_enum(gpd, "draw_mode", 'STROKE')
+
+		row = col.row(align=False)
+		row.active = gpd.draw_mode in {'SURFACE', 'STROKE'}
+		row.prop(gpd, "use_stroke_endpoints")
+
+def VIEW3D_TP_greasepencil(layout, context):
+	col = layout.column(align=True)
+
+	col.label(text="Draw:")
+	row = col.row(align=True)
+	row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
+	row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
+
+	row = col.row(align=True)
+	row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
+	row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
+
+	row = col.row(align=True)
+	row.prop(context.tool_settings, "use_grease_pencil_sessions", text="Continuous Drawing")
+
+	if context.space_data.type in {'VIEW_3D', 'CLIP_EDITOR'}:
+		col.separator()
+		col.label("Data Source:")
+		row = col.row(align=True)
+		if context.space_data.type == 'VIEW_3D':
+			row.prop(context.tool_settings, "grease_pencil_source", expand=True)
+		elif context.space_data.type == 'CLIP_EDITOR':
+			row.prop(context.space_data, "grease_pencil_source", expand=True)
+
+	gpd = context.gpencil_data
+	if gpd:
+		col.separator()
+		gpencil_stroke_placement_settings(context, col, gpd)
+
+	if context.space_data.type == 'VIEW_3D':
+		col.separator()
+		col.separator()
+
+		col.label(text="Tools:")
+		col.operator("gpencil.convert", text="Convert...")
+		col.operator("view3d.ruler")
+
+	gpd = context.gpencil_data
+	edit_ok = bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
+
+	col = layout.column(align=True)
+	col.prop(gpd, "use_stroke_edit_mode", text="Enable Editing", icon='EDIT', toggle=True)
+
+	col.separator()
+
+	col.label(text="Select:")
+	subcol = col.column(align=True)
+	subcol.active = edit_ok
+	subcol.operator("gpencil.select_all", text="Select All")
+	subcol.operator("gpencil.select_border")
+	subcol.operator("gpencil.select_circle")
+
+	col.separator()
+
+	subcol = col.column(align=True)
+	subcol.active = edit_ok
+	subcol.operator("gpencil.select_linked")
+	subcol.operator("gpencil.select_more")
+	subcol.operator("gpencil.select_less")
+
+	col.separator()
+
+	col.label(text="Edit:")
+	row = col.row(align=True)
+	row.active = edit_ok
+	row.operator("gpencil.copy", text="Copy")
+	row.operator("gpencil.paste", text="Paste")
+
+	subcol = col.column(align=True)
+	subcol.active = edit_ok
+	subcol.operator("gpencil.delete", text="Delete")
+	subcol.operator("gpencil.duplicate_move", text="Duplicate")
+	subcol.operator("transform.mirror", text="Mirror").gpencil_strokes = True
+
+	col.separator()
+
+	subcol = col.column(align=True)
+	subcol.active = edit_ok
+	subcol.operator("transform.translate").gpencil_strokes = True   # icon='MAN_TRANS'
+	subcol.operator("transform.rotate").gpencil_strokes = True      # icon='MAN_ROT'
+	subcol.operator("transform.resize", text="Scale").gpencil_strokes = True      # icon='MAN_SCALE'
+
+	col.separator()
+
+	subcol = col.column(align=True)
+	subcol.active = edit_ok
+	subcol.operator("transform.bend", text="Bend").gpencil_strokes = True
+	subcol.operator("transform.shear", text="Shear").gpencil_strokes = True
+	subcol.operator("transform.tosphere", text="To Sphere").gpencil_strokes = True
+
+
+
+def VIEW3D_PP_motiontracking(layout, context):
+	v3d = GUI.get_screen_area(type = "VIEW_3D")
+	layout.prop(v3d, "show_reconstruction", text="Motion Tracking")
+	if v3d.show_reconstruction:
+		col = layout.column()
+		col.prop(v3d, "show_camera_path", text="Camera Path")
+		col.prop(v3d, "show_bundle_names", text="3D Marker Names")
+		col.label(text="Track Type and Size:")
+		row = col.row(align=True)
+		row.prop(v3d, "tracks_draw_type", text="")
+		row.prop(v3d, "tracks_draw_size", text="")
+
+def VIEW3D_TP_meshedit(layout, context):
+	mode = MESH.get_selection_mode()
+	if mode == "OBJECT":
+		mesh_edit_object_mode(layout, context)
+	else:
+		mesh_edit_edit_mode(layout, context)
+def mesh_edit_edit_mode(layout, context):
+	r""" Taken from blender mesh edit layout"""
+	col = layout.column(align=True)
+	col.label(text="Deform:")
+	row = col.row(align=True)
+	row.operator("transform.edge_slide", text="Slide Edge")
+	row.operator("transform.vert_slide", text="Vertex")
+	col.operator("mesh.noise")
+	col.operator("mesh.vertices_smooth")
+	col.operator("transform.vertex_random")
+
+	col = layout.column(align=True)
+	col.label(text="Add:")
+
+	col.menu("VIEW3D_MT_edit_mesh_extrude")
+	col.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Region")
+	col.operator("view3d.edit_mesh_extrude_individual_move", text="Extrude Individual")
+	col.operator("mesh.inset", text="Inset Faces")
+	col.operator("mesh.edge_face_add")
+	col.operator("mesh.subdivide")
+	col.operator("mesh.loopcut_slide")
+	col.operator("mesh.offset_edge_loops_slide")
+	col.operator("mesh.duplicate_move", text="Duplicate")
+	row = col.row(align=True)
+	row.operator("mesh.spin")
+	row.operator("mesh.screw")
+
+	row = col.row(align=True)
+	props = row.operator("mesh.knife_tool", text="Knife")
+	props.use_occlude_geometry = True
+	props.only_selected = False
+	props = row.operator("mesh.knife_tool", text="Select")
+	props.use_occlude_geometry = False
+	props.only_selected = True
+	col.operator("mesh.knife_project")
+	col.operator("mesh.bisect")
+
+	col = layout.column(align=True)
+	col.label(text="Remove:")
+	col.menu("VIEW3D_MT_edit_mesh_delete")
+	col.operator_menu_enum("mesh.merge", "type")
+	col.operator("mesh.remove_doubles")
+
+def mesh_edit_object_mode(layout, context):
+	r""" Taken from blender mesh edit layout"""
+	col = layout.column(align=True)
+	col.operator("object.duplicate_move", text="Duplicate")
+	col.operator("object.duplicate_move_linked", text="Duplicate Linked")
+
+	col.operator("object.delete")
+
+	obj = context.active_object
+	if obj:
+		obj_type = obj.type
+
+		if obj_type in {'MESH', 'CURVE', 'SURFACE', 'ARMATURE'}:
+			col = layout.column(align=True)
+			col.operator("object.join")
+
+		if obj_type in {'MESH', 'CURVE', 'SURFACE', 'ARMATURE', 'FONT', 'LATTICE'}:
+			col = layout.column(align=True)
+			col.operator_menu_enum("object.origin_set", "type", text="Set Origin")
+
+		if obj_type in {'MESH', 'CURVE', 'SURFACE'}:
+			col = layout.column(align=True)
+			col.label(text="Shading:")
+			row = col.row(align=True)
+			row.operator("object.shade_smooth", text="Smooth")
+			row.operator("object.shade_flat", text="Flat")
+
+		if obj_type == 'MESH':
+			col = layout.column(align=True)
+			col.label(text="Data Transfer:")
+			row = col.row(align=True)
+			row.operator("object.data_transfer", text="Data")
+			row.operator("object.datalayout_transfer", text="Data Layout")
+
+
+def bsi_modeling_panel(layout, context):
+	col = layout.column(align=True)
+	col.operator("wm.bsi_decorator_button",text="Get")
+	col.menu("INFO_MT_bsi_primitive", text="Primitive")
+	col.menu("INFO_MT_bsi_material", text="Material")
+	col.menu("INFO_MT_bsi_property", text="Property")
+
+	col = layout.column(align=True)
+	col.operator("wm.bsi_decorator_button",text="Create")
+	col.menu("VIEW3D_MT_BSI_curve_create", text="Curve")
+	col.menu("INFO_MT_add", text="Surf.Mesh")
+	col.menu("INFO_MT_add", text="Poly.Mesh")
+	col.menu("INFO_MT_add", text="Skeleton")
+	col.menu("INFO_MT_add", text="Model")
+	col.menu("INFO_MT_add", text="Text")
+
+	layout = self.layout
+	col = layout.column(align=True)
+	col.operator("wm.bsi_decorator_button",text="Modify")
+	col.menu("INFO_MT_add", text="Curve")
+	col.menu("INFO_MT_add", text="Surf.Mesh")
+	col.menu("INFO_MT_add", text="Poly.Mesh")
+	col.menu("INFO_MT_add", text="Deform")
+	col.menu("INFO_MT_add", text="Model")
+
+def viewport_shading_panel(layout, context):
+	v3d 	= GUI.get_screen_area("VIEW_3D")
+	scene 	= context.scene
+
+	box = layout.box()
+	box.label(text= "Viewport Shading")
+	col = box.column()
+	col.prop(context.scene, "boundbox", text="Bounding Box")
+	col.prop(context.scene, "wireframe", text="Wireframe")
+	col.prop(context.scene, "constant", text="Constant")
+	col.prop(context.scene, "solid", text="Shaded")
+	col.prop(context.scene, "textured", text="Textured")
+	col.prop(context.scene, "textured_decal", text="Textured Decal")
+
+def viewport_fx_panel(layout, context):
+	v3d 			= GUI.get_screen_area("VIEW_3D")
+	scene 			= context.scene
+	game_settings 	= scene.game_settings
+	box = layout.box()
+	box.label(text= "FX Shading")
+	col = box.column()
+	if not scene.render.use_shading_nodes:
+		col.prop(game_settings, "material_mode", text="")
+
+	if v3d.viewport_shade == 'SOLID':
+		col.prop(v3d, "use_matcap")
+		if v3d.use_matcap:
+			col.template_icon_view(v3d, "matcap_icon")
+		if not v3d.use_matcap:
+			col.prop(v3d, "show_textured_solid")
+
+	fx_settings = v3d.fx_settings
+
+	if v3d.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
+		sub = col.column()
+		sub.active = v3d.region_3d.view_perspective == 'CAMERA'
+		sub.prop(fx_settings, "use_dof")
+		col.prop(fx_settings, "use_ssao", text="Ambient Occlusion")
+		if fx_settings.use_ssao:
+			ssao_settings = fx_settings.ssao
+			subcol = col.column(align=True)
+			subcol.prop(ssao_settings, "factor")
+			subcol.prop(ssao_settings, "distance_max")
+			subcol.prop(ssao_settings, "attenuation")
+			subcol.prop(ssao_settings, "samples")
+			subcol.prop(ssao_settings, "color")
+
+	col.prop(v3d, "show_only_render")
+	col.prop(v3d, "show_world")
+
+def viewport_objects_panel(layout, context):
+	v3d 	= GUI.get_screen_area("VIEW_3D")
+	scene 	= context.scene
+	obj = context.object
+	display_all = v3d.show_only_render
+	box = layout.box()
+	col = box.column()
+	col.label(text="Object Shading")
+	if display_all:
+		col.label(text="Hidden because of \"Only Render\"")
+	if not display_all:
+		col.prop(context.scene, "show_wire", text="Wireframe On Shaded")
+		if v3d.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
+			if obj and obj.mode == 'EDIT':
+				col.prop(context.scene, "occlude_wire", text="Occlude Wire")
+				col.prop(v3d, "show_occlude_wire")
+		col.prop(context.scene, "show_x_ray", text="X Ray <--LAME")
+		col.prop(context.scene, "show_all_edges", text="All Edges <--WTF is this")
+		col.prop(context.scene, "show_axis", text="Axis")
+		col.prop(context.scene, "show_bounds", text="Bounding Boxes")
+		col.prop(context.scene, "show_name", text="Names")
+		col.prop(context.scene, "show_only_shape_key", text="Shapes")
+		col.prop(v3d, "show_backface_culling")
+
+		if v3d.show_backface_culling:
+			col.prop(context.scene, "show_transparent", text="Hide Outline")
+		col.prop(context.scene, "show_texture_space", text="Texture Space")
+		col.prop(v3d, "show_outline_selected")
+		col.prop(v3d, "show_all_objects_origin", text = "Object Origins")
+		col.prop(v3d, "show_relationship_lines", text = "Relationships")
+
+def viewport_widgets_panel(layout, context):
+	v3d 			= GUI.get_screen_area("VIEW_3D")
+	scene 			= context.scene
+
+	box = layout.box()
+	col = box.column()
+	col.label(text="Viewport Widgets")
+	display_all = v3d.show_only_render
+	if display_all:
+		col.label(text="Hidden because of \"Only Render\"")
+	if not display_all:
+		split = col.split(percentage=0.55)
+		split.prop(v3d, "show_floor", text="Grid Floor")
+
+		row = split.row(align=True)
+		row.prop(v3d, "show_axis_x", text="X", toggle=True)
+		row.prop(v3d, "show_axis_y", text="Y", toggle=True)
+		row.prop(v3d, "show_axis_z", text="Z", toggle=True)
+
+		sub = col.column(align=True)
+		sub.prop(v3d, "grid_lines", text="Lines")
+		sub.prop(v3d, "grid_scale", text="Scale")
+		col.prop(v3d ,"cursor_location")
+		subsub = sub.column(align=True)
+		subsub.active = scene.unit_settings.system == 'NONE'
+		subsub.prop(v3d, "grid_subdivisions", text="Subdivisions")
+
+		box.operator("screen.region_quadview", text="Toggle Quad View")
+
+		if v3d.region_quadviews:
+			region = v3d.region_quadviews[2]
+			col = box.column()
+			col.prop(region, "lock_rotation")
+			row = col.row()
+			row.enabled = region.lock_rotation
+			row.prop(region, "show_sync_view")
+			row = col.row()
+			row.enabled = region.lock_rotation and region.show_sync_view
+			row.prop(region, "use_box_clip")
+
+def viewport_properties_panel(layout, context):
+	viewport_shading_panel(layout, context)
+	viewport_fx_panel(layout, context)
+	viewport_objects_panel(layout, context)
+	viewport_widgets_panel(layout, context)
+
+##########################################################
+# dynamic prop panel methods
+##########################################################
+
+
+def ANKI_PP_home(layout, context):
+	scene = context.scene
+
+	# Create a simple row.
+	layout.label(text=" Simple Row:")
+
+	row = layout.row()
+	row.prop(scene, "frame_start")
+	row.prop(scene, "frame_end")
+	row.prop(scene, "frame_end")
+	row.prop(scene, "frame_end")
+
+	# Create an row where the buttons are aligned to each other.
+	layout.label(text=" Aligned Row:")
+
+	row = layout.row(align=True)
+	row.prop(scene, "frame_start")
+	row.prop(scene, "frame_end")
+
+	# Create two columns, by using a split layout.
+	split = layout.split()
+
+	# First column
+	col = split.column()
+	col.label(text="Column One:")
+	col.prop(scene, "frame_end")
+	col.prop(scene, "frame_start")
+
+	# Second column, aligned
+	col = split.column(align=True)
+	col.label(text="Column Two:")
+	col.prop(scene, "frame_start")
+	col.prop(scene, "frame_end")
+
+	# Big render button
+	layout.label(text="Big Button:")
+	row = layout.row()
+	row.scale_y = 3.0
+	row.operator("render.render")
+
+	# Different sizes in a row
+	layout.label(text="Different button sizes:")
+	row = layout.row(align=True)
+	row.operator("render.render")
+
+	sub = row.row()
+	sub.scale_x = 2.0
+	sub.operator("render.render")
+
+	row.operator("render.render")
+
+def uv_tiling_layout(layout, texture_node):
+	r""" UV tiling properties"""
+	box =layout.box()
+	box.prop(texture_node, "extension", text= "")
+	col = box.column(align=True)
+	row = col.row(align=True)
+
+	if texture_node.extension == 'REPEAT':
+		row.label(text="Mirror and Repeat:")
+		col = box.column(align=True)
+		row = col.row()
+		row.prop(texture_node, "use_mirror_x", text="",
+					icon_value=(ico["toggle_on"].icon_id
+					if texture_node.use_mirror_x
+					else ico["toggle_off"].icon_id ),
+					emboss=False)
+		row.prop(texture_node, "repeat_x", text="Repeat X")
+		row.active = (texture_node.repeat_x > 1)
+
+		row = col.row()
+		row.prop(texture_node, "use_mirror_y", text="",
+			icon_value=(ico["toggle_on"].icon_id
+			if texture_node.use_mirror_y
+			else ico["toggle_off"].icon_id ),
+			emboss=False)
+		row.prop(texture_node, "repeat_y", text="Repeat Y")
+		row.active = (texture_node.repeat_y > 1)
+
+	elif texture_node.extension == 'CHECKER':
+		row = col.row(align=True)
+		row.prop(texture_node, "use_checker_even", text="Even",
+			icon_value=(ico["toggle_on"].icon_id
+			if texture_node.use_checker_even
+			else ico["toggle_off"].icon_id ),
+			emboss=False)
+		row.prop(texture_node, "use_checker_odd", text="Odd",
+			icon_value=(ico["toggle_on"].icon_id
+			if texture_node.use_checker_odd
+			else ico["toggle_off"].icon_id ),
+			emboss=False)
+
+		col = box.column(align=True)
+		col.prop(texture_node, "checker_distance", text="Distance")
+
+	col.label(text="Crop:")
+	row = col.row(align=True)
+	row.prop(texture_node, "crop_min_y", text="Min Y")
+	row.prop(texture_node, "crop_max_x", text="Max X")
+	row = col.row(align=True)
+	row.prop(texture_node, "crop_min_x", text="Min Y")
+	row.prop(texture_node, "crop_max_y", text="Max Y")
+
+def common_texture_filter(tex, col):
+	row = col.row(align=True)
+	row.label(text=":: Filter Properties" )
+	row.label(text="" )
+
+	row = col.row(align=True)
+	row.prop(tex, "filter_type", text="")
+	if tex.use_mipmap and tex.filter_type in {'AREA', 'EWA', 'FELINE'}:
+		if tex.filter_type == 'FELINE':
+			row.prop(tex, "filter_probes", text="Probes")
+		else:
+			row.prop(tex, "filter_eccentricity", text="Eccentricity")
+
+	row = col.row(align=True)
+	row.prop(tex, "use_filter_size_min", text="Min Size")
+	row.prop(tex, "filter_size")
+
+def uv_projection_layout(layout, texture_slot, object_node):
+	r"""UV layout and project types """
+	box =layout.box()
+	col = box.column(align=True)
+	row = col.row(align=True)
+	row.prop(texture_slot, "texture_coords", text="")
+	row.prop(texture_slot, "mapping", text="")
+	if texture_slot.texture_coords == 'UV':
+		row.prop_search(texture_slot, "uv_layer", object_node.data, "uv_textures", text="")
+	elif texture_slot.texture_coords == 'OBJECT':
+		row.prop(texture_slot, "object", text="")
+	row.operator("mesh.uv_texture_add", text="", icon='ZOOMIN')
+
+	col = box.column(align=True)
+	row = col.row(align=True)
+	if texture_slot.texture_coords in {'ORCO', 'UV'}:
+		row.prop(texture_slot, "use_from_dupli", text="",
+				  icon_value=(ico["toggle_on"].icon_id
+								if texture_slot.use_from_dupli
+								else ico["toggle_off"].icon_id ),
+				  emboss=False)
+
+
+	row.prop(texture_slot, "mapping_x", text="")
+	row.prop(texture_slot, "mapping_y", text="")
+	row.prop(texture_slot, "mapping_z", text="")
+
+	col = box.column(align=True)
+	row = box.row(align=True)
+	row = col.row(align=True)
+
+	row.column().prop(texture_slot, "offset")
+	row.column().prop(texture_slot, "scale")
+
+def texture_sampling_layout(layout, texture_slot):
+	slot = texture_slot #getattr(context, "texture_slot", None)
+	tex = slot.texture #context.texture
+	box =layout.box()
+	col = box.column(align=True)
+
+	row = col.row(align=True)
+	row.label(text=":: Alpha Properties" )
+	row.label(text="" )
+
+	row = col.row(align=True)
+	row.prop(tex, "use_preview_alpha")
+
+	row = col.row(align=True)
+	row.prop(tex, "use_alpha", text="Use")
+	row.prop(tex, "use_calculate_alpha", text="Calculate")
+
+	row = col.row(align=True)
+	row.prop(tex, "invert_alpha", text="Invert")
+	row.prop(tex, "use_flip_axis", text="Flip X/Y Axis")
+
+	col.separator()
+	row = col.row(align=True)
+	row.label(text=":: Normal Properties" )
+	row.label(text="" )
+
+	row = col.row(align=True)
+	row.prop(tex, "use_normal_map")
+	row.active = tex.use_normal_map
+	row.prop(slot, "normal_map_space", text="")
+	row.active = tex.use_normal_map
+
+	row = col.row(align=True)
+	row.prop(tex, "use_mipmap")
+	row.prop(tex, "use_derivative_map")
+	row.active = tex.use_mipmap
+
+	row = col.row(align=True)
+	row.prop(tex, "use_mipmap_gauss", text ="MIP Blur")
+	row.prop(tex, "use_interpolation")
+
+	col.separator()
+	common_texture_filter(tex, col)
+
+def texture_influence_layout(layout, texture_slot, port_type="diffuse"):
+	tex = texture_slot
+	box =layout.box()
+	col = box.column()
+	if port_type == "diffuse":
+		GUI.button_slider(col, texture_slot, "use_map_diffuse", "diffuse_factor", "Intensity")
+		GUI.button_slider(col, texture_slot, "use_map_color_diffuse", "diffuse_color_factor", "Color")
+		GUI.button_slider(col, texture_slot, "use_map_alpha", "alpha_factor", "Alpha")
+		GUI.button_slider(col, texture_slot, "use_map_translucency", "translucency_factor", "Translucency")
+	if port_type == "specular":
+		GUI.button_slider(col, texture_slot,"use_map_specular", "specular_factor", "Intensity")
+		GUI.button_slider(col, texture_slot,"use_map_hardness", "hardness_factor", "Hardness")
+		GUI.button_slider(col, texture_slot,"use_map_color_spec", "specular_color_factor", "Color")
+	col = box.column(align=False)
+	row = col.row(align =True)
+	row.prop(texture_slot, "blend_type", text="")
+	row = col.row(align =True)
+	row.prop(texture_slot, "invert", text="Negative")
+	row.prop(texture_slot, "use_stencil")
+	# color is used on gray-scale textures even when use_rgb_to_intensity is disabled.
+	row = col.row(align =True)
+	row.prop(texture_slot, "use_rgb_to_intensity")
+	if texture_slot.use_rgb_to_intensity:
+		row.prop(texture_slot, "color", text="")
+
+	row = col.row(align =True)
+	row.prop(texture_slot, "default_value", text="DVar", slider=True)
+
+def shader_property_layout(context, layout, material):
+	col = layout.column(align=True)
+	row = col.row(align=True)
+	row.operator("wm.bsi_decorator_button", text="", emboss=False) # pushes to the right top buttons
+
+	row.prop( material.BSI, "shader_stand", text="",
+			  icon_value=(ico["shader_strand_on"].icon_id
+							if material.BSI.shader_stand
+							else ico["shader_strand_off"].icon_id ),
+			  emboss=False)
+
+	row.prop( material.BSI, "indirect_illum", text="",
+			  icon_value=(ico["shader_shading_on"].icon_id
+							if material.BSI.indirect_illum
+							else ico["shader_shading_off"].icon_id ),
+			  emboss=False)
+
+	row.prop( material.BSI, "shader_rendering", text="",
+			  icon=('RESTRICT_RENDER_OFF'
+							if material.BSI.shader_rendering
+							else 'RESTRICT_RENDER_ON' ),
+			  emboss=False)
+
+	row.prop( material.BSI, "shader_shadow", text="",
+			  icon_value=(ico["shader_shadow_on"].icon_id
+							if material.BSI.shader_shadow
+							else ico["shader_shadow_off"].icon_id ),
+			  emboss=False)
+
+	row.prop( material.BSI, "shader_sss", text="",
+			  icon_value=(ico["shader_sss_on"].icon_id
+							if material.BSI.shader_sss
+							else ico["shader_sss_off"].icon_id ),
+			  emboss=False)
+	row.prop( material.BSI, "shader_transparency", text="",
+			  icon_value=(ico["shader_transparency_on"].icon_id
+							if material.BSI.shader_transparency
+							else ico["shader_transparency_off"].icon_id ),
+			  emboss=False)
+	row.prop( material.BSI, "shader_reflection", text="",
+			  icon_value=(ico["shader_reflect_on"].icon_id
+							if material.BSI.shader_reflection
+							else ico["shader_reflect_off"].icon_id ),
+			  emboss=False)
+
+	if material.BSI.shader_stand:
+		shader_strand_layout(context, layout, material)
+
+	if material.BSI.indirect_illum:
+		shader_indirect_illum_layout(layout, material)
+
+	if material.BSI.shader_rendering:
+		shader_rendering_layout(layout, material)
+
+	if material.BSI.shader_shadow:
+		shader_shadow_layout(layout, material)
+
+	if material.BSI.shader_sss:
+		shader_sss(layout, material)
+
+	if material.BSI.shader_transparency:
+		shader_transparency(layout, material)
+
+	if material.BSI.shader_reflection:
+		shader_reflection(layout, material)
+
+def shader_ramp_layout(layout, material):
+	box = layout.box()
+	box.prop(material, "use_diffuse_ramp", text="Use Ramp Shader")
+	if material.use_diffuse_ramp:
+		col = box.column()
+		col.active = (not material.use_shadeless)
+		col.separator()
+		col.template_color_ramp(material, "diffuse_ramp", expand=True)
+		col.separator()
+
+		row = col.row()
+		row.prop(material, "diffuse_ramp_input", text="Input")
+		row.prop(material, "diffuse_ramp_blend", text="Blend")
+
+		col.prop(material, "diffuse_ramp_factor", text="Factor")
+
+def shader_strand_layout(context, layout, material):
+	box = layout.box()
+	box.label(text="Strand Properties")
+	tan = material.strand
+
+	col = box.column(align=True)
+	col.prop(tan, "use_blender_units")
+	col.prop(tan, "root_size", text="Size Root")
+	col.prop(tan, "tip_size", text="Size Tip")
+	col.prop(tan, "size_min", text="Size Min")
+
+	col = box.column(align=True)
+	col.active = (not material.use_shadeless)
+	col.prop(tan, "use_tangent_shading")
+	col.prop(tan, "shape", text="Tangent Shape")
+
+	col = box.column(align=True)
+	row = col.row(align=True)
+	row.prop(tan, "width_fade", text="Shading")
+	if context.object and context.object.type == 'MESH':
+		row.prop_search(tan, "uv_layer", context.object.data, "uv_textures", text="")
+	else:
+		row.prop(tan, "uv_layer", text="")
+	col.label("Surface diffuse:")
+	col.prop(tan, "blend_distance", text="Distance")
+
+def shader_indirect_illum_layout(layout, material):
+	box = layout.box()
+	box.label(text="Indirect Illumination Properties")
+	if material.type in {'SURFACE', 'WIRE'}:
+		col = box.column(align=True)
+		row = col.row(align=True)
+		row.prop(material, "use_shadeless", text="Constant")
+		col.active = not material.use_shadeless
+		row.prop(material, "emit")
+		row = col.row(align=True)
+		row.prop(material, "use_tangent_shading", text="Tangent")
+		row.prop(material, "ambient")
+		row = col.row(align=True)
+		row.prop(material, "use_cubic", text="Cubic ")
+		row.prop(material, "translucency")
+
+def shader_rendering_layout(layout, material):
+	box = layout.box()
+	col = box.column(align=True)
+	row = col.row(align=True)
+	row.label(text=":: Rendering")
+	row.label(text="")
+
+	row = col.row(align=True)
+	if not material.use_nodes:
+		row.prop(material, "use_raytrace")
+		row.prop(material, "use_sky")
+		row = col.row(align=True)
+		row.prop(material, "use_full_oversampling", text="Oversampling")
+	row.prop(material, "use_mist")
+
+	col = box.column(align=True)
+	row = col.row(align=True)
+	if not material.use_nodes:
+		row.prop(material, "invert_z")
+		sub = row.row()
+		sub.active = material.use_transparency and material.transparency_method == 'Z_TRANSPARENCY'
+		sub.prop(material, "offset_z")
+
+	col.separator()
+	row = col.row(align=True)
+	row.label(text=":: Shading")
+	row.label(text="")
+
+	row = col.row(align=True)
+	row.prop(material, "use_face_texture")
+	sub = row.column()
+	sub.active = material.use_face_texture
+	sub.prop(material, "use_face_texture_alpha", text="Use Alpha")
+
+	row = col.row(align=True)
+	row.prop(material, "use_vertex_color_paint")
+	row.prop(material, "use_vertex_color_light")
+
+	row = col.row(align=True)
+	row.prop(material, "use_object_color")
+	row.prop(material, "use_uv_project")
+
+	row = col.row(align=True)
+	row.label(text=":: Lighting")
+	row.label(text="")
+
+	col.separator()
+	row = col.row()
+	row.prop(material, "light_group", text="Light Group:")
+	if not material.use_nodes:
+		row.prop(material, "pass_index")
+
+	row = col.row(align=True)
+	row.active = bool(material.light_group)
+	row.prop(material, "use_light_group_exclusive", text="Exclusive")
+	row.prop(material, "use_light_group_local", text="Local")
+
+def shader_shadow_layout(layout, material):
+	box = layout.box()
+	box.label(text="Shadow Properties")
+	if not material.use_nodes:
+		col = box.column()
+		row = col.row(align=True)
+		row.prop(material, "use_shadows", text="Receive")
+		row.prop(material, "use_cast_shadows", text="Cast")
+		row = col.row(align=True)
+		row.prop(material, "use_transparent_shadows", text="Receive Transparent")
+		row.prop(material, "use_cast_shadows_only", text="Cast Only")
+		row = col.row(align=True)
+		row.prop(material, "use_cast_approximate")
+		row = col.row(align=True)
+		row.prop(material, "use_only_shadow", text="Shadows Only")
+		row.active = material.use_only_shadow
+		row.prop(material, "shadow_only_type", text="")
+		row = col.row(align=True)
+		row.prop(material, "use_cast_buffer_shadows")
+		row.active = material.use_cast_buffer_shadows
+		row.prop(material, "shadow_buffer_bias", text="Buffer Bias")
+		row = col.row(align=True)
+		row.label(text="")
+		row.active = material.use_cast_buffer_shadows
+		row.prop(material, "shadow_cast_alpha", text="Casting Alpha")
+	row = col.row(align=True)
+	row.prop(material, "use_ray_shadow_bias", text="Auto Ray Bias")
+	row.active = (not material.use_ray_shadow_bias)
+	row.prop(material, "shadow_ray_bias", text="Ray Bias")
+
+def shader_sss(layout, material):
+	sss = material.subsurface_scattering
+	box = layout.box()
+	box.prop(sss, "use", text="Subsurface Scattering")
+
+	if sss.use:
+		row = box.row().split()
+		sub = row.row(align=True).split(align=True, percentage=0.75)
+		sub.menu("MATERIAL_MT_sss_presets", text=bpy.types.MATERIAL_MT_sss_presets.bl_label)
+		sub.operator("material.sss_preset_add", text="", icon='ZOOMIN')
+		sub.operator("material.sss_preset_add", text="", icon='ZOOMOUT').remove_active = True
+
+		split = box.split()
+
+		col = split.column()
+		col.prop(sss, "ior")
+		col.prop(sss, "scale")
+		col.prop(sss, "color", text="")
+		col.prop(sss, "radius", text="RGB Radius", expand=True)
+
+		col = split.column()
+		sub = col.column(align=True)
+		sub.label(text="Blend:")
+		sub.prop(sss, "color_factor", text="Color")
+		sub.prop(sss, "texture_factor", text="Texture")
+		sub.label(text="Scattering Weight:")
+		sub.prop(sss, "front")
+		sub.prop(sss, "back")
+		col.separator()
+		col.prop(sss, "error_threshold", text="Error")
+
+def shader_transparency(layout, material):
+	box = layout.box()
+	box.prop(material, "use_transparency", text="Transparency")
+	if material.use_transparency:
+		rt_transparency = material.raytrace_transparency
+		row = box.row()
+		row.active = material.use_transparency
+		row.prop(material, "transparency_method", expand=True)
+
+		split = box.split()
+		split.active = material.use_transparency
+
+		col = split.column()
+		col.prop(material, "alpha")
+		row = col.row()
+		row.active = (material.transparency_method != 'MASK') and (not material.use_shadeless)
+		row.prop(material, "specular_alpha", text="Specular")
+
+		col = split.column()
+		col.active = (not material.use_shadeless)
+		col.prop(rt_transparency, "fresnel")
+		sub = col.column()
+		sub.active = (rt_transparency.fresnel > 0.0)
+		sub.prop(rt_transparency, "fresnel_factor", text="Blend")
+
+		if material.transparency_method == 'RAYTRACE':
+			box.separator()
+			split = box.split()
+			split.active = material.use_transparency
+
+			col = split.column()
+			col.prop(rt_transparency, "ior")
+			col.prop(rt_transparency, "filter")
+			col.prop(rt_transparency, "falloff")
+			col.prop(rt_transparency, "depth_max")
+			col.prop(rt_transparency, "depth")
+
+			col = split.column()
+			col.label(text="Gloss:")
+			col.prop(rt_transparency, "gloss_factor", text="Amount")
+			sub = col.column()
+			sub.active = rt_transparency.gloss_factor < 1.0
+			sub.prop(rt_transparency, "gloss_threshold", text="Threshold")
+			sub.prop(rt_transparency, "gloss_samples", text="Samples")
+
+def shader_reflection(layout, material):
+	refl_mat = material.raytrace_mirror
+	box = layout.box()
+	box.prop(refl_mat, "use", text="Reflection")
+
+	if refl_mat.use:
+		box.active = refl_mat.use
+
+		split = box.split()
+
+		col = split.column()
+		col.prop(refl_mat, "reflect_factor")
+		col.prop(material, "mirror_color", text="")
+
+		col = split.column()
+		col.prop(refl_mat, "fresnel")
+		sub = col.column()
+		sub.active = (refl_mat.fresnel > 0.0)
+		sub.prop(refl_mat, "fresnel_factor", text="Blend")
+
+		split = box.split()
+
+		col = split.column()
+		col.separator()
+		col.prop(refl_mat, "depth")
+		col.prop(refl_mat, "distance", text="Max Dist")
+		col.separator()
+		sub = col.split(percentage=0.4)
+		sub.active = (refl_mat.distance > 0.0)
+		sub.label(text="Fade To:")
+		sub.prop(refl_mat, "fade_to", text="")
+
+		col = split.column()
+		col.label(text="Gloss:")
+		col.prop(refl_mat, "gloss_factor", text="Amount")
+		sub = col.column()
+		sub.active = (refl_mat.gloss_factor < 1.0)
+		sub.prop(refl_mat, "gloss_threshold", text="Threshold")
+		sub.prop(refl_mat, "gloss_samples", text="Samples")
+		sub.prop(refl_mat, "gloss_anisotropic", text="Anisotropic")
+
+def material_panel(layout, context):
+	material = context.active_object.active_material
+
+	ob = context.active_object
+	is_sortable = (len(ob.material_slots) > 1)
+	rows = 1
+	if is_sortable:
+		rows = 4
+	layout.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows)
+	layout.template_ID(ob, "active_material", new="material.new")
+
+	if material!= None:
+		scene = context.scene
+		ob = context.active_object
+
+		diff_texture_slot = material.texture_slots[0]
+		spec_texture_slot = material.texture_slots[1]
+		nrml_texture_slot = material.texture_slots[2]
+		refl_texture_slot = material.texture_slots[3]
+		trns_texture_slot = material.texture_slots[4]
+
+		shader_property_layout(context, layout, material)
+
+		##########################################################
+		# DIFFUSE PORT
+		##########################################################
+		split = layout.split(percentage=0.1)
+		row = split.row(align=True)
+		row.prop(material, "diffuse_color", text="")
+		row = split.row(align=True)
+		row.prop(material, "diffuse_shader", text="")
+		row.prop(material, "diffuse_intensity", text="Intensity")
+		col = layout.column(align=True)
+		row = col.row(align=True)
+		row.operator("wm.bsi_decorator_button", text="DIFFUSE PORT", emboss=False)
+
+		row.prop( material.BSI, "diff_image", text="",
+				  icon=('TEXTURE'
+								if material.BSI.diff_image
+								else 'IMASEL' ),
+				  emboss=False)
+
+		row.prop( material.BSI, "diff_uvs", text="",
+				  icon_value=(ico["uv_conn"].icon_id
+								if material.BSI.diff_uvs
+								else ico["uv"].icon_id ),
+				  emboss=False)
+
+		row.prop( material.BSI, "diff_sampling", text="",
+				  icon_value=(ico["sampling_on"].icon_id
+								if material.BSI.diff_sampling
+								else ico["sampling_off"].icon_id ),
+				  emboss=False)
+
+		row.prop( material.BSI, "diff_influence", text="",
+				  icon_value=(ico["influences_on"].icon_id
+								if material.BSI.diff_influence
+								else ico["influences_off"].icon_id ),
+				  emboss=False)
+
+		row.prop( material.BSI, "diff_ramp", text="",
+				  icon_value=(ico["ramp_on"].icon_id
+								if material.BSI.diff_ramp
+								else ico["ramp_off"].icon_id ),
+				  emboss=False)
+
+		if material.BSI.diff_image:
+			if diff_texture_slot  != None:
+				col = layout.column(align=True)
+				row = col.row(align=True)
+
+				diff_port = row.operator("bsi.apply_texture_image", text="Re-Apply New Diffuse Image")
+				diff_port.mat_port_type = "diffuse"
+
+				prop = row.operator("bsi.clear_texture_slot" ,text="",icon = 'X', emboss=True)
+				prop.port_type= "diffuse"
+
+				row = col.row(align=True)
+				row.label(text="") #spacer align to the right
+				row.prop(material.BSI, "diff_img_display", text="",
+						  icon=('VISIBLE_IPO_ON'
+										if material.BSI.diff_img_display
+										else 'VISIBLE_IPO_OFF'),
+						  emboss=False)
+				if material.BSI.diff_img_display:
+					box = layout.box()
+					box.label(text="UGLY BLENDER DESIGN---> CAN'T FIX")
+					box.template_image(diff_texture_slot.texture, "image", diff_texture_slot.texture.image_user)
+			else:
+				diff_port = layout.operator("bsi.apply_texture_image", text="Load Diffuse Image")
+				diff_port.mat_port_type = "diffuse"
+
+		if material.BSI.diff_uvs:
+			if diff_texture_slot  != None:
+				uv_projection_layout(layout, diff_texture_slot, ob)
+				uv_tiling_layout(layout, diff_texture_slot.texture)
+
+			else:
+				layout.label(text="No Texture Connection")
+
+		if material.BSI.diff_sampling:
+			if diff_texture_slot  != None:
+				texture_sampling_layout(layout, diff_texture_slot)
+			else:
+				layout.label(text="No Texture Connection")
+
+		if material.BSI.diff_influence:
+			if diff_texture_slot  != None:
+				texture_influence_layout(layout, diff_texture_slot, port_type="diffuse")
+			else:
+				layout.label(text="No Texture Connection")
+
+		if material.BSI.diff_ramp:
+			shader_ramp_layout(layout, material)
+		##########################################################
+		# SPECULAR PORT
+		##########################################################
+		split = layout.split(percentage=0.1)
+		row = split.row(align=True)
+		row.prop(material, "specular_color", text="")
+		row = split.row(align=True)
+		row.prop(material, "specular_shader", text="")
+		row.prop(material, "specular_intensity", text="Intensity")
+
+		col = layout.column(align=True)
+		row = col.row(align=True)
+		row.operator("wm.bsi_decorator_button", text="SPECULAR PORT", emboss=False)
+
+		row.prop( material.BSI, "spec_image", text="",
+				  icon=('TEXTURE'
+								if material.BSI.spec_image
+								else 'IMASEL' ),
+				  emboss=False)
+		row.prop( material.BSI, "spec_uvs", text="",
+				  icon_value=(ico["uv_conn"].icon_id
+								if material.BSI.spec_uvs
+								else ico["uv"].icon_id ),
+				  emboss=False)
+
+		row.prop( material.BSI, "spec_sampling", text="",
+				  icon_value=(ico["sampling_on"].icon_id
+								if material.BSI.spec_sampling
+								else ico["sampling_off"].icon_id ),
+				  emboss=False)
+
+		row.prop( material.BSI, "spec_influence", text="",
+				  icon_value=(ico["influences_on"].icon_id
+								if material.BSI.spec_influence
+								else ico["influences_off"].icon_id ),
+				  emboss=False)
+
+		row.prop( material.BSI, "spec_ramp", text="",
+				  icon_value=(ico["ramp_on"].icon_id
+								if material.BSI.spec_ramp
+								else ico["ramp_off"].icon_id ),
+				  emboss=False)
+
+		if material.BSI.spec_image:
+			if spec_texture_slot  != None:
+				col = layout.column(align=True)
+				row = col.row(align=True)
+
+				spec_port = row.operator("bsi.apply_texture_image", text="Re-Apply New Specular Image")
+				spec_port.mat_port_type = "specular"
+
+				prop = row.operator("bsi.clear_texture_slot" ,text="",icon = 'X', emboss=True)
+				prop.port_type= "specular"
+
+				row = col.row(align=True)
+				row.label(text="") #spacer align to the right
+				row.prop(material.BSI, "spec_img_display", text="",
+						  icon=('VISIBLE_IPO_ON'
+										if material.BSI.spec_img_display
+										else 'VISIBLE_IPO_OFF'),
+						  emboss=False)
+				if material.BSI.spec_img_display:
+					box = layout.box()
+					box.label(text="UGLY BLENDER DESIGN---> CAN'T FIX")
+					box.template_image(spec_texture_slot.texture, "image", spec_texture_slot.texture.image_user)
+			else:
+				spec_port = layout.operator("bsi.apply_texture_image", text="Load Specular Image")
+				spec_port.mat_port_type = "specular"
+
+		if material.BSI.spec_uvs:
+			if spec_texture_slot  != None:
+				uv_projection_layout(layout, spec_texture_slot, ob)
+				uv_tiling_layout(layout, spec_texture_slot.texture)
+
+			else:
+				layout.label(text="No Texture Connection")
+
+		if material.BSI.spec_sampling:
+			if spec_texture_slot  != None:
+				texture_sampling_layout(layout, spec_texture_slot)
+			else:
+				layout.label(text="No Texture Connection")
+
+		if material.BSI.spec_influence:
+			if spec_texture_slot  != None:
+				texture_influence_layout(layout, spec_texture_slot, port_type="specular")
+			else:
+				layout.label(text="No Texture Connection")
+
+		if material.BSI.spec_ramp:
+			shader_ramp_layout(layout, material)
+		##########################################################
+		# NORMAL - BUMP PORT
+		##########################################################
+		split = layout.split(percentage=0.1)
+		row = split.row(align=True)
+		row.prop(material, "diffuse_color", text="")
+		row = split.row(align=True)
+		row.prop(material, "diffuse_shader", text="")
+		row.prop(material, "diffuse_intensity", text="Intensity")
+		col = layout.column(align=True)
+		row = col.row(align=True)
+		row.operator("wm.bsi_decorator_button", text="BUMP PORT", emboss=False)
+
+		row.prop( material.BSI, "spec_image", text="",
+				  icon=('TEXTURE'
+								if material.BSI.spec_image
+								else 'IMASEL' ),
+				  emboss=False)
+		row.prop( material.BSI, "spec_uvs", text="",
+				  icon_value=(ico["uv_conn"].icon_id
+								if material.BSI.spec_uvs
+								else ico["uv"].icon_id ),
+				  emboss=False)
+
+		row.prop( material.BSI, "spec_sampling", text="",
+				  icon_value=(ico["sampling_on"].icon_id
+								if material.BSI.spec_sampling
+								else ico["sampling_off"].icon_id ),
+				  emboss=False)
+
+		row.prop( material.BSI, "spec_influence", text="",
+				  icon_value=(ico["influences_on"].icon_id
+								if material.BSI.spec_influence
+								else ico["influences_off"].icon_id ),
+				  emboss=False)
+
+		row.prop( material.BSI, "spec_ramp", text="",
+				  icon_value=(ico["ramp_on"].icon_id
+								if material.BSI.spec_ramp
+								else ico["ramp_off"].icon_id ),
+				  emboss=False)
+
+# def bl_shading_panel(layout):
+# 	context = bpy.context
+# 	view = context.space_data
+# 	scene = context.scene
+# 	gs = scene.game_settings
+# 	obj = context.object
+
+# 	col = layout.column()
+
+# 	if not scene.render.use_shading_nodes:
+# 		col.prop(gs, "material_mode", text="")
+
+# 	if view.viewport_shade == 'SOLID':
+# 		col.prop(view, "show_textured_solid")
+# 		col.prop(view, "use_matcap")
+# 		if view.use_matcap:
+# 			col.template_icon_view(view, "matcap_icon")
+# 	elif view.viewport_shade == 'TEXTURED':
+# 		if scene.render.use_shading_nodes or gs.material_mode != 'GLSL':
+# 			col.prop(view, "show_textured_shadeless")
+
+# 	col.prop(view, "show_backface_culling")
+
+# 	if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
+# 		if obj and obj.mode == 'EDIT':
+# 			col.prop(view, "show_occlude_wire")
+
+# 	fx_settings = view.fx_settings
+
+# 	if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
+# 		sub = col.column()
+# 		sub.active = view.region_3d.view_perspective == 'CAMERA'
+# 		sub.prop(fx_settings, "use_dof")
+# 		col.prop(fx_settings, "use_ssao", text="Ambient Occlusion")
+# 		if fx_settings.use_ssao:
+# 			ssao_settings = fx_settings.ssao
+# 			subcol = col.column(align=True)
+# 			subcol.prop(ssao_settings, "factor")
+# 			subcol.prop(ssao_settings, "distance_max")
+# 			subcol.prop(ssao_settings, "attenuation")
+# 			subcol.prop(ssao_settings, "samples")
+# 			subcol.prop(ssao_settings, "color")
+

+ 276 - 0
tools/anki_scene_exporter/ui/panel_material.py

@@ -0,0 +1,276 @@
+import bpy
+
+from bpy.types import Panel
+
+def shader_property_layout(context, layout, material):
+	col = layout.column(align=True)
+	row = col.row(align=True)
+	row.operator("wm.anki_proxy_button", text="", emboss=True) # pushes to the right top buttons
+
+	row.prop( material.ANKI, "shader_stand", text="",
+			  icon=('STRANDS'
+							if material.ANKI.shader_stand
+							else'STRANDS' ),
+			  emboss=True)
+
+	row.prop( material.ANKI, "indirect_illum", text="",
+			  icon=('MATERIAL'
+							if material.ANKI.indirect_illum
+							else 'MATERIAL' ),
+			  emboss=True)
+
+	row.prop( material.ANKI, "shader_rendering", text="",
+			  icon=('RESTRICT_RENDER_OFF'
+							if material.ANKI.shader_rendering
+							else 'RESTRICT_RENDER_ON' ),
+			  emboss=True)
+
+	row.prop( material.ANKI, "shader_shadow", text="",
+			  icon=('MATERIAL'
+							if material.ANKI.shader_shadow
+							else 'MATERIAL' ),
+			  emboss=True)
+
+	row.prop( material.ANKI, "shader_sss", text="",
+			  icon=('MATERIAL'
+							if material.ANKI.shader_sss
+							else 'MATERIAL' ),
+			  emboss=True)
+	row.prop( material.ANKI, "shader_transparency", text="",
+			  icon=('MATERIAL'
+							if material.ANKI.shader_transparency
+							else 'MATERIAL' ),
+			  emboss=True)
+	row.prop( material.ANKI, "shader_reflection", text="",
+			  icon=('MATERIAL'
+							if material.ANKI.shader_reflection
+							else 'MATERIAL' ),
+			  emboss=True)
+
+	if material.ANKI.shader_stand:
+		shader_strand_layout(context, layout, material)
+
+	if material.ANKI.indirect_illum:
+		shader_indirect_illum_layout(layout, material)
+
+	if material.ANKI.shader_rendering:
+		shader_rendering_layout(layout, material)
+
+	if material.ANKI.shader_shadow:
+		shader_shadow_layout(layout, material)
+
+	if material.ANKI.shader_sss:
+		shader_sss(layout, material)
+
+	if material.ANKI.shader_transparency:
+		shader_transparency(layout, material)
+
+	if material.ANKI.shader_reflection:
+		shader_reflection(layout, material)
+
+class ANKI_material(Panel):
+	"""Creates a Panel in the scene context of the properties editor"""
+	bl_label = "Layout Demo"
+	bl_idname = "SCENE_PT_layout"
+	bl_space_type = 'VIEW_3D'
+	bl_region_type = 'UI'
+	bl_context = "scene"
+
+	def draw(self, context):
+		layout = self.layout
+		scene = context.scene
+		ob = context.active_object
+		material = context.active_object.active_material
+
+		is_sortable = (len(ob.material_slots) > 1)
+		rows = 1
+		if is_sortable:
+			rows = 4
+		layout.template_list("MATERIAL_UL_matslots", "",
+		ob, "material_slots", ob, "active_material_index", rows=rows)
+		layout.template_ID(ob, "active_material", new="material.new")
+
+		if material!= None:
+			#scene = context.scene
+			#ob = context.active_object
+			diff_texture_slot = material.texture_slots[0]
+			ruff_texture_slot = material.texture_slots[1]
+			nrml_texture_slot = material.texture_slots[2]
+			refl_texture_slot = material.texture_slots[3]
+			trns_texture_slot = material.texture_slots[4]
+
+			# shader_property_layout(context, layout, material)
+
+			##########################################################
+			# DIFFUSE PORT
+			##########################################################
+			split = layout.split(percentage=0.1)
+			row = split.row(align=True)
+			row.prop(material, "diffuse_color", text="")
+			row = split.row(align=True)
+			row.prop(material, "diffuse_intensity", text="Diffuse Intensity")
+			# row.operator("wm.anki_proxy_button", text="", icon='IMAGE_COL')
+			diff_port = row.operator("anki.apply_texture_image", text = "", icon='IMAGE_COL')
+			diff_port.mat_port_type = "diffuse"
+
+			# if material.ANKI.diff_image:
+			if diff_texture_slot:
+				col = layout.column(align=True)
+				row = col.row(align=True)
+
+				# diff_port = row.operator("anki.apply_texture_image", text="Re-Apply New Diffuse Image")
+				# diff_port.mat_port_type = "diffuse"
+
+
+				# row = col.row(align=True)
+				# row.label(text="") #spacer align to the right
+				row.prop(material.ANKI, "diff_img_display", text="Toggle Properties",
+						 icon=('VISIBLE_IPO_ON' if material.ANKI.diff_img_display
+								else 'VISIBLE_IPO_OFF'), emboss=True)
+
+				prop = row.operator("anki.clear_texture_slot" ,text="",icon = 'X', emboss=True)
+				prop.port_type= "diffuse"
+
+				if material.ANKI.diff_img_display:
+					box = layout.box()
+					box.prop_search(diff_texture_slot, "uv_layer", ob.data, "uv_textures", text="")
+					box.label(text="UGLY BLENDER DESIGN---> CAN'T FIX")
+					box.template_image(diff_texture_slot.texture, "image", diff_texture_slot.texture.image_user)
+			# else:
+			# 	diff_port = layout.operator("anki.apply_texture_image", text="Load Diffuse Image")
+			# 	diff_port.mat_port_type = "diffuse"
+
+			# ROUGHNESS PORT
+			port_type = "roughness"
+			split = layout.split(percentage=0.1)
+			row = split.row(align=True)
+			row.prop(material, "specular_color", text="")
+			row = split.row(align=True)
+			row.prop(material, "specular_hardness", text="Roughness Intensity")
+			ruff_port = row.operator("anki.apply_texture_image", text = "", icon='IMAGE_COL')
+			ruff_port.mat_port_type = port_type
+
+			if ruff_texture_slot:
+				col = layout.column(align=True)
+				row = col.row(align=True)
+				row.prop(material.ANKI, "ruff_img_display", text="Toggle Properties",
+						 icon=('VISIBLE_IPO_ON' if material.ANKI.ruff_img_display
+								else 'VISIBLE_IPO_OFF'), emboss=True)
+
+				prop = row.operator("anki.clear_texture_slot" ,text="",icon = 'X', emboss=True)
+				prop.port_type = port_type
+
+				if material.ANKI.ruff_img_display:
+					box = layout.box()
+					box.prop(ruff_texture_slot, "hardness_factor", text="", slider=True)
+					box.prop_search(ruff_texture_slot, "uv_layer", ob.data, "uv_textures", text="")
+					# sub.prop(tex, factor, text=name, slider=True)
+					box.label(text="UGLY BLENDER DESIGN---> CAN'T FIX")
+					box.template_image(ruff_texture_slot.texture, "image", ruff_texture_slot.texture.image_user)
+
+			# SPECULAR COLOR PORT
+			# split = layout.split(percentage=0.1)
+			# row = split.row(align=True)
+			# row.prop(material, "specular_hardness", text="Roughness Intensity")
+			# row.prop(material, "specular_hardness", text="Roughness Intensity")
+			# row.operator("wm.anki_proxy_button", text="", icon='IMAGE_COL')
+
+			# METALIC PORT
+			split = layout.split(percentage=0.1)
+			row = split.row(align=True)
+			row.prop(material, "mirror_color", text="")
+			row = split.row(align=True)
+			row.prop(material.raytrace_mirror,"reflect_factor", text="Metallic Intensity")
+			row.operator("wm.anki_proxy_button", text="", icon='IMAGE_COL')
+
+
+
+
+			 # Diffuse, normal, roughness, metallic, emission, height
+
+			# split = layout.split(percentage=0.1)
+			# row = split.row(align=True)
+			# row.prop(material, "diffuse_color", text="")
+
+			row = layout.row(align=True)
+			row.prop(material, "diffuse_intensity", text="Normal Intensity")
+			row.operator("wm.anki_proxy_button", text="", icon='IMAGE_COL')
+
+
+			# row.prop(material, "diffuse_color", text="")
+			# row = split.row(align=True)
+			# row.prop(material, "diffuse_intensity", text="Intensity")
+			# row.operator("wm.anki_proxy_button", text="", icon='IMAGE_COL')
+
+			layout.label(text=" Emission:")
+			split = layout.split(percentage=0.1)
+			row = split.row(align=True)
+			row.prop(material, "diffuse_color", text="")
+			row = split.row(align=True)
+			row.prop(material, "diffuse_intensity", text="Intensity")
+			row.operator("wm.anki_proxy_button", text="", icon='IMAGE_COL')
+
+			layout.label(text=" Height:")
+			split = layout.split(percentage=0.1)
+			row = split.row(align=True)
+			row.prop(material, "diffuse_color", text="")
+			row = split.row(align=True)
+			row.prop(material, "diffuse_intensity", text="Intensity")
+			row.operator("wm.anki_proxy_button", text="", icon='IMAGE_COL')
+
+		# # Create a simple row.
+
+		# row = layout.row()
+		# row.prop(scene, "frame_start")
+		# row.prop(scene, "frame_end")
+
+		# # Create an row where the buttons are aligned to each other.
+		# layout.label(text=" Aligned Row:")
+
+		# row = layout.row(align=True)
+		# row.prop(scene, "frame_start")
+		# row.prop(scene, "frame_end")
+
+		# # Create two columns, by using a split layout.
+		# split = layout.split()
+
+		# # First column
+		# col = split.column()
+		# col.label(text="Column One:")
+		# col.prop(scene, "frame_end")
+		# col.prop(scene, "frame_start")
+
+		# # Second column, aligned
+		# col = split.column(align=True)
+		# col.label(text="Column Two:")
+		# col.prop(scene, "frame_start")
+		# col.prop(scene, "frame_end")
+
+		# # Big render button
+		# layout.label(text="Big Button:")
+		# row = layout.row()
+		# row.scale_y = 3.0
+		# row.operator("render.render")
+
+		# # Different sizes in a row
+		# layout.label(text="Different button sizes:")
+		# row = layout.row(align=True)
+		# row.operator("render.render")
+
+		# sub = row.row()
+		# sub.scale_x = 2.0
+		# sub.operator("render.render")
+
+		# row.operator("render.render")
+
+
+def register():
+	bpy.utils.register_class(ANKI_material)
+
+
+def unregister():
+	bpy.utils.unregister_class(ANKI_material)
+
+
+if __name__ == "__main__":
+	register()

+ 58 - 0
tools/anki_scene_exporter/ui/panel_prop_dynamic.py

@@ -0,0 +1,58 @@
+# Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+# All rights reserved.
+# Code licensed under the BSD License.
+# http://www.anki3d.org/LICENSE
+# keep methods in alphabetical order
+
+import bpy
+from bpy.types import Panel, Operator
+from bpy.props import StringProperty
+from . import panel_layouts as PANEL
+
+
+def _callback(scene, prop):
+	print("Property '%s' of %s updated to value %s" % (prop, scene.name, getattr(scene, prop)))
+
+def test(prop):
+	def update(self, context):
+		_callback(self, prop)
+	return update
+
+
+class ANKI_dynamic_prop_panel(Panel):
+	bl_label = " "
+	bl_idname = "ANKI_dynamic_prop_panel"
+	bl_space_type = "VIEW_3D"
+	bl_region_type = "UI"
+
+	panel = "ANKI_PP_home"
+
+	def draw_header(self, context):
+		layout = self.layout
+		layout.operator("anki.view3d_dynamic_prop_panel", icon='RADIO').panel="ANKI_PP_home"
+
+	def draw(self, context):
+		layout = self.layout
+		dyn_panel = "PANEL.%s(layout, context)" % self.panel
+		exec (dyn_panel)
+
+class ANKI_VIEW3D_dynamic_prop_panel_op(Operator):
+	"""ANKI dynamic props panel exec"""
+	bl_idname = "anki.view3d_dynamic_prop_panel"
+	bl_label = ""
+	bl_options = {'REGISTER'}
+
+	panel = StringProperty(
+							name="panel",
+							default="",
+							description="string of a method panel"
+							)
+
+	def execute(self, context):
+		dyn = bpy.types.ANKI_dynamic_prop_panel
+		bpy.utils.unregister_class(dyn)
+		dyn.panel = self.panel
+		bpy.utils.register_class(dyn)
+
+		return {'FINISHED'}
+