From 620e9b28291f1dabd55d5b66b874516cee1734bf Mon Sep 17 00:00:00 2001 From: Bastien Montagne <montagne29@wanadoo.fr> Date: Mon, 7 Nov 2016 14:20:29 +0100 Subject: [PATCH] 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! --- utils/blend2json.py | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/utils/blend2json.py b/utils/blend2json.py index 23ff94b..ba08d65 100755 --- a/utils/blend2json.py +++ b/utils/blend2json.py @@ -32,20 +32,24 @@ WARNING! This is still WIP tool! 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: - ./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, 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): - ./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): def bblocks_to_json(args, fw, blend, address_map, indent, indent_step): no_address = args.no_address full_data = args.full_data + filter_data = args.filter_data def gen_meta_keyval(blend, block): keyval = [ @@ -245,9 +250,12 @@ def bblocks_to_json(args, fw, blend, address_map, indent, indent_step): ] return keyval - def gen_data_keyval(blend, block): + def gen_data_keyval(blend, block, key_filter=None): def _is_pointer(k): 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)) for k, v in block.items_recursive_iter()] @@ -267,6 +275,9 @@ def bblocks_to_json(args, fw, blend, address_map, indent, indent_step): if full_data: meta_keyval.append(("data", keyval_to_json(gen_data_keyval(blend, block), 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) fw('%s%s%s' % ('' if is_first else ',\n', indent, keyval)) is_first = False @@ -376,7 +387,12 @@ def argparse_create(): "--full-data", dest="full_data", default=False, action='store_true', required=False, 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( "--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)")) @@ -407,6 +423,12 @@ def main(): re.compile(f), re.compile(d)) 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): with blendfile.open_blend(infile) as blend: address_map = gen_fake_addresses(args, blend) -- GitLab