# -*- coding: utf-8 -*- """Takes one ore type out of a built set without rebuilding the rest: its objects, meshes, materials and images in OrePatches.blend, its entries in OrePatches.json and build_report.json. The columns and rows after it close up, as a build without that type would lay them out. The type's files (textures, fbx, previews) are moved by hand. blender -b ../OrePatches.blend --python remove_ore.py -- Pearl """ import bpy, os, sys, json HERE = os.path.dirname(os.path.abspath(__file__)) ROOT = os.path.dirname(HERE) ORE = sys.argv[sys.argv.index('--') + 1] tag = '_%s_' % ORE key = ORE.lower() gone = [o for o in bpy.data.objects if tag in o.name] col_x = [o.location.x for o in gone if o.type == 'EMPTY' and o.name.startswith('OrePatch_')] row_y = [o.location.y for o in gone if o.name.startswith('SM_OreCluster_')] assert gone and col_x and row_y, 'nothing of %s in this file' % ORE meshes = {o.data for o in gone if o.type == 'MESH'} mats = {s.material for o in gone if o.type == 'MESH' for s in o.material_slots if s.material} for o in gone: bpy.data.objects.remove(o) for me in meshes: if me.users == 0: bpy.data.meshes.remove(me) imgs = set() for m in mats: if m.users == 0: imgs |= {n.image for n in m.node_tree.nodes if n.type == 'TEX_IMAGE' and n.image} bpy.data.materials.remove(m) for im in imgs: if im.users == 0: bpy.data.images.remove(im) for c in list(bpy.data.collections): if ORE in c.name and not c.all_objects: bpy.data.collections.remove(c) # close the gap: one column of patches (4.6 m) and one row of pieces (1.6 m) for o in bpy.data.objects: if o.parent is None and o.type == 'EMPTY' and o.name.startswith('OrePatch_') and o.location.x > col_x[0] + 0.1: o.location.x -= 4.6 if o.name.startswith(('SM_OreCluster_', 'SM_OreChunk_', 'UCX_SM_OreCluster_', 'UCX_SM_OreChunk_')) and o.location.y > row_y[0] + 0.1: o.location.y -= 1.6 left = [o.name for o in bpy.data.objects if ORE in o.name] + [d.name for d in list(bpy.data.meshes) + list(bpy.data.materials) + list(bpy.data.images) if ORE in d.name] bpy.ops.wm.save_mainfile() mf = os.path.join(ROOT, 'OrePatches.json') man = json.load(open(mf)) man['ore_types'].pop(key) man['patches'] = [p for p in man['patches'] if p['ore'] != key] json.dump(man, open(mf, 'w'), indent=1) rf = os.path.join(HERE, 'build_report.json') rep = json.load(open(rf)) rep['meshes'] = {k: v for k, v in rep['meshes'].items() if tag not in k} rep['patches'] = {k: v for k, v in rep['patches'].items() if tag not in k} json.dump(rep, open(rf, 'w'), indent=1) print('[remove] %s: %d objects, %d meshes, %d materials, %d images removed; still named %s in the file: %s' % ( ORE, len(gone), len(meshes), len(mats), len(imgs), ORE, left or 'nothing')) print('[remove] left: %d ore types, %d patches, %d meshes in the report' % (len(man['ore_types']), len(man['patches']), len(rep['meshes'])))