changeset 660:e1856ef4fc74

export xml3 not yet worked.
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 27 Nov 2009 20:16:51 +0900
parents 00391feebc79
children 68f0253f5a71
files SceneGraph/BlenderScript/export_xml3.py
diffstat 1 files changed, 195 insertions(+), 200 deletions(-) [+]
line wrap: on
line diff
--- a/SceneGraph/BlenderScript/export_xml3.py	Fri Nov 27 18:27:32 2009 +0900
+++ b/SceneGraph/BlenderScript/export_xml3.py	Fri Nov 27 20:16:51 2009 +0900
@@ -21,19 +21,23 @@
 #from Blender import sys as bsys, Mathutils, Draw, BGL
 #from Blender.sys import *
 
+global anim
+anim = 0
+
+
 global images, imageCount
 images = {}
 imageCount = 0
 
-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(["{0:s} {1:s}".format((method.ljust(spacing),
-					  processFunc(str(getattr(object, method).__doc__))))
-					 for method in methodList]))
+__author__ = ["Shinji KONO"]
+__url__ = ("www.ie.u-ryukyu.ac.jp/~kono/")
+__version__ = "0.01a"
+__bpydoc__ = """\
+
+Cerium XML converter
+
+"""
 
 
 ######################################################
@@ -47,10 +51,20 @@
 # Functions
 ######################################################
 
-# Image Get ?
-# New name based on old with a different extension
-def newFName(ext):
-	return Blender.Get('filename')[: -len(Blender.Get('filename').split('.', -1)[-1]) ] + ext
+
+def create_derived_objects(ob):
+	if ob.parent and ob.parent.dupli_type != 'NONE':
+		return False, None
+
+	if ob.dupli_type != 'NONE':
+		ob.create_dupli_list()
+		return True, [(dob.object, dob.matrix) for dob in ob.dupli_list]
+	else:
+		return False, [(ob, ob.matrix)]
+
+# also used by X3D exporter
+def free_derived_objects(ob):
+	ob.free_dupli_list()
 
 
 #exporting an anime
@@ -79,7 +93,7 @@
 			if obj.Layer in activelayers:
 				object_list.append(obj)
 
-				if obj.getType() == "Mesh":
+				if obj.type == 'Mesh':
 					materials_obj_list = []
 					materials_obj_list = obj.getData().materials
 					for mat in materials_obj_list:
@@ -142,12 +156,14 @@
 		##change
 		#str = ""
 		file.write("")
-		matrix = obj.getMatrix()
+		# matrix = obj.matrix
+		# already calcurated?
+		matrix = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
 
 		for mindex in range(len(flist)):
 			fl = flist[mindex]
 			if fl != []:
-				parent_name = obj.getParent()
+				parent_name = obj.parent
 				if parent_name:
 					parent_name = "{0:s}".format(parent_name)
 					###change
@@ -204,14 +220,9 @@
 				### get texture_image and change base64 data
 				texture = mesh.faces[0].image
 				if texture:
-					file.write(loadTexture(texture))	
-					
+					file.write(loadTexture(texture.name))	
 				else:
 					file.write("\t\t<image name=\"{0:s}\">\n".format(("sample_white.png") ))
-
-					file.write("\t\t\tiVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAAAAADhZOFXAAAAEElEQVQImWP8zwABTAwUMQBJQQEP\n");
-					file.write("\t\t\tlYH+agAAAABJRU5ErkJggg==\n");
-
 					file.write("\t\t</image>\n")
 
 		#return str
@@ -242,210 +253,159 @@
 
 	#return str
 
+def make_material_chunk(material, image):
+	if image:
+		file.write(loadTexture(image))	
+	else:
+		file.write("\t\t<image name=\"{0:s}\">\n".format(("sample_white.png") ))
+		global sample_whited
+		if (sample_whited == 0):
+
+		    file.write("\t\t\tiVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAAAAADhZOFXAAAAEElEQVQImWP8zwABTAwUMQBJQQEP\n");
+		    file.write("\t\t\tlYH+agAAAABJRU5ErkJggg==\n");
+		    sample_whited=1
+
+		file.write("\t\t</image>\n")
 
 ######################################################
 # EXPORT
 ######################################################
-def save_xml(filename, unindexedname, anim):
-	print("XML EXPORT\n")
-	time1 = Blender.sys.time()
+
+
+def save_xml(filename, context):
+	'''Save the Blender scene to a Cerium xml file.'''
+	# Time the export
+	global MatSaved
+	global anim
+	MatSaved = 0
+	
+	if not filename.lower().endswith('.xml'):
+		filename += '.xml' 
 	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')
+    
+	# XXX
+#       if not BPyMessages.Warning_SaveOver(filename):
+#               return
+	
+	# XXX
+	time1 = time.clock()
+#       time1= Blender.sys.time()
+#       Blender.Window.WaitCursor(1)
 
 	##### XML header ######
 	file.write("<?xml version=\"1.0\"?>\n")
+	file.write("<OBJECT-3D>\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)
+	sce = context.scene
+  
+	# Get all the supported objects selected in this scene:
+	# ob_sel= list(sce.objects.context)
+	# mesh_objects = [ (ob, me) for ob in ob_sel   for me in (BPyMesh.getMeshFromObject(ob, None, True, False, sce),) if me ]
+	# empty_objects = [ ob for ob in ob_sel if ob.type == 'Empty' ]
+
+	# Make a list of all materials used in the selected meshes (use a dictionary,
+	# each material is added once):
+	materialDict = {}
+	mesh_objects = []
+	for ob in [ob for ob in context.scene.objects if ob.is_visible()]:
+#       for ob in sce.objects.context:
+
+		# get derived objects
+		free, derived = create_derived_objects(ob)
+
+		if derived == None: continue
+
+		for ob_derived, mat in derived:
+#               for ob_derived, mat in getDerivedObjects(ob, False):
+
+			if ob.type not in ('MESH', 'CURVE', 'SURFACE', 'TEXT', 'META'):
+				continue
 
-	##### 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 \"{0:s}\" as Meshlight (Mesh \"{1:s}\")...".format((objectname, meshname)))
-			else:
-				print("processing Object \"{0:s}\" (Mesh \"{1:s}\")...".format((objectname, meshname)))
-			try:
-				meshlist.index(meshname)
-			except ValueError:
-				###change
-				#file.write(exportMesh(mesh,obj))
-				exportMesh(mesh,obj,file)
-				meshlist.append(meshname)
-				if anim == 1:
-					#file.write("\t\t<anim>\n")
-					###change
-					#file.write(export_anime(obj))
-					export_anime(obj,file)
-					#file.write("\t\t</anim>\n")
-				file.write("\t</surface>\n")
-				file_h.write("#define {0:s} scene_graph".format((obj.name)))
-				while n != count_h:
-					file_h.write("->next")
-					n = n + 1
-				file_h.write("\n")
-				count_h = count_h + 1
-				n = 0
+			data = ob_derived.create_mesh(True, 'PREVIEW')
+#                       data = getMeshFromObject(ob_derived, None, True, False, sce)
+			if data:
+				data.transform(mat)
+#                               data.transform(mat, recalc_normals=False)
+				mesh_objects.append((ob_derived, data))
+				mat_ls = data.materials
+				mat_ls_len = len(mat_ls)
+
+				# get material/image tuples.
+				if len(data.uv_textures):
+#                               if data.faceUV:
+					if not mat_ls:
+						mat = mat_name = None
 
+					for f, uf in zip(data.faces, data.active_uv_texture.data):
+						if mat_ls:
+							mat_index = f.material_index
+#                                                       mat_index = f.mat
+							if mat_index >= mat_ls_len:
+								mat_index = f.mat = 0
+							mat = mat_ls[mat_index]
+							if mat: mat_name = mat.name
+							else:   mat_name = None
+						# else there alredy set to none
 
-	##### XML FOOTER ######
-	file.write("</OBJECT-3D>")
-	file.close()
-	file_h.close()
-	print("Finished.\n")
-				
-	time2 = Blender.sys.time()
-	print("Processing time: {0:f}\n".format((time2-time1)))
-	Draw.Exit()
+						img = uf.image
+#                                               img = f.image
+						if img: img_name = img.name
+						else:   img_name = None
 
-
-### SAVE ANIMATION ###
-def save_anim(filename):
-	global MatSaved
-	
-	MatSaved = 0
-	unindexedname = filename
-	save_xml(filename, unindexedname, 1)
+						materialDict.setdefault((mat_name, img_name), (mat, img) )
 
 
-#### 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)
+				else:
+					for mat in mat_ls:
+						if mat: # material may be None so check its not.
+							materialDict.setdefault((mat.name, None), (mat, None) )
 
-##	<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)
+					# Why 0 Why!
+					for f in data.faces:
+						if f.material_index >= mat_ls_len:
+#                                               if f.mat >= mat_ls_len:
+							f.material_index = 0
+							# f.mat = 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]
+		if free:
+			free_derived_objects(ob)
 
 
-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
+	# Make material chunks for all materials used in the meshes:
+	for mat_and_image in materialDict.values():
+		print("make material chunk {0:s}\n".format(mat_and_image[1]))
+		make_material_chunk(mat_and_image[0], mat_and_image[1])
 
-    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")
+	# Give all objects a unique ID and build a dictionary from object name to object id:
+	"""
+	name_to_id = {}
+	for ob, data in mesh_objects:
+		name_to_id[ob.name]= len(name_to_id)
+	#for ob in empty_objects:
+	#       name_to_id[ob.name]= len(name_to_id)
+	"""
 
-    
-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()
+	# Create object chunks for all meshes:
+	for ob, blender_mesh in mesh_objects:
+		print("export mesh {0:s}\n".format(ob.name))
+		exportMesh(blender_mesh,ob,file)
+		if (anim):
+		    export_anime(obj,file)
+		file.write("\t</surface>\n")
+#               if not blender_mesh.users:
+		bpy.data.remove_mesh(blender_mesh)
+#               blender_mesh.verts = None
+
+	# Close the file:
+	file.close()
+
+
 
 
 def loadTexture(texture):
 	global images, imageCount
-	name = texture.getName()
+	name = texture.name
 	if name in images:
 		return "\t\t<image name=\"" + name + "\"/>\n"	
 	out = "\t\t<image name=\"" + name + "\">\n"
@@ -465,6 +425,41 @@
 	out += "\t\t</image>\n"
 	return out
 
-Draw.Register(gui, event, buttonEvt)
+
+from bpy.props import *
+class ExportPS3(bpy.types.Operator):
+	'''Export to Cerium XML file format.'''
+	bl_idname = "export.ps3cerium"
+	bl_label = 'Export PS3 Cerium'
+
+	# List of operator properties, the attributes will be assigned
+	# to the class instance from the operator settings before calling.
+
+
+	path = StringProperty(name="File Path", description="File path used for exporting the Cerium XML file", maxlen= 1024, default= "")
 
 
+	def execute(self, context):
+		save_xml(self.properties.path, context)
+		return ('FINISHED',)
+
+	def invoke(self, context, event):
+		wm = context.manager
+		wm.add_fileselect(self)
+		return ('RUNNING_MODAL',)
+
+	def poll(self, context): # Poll isnt working yet
+		return context.active_object != None
+
+bpy.ops.add(ExportPS3)
+
+# Add to a menu
+import dynamic_menu
+
+def menu_func(self, context):
+    default_path = bpy.data.filename.replace(".blend", ".xml")
+    self.layout.operator(ExportPS3.bl_idname, text="PS3 Cerium...").path = default_path 
+
+menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
+
+# end