Pipeline update
This commit is contained in:
@@ -354,7 +354,11 @@ class OgreMaterialGenerator(object):
|
||||
else:
|
||||
image_filepath = bpy.path.abspath(image.filepath, library=image.library)
|
||||
image_filepath = os.path.normpath(image_filepath)
|
||||
|
||||
|
||||
if not os.path.isfile(image_filepath):
|
||||
logger.warning("Skipping texture copy: source path is not a file (%s)", image_filepath)
|
||||
return
|
||||
|
||||
# Should we update the file
|
||||
update = False
|
||||
if os.path.isfile(target_filepath):
|
||||
|
||||
@@ -186,26 +186,32 @@ def extra_linear(angle, offset):
|
||||
|
||||
mapping_blend_path = argv[0]
|
||||
mapping_gltf_path = argv[1]
|
||||
mapping_objects = argv[2]
|
||||
mapping_armature_name = argv[3]
|
||||
mapping_outfile = argv[4]
|
||||
# Backward compat: support both 4-arg (blend, gltf, armature, outfile) and 5-arg (blend, gltf, objects, armature, outfile)
|
||||
if len(argv) >= 5:
|
||||
mapping_objects = argv[2]
|
||||
mapping_armature_name = argv[3]
|
||||
mapping_outfile = argv[4]
|
||||
else:
|
||||
mapping_objects = "AUTO"
|
||||
mapping_armature_name = argv[2]
|
||||
mapping_outfile = argv[3]
|
||||
|
||||
#for mapping in [ExportMappingFemale(), ExportMappingMale(), ExportMappingMaleBabyShape(), ExportMappingMaleEdited(), ExportMappingFemaleEdited(), ExportMappingMaleTestShapeEdited(), ExportMappingMaleBaseShapeEdited()]:
|
||||
class CommandLineMapping:
|
||||
blend_path = mapping_blend_path
|
||||
gltf_path = mapping_gltf_path
|
||||
# ogre_scene = "characters/female/vroid-normal-female.scene"
|
||||
inner_path = "Object"
|
||||
# objs = ["male", "Body", "Hair", "Face", "BackHair", "Tops", "Bottoms", "Shoes", "Accessory"]
|
||||
# objs = ["female", "Body", "Hair", "Face", "BackHair", "Tops", "Bottoms", "Shoes", "Accessory"]
|
||||
objs = []
|
||||
armature_name = mapping_armature_name
|
||||
outfile = mapping_outfile
|
||||
default_action = 'default'
|
||||
auto_discover = False
|
||||
def __init__(self):
|
||||
self.objs = [mapping_armature_name]
|
||||
if len(mapping_objects) > 0:
|
||||
if len(mapping_objects) > 0 and mapping_objects != "AUTO":
|
||||
self.objs += [o.strip() for o in mapping_objects.split(";")]
|
||||
else:
|
||||
self.auto_discover = True
|
||||
self.files = []
|
||||
for fobj in self.objs:
|
||||
self.files.append({"name": fobj})
|
||||
@@ -224,11 +230,30 @@ for mapping in[CommandLineMapping()]:
|
||||
bpy.app.driver_namespace["angle_to_linear_x"] = angle_to_linear_x
|
||||
print("Driver setup done...")
|
||||
|
||||
bpy.ops.wm.append(
|
||||
filepath=os.path.join(mapping.blend_path, mapping.inner_path),
|
||||
directory=os.path.join(mapping.blend_path, mapping.inner_path),
|
||||
files=mapping.files)
|
||||
print("Append done...")
|
||||
if mapping.auto_discover:
|
||||
# Load all objects from the blend file so we can discover meshes by custom props
|
||||
with bpy.data.libraries.load(mapping.blend_path) as (data_from, data_to):
|
||||
data_to.objects = data_from.objects
|
||||
for obj in data_to.objects:
|
||||
if obj is not None:
|
||||
try:
|
||||
bpy.context.collection.objects.link(obj)
|
||||
except RuntimeError:
|
||||
pass # Already linked
|
||||
print("Library load done...")
|
||||
|
||||
discovered = []
|
||||
for ob in bpy.data.objects:
|
||||
if ob.type == 'MESH' and all(p in ob.keys() for p in ["age", "sex", "slot"]):
|
||||
discovered.append(ob.name)
|
||||
mapping.objs += discovered
|
||||
print(f"Auto-discovered {len(discovered)} body part objects: {discovered}")
|
||||
else:
|
||||
bpy.ops.wm.append(
|
||||
filepath=os.path.join(mapping.blend_path, mapping.inner_path),
|
||||
directory=os.path.join(mapping.blend_path, mapping.inner_path),
|
||||
files=mapping.files)
|
||||
print("Append done...")
|
||||
|
||||
prepare_armature(mapping)
|
||||
print("Armature done...")
|
||||
@@ -239,6 +264,10 @@ for mapping in[CommandLineMapping()]:
|
||||
bpy.data.objects.remove(ob)
|
||||
elif ob.name.startswith("Face") and ob.name != "Face":
|
||||
bpy.data.objects.remove(ob)
|
||||
# Remove auto-discovered objects that weren't meant for export
|
||||
elif mapping.auto_discover and ob.type == 'MESH' and ob.name not in mapping.objs:
|
||||
if not ob.name.endswith("-noimp"):
|
||||
ob.name = ob.name + "-noimp"
|
||||
|
||||
print("Removing original armature and actions...")
|
||||
orig_arm = bpy.data.objects[mapping.armature_name + '_orig']
|
||||
@@ -317,12 +346,48 @@ for mapping in[CommandLineMapping()]:
|
||||
save_data[key] = obj[key]
|
||||
if key.startswith("body_"):
|
||||
save_data[key.replace("body_", "", 1)] = obj[key]
|
||||
|
||||
# Export aggregated clothing metadata
|
||||
if "layer" in obj:
|
||||
save_data["layer"] = int(obj["layer"])
|
||||
else:
|
||||
save_data["layer"] = 0
|
||||
|
||||
tags = []
|
||||
if "garments" in obj and obj["garments"]:
|
||||
garments = [g.strip() for g in str(obj["garments"]).split(";") if g.strip()]
|
||||
save_data["garments"] = garments
|
||||
tags.extend(garments)
|
||||
else:
|
||||
save_data["garments"] = []
|
||||
|
||||
if "clothing_tags" in obj and obj["clothing_tags"]:
|
||||
clothing_tags = [t.strip() for t in str(obj["clothing_tags"]).split(";") if t.strip()]
|
||||
tags.extend(clothing_tags)
|
||||
|
||||
# Deduplicate and sort
|
||||
seen = set()
|
||||
unique_tags = []
|
||||
for t in tags:
|
||||
t_lower = t.lower()
|
||||
if t_lower not in seen:
|
||||
seen.add(t_lower)
|
||||
unique_tags.append(t)
|
||||
save_data["tags"] = unique_tags
|
||||
|
||||
# Export shape keys if present
|
||||
shape_keys = []
|
||||
if obj.data.shape_keys and obj.data.shape_keys.key_blocks:
|
||||
for sk in obj.data.shape_keys.key_blocks:
|
||||
shape_keys.append(sk.name)
|
||||
save_data["shape_keys"] = shape_keys
|
||||
|
||||
save_data["mesh"] = obj.data.name + ".mesh"
|
||||
json_dir = os.path.dirname(mapping.gltf_path)
|
||||
save_file = json_dir + "/body_part_" + obj.data.name + ".json"
|
||||
json_filepath = os.path.join(json_dir, save_file)
|
||||
with open(json_filepath, 'w') as f:
|
||||
json.dump(save_data, f)
|
||||
json.dump(save_data, f, indent=2)
|
||||
|
||||
armobj = bpy.data.objects.get(mapping.armature_name)
|
||||
armobj.data.name = armobj.name
|
||||
|
||||
Reference in New Issue
Block a user