Skip to content
Snippets Groups Projects
Commit 620e9b28 authored by Bastien Montagne's avatar Bastien Montagne
Browse files

blend2json.py: add option to only include some data fields (based on their names).

Typical usecase: --filter-data="name" to only get DNA structs' name
field value, much helpful to indentify datablocks in JSon result!
parent 896c5f78
No related branches found
No related tags found
No related merge requests found
...@@ -32,20 +32,24 @@ WARNING! This is still WIP tool! ...@@ -32,20 +32,24 @@ WARNING! This is still WIP tool!
Example usage: Example usage:
./blend2json.py -i foo.blend ./blend2json.py foo.blend
To output also all 'name' fields from data:
./blend2json.py --filter-data="name" foo.blend
To output complete DNA struct info: To output complete DNA struct info:
./blend2json.py --full-dna -i foo.blend ./blend2json.py --full-dna foo.blend
To avoid getting all 'uid' old addresses (those will change really often even when data itself does not change, To avoid getting all 'uid' old addresses (those will change really often even when data itself does not change,
making diff pretty noisy): making diff pretty noisy):
./blend2json.py --no-old-addresses -i foo.blend ./blend2json.py --no-old-addresses foo.blend
To check a .blend file instead of outputting its JSon version (use explicit -o option to do both at the same time): To check a .blend file instead of outputting its JSon version (use explicit -o option to do both at the same time):
./blend2json.py -c -i foo.blend ./blend2json.py -c foo.blend
""" """
...@@ -231,6 +235,7 @@ def do_bblock_filter(filters, blend, block, meta_keyval, data_keyval): ...@@ -231,6 +235,7 @@ def do_bblock_filter(filters, blend, block, meta_keyval, data_keyval):
def bblocks_to_json(args, fw, blend, address_map, indent, indent_step): def bblocks_to_json(args, fw, blend, address_map, indent, indent_step):
no_address = args.no_address no_address = args.no_address
full_data = args.full_data full_data = args.full_data
filter_data = args.filter_data
def gen_meta_keyval(blend, block): def gen_meta_keyval(blend, block):
keyval = [ keyval = [
...@@ -245,9 +250,12 @@ def bblocks_to_json(args, fw, blend, address_map, indent, indent_step): ...@@ -245,9 +250,12 @@ def bblocks_to_json(args, fw, blend, address_map, indent, indent_step):
] ]
return keyval return keyval
def gen_data_keyval(blend, block): def gen_data_keyval(blend, block, key_filter=None):
def _is_pointer(k): def _is_pointer(k):
return blend.structs[block.sdna_index].field_from_path(blend.header, blend.handle, k).dna_name.is_pointer return blend.structs[block.sdna_index].field_from_path(blend.header, blend.handle, k).dna_name.is_pointer
if key_filter is not None:
return [(json_dumps(k)[1:-1], json_dumps(address_map.get(v, v) if _is_pointer(k) else v))
for k, v in block.items_recursive_iter() if k in key_filter]
return [(json_dumps(k)[1:-1], json_dumps(address_map.get(v, v) if _is_pointer(k) else v)) return [(json_dumps(k)[1:-1], json_dumps(address_map.get(v, v) if _is_pointer(k) else v))
for k, v in block.items_recursive_iter()] for k, v in block.items_recursive_iter()]
...@@ -267,6 +275,9 @@ def bblocks_to_json(args, fw, blend, address_map, indent, indent_step): ...@@ -267,6 +275,9 @@ def bblocks_to_json(args, fw, blend, address_map, indent, indent_step):
if full_data: if full_data:
meta_keyval.append(("data", keyval_to_json(gen_data_keyval(blend, block), meta_keyval.append(("data", keyval_to_json(gen_data_keyval(blend, block),
indent + indent_step, indent_step, args.compact_output))) indent + indent_step, indent_step, args.compact_output)))
elif filter_data:
meta_keyval.append(("data", keyval_to_json(gen_data_keyval(blend, block, filter_data),
indent + indent_step, indent_step, args.compact_output)))
keyval = keyval_to_json(meta_keyval, indent, indent_step, args.compact_output) keyval = keyval_to_json(meta_keyval, indent, indent_step, args.compact_output)
fw('%s%s%s' % ('' if is_first else ',\n', indent, keyval)) fw('%s%s%s' % ('' if is_first else ',\n', indent, keyval))
is_first = False is_first = False
...@@ -377,6 +388,11 @@ def argparse_create(): ...@@ -377,6 +388,11 @@ def argparse_create():
default=False, action='store_true', required=False, default=False, action='store_true', required=False,
help=("Also put in JSon file data itself " help=("Also put in JSon file data itself "
"(WARNING! will generate *huge* verbose files - and is far from complete yet)")) "(WARNING! will generate *huge* verbose files - and is far from complete yet)"))
parser.add_argument(
"--filter-data", dest="filter_data",
default=None, required=False,
help=("Only put in JSon file data fields which names match given comma-separated list "
"(ignored if --full-data is set)"))
parser.add_argument( parser.add_argument(
"--full-dna", dest="full_dna", default=False, action='store_true', required=False, "--full-dna", dest="full_dna", default=False, action='store_true', required=False,
help=("Also put in JSon file dna properties description (ignored when --compact-output is used)")) help=("Also put in JSon file dna properties description (ignored when --compact-output is used)"))
...@@ -407,6 +423,12 @@ def main(): ...@@ -407,6 +423,12 @@ def main():
re.compile(f), re.compile(d)) re.compile(f), re.compile(d))
for m, f, d in args.block_filters] for m, f, d in args.block_filters]
if args.filter_data:
if args.full_data:
args.filter_data = None
else:
args.filter_data = {n.encode() for n in args.filter_data.split(',')}
for infile, outfile in zip(args.input, args.output): for infile, outfile in zip(args.input, args.output):
with blendfile.open_blend(infile) as blend: with blendfile.open_blend(infile) as blend:
address_map = gen_fake_addresses(args, blend) address_map = gen_fake_addresses(args, blend)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment