#!/usr/bin/env python3 import pathlib import sys import bpy LIBRARY_NAME = "WBV2P3005Library.blend" LINKED_OBJECT = "WBV2P3005LinkedObject" APPEND_OBJECT = "WBV2P3005AppendObject" def reset() -> None: bpy.ops.wm.read_factory_settings(use_empty=True) def mesh_object(name: str, mesh_name: str, location: tuple[float, float, float]) -> bpy.types.Object: mesh = bpy.data.meshes.new(mesh_name) mesh.from_pydata( [(-0.75, -0.75, 0.0), (0.75, -0.75, 0.0), (0.75, 0.75, 0.0), (-0.75, 0.75, 0.0)], [], [(0, 1, 2), (0, 2, 3)], ) mesh.update() obj = bpy.data.objects.new(name, mesh) obj.location = location bpy.context.collection.objects.link(obj) return obj def create_source(path: pathlib.Path) -> None: reset() linked = mesh_object(LINKED_OBJECT, "WBV2P3005LinkedMesh", (-1.5, 0.0, 0.0)) linked_material = bpy.data.materials.new("WBV2P3005LinkedMaterial") linked_material.diffuse_color = (0.18, 0.38, 0.62, 1.0) linked.data.materials.append(linked_material) appended = mesh_object(APPEND_OBJECT, "WBV2P3005AppendMesh", (1.5, 0.0, 0.0)) material = bpy.data.materials.new("WBV2P3005AppendMaterial") material.use_nodes = True principled = material.node_tree.nodes.get("Principled BSDF") principled.inputs["Base Color"].default_value = (0.76, 0.28, 0.12, 1.0) principled.inputs["Metallic"].default_value = 0.2 principled.inputs["Roughness"].default_value = 0.5 principled.inputs["Emission Color"].default_value = (0.0, 0.0, 0.0, 1.0) principled.inputs["Emission Strength"].default_value = 1.0 image_path = pathlib.Path("tests/files/web/resources/udim_1001.png").resolve() image = bpy.data.images.load(str(image_path), check_existing=False) image.name = "WBV2P3005AppendImage" image.pack() texture = material.node_tree.nodes.new("ShaderNodeTexImage") texture.name = "WBV2P3005AppendImageNode" texture.image = image material.node_tree.links.new(texture.outputs["Color"], principled.inputs["Base Color"]) appended.data.materials.append(material) bpy.ops.wm.save_as_mainfile(filepath=str(path.resolve()), check_existing=False, compress=True) def create_fixture(output: pathlib.Path) -> None: source = output.with_name(LIBRARY_NAME) create_source(source) reset() with bpy.data.libraries.load(str(source.resolve()), link=True) as (data_from, data_to): if LINKED_OBJECT not in data_from.objects: raise RuntimeError("linked source object is missing") data_to.objects = [LINKED_OBJECT] linked = data_to.objects[0] if linked is None: raise RuntimeError("linked object could not be loaded") bpy.context.collection.objects.link(linked) bpy.context.view_layer.objects.active = linked linked.select_set(True) bpy.ops.wm.save_as_mainfile(filepath=str(output.resolve()), check_existing=False, compress=True) def main(output: pathlib.Path) -> None: output.parent.mkdir(parents=True, exist_ok=True) create_fixture(output.resolve()) if __name__ == "__main__": arguments = sys.argv[sys.argv.index("--") + 1:] if len(arguments) != 1: raise SystemExit("usage: blender -b --factory-startup --python WBV2-P3-005.py -- OUTPUT") main(pathlib.Path(arguments[0]))