# HG changeset patch # User Shinji KONO # Date 1259320611 -32400 # Node ID e1856ef4fc7472aff558ae84e1956416661a79a5 # Parent 00391feebc794cf4ccab8c45376666ddb20d33c9 export xml3 not yet worked. diff -r 00391feebc79 -r e1856ef4fc74 SceneGraph/BlenderScript/export_xml3.py --- 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\n".format(("sample_white.png") )) - - file.write("\t\t\tiVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAAAAADhZOFXAAAAEElEQVQImWP8zwABTAwUMQBJQQEP\n"); - file.write("\t\t\tlYH+agAAAABJRU5ErkJggg==\n"); - file.write("\t\t\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\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\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("\n") + file.write("\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("\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\n") - ###change - #file.write(export_anime(obj)) - export_anime(obj,file) - #file.write("\t\t\n") - file.write("\t\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("") - 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 - -## 800 600 - -sceneSizeX = Scene.GetCurrent().getRenderingContext().imageSizeX() -sceneSizeY = Scene.GetCurrent().getRenderingContext().imageSizeY() - -SizeX = Draw.Create(sceneSizeX) -SizeY = Draw.Create(sceneSizeY) -TexExponent = Draw.Create(2.3) - -## 1 -MLT = Draw.Create(1) - -## 0.1 -LMP = Draw.Create(0.1) - -## 0.02 -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) ) -## 0.7 -RRLP = Draw.Create(0.7) - -## 100 -MaxDepth = Draw.Create(100) - -## false -Bidirectional = Draw.Create(0) - -## 14 -StrataWidth = Draw.Create(14) - -## 0 -Logging = Draw.Create(0) - -## false -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 -## false -SaveTMExr = Draw.Create(0) - -## 0.0 -LensRadius = Draw.Create(0.0) - -## 2.0 -FocusDistance = Draw.Create(2.0) - -## 2.0 -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\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\n" out = "\t\t\n" @@ -465,6 +425,41 @@ out += "\t\t\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