changeset 107:ce5755f544c1 cvs

Initial revision
author chiaki
date Tue, 04 Mar 2008 18:06:44 +0900
parents c9efdb17e8d2
children 6f3b3dd3c095
files SceneGraph/BlenderScript/export_xml.py
diffstat 1 files changed, 433 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SceneGraph/BlenderScript/export_xml.py	Tue Mar 04 18:06:44 2008 +0900
@@ -0,0 +1,433 @@
+#!BPY
+"""Registration info for Blender menus:
+Name: 'Libps3 (.xml)'
+Blender: 240
+Group: 'Export'
+Tooltip: 'Export to (.xml) for libps3'
+"""
+
+
+######################################################
+# Importing modules
+######################################################
+
+import math
+#import subprocess
+import os
+import Blender
+import struct
+import base64
+from Blender import NMesh, Scene, Object, Material, Texture, Window
+from Blender import sys as bsys, Mathutils, Draw, BGL
+from Blender.sys import *
+
+
+def info(object, spacing=10, collapse=1):
+	"""Print methods and doc strings.
+
+	Takes module, class, list, dictionary, or string."""
+	methodList = [e for e in dir(object) if callable(getattr(object, e))]
+	processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
+	print "\n".join(["%s %s" %
+					 (method.ljust(spacing),
+					  processFunc(str(getattr(object, method).__doc__)))
+					 for method in methodList])
+
+
+######################################################
+# Data Structures
+######################################################
+
+
+
+
+######################################################
+# Functions
+######################################################
+
+
+# New name based on old with a different extension
+def newFName(ext):
+	return Blender.Get('filename')[: -len(Blender.Get('filename').split('.', -1)[-1]) ] + ext
+
+
+#exporting an anime
+def export_anime(object_name):
+	startF = Blender.Get('staframe')
+        endF = Blender.Get('endframe')
+	str = ""
+	str += "\t\t<anim frame=\"%d\">\n" %(endF)
+	for i in range (startF, endF+1):
+		Blender.Set('curframe', i)
+		Blender.Redraw()
+		time1 = Blender.sys.time()
+
+	        ##### XML header ######
+	        #get all the objects in this scene
+		activelayers = Window.ViewLayer()
+		for i in range(len(activelayers)):
+			activelayers[i] = 2**(activelayers[i]-1)
+		object_list1 = Blender.Scene.GetCurrent().getChildren()
+		object_list = []
+		matnames= []
+		for obj in object_list1:
+			if obj.Layer in activelayers:
+				object_list.append(obj)
+
+				if obj.getType() == "Mesh":
+					materials_obj_list = []
+					materials_obj_list = obj.getData().materials
+					for mat in materials_obj_list:
+						if mat.name not in matnames:
+							matnames.append(mat.name)
+
+		##### Process Meshes ######
+		for obj in object_list:
+			matrix = obj.getMatrix()
+			if obj == object_name:
+				str +="\t\t\t%f %f %f\n" %(matrix[3][0], matrix[3][1], matrix[3][2])
+
+	str += "\t\t</anim>\n"
+        return str
+
+
+
+# exporting a mesh
+def exportMesh(mesh, obj):
+	vdata = []   # list of [ii0, ii1, ii2, ...] lists indexed by Blender-Vertex-index
+	vlist = []
+	flist = []
+	tri_first = []
+	tri_second = []
+	tri_third = []
+
+	def addVertex(bvindex, coord, normal, uv):
+		index = -1
+		if bvindex < len(vdata):
+			for ivindex in vdata[bvindex]:
+				v = vlist[ivindex]
+				if (abs(v[0][0]-coord[0])<0.0001) and \
+				(abs(v[0][1]-coord[1])<0.0001) and \
+				(abs(v[0][2]-coord[2])<0.0001) and \
+				(abs(v[1][0]-normal[0])<0.0001) and \
+				(abs(v[1][1]-normal[1])<0.0001) and \
+				(abs(v[1][2]-normal[2])<0.0001):
+					if ((v[2]==[]) and (uv==[])) or \
+					((abs(v[2][0]-uv[0])<0.0001) and \
+					(abs(v[2][1]-uv[1])<0.0001)):
+						index = ivindex
+		if index < 0:
+			index = len(vlist)
+			vlist.append([coord, normal, uv])
+			while bvindex >= len(vdata):
+				vdata.append([])
+			vdata[bvindex].append(index)
+		return index
+
+	def addFace(mindex, index0, index1, index2):
+		while mindex >= len(flist):
+			flist.append([])
+		flist[mindex].append([index0, index1, index2])
+
+	def getFaces():
+		str = ""
+		matrix = obj.getMatrix()
+
+		for mindex in range(len(flist)):
+			fl = flist[mindex]
+			if fl != []:
+				parent_name = obj.getParent()
+				if parent_name:
+					parent_name = "%s" %parent_name
+					str += "\t<surface name=\"%s\" size=\"%d\" prim=\"Triangle\" parent=%s>\n" %(obj.name, len(fl)*3, parent_name[8:-1])
+				else:
+					str += "\t<surface name=\"%s\" size=\"%d\" prim=\"Triangle\" parent=\"NULL\">\n" %(obj.name, len(fl)*3)
+
+				str += "\t\t<coordinate>\n"
+				for f in fl:
+					tri_first = vlist[f[0]]
+					tri_second = vlist[f[1]]
+					tri_third = vlist[f[2]]
+
+					str += "\t\t\t%f %f %f\n" %(tri_first[0][0] + matrix[3][0], tri_first[0][1] + matrix[3][1], tri_first[0][2] + matrix[3][2])
+					str += "\t\t\t%f %f %f\n" %(tri_second[0][0] + matrix[3][0], tri_second[0][1] + matrix[3][1], tri_second[0][2] + matrix[3][2])
+					str += "\t\t\t%f %f %f\n" %(tri_third[0][0] + matrix[3][0], tri_third[0][1] + matrix[3][1], tri_third[0][2] + matrix[3][2])
+				str += "\t\t</coordinate>\n"
+
+				str += "\t\t<normal>\n"
+				for f in fl:
+					tri_first = vlist[f[0]]
+					tri_second = vlist[f[1]]
+					tri_third = vlist[f[2]]
+
+					str += "\t\t\t%f %f %f\n" %(tri_first[1][0], tri_first[1][1], tri_first[1][2])
+					str += "\t\t\t%f %f %f\n" %(tri_second[1][0], tri_second[1][1], tri_second[1][2])
+					str += "\t\t\t%f %f %f\n" %(tri_third[1][0], tri_third[1][1], tri_third[1][2])
+				str += "\t\t</normal>\n"
+
+				str += "\t\t<model>\n"
+				###parameter of translate
+				str += "\t\t\t%f %f %f\n" % (matrix[3][0], matrix[3][1], matrix[3][2])
+				str += "\t\t</model>\n"
+
+				if tri_first[2] != []:
+					str += "\t\t<texture>\n"
+					for f in fl:
+						tri_first = vlist[f[0]]
+						tri_second = vlist[f[1]]
+						tri_third = vlist[f[2]]
+
+						str += "\t\t\t%f %f\n" %(tri_first[2][0], tri_first[2][1])
+						str += "\t\t\t%f %f\n" %(tri_second[2][0], tri_second[2][1])
+						str += "\t\t\t%f %f\n" %(tri_third[2][0], tri_third[2][1])
+					str += "\t\t</texture>\n"
+				else:
+					str += "\t\t<texture/>\n"
+
+
+				### get texture_image and change base64 data
+				texture = mesh.faces[0].image
+				if texture:
+					str += "\t\t<image name=\"%s\">\n" %(texture.getName())
+					image_path = texture.getFilename()
+					input = open(expandpath(image_path), 'r')
+					output = open('output.txt', 'w')
+					base64.encode(input,output)
+					input.close()
+					output.close()
+					input = open('output.txt', 'r')
+					for b64 in input.readlines():
+						str += "\t\t\t%s" %b64
+					input.close()
+					str += "\t\t</image>\n"
+				else:
+					str += "\t\t<image/>\n"
+
+				#str += "\t</surface>\n"
+
+		return str
+
+	vdata = []
+	vlist = []
+	flist = []
+	for face in mesh.faces:
+		iis = [-1, -1, -1, -1]
+		for vi in range(len(face.v)):
+			vert = face.v[vi]
+			if face.smooth:
+				normal = vert.no
+			else:
+				normal = face.no
+			if len(face.uv) == len(face.v):
+				uv = face.uv[vi]
+			else:
+				uv = []
+			iis[vi] = addVertex(vert.index, vert.co, normal, uv)
+		addFace(face.materialIndex, iis[0], iis[1], iis[2])
+		if len(face.v)==4:
+			addFace(face.materialIndex, iis[2], iis[3], iis[0])
+
+	str = ""
+	str += getFaces()
+
+	return str
+
+
+######################################################
+# EXPORT
+######################################################
+def save_xml(filename, unindexedname, anim):
+	print("XML EXPORT\n")
+	time1 = Blender.sys.time()
+	print("Saving to '" + filename + "'...\n")
+	file = open(filename, 'w')
+
+	count_h = 0
+	n = 0
+	filename_h = filename[:-4] + ".h"  #header file for cpp
+	file_h = open(filename_h, 'w')
+
+	##### XML header ######
+	file.write("<?xml version=\"1.0\"?>\n")
+
+	#get all the objects in this scene
+	activelayers = Window.ViewLayer()
+	for i in range(len(activelayers)):
+		activelayers[i] = 2**(activelayers[i]-1)
+	object_list1 = Blender.Scene.GetCurrent().getChildren()
+	object_list = []
+	matnames= []
+	for obj in object_list1:
+		if obj.Layer in activelayers:
+			object_list.append(obj)
+			
+			if obj.getType() == "Mesh":
+				materials_obj_list = []
+				materials_obj_list = obj.getData().materials
+				for mat in materials_obj_list:
+					if mat.name not in matnames:
+						matnames.append(mat.name)
+
+	##### Process Meshes ######
+	meshlist = []
+	file.write("<OBJECT-3D>\n")
+	for obj in object_list:
+		if obj.getType() == "Mesh":
+			objectname = obj.getName()
+			mesh = Blender.NMesh.GetRawFromObject(objectname)
+			meshname = mesh.name
+			meshlight = 0
+			if len(mesh.materials) > 0:
+				mat0 = mesh.materials[0]
+				if mat0.emit > 0:
+					meshlight = 1
+			if meshlight:
+				print "processing Object \"%s\" as Meshlight (Mesh \"%s\")..." %(objectname, meshname)
+			else:
+				print "processing Object \"%s\" (Mesh \"%s\")..." %(objectname, meshname)
+			try:
+				meshlist.index(meshname)
+			except ValueError:
+				file.write(exportMesh(mesh,obj))
+				meshlist.append(meshname)
+				if anim == 1:
+					#file.write("\t\t<anim>\n")
+					file.write(export_anime(obj))
+					#file.write("\t\t</anim>\n")
+				file.write("\t</surface>\n")
+				file_h.write("#define %s scene_graph" %(obj.name))
+				while n != count_h:
+					file_h.write("->next")
+					n = n + 1
+				file_h.write("\n")
+				count_h = count_h + 1
+				n = 0
+
+
+	##### XML FOOTER ######
+	file.write("</OBJECT-3D>")
+	file.close()
+	file_h.close()
+	print("Finished.\n")
+				
+	time2 = Blender.sys.time()
+	print("Processing time: %f\n" %(time2-time1))
+	Draw.Exit()
+
+
+### SAVE ANIMATION ###
+def save_anim(filename):
+	global MatSaved
+	
+	MatSaved = 0
+	unindexedname = filename
+	save_xml(filename, unindexedname, 1)
+
+
+#### SAVE STILL (hackish...) ####
+def save_still(filename):
+	global MatSaved
+	
+	MatSaved = 0
+	unindexedname = filename
+	save_xml(filename, unindexedname, 0)
+
+######################################################
+# Settings GUI
+######################################################
+
+# Assign event numbers to buttons
+evtNoEvt	= 0
+evtExport	= 1
+evtExportAnim	= 2
+
+# Set initial values of buttons
+
+##	<size>800 600</size>
+
+sceneSizeX = Scene.GetCurrent().getRenderingContext().imageSizeX()
+sceneSizeY = Scene.GetCurrent().getRenderingContext().imageSizeY()
+
+SizeX = Draw.Create(sceneSizeX)
+SizeY = Draw.Create(sceneSizeY)
+TexExponent = Draw.Create(2.3)
+
+##	<metropolis>1</metropolis>
+MLT = Draw.Create(1)
+
+##	<large_mutation_prob>0.1</large_mutation_prob>
+LMP = Draw.Create(0.1)
+
+##	<max_change>0.02</max_change>
+MaxChange = Draw.Create(0.02)
+
+##	<russian_roulette_live_prob>0.7</russian_roulette_live_prob>
+RRLP = Draw.Create(0.7)
+
+##	<max_depth>100</max_depth>
+MaxDepth = Draw.Create(100)
+
+##  <bidirectional>false</bidirectional>
+Bidirectional = Draw.Create(0)
+
+##	<strata_width>14</strata_width>
+StrataWidth = Draw.Create(14)
+
+##	<logging>0</logging>
+Logging = Draw.Create(0)
+
+##  <save_untonemapped_exr>false</save_untonemapped_exr>
+SaveUTMExr = Draw.Create(0)
+
+##  <save_tonemapped_exr>false</save_tonemapped_exr>
+SaveTMExr = Draw.Create(0)
+
+##	<lens_radius>0.0</lens_radius>
+LensRadius = Draw.Create(0.0)
+
+##	<focus_distance>2.0</focus_distance>
+FocusDistance = Draw.Create(2.0)
+
+##  <turbidity>2.0</turbidity>
+Turbidity = Draw.Create(2.0)
+
+GroundPlane = Draw.Create(1)
+
+## Separate materials
+MatFile = Draw.Create(1)
+
+# text color fix
+textcol = [0, 0, 0]
+
+
+def gui():
+    global evtNoEvt, evtExport, evtExportAnim
+    global SizeX, SizeY, TexExponent, MLT, LMP, MaxChange, RRLP, MaxDepth, Bidirectional, StrataWidth, Logging, SaveUTMExr, SaveTMExr, LensRadius, FocusDistance,Turbidity, GroundPlane, MatFile
+    global textcol
+
+    Draw.Button("Export", evtExport, 10, 25, 100, 18, "Open file dialog and export")
+    Draw.Button("Export Animation", evtExportAnim, 130, 25, 150, 18, "Open filedialog and export animation (careful: takes a lot of diskspace!!!)")
+    BGL.glColor3f(textcol[0], textcol[1], textcol[2]) ; BGL.glRasterPos2i(10,10) ; Draw.Text("Press Q or ESC to quit.", "tiny")
+
+    BGL.glRasterPos2i(10,60) ; Draw.Text("xml exporter for libps3")
+
+    
+def event(evt, val):  # function that handles keyboard and mouse events
+    if evt == Draw.ESCKEY or evt == Draw.QKEY:
+        stop = Draw.PupMenu("OK?%t|Cancel export %x1")
+        if stop == 1:
+            Draw.Exit()
+            return
+    
+def buttonEvt(evt):  # function that handles button events
+    if evt == evtExport:
+    	Blender.Window.FileSelector(save_still, "Export", newFName('xml'))
+    if evt == evtExportAnim:
+    	Blender.Window.FileSelector(save_anim, "Export Animation", newFName('xml'))
+    #if there was an event, redraw the window   
+    if evt:
+        Draw.Redraw()
+
+Draw.Register(gui, event, buttonEvt)
+
+