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.
master
TigerKat 5 years ago
parent 369c9ae4a7
commit 7b316f2386

@ -16,7 +16,7 @@ The Blender add-on allows you to export .geo files.
## Using the Add-On ## Using the Add-On
1. Select the meshes to export in object mode. 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". 3. Browse to the file you want to create and click "Export GEO".
# Tools # Tools
@ -51,8 +51,11 @@ Operation | Description
rename_model <old> <new> | Rename a model from <old> to <new>. rename_model <old> <new> | Rename a model from <old> to <new>.
rename_texture <old> <new> | Rename a texture 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> . 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. 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 ## geo_list.py
A command line tool for list the model name inside of 1 or more .geo files. A command line tool for list the model name inside of 1 or more .geo files.

@ -2,7 +2,7 @@
bl_info = { bl_info = {
"name": "City of Heroes (.geo)", "name": "City of Heroes (.geo)",
"author": "TigerKat", "author": "TigerKat",
"version": (0, 1, 2), "version": (0, 1, 3),
"blender": (2, 79, 0), "blender": (2, 79, 0),
"location": "File > Import/Export,", "location": "File > Import/Export,",
"description": "City of Heroes (.geo)", "description": "City of Heroes (.geo)",
@ -55,7 +55,18 @@ class ImportGeo(bpy.types.Operator, ImportHelper):
def execute(self, context): def execute(self, context):
from . import import_geo from . import import_geo
keywords = self.as_keywords(ignore=("filter_glob",)) 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): class ExportGeo(bpy.types.Operator, ExportHelper):
bl_idname = "export_scene.geo" bl_idname = "export_scene.geo"
@ -68,16 +79,33 @@ class ExportGeo(bpy.types.Operator, ExportHelper):
keywords = self.as_keywords(ignore=("filter_glob", keywords = self.as_keywords(ignore=("filter_glob",
"check_existing", "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): def menu_func_import(self, context):
self.layout.operator(ImportGeo.bl_idname, 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): def menu_func_export(self, context):
self.layout.operator(ExportGeo.bl_idname, 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(): def register():
bpy.utils.register_module(__name__) bpy.utils.register_module(__name__)

@ -60,12 +60,12 @@ def convert_mesh(geo_model, mesh, obj):
geomesh.addFace(geoverts, texture_name) geomesh.addFace(geoverts, texture_name)
print("face: vertices: %s uvs: %s norms: %s groups: %s" % (verts, uv, norms, weights)) print("face: vertices: %s uvs: %s norms: %s groups: %s" % (verts, uv, norms, weights))
#todo: optimize face order for bone association
geomesh.dump() geomesh.dump()
geo_model.loadFromGeoMesh(geomesh) geo_model.loadFromGeoMesh(geomesh)
#todo:
pass 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, )) print("export_geo.save(): %s" % (filepath, ))
geo = Geo() 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 = axis_conversion('-Y', 'Z', 'Z', 'Y')
axis_rotation.resize_4x4() axis_rotation.resize_4x4()
print("scale: %s" % (scale, ))
for ob in context.selected_objects: for ob in context.selected_objects:
print("Object: %s (%s)" % (ob.name, ob.type)) print("Object: %s (%s)" % (ob.name, ob.type))
if ob.type != "MESH": 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.Translation(-ob.location)
translate_matrix = Matrix() translate_matrix = Matrix()
#scale_matrix = Matrix.Scale(1 / 0.30480000376701355, 4) #scale_matrix = Matrix.Scale(1 / 0.30480000376701355, 4)
scale_matrix = Matrix.Scale(1, 4)
obj_matrix = ob.matrix_world obj_matrix = ob.matrix_world
print(obj_matrix)
obj_scale = obj_matrix.to_scale()[0] #assume scaling is uniform on all axis 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() mesh.calc_normals()

@ -16,6 +16,7 @@ if len(sys.argv) < 4:
print(" rename_model <old> <new> Rename model <old> to <new>.") print(" rename_model <old> <new> Rename model <old> to <new>.")
print(" rename_texture <old> <new> Rename texture <old> to <new>.") print(" rename_texture <old> <new> Rename texture <old> to <new>.")
print(" rescale_all <scale> Rescale all models by the given amount.") print(" rescale_all <scale> Rescale all models by the given amount.")
print(" set_model_scale <model> <x> <y> <z> Set scale property of <model> to <x> <y> <z>.")
exit() exit()
fn_in = sys.argv[1] fn_in = sys.argv[1]
@ -85,6 +86,21 @@ while arg_i < len(sys.argv):
for i in range(len(m.verts)): for i in range(len(m.verts)):
for j in range(3): for j in range(3):
m.verts[i][j] *= scale 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: else:
print("Unknown operation: '%s'" % (operation, )) print("Unknown operation: '%s'" % (operation, ))
exit() exit()

@ -5,6 +5,7 @@ import re
from geo import Geo from geo import Geo
show_triangles = False show_triangles = False
show_scales = False
def listGeo(fn, fh): def listGeo(fn, fh):
geo = Geo() 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")) s = "%s : %s" % (geo.header_modelheader_name.decode("utf-8"), m.name.decode("utf-8"))
if show_triangles: if show_triangles:
s += " : %d" % (m.tris and len(m.tris) or 0, ) s += " : %d" % (m.tris and len(m.tris) or 0, )
if show_scales:
s += " : %f, %f, %f" % tuple(m.scale)
print(s) print(s)
def parseOption(opt): def parseOption(opt):
global show_triangles global show_triangles
global show_scales
for c in opt[1:]: for c in opt[1:]:
if c == "t": if c == "t":
show_triangles = True show_triangles = True
elif c == "s":
show_scales = True
if len(sys.argv) <= 1: if len(sys.argv) <= 1:
@ -27,6 +33,7 @@ if len(sys.argv) <= 1:
print(" %s [<options>] <infile.geo>" % (sys.argv[0], )) print(" %s [<options>] <infile.geo>" % (sys.argv[0], ))
print("Options:") print("Options:")
print(" -t Display triangle count.") print(" -t Display triangle count.")
print(" -s Display model scale.")
exit() exit()

Loading…
Cancel
Save