Files
workinf_Blender_Wasm/tools/web/generate-b4-world-readback-fixture.py
mes123456 f3e21c6b98
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
chore: checkpoint web Blender migration source, tools and docs
Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer,
web workflow engine and protocol, tooling, docs and task records.
Large generated evidence, user-testing archives, build snapshots and
imported test assets remain untracked.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-11-10 11:18:01 +08:00

66 lines
3.3 KiB
Python

"""Generate a World readback input fixture; do not run acceptance checks."""
import bpy
import json
from pathlib import Path
import sys
source, destination = sys.argv[sys.argv.index("--") + 1:]
bpy.ops.wm.open_mainfile(filepath=str(Path(source).resolve()))
scene = bpy.context.scene
world = scene.world.copy() if scene.world else bpy.data.worlds.new("B4WorldReadback")
world.name = "B4WorldReadback"
scene.world = world
if world.node_tree is None: world.use_nodes = True
tree = world.node_tree
tree.nodes.clear()
scene.render.engine = "BLENDER_EEVEE"
def background(name, strength):
node = tree.nodes.new("ShaderNodeBackground")
node.name = name
node.inputs["Strength"].default_value = strength
return node
def environment(name, color):
node = tree.nodes.new("ShaderNodeTexEnvironment")
node.name = name
node.image = bpy.data.images.new(name, width=1, height=1)
node.image.pixels[:] = color
node.image.pack()
return node
background("B4_unused_first", 17.0)
active = background("B4_active", 2.5)
texture = environment("B4_active_environment", (0.25, 0.5, 0.75, 1.0))
output = tree.nodes.new("ShaderNodeOutputWorld")
output.is_active_output = True
tree.links.new(active.outputs["Background"], output.inputs["Surface"])
tree.links.new(texture.outputs["Color"], active.inputs["Color"])
background("B4_unused_last", 99.0)
environment("B4_unused_environment", (1.0, 0.0, 0.0, 1.0))
driver = tree.nodes.new("ShaderNodeValue")
driver.name = "B4_strength_driver"
driver.outputs[0].default_value = 7.5
mesh = next((obj for obj in scene.objects if obj.type == "MESH"), None)
if mesh and not any(obj.type == "MESH" and any(obj.data.materials) for obj in scene.objects):
material = bpy.data.materials.new("B4FixtureMaterial")
material.diffuse_color = (0.65, 0.65, 0.65, 1.0)
if mesh.data.materials: mesh.data.materials[0] = material
else: mesh.data.materials.append(material)
if scene.camera:
scene.camera.data.lens = 52.0
scene.camera.data.clip_start = 0.125
scene.camera.data.clip_end = 2500.0
for light_object in (obj for obj in scene.objects if obj.type == "LIGHT"):
light_object.data.energy = 650.0
light_object.data.shadow_soft_size = 0.35
if light_object.data.type == 'AREA': light_object.data.size = 2.0
scene.render.resolution_x, scene.render.resolution_y, scene.render.resolution_percentage = 1280, 720, 80
scene.render.image_settings.file_format = 'PNG'
destination = Path(destination).resolve()
destination.parent.mkdir(parents=True, exist_ok=True)
bpy.ops.wm.save_as_mainfile(filepath=str(destination), check_existing=False)
facts = {"kind": "input_fixture", "source": str(Path(source).resolve()), "fixture": str(destination),
"world": world.name, "expectedStrength": 2.5, "expectedImage": texture.image.name,
"inactiveStrengths": [17.0, 99.0], "driver": driver.name, "camera": scene.camera.name if scene.camera else None,
"lights": [obj.name for obj in scene.objects if obj.type == "LIGHT"],
"materialObjects": [obj.name for obj in scene.objects if obj.type == "MESH" and any(obj.data.materials)],
"resolution": [scene.render.resolution_x, scene.render.resolution_y, scene.render.resolution_percentage], "format": scene.render.image_settings.file_format}
destination.with_suffix(".json").write_text(json.dumps(facts, indent=2) + "\n")