From 6224e021cee06ed8bce0a1ac330abe62a66286b4 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Fri, 13 Mar 2020 14:21:12 +0900 Subject: [PATCH] Support concatinating multiple glTF files. --- examples/mesh-conv/sandbox/README.md | 13 +- examples/mesh-conv/sandbox/concat_mesh.py | 190 ++++++++++++++-------- 2 files changed, 132 insertions(+), 71 deletions(-) diff --git a/examples/mesh-conv/sandbox/README.md b/examples/mesh-conv/sandbox/README.md index a7c28b5..df01840 100644 --- a/examples/mesh-conv/sandbox/README.md +++ b/examples/mesh-conv/sandbox/README.md @@ -6,12 +6,21 @@ Append(merge) mesh of glTF A to glTF B. `skin`, `nodes`, etc are not appended(to be merged). +## Usage + +concatenate sourceN.gltf to target.gltf and save it to merged.gltf + +``` +$ python concat_mesh.py source0.gltf target.gltf merged.gltf +``` + ## TODO -* [ ] Support multiple glTFs to merge +* [x] Support multiple glTFs to merge(concat) * [ ] Support merging skin * [ ] Support merging different node hierarchies -* [ ] `images`, `textures` +* [ ] Support `images`, `textures`, `materials` +* [ ] Support other glTF info # replace_attrib.py diff --git a/examples/mesh-conv/sandbox/concat_mesh.py b/examples/mesh-conv/sandbox/concat_mesh.py index 164a598..15ea297 100644 --- a/examples/mesh-conv/sandbox/concat_mesh.py +++ b/examples/mesh-conv/sandbox/concat_mesh.py @@ -1,20 +1,116 @@ # concat mesh to glTF +# support multiple source glTF to me concatenated to target.gltf import json import sys, os -prefix = "added/" +g_prefix = "added/" + +def concat(source, target, offsets, prefix, extraInfo): + # Args: + # source: dict(modified), target: dict(modified), + # offsets: dict(modified). contains offset table. + # prefix: str + # extraInfo: dict(inout) + + num_source_meshes = len(source["meshes"]) + num_source_buffers = len(source["buffers"]) + num_source_bufferViews = len(source["bufferViews"]) + num_source_accessors = len(source["accessors"]) + num_source_materials = len(source["materials"]) if "materials" in source else 0 + print("src =====") + print("num_src_meshes: ", num_source_meshes) + print("num_src_buffers: ", num_source_buffers) + print("num_src_bufferViews: ", num_source_bufferViews) + print("num_src_accessors: ", num_source_accessors) + print("num_src_materials: ", num_source_materials) + + + # + # Adjust name and index offset + # + for i in range(len(source["buffers"])): + if "name" in source["buffers"][i]: + source["buffers"][i]["name"] = prefix + source["buffers"][i]["name"] + + for i in range(len(source["bufferViews"])): + if "name" in source["bufferViews"][i]: + source["bufferViews"][i]["name"] = prefix + source["bufferViews"][i]["name"] + + source["bufferViews"][i]["buffer"] += offsets["buffers"] + + for i in range(len(source["accessors"])): + if "name" in source["accessors"][i]: + source["accessors"][i]["name"] = prefix + source["accessors"][i]["name"] + + source["accessors"][i]["bufferView"] += offsets["bufferViews"] + + for i in range(len(source["meshes"])): + mesh = source["meshes"][i] + + if "name" in mesh: + source["meshes"][i]["name"] = prefix + source["meshes"][i]["name"] + + for primid in range(len(mesh["primitives"])): + for attrib in mesh["primitives"][primid]["attributes"]: + #print(source["meshes"][i]["primitives"][primid]["attributes"][attrib]) + source["meshes"][i]["primitives"][primid]["attributes"][attrib] += offsets["accessors"] + + + source["meshes"][i]["primitives"][primid]["indices"] += offsets["accessors"] + if "material" in source["meshes"][i]["primitives"][primid]: + source["meshes"][i]["primitives"][primid]["material"] += offsets["materials"] + + + # + # Append mesh info + # + target["buffers"] += source["buffers"] + target["bufferViews"] += source["bufferViews"] + target["meshes"] += source["meshes"] + target["accessors"] += source["accessors"] + if "materials" in source: + target["materials"] += source["materials"] + + # assume `prefix` is unique + extraInfo["num_{}_meshes".format(prefix)] = num_source_meshes + extraInfo["num_{}_buffers".format(prefix)] = num_source_buffers + extraInfo["num_{}_bufferViews".format(prefix)] = num_source_bufferViews + extraInfo["num_{}_accessors".format(prefix)] = num_source_accessors + extraInfo["num_{}_materials".format(prefix)] = num_source_materials + + # update offsets + offsets["meshes"] += num_source_meshes + offsets["buffers"] += num_source_buffers + offsets["bufferViews"] += num_source_bufferViews + offsets["accessors"] += num_source_accessors + offsets["materials"] += num_source_materials + def main(): if len(sys.argv) < 4: - print("Needs source.gltf target.gltf output.gltf") + print("Needs source0.gltf target.gltf output.gltf") sys.exit(-1) - source_filename = sys.argv[1] - target_filename = sys.argv[2] - output_filename = sys.argv[3] + num_args = len(sys.argv) + print("num_args = ", num_args) - source = json.loads(open(source_filename).read()) + source_filenames = [] + + num_srcs = num_args - 3 + + for i in range(num_srcs): + source_filenames.append(sys.argv[1+i]) + print("source[{}] = {}".format(i, sys.argv[1+i])) + + target_filename = sys.argv[num_args - 2] + output_filename = sys.argv[num_args - 1] + print("target = ", target_filename) + print("output = ", output_filename) + + sources = [] + for i in range(num_srcs): + sources.append(json.loads(open(source_filenames[i]).read())) target = json.loads(open(target_filename).read()) num_target_meshes = len(target["meshes"]) @@ -28,65 +124,8 @@ def main(): print("num_target_accessors: ", num_target_accessors) print("num_target_materials: ", num_target_accessors) - num_source_meshes = len(source["meshes"]) - num_source_buffers = len(source["buffers"]) - num_source_bufferViews = len(source["bufferViews"]) - num_source_accessors = len(source["accessors"]) - num_source_materials = len(source["materials"]) if "materials" in source else 0 - print("num_source_meshes: ", num_source_meshes) - print("num_source_buffers: ", num_source_buffers) - print("num_source_bufferViews: ", num_source_bufferViews) - print("num_source_accessors: ", num_source_accessors) - print("num_source_materials: ", num_source_materials) - # - # Adjust name and index - # - for i in range(len(source["buffers"])): - if "name" in source["buffers"][i]: - source["buffers"][i]["name"] = prefix + source["buffers"][i]["name"] - - for i in range(len(source["bufferViews"])): - if "name" in source["bufferViews"][i]: - source["bufferViews"][i]["name"] = prefix + source["bufferViews"][i]["name"] - - source["bufferViews"][i]["buffer"] += num_target_buffers - - for i in range(len(source["accessors"])): - if "name" in source["accessors"][i]: - source["accessors"][i]["name"] = prefix + source["accessors"][i]["name"] - - source["accessors"][i]["bufferView"] += num_target_bufferViews - - for i in range(len(source["meshes"])): - mesh = source["meshes"][i] - - if "name" in mesh: - source["meshes"][i]["name"] = prefix + source["meshes"][i]["name"] - - for primid in range(len(mesh["primitives"])): - for attrib in mesh["primitives"][primid]["attributes"]: - #print(source["meshes"][i]["primitives"][primid]["attributes"][attrib]) - source["meshes"][i]["primitives"][primid]["attributes"][attrib] += num_target_accessors - - - source["meshes"][i]["primitives"][primid]["indices"] += num_target_accessors - if "material" in source["meshes"][i]["primitives"][primid]: - source["meshes"][i]["primitives"][primid]["material"] += num_target_materials - - - # - # Append mesh info - # - target["buffers"] += source["buffers"] - target["bufferViews"] += source["bufferViews"] - target["meshes"] += source["meshes"] - target["accessors"] += source["accessors"] - if "materials" in source: - target["materials"] += source["materials"] - - # - # add some info + # add some info to asset.extras # extraInfo = {} extraInfo["num_target_meshes"] = num_target_meshes @@ -95,11 +134,24 @@ def main(): extraInfo["num_target_accessors"] = num_target_accessors extraInfo["num_target_materials"] = num_target_materials - extraInfo["num_source_meshes"] = num_source_meshes - extraInfo["num_source_buffers"] = num_source_buffers - extraInfo["num_source_bufferViews"] = num_source_bufferViews - extraInfo["num_source_accessors"] = num_source_accessors - extraInfo["num_source_materials"] = num_source_materials + offsets = {} + offsets["meshes"] = num_target_meshes + offsets["buffers"] = num_target_buffers + offsets["bufferViews"] = num_target_bufferViews + offsets["accessors"] = num_target_accessors + offsets["materials"] = num_target_materials + + for i in range(num_srcs): + source = sources[i] + + prefix = g_prefix + "{}/".format(source_filenames[i]) + concat(source, target, offsets, prefix, extraInfo) + + extraInfo["num_total_meshes"] = offsets["meshes"] + extraInfo["num_total_buffers"] = offsets["buffers"] + extraInfo["num_total_bufferViews"] = offsets["bufferViews"] + extraInfo["num_total_accessors"] = offsets["accessors"] + extraInfo["num_total_materials"] = offsets["materials"] target["asset"]["extras"] = extraInfo