From ec27eb2f3318a6ed472981883e047569d5633487 Mon Sep 17 00:00:00 2001 From: lifelandman Date: Sun, 9 Apr 2023 21:07:47 -0600 Subject: [PATCH] Add files --- ZABEE main/__init__.py | 29 ++++++ ZABEE main/export.py | 65 ++++++++++++++ ZABEE main/parse.py | 195 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 289 insertions(+) create mode 100644 ZABEE main/__init__.py create mode 100644 ZABEE main/export.py create mode 100644 ZABEE main/parse.py diff --git a/ZABEE main/__init__.py b/ZABEE main/__init__.py new file mode 100644 index 0000000..f67b74b --- /dev/null +++ b/ZABEE main/__init__.py @@ -0,0 +1,29 @@ + +bl_info = { + "name": "ZABEE", + "author": "Jackson \"Lifeland\" S.", + "version": (0, 1), + "blender": (3, 5, 0), + "description": "", + "warning": "", + "location": "File > Export", + "wiki_url": "", + "category": "Export"} + +import bpy +from . import export + +modules = [export] + +def register(): + + for module in modules: + module.register() + +def unregister(): + + for module in modules: + module.unregister() + +if __name__ == "__main__": + register() diff --git a/ZABEE main/export.py b/ZABEE main/export.py new file mode 100644 index 0000000..3fcdc63 --- /dev/null +++ b/ZABEE main/export.py @@ -0,0 +1,65 @@ +import bpy +from . import parse + +def write_egg(context, filepath, egg_string): + print("running write_egg...") + f = open(filepath, 'w', encoding='utf-8') + f.write(egg_string) + f.close() + + return {'FINISHED'} + + +# ExportHelper is a helper class, defines filename and +# invoke() function which calls the file selector. +from bpy_extras.io_utils import ExportHelper +from bpy.props import StringProperty, BoolProperty, EnumProperty +from bpy.types import Operator + + +class export_egg(Operator, ExportHelper): + """This function generates and exports an EGG file intended for use with panda3d.""" + bl_idname = "export_egg.some_data" # important since its how bpy.ops.import_test.some_data is constructed + bl_label = "Export Egg File" + + # ExportHelper mixin class uses this + filename_ext = ".egg" + + filter_glob: StringProperty( + default="*.egg", + options={'HIDDEN'}, + maxlen=255, # Max internal buffer length, longer would be clamped. + ) + + # List of operator properties, the attributes will be assigned + # to the class instance from the operator settings before calling. + imageDir: StringProperty( + default="images\\", + description="The path to this model's textures relative\nto the config file's model path" + ) + + def execute(self, context):##Put egg generating code here: + egg_string = parse.write_egg_string(self.imageDir) + return write_egg(context, self.filepath, egg_string) + + +# Only needed if you want to add into a dynamic menu +def menu_func_export(self, context): + self.layout.operator(export_egg.bl_idname, text="Egg (Panda3D)") + + +# Register and add to the "file selector" menu (required to use F3 search "Text Export Operator" for quick access). +def register(): + bpy.utils.register_class(export_egg) + bpy.types.TOPBAR_MT_file_export.append(menu_func_export) + + +def unregister(): + bpy.utils.unregister_class(export_egg) + bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) + + +if __name__ == "__main__": + register() + + # test call diff --git a/ZABEE main/parse.py b/ZABEE main/parse.py new file mode 100644 index 0000000..d23f1dd --- /dev/null +++ b/ZABEE main/parse.py @@ -0,0 +1,195 @@ +import bpy + +accepted_types = ('MESH') + +def process_mesh(mesh, name, mats, useTex, indent = 1):#should return egg string for this mesh without hierarchy indentation + newliner = "\n" + (" "* indent) + + + #create vertecies. + #We have several duplicate verticies so the same point can coorispond to multiple uv coordinates. + + loop_id_lookup = {}#This is gonna be a dictionary where a loop id coorisponds to one of the vertexpool's verticies. + #This is so when we're making polygons, we can look up verticie ids by loop, if need be. + + uv_match_check = {}#ex of what this will look like: {vert.id, {(uxx, uvy), eggvertid}} + + egg_data = newliner + " " + name + "_pool {" + + idNum = 0 + + for loop in mesh.loops:#Generate verticies and lookup table(s) + + vertex_id = loop.vertex_index + loop_id = loop.index + uvLoop = mesh.uv_layers[0] + uv_cor = uvLoop.uv[loop_id] + + vert = mesh.vertices[vertex_id] + + if vertex_id in uv_match_check: + if uv_cor in uv_match_check[vertex_id]: + loop_id_lookup[loop_id] = uv_match_check[vertex_id][uv_cor] + continue + + egg_data += (newliner + " " + str(idNum) + ' { ' + str(vert.co[0]) + ' ' + str(vert.co[1]) + ' ' + str(vert.co[2]) + + newliner + " { " + str(vert.normal[0]) + ' ' + str(vert.normal[1]) + ' ' + str(vert.normal[2]) + '}' + newliner + + " { " + str(uv_cor.vector.x) + ' ' + str(uv_cor.vector.y) + " }" + ) + egg_data += '}' + + if not vertex_id in uv_match_check: + uv_match_check[vertex_id] = {} + + uv_match_check[vertex_id][uv_cor] = vert + loop_id_lookup[loop_id] = idNum + idNum +=1#counter for how many vertices we've made + + + egg_data += '\n}' + + idNum = 0 + for poly in mesh.polygons: + egg_data += newliner + " " + str(idNum) + " { " + + if useTex: + egg_data += " { " + mats[poly.material_index] + " }" + newliner + + egg_data += " { " + for loop in poly.loop_indices: + egg_data += str(loop_id_lookup[loop]) + ' ' + egg_data += " { " + name + "_pool }}}" + + idNum += 1 + + return egg_data + + + +def childProcess(objects, known_objects, known_names, texture_path, indent = 1): + newliner = "\n" + (" "* indent) + egg_string = "\n" + + for obj in objects: + if not obj in known_objects: + known_objects.append(obj) + + mats = [] + + name = obj.name.replace(" ", "_") + nameinc = 0 + nameTest = name + while nameTest in known_names: + nameinc += 1 + nameTest = name + str(nameinc) + if nameinc > 0: + name = nameTest + known_names.append(name) + + if obj.type in accepted_types: + + egg_string += (newliner + " %s {\n" % name) + + child_addition = '' + children = obj.children + if len(children) > 0: + child_addition = childProcess(children, known_objects, known_names, texture_path, indent + 1) + if obj.type == "MESH": + + useTex = False + #Add texture references, and calculate the slot data for materials + picnum = len(obj.to_mesh().materials) + if picnum != 0: + useTex = True + for i in range(picnum): + mat = obj.to_mesh().materials[i] + img_name = None + for x in mat.node_tree.nodes: + if x.bl_static_type=='TEX_IMAGE': + img_name = x.image.name + tex_name = img_name.replace(' ', '_') + break + + if tex_name != None: + mats.append(tex_name) + egg_string += "\n " + tex_name + " { " + texture_path + img_name + " }" + + egg_string += newliner + + #Process the mesh, and apply texture stuff in necissary + new_addition = process_mesh(obj.to_mesh(), name, mats, useTex, indent) + egg_string += new_addition + + egg_string += child_addition + + egg_string += newliner + "}" + return egg_string + + +######################## MAIN FUNCTION ##################################################### + +def write_egg_string(texture_path): + known_objects = [] + known_names = []#necissary so we can tell when we need to add an incrementing digit if multiple objects share a name. + + egg_string = " { Z-Up }\n\n" + + mats = [] + + for obj in bpy.data.objects: + if not obj in known_objects: + known_objects.append(obj) + + + name = obj.name.replace(" ", "_") + nameinc = 0 + nameTest = name + while nameTest in known_names: + nameinc += 1 + nameTest = name + str(nameinc) + if nameinc > 0: + name = nameTest + known_names.append(name) + + if obj.type in accepted_types: + + + + egg_string += ("\n %s {\n" % name) + + child_addition = '' + children = obj.children + if len(children) > 0: + child_addition = childProcess(children, known_objects, known_names, texture_path) + if obj.type == "MESH": + + useTex = False + #Add texture references, and calculate the slot data for materials + picnum = len(obj.to_mesh().materials) + if picnum > 0: + useTex = True + for i in range(picnum): + mat = obj.to_mesh().materials[i] + img_name = None + tex_name = None + for x in mat.node_tree.nodes: + if x.bl_static_type=='TEX_IMAGE':##THIS IS APPARENTLY DEPRICATED; and for some f*****g reason the only alternative I can find is as well. good luck, future me! + img_name = x.image.name + tex_name = img_name.replace(' ', '_') + break + + if tex_name != None: + mats.append(tex_name) + egg_string += "\n " + tex_name + " { " + texture_path + img_name + " }" + + egg_string += '\n' + + #Process the mesh, and apply texture stuff in necissary + new_addition = process_mesh(obj.to_mesh(), name, mats, useTex) + egg_string += new_addition + + egg_string += child_addition + + egg_string += "\n}" + return egg_string + \ No newline at end of file