kopia lustrzana https://gitlab.com/subdivided_xyz/nodes_xyz
154 wiersze
5.2 KiB
Python
154 wiersze
5.2 KiB
Python
#!/usr/bin/python3
|
|
|
|
import os
|
|
import pathlib
|
|
import random
|
|
import math
|
|
from posixpath import relpath
|
|
import tempfile
|
|
|
|
import bpy
|
|
|
|
# Config
|
|
|
|
tags=[""]
|
|
force_preview_update = True
|
|
|
|
# Nothing to change below
|
|
|
|
def find_catalog_id():
|
|
pathsUUIDs = {}
|
|
blender_catalogs_file = "blender_assets.cats.txt"
|
|
current_dir = pathlib.Path().absolute()
|
|
blender_catalogs_dir = None
|
|
catalog_id = None
|
|
|
|
for x in [current_dir, *pathlib.Path(current_dir).parents]:
|
|
if os.path.exists(os.path.join(x, blender_catalogs_file)):
|
|
blender_catalogs_dir = x
|
|
break
|
|
|
|
if blender_catalogs_dir is not None:
|
|
with open(os.path.join(blender_catalogs_dir, blender_catalogs_file)) as f:
|
|
for line in f.readlines():
|
|
if not line.startswith("#") and ":" in line:
|
|
line_uuid = line.split(":")[0].strip()
|
|
path = line.split(":")[1].strip()
|
|
pathsUUIDs[path] = line_uuid
|
|
rel_path = os.path.relpath(current_dir, blender_catalogs_dir)
|
|
while rel_path != ".":
|
|
if rel_path in pathsUUIDs:
|
|
catalog_id = pathsUUIDs[rel_path]
|
|
break
|
|
rel_path = str(pathlib.Path(rel_path).parent)
|
|
return catalog_id
|
|
|
|
|
|
def setup_world(scene):
|
|
# Make sure we have a camera
|
|
camera_data = bpy.data.cameras.new(name='Camera')
|
|
camera = bpy.data.objects.new('Camera', camera_data)
|
|
scene.camera = camera
|
|
bpy.context.scene.collection.objects.link(camera)
|
|
|
|
# Change Settings
|
|
camera.rotation_euler = (70/180*math.pi, 0, -20/180*math.pi)
|
|
# This was needed for very small assets. We could base the clip planes on the scene's bounding box.
|
|
# camera_data.clip_start = 0.001
|
|
# camera_data.clip_end = 10
|
|
scene.render.engine = 'CYCLES'
|
|
scene.render.resolution_y = 256
|
|
scene.render.resolution_x = 256
|
|
scene.render.film_transparent = True
|
|
scene.render.image_settings.file_format = 'PNG'
|
|
|
|
# Setup the environment map
|
|
scene.world.use_nodes = True
|
|
world_tree = scene.world.node_tree
|
|
env_node = world_tree.nodes.new('ShaderNodeTexEnvironment')
|
|
bg_node = world_tree.nodes['Background']
|
|
world_tree.links.new(bg_node.inputs['Color'], env_node.outputs['Color'])
|
|
env_node.image = bpy.data.images.load("/windows/d/3DLibrary/hdri/HDRIHaven/old_depot_4k.hdr")
|
|
|
|
|
|
def snapshot(scene, entity, tmpdirname):
|
|
bpy.ops.object.select_all(action='DESELECT')
|
|
if entity.rna_type.name == 'Collection':
|
|
for o in entity.objects:
|
|
o.select_set(True)
|
|
else:
|
|
entity.select_set(True)
|
|
bpy.ops.view3d.camera_to_view_selected()
|
|
|
|
filename = str(random.randint(0,100000000000))+".png"
|
|
filepath = str(os.path.abspath(os.path.join(tmpdirname, filename)))
|
|
scene.render.filepath = filepath
|
|
|
|
#Render File, Mark Asset and Set Image
|
|
bpy.ops.render.render(write_still = True)
|
|
|
|
return filepath
|
|
|
|
|
|
def ensure_preview_image(obj, tmpdirname):
|
|
preview_filepath = None
|
|
if obj.preview is None or force_preview_update:
|
|
exts=['.jpg', '.jpeg', '.png']
|
|
for ext in exts:
|
|
check_filepath = bpy.data.filepath.replace(".blend", ext)
|
|
if os.path.exists(check_filepath):
|
|
preview_filepath = check_filepath
|
|
if preview_filepath is None:
|
|
print("Generating preview image")
|
|
preview_filepath = snapshot(bpy.context.scene, obj, tmpdirname)
|
|
return preview_filepath
|
|
|
|
def mark_entity(obj, preview_filepath, catalog_id):
|
|
# Mark asset
|
|
if obj.asset_data is None:
|
|
print("Marking ", obj)
|
|
obj.asset_mark()
|
|
# Set tags
|
|
for tag in tags:
|
|
if not tag in obj.asset_data.tags:
|
|
print("Creating tag ", tag)
|
|
obj.asset_data.tags.new(tag)
|
|
# Set preview
|
|
if obj.preview is None or force_preview_update:
|
|
override = bpy.context.copy()
|
|
override['id'] = obj
|
|
print("Loading preview image: ", preview_filepath)
|
|
with bpy.context.temp_override(**override):
|
|
bpy.ops.ed.lib_id_load_custom_preview(filepath=preview_filepath)
|
|
# Put into right catalog
|
|
if catalog_id is not None:
|
|
print("Setting catalog id:", catalog_id)
|
|
obj.asset_data.catalog_id = catalog_id
|
|
|
|
|
|
def collect_asset_entities():
|
|
asset_entities = []
|
|
if len(bpy.data.objects)==1:
|
|
for obj in bpy.data.objects:
|
|
if obj.parent is None:
|
|
asset_entities.append(obj)
|
|
else:
|
|
# We are only interested in root collections, which we can find as
|
|
# children of the scene collection
|
|
for col in bpy.context.scene.collection.children:
|
|
asset_entities.append(col)
|
|
return asset_entities
|
|
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
|
setup_world(bpy.context.scene)
|
|
preview_file_paths = []
|
|
for entity in collect_asset_entities():
|
|
preview_file_paths.append(ensure_preview_image(entity, tmpdirname))
|
|
#Cleanup
|
|
bpy.ops.wm.revert_mainfile()
|
|
# We need to collect the entities twice, because we might revert the blend file inbetween
|
|
for entity,preview_file_path in zip(collect_asset_entities(), preview_file_paths):
|
|
mark_entity(entity, preview_file_path, find_catalog_id())
|
|
bpy.ops.wm.save_mainfile()
|