Add Chromium-only Blender WebEngine parity work
This commit is contained in:
144
tools/web/generate-modifier-goldens.py
Normal file
144
tools/web/generate-modifier-goldens.py
Normal file
@@ -0,0 +1,144 @@
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
FIXTURES = [
|
||||
"modifier_generate_scene.blend",
|
||||
"modifier_deform_scene.blend",
|
||||
"modifier_deform_curve_scene.blend",
|
||||
"modifier_physics_scene.blend",
|
||||
"modifier_geometry_nodes_scene.blend",
|
||||
"modifier_grease_pencil_scene.blend",
|
||||
]
|
||||
|
||||
|
||||
def modifier_type_code(modifier):
|
||||
items = bpy.types.Modifier.bl_rna.properties["type"].enum_items
|
||||
item = items.get(modifier.type)
|
||||
return item.value if item is not None else -1
|
||||
|
||||
|
||||
def modifier_record(modifier):
|
||||
record = {
|
||||
"name": modifier.name,
|
||||
"type": modifier.type,
|
||||
"typeCode": modifier_type_code(modifier),
|
||||
"showViewport": modifier.show_viewport,
|
||||
"showRender": modifier.show_render,
|
||||
"showEditmode": modifier.show_in_editmode,
|
||||
"showOnCage": modifier.show_on_cage,
|
||||
}
|
||||
targets = []
|
||||
for field in ("object", "target", "auxiliary_target"):
|
||||
if hasattr(modifier, field):
|
||||
target = getattr(modifier, field)
|
||||
if target is not None and target.name not in targets:
|
||||
targets.append(target.name)
|
||||
if targets:
|
||||
record["targetObjects"] = targets
|
||||
if modifier.type == "NODES" and modifier.node_group is not None:
|
||||
record["nodeGroup"] = modifier.node_group.name
|
||||
return record
|
||||
|
||||
|
||||
def evaluated_mesh_record(obj, depsgraph):
|
||||
evaluated = obj.evaluated_get(depsgraph)
|
||||
mesh = evaluated.to_mesh(preserve_all_data_layers=True, depsgraph=depsgraph)
|
||||
try:
|
||||
mesh.calc_loop_triangles()
|
||||
return {
|
||||
"object": obj.name,
|
||||
"sourceMesh": obj.data.name,
|
||||
"vertexCount": len(mesh.vertices),
|
||||
"triangleCount": len(mesh.loop_triangles),
|
||||
"positions": [component for vertex in mesh.vertices for component in vertex.co],
|
||||
"indices": [index for triangle in mesh.loop_triangles for index in triangle.vertices],
|
||||
"worldMatrix": [value for row in evaluated.matrix_world for value in row],
|
||||
}
|
||||
finally:
|
||||
evaluated.to_mesh_clear()
|
||||
|
||||
|
||||
def grease_pencil_record(obj):
|
||||
layers = []
|
||||
for layer in obj.data.layers:
|
||||
frames = []
|
||||
for frame in layer.frames:
|
||||
drawing = frame.drawing
|
||||
frames.append({
|
||||
"frame": frame.frame_number,
|
||||
"strokeCount": len(drawing.strokes),
|
||||
"pointCount": sum(len(stroke.points) for stroke in drawing.strokes),
|
||||
"positions": [component for stroke in drawing.strokes for point in stroke.points
|
||||
for component in point.position],
|
||||
})
|
||||
layers.append({"name": layer.name, "frames": frames})
|
||||
return {"object": obj.name, "data": obj.data.name, "layers": layers}
|
||||
|
||||
|
||||
def node_group_records():
|
||||
return [{
|
||||
"name": group.name,
|
||||
"type": group.bl_idname,
|
||||
"nodes": [{"name": node.name, "type": node.bl_idname} for node in group.nodes],
|
||||
"links": len(group.links),
|
||||
} for group in bpy.data.node_groups]
|
||||
|
||||
|
||||
def golden_for_fixture(path):
|
||||
bpy.ops.wm.open_mainfile(filepath=path)
|
||||
scene = bpy.context.scene
|
||||
scene.frame_set(scene.frame_current)
|
||||
depsgraph = bpy.context.evaluated_depsgraph_get()
|
||||
objects = []
|
||||
meshes = []
|
||||
grease_pencils = []
|
||||
for obj in sorted(bpy.data.objects, key=lambda item: item.name):
|
||||
objects.append({
|
||||
"name": obj.name,
|
||||
"type": obj.type,
|
||||
"modifiers": [modifier_record(modifier) for modifier in obj.modifiers],
|
||||
})
|
||||
if obj.type == "MESH":
|
||||
meshes.append(evaluated_mesh_record(obj, depsgraph))
|
||||
elif obj.type == "GREASEPENCIL":
|
||||
grease_pencils.append(grease_pencil_record(obj))
|
||||
return {
|
||||
"schemaVersion": 1,
|
||||
"blenderVersion": bpy.app.version_string,
|
||||
"fixture": os.path.basename(path),
|
||||
"frame": scene.frame_current,
|
||||
"objects": objects,
|
||||
"meshes": meshes,
|
||||
"nodeGroups": node_group_records(),
|
||||
"greasePencils": grease_pencils,
|
||||
"tolerance": {"maxPositionError": 1e-5, "rmsPositionError": 1e-6},
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
if "--" not in sys.argv or len(sys.argv[sys.argv.index("--") + 1:]) < 2:
|
||||
raise SystemExit("usage: blender -b --python generate-modifier-goldens.py -- fixture-directory output-directory")
|
||||
args = sys.argv[sys.argv.index("--") + 1:]
|
||||
fixture_directory, output_directory = args[:2]
|
||||
fixture_directory = os.path.abspath(fixture_directory)
|
||||
output_directory = os.path.abspath(output_directory)
|
||||
os.makedirs(output_directory, exist_ok=True)
|
||||
requested = args[2:] or FIXTURES
|
||||
for fixture in requested:
|
||||
if fixture not in FIXTURES:
|
||||
raise SystemExit(f"unknown modifier fixture: {fixture}")
|
||||
source = os.path.join(fixture_directory, fixture)
|
||||
golden = golden_for_fixture(source)
|
||||
output = os.path.join(output_directory, fixture.replace(".blend", ".json"))
|
||||
with open(output, "w", encoding="utf-8") as handle:
|
||||
json.dump(golden, handle, indent=2, sort_keys=True)
|
||||
handle.write("\n")
|
||||
print(f"modifier-golden-generated fixture={fixture} output={output}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user