From 7b316f23863b7707f09ad0539c053429e7a1c87e Mon Sep 17 00:00:00 2001 From: TigerKat Date: Thu, 25 Jul 2019 00:52:26 +0930 Subject: [PATCH] The Blender add-on export/import menus now have an option for feet and meters. Added the operation 'set_model_scale' to geo_edit.py . This intended for edit the scale of bone .geos . Added '-s' option to geo_list.py to display the scale of models. --- README.md | 5 ++++- __init__.py | 38 +++++++++++++++++++++++++++++++++----- export_geo.py | 12 ++++++++---- geo_edit.py | 16 ++++++++++++++++ geo_list.py | 7 +++++++ 5 files changed, 68 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 7e8e50a..610831a 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The Blender add-on allows you to export .geo files. ## Using the Add-On 1. Select the meshes to export in object mode. -2. From the menu select File->Export->City of Heroes (.geo) +2. From the menu select File->Export->"City of Heroes (Feet) (.geo)" (or "City of Heroes (Meters) (.geo)" if your meshes have been scaled in meters). 3. Browse to the file you want to create and click "Export GEO". # Tools @@ -51,8 +51,11 @@ Operation | Description rename_model <old> <new> | Rename a model from <old> to <new>. rename_texture <old> <new> | Rename a texture from <old> to <new>. rescale_all <scale> | Rescale all vertices in all models by multiplying them all by <scale> . + set_model_scale <model> <x> <y> <z> | Set the scale properties of the given model (not the same as rescaling). Multiple operations can be specified and performed in the same run. +Unless noted otherwise, model names and regular expressions are case sensitive. + ## geo_list.py A command line tool for list the model name inside of 1 or more .geo files. diff --git a/__init__.py b/__init__.py index f214823..eef6f21 100644 --- a/__init__.py +++ b/__init__.py @@ -2,7 +2,7 @@ bl_info = { "name": "City of Heroes (.geo)", "author": "TigerKat", - "version": (0, 1, 2), + "version": (0, 1, 3), "blender": (2, 79, 0), "location": "File > Import/Export,", "description": "City of Heroes (.geo)", @@ -55,7 +55,18 @@ class ImportGeo(bpy.types.Operator, ImportHelper): def execute(self, context): from . import import_geo keywords = self.as_keywords(ignore=("filter_glob",)) - return import_geo.load(self, context, **keywords) + return import_geo.load(self, context, 1.0, **keywords) + +class ImportGeoMetric(bpy.types.Operator, ImportHelper): + bl_idname = "import_scene.geo" + bl_label = "Import GEO" + + filename_ext = ".geo" + filter_glob = StringProperty(default="*.geo", options={'HIDDEN'}) + def execute(self, context): + from . import import_geo + keywords = self.as_keywords(ignore=("filter_glob",)) + return import_geo.load(self, context, 0.30480000376701355, **keywords) class ExportGeo(bpy.types.Operator, ExportHelper): bl_idname = "export_scene.geo" @@ -68,16 +79,33 @@ class ExportGeo(bpy.types.Operator, ExportHelper): keywords = self.as_keywords(ignore=("filter_glob", "check_existing", )) - return export_geo.save(self, context, **keywords) + return export_geo.save(self, context, 1.0, **keywords) + +class ExportGeoMetric(bpy.types.Operator, ExportHelper): + bl_idname = "export_scene.geo" + bl_label = "Export GEO" + + filename_ext = ".geo" + filter_glob = StringProperty(default="*.geo", options={'HIDDEN'}) + def execute(self, context): + from . import export_geo + keywords = self.as_keywords(ignore=("filter_glob", + "check_existing", + )) + return export_geo.save(self, context, 1.0 / 0.30480000376701355, **keywords) def menu_func_import(self, context): self.layout.operator(ImportGeo.bl_idname, - text="City of Heroes (.geo)") + text="City of Heroes (Feet) (.geo)") + self.layout.operator(ImportGeoMetric.bl_idname, + text="City of Heroes (Meters) (.geo)") def menu_func_export(self, context): self.layout.operator(ExportGeo.bl_idname, - text="City of Heroes (.geo)") + text="City of Heroes (Feet) (.geo)") + self.layout.operator(ExportGeoMetric.bl_idname, + text="City of Heroes (Meters) (.geo)") def register(): bpy.utils.register_module(__name__) diff --git a/export_geo.py b/export_geo.py index 425b9e8..822d216 100644 --- a/export_geo.py +++ b/export_geo.py @@ -60,12 +60,12 @@ def convert_mesh(geo_model, mesh, obj): geomesh.addFace(geoverts, texture_name) print("face: vertices: %s uvs: %s norms: %s groups: %s" % (verts, uv, norms, weights)) + #todo: optimize face order for bone association geomesh.dump() geo_model.loadFromGeoMesh(geomesh) - #todo: pass -def save(operator, context, filepath = "", global_matrix = None, use_mesh_modifiers = True): +def save(operator, context, scale = 1.0, filepath = "", global_matrix = None, use_mesh_modifiers = True): print("export_geo.save(): %s" % (filepath, )) geo = Geo() @@ -78,6 +78,7 @@ def save(operator, context, filepath = "", global_matrix = None, use_mesh_modifi axis_rotation = axis_conversion('-Y', 'Z', 'Z', 'Y') axis_rotation.resize_4x4() + print("scale: %s" % (scale, )) for ob in context.selected_objects: print("Object: %s (%s)" % (ob.name, ob.type)) if ob.type != "MESH": @@ -94,10 +95,13 @@ def save(operator, context, filepath = "", global_matrix = None, use_mesh_modifi #translate_matrix = Matrix.Translation(-ob.location) translate_matrix = Matrix() #scale_matrix = Matrix.Scale(1 / 0.30480000376701355, 4) - scale_matrix = Matrix.Scale(1, 4) obj_matrix = ob.matrix_world + print(obj_matrix) obj_scale = obj_matrix.to_scale()[0] #assume scaling is uniform on all axis - mesh.transform(global_matrix *obj_scale * translate_matrix * scale_matrix * axis_rotation) + print("obj_scale: %s final_scale: %s" % (obj_scale, obj_scale * scale)) + print(obj_scale * scale) + scale_matrix = Matrix.Scale(obj_scale * scale, 4) + mesh.transform(global_matrix * scale_matrix * translate_matrix * axis_rotation) mesh.calc_normals() diff --git a/geo_edit.py b/geo_edit.py index 4e14123..415a006 100755 --- a/geo_edit.py +++ b/geo_edit.py @@ -16,6 +16,7 @@ if len(sys.argv) < 4: print(" rename_model Rename model to .") print(" rename_texture Rename texture to .") print(" rescale_all Rescale all models by the given amount.") + print(" set_model_scale Set scale property of to .") exit() fn_in = sys.argv[1] @@ -85,6 +86,21 @@ while arg_i < len(sys.argv): for i in range(len(m.verts)): for j in range(3): m.verts[i][j] *= scale + elif operation == "set_model_scale": + name = bytes(sys.argv[arg_i], "utf-8") + scale = sys.argv[arg_i + 1 : arg_i + 4] + for i in range(3): + scale[i] = float(scale[i]) + arg_i += 4 + found = 0 + for m in geo.models: + if m.name == name: + found += 1 + print("Changed scale of '%s' from %s to %s" % (name.decode("utf-8"), m.scale, scale)) + m.scale = scale + break + if found <= 0: + print(" **Warning!*** Set model scale failed, no model named '%s'." % (nameold.decode("utf-8"), )) else: print("Unknown operation: '%s'" % (operation, )) exit() diff --git a/geo_list.py b/geo_list.py index b3c3be5..b850d5e 100644 --- a/geo_list.py +++ b/geo_list.py @@ -5,6 +5,7 @@ import re from geo import Geo show_triangles = False +show_scales = False def listGeo(fn, fh): geo = Geo() @@ -13,13 +14,18 @@ def listGeo(fn, fh): s = "%s : %s" % (geo.header_modelheader_name.decode("utf-8"), m.name.decode("utf-8")) if show_triangles: s += " : %d" % (m.tris and len(m.tris) or 0, ) + if show_scales: + s += " : %f, %f, %f" % tuple(m.scale) print(s) def parseOption(opt): global show_triangles + global show_scales for c in opt[1:]: if c == "t": show_triangles = True + elif c == "s": + show_scales = True if len(sys.argv) <= 1: @@ -27,6 +33,7 @@ if len(sys.argv) <= 1: print(" %s [] " % (sys.argv[0], )) print("Options:") print(" -t Display triangle count.") + print(" -s Display model scale.") exit()