Files
workinf_Blender_Wasm/tools/web/generate-modifier-extended-fixture.py
2026-08-12 04:47:48 -04:00

153 lines
5.0 KiB
Python

import json
import math
import os
import sys
import bpy
def mesh_object(name, vertices, edges, faces, location):
mesh = bpy.data.meshes.new(f"{name}Mesh")
mesh.from_pydata(vertices, edges, faces)
mesh.update()
obj = bpy.data.objects.new(name, mesh)
obj.location = location
bpy.context.scene.collection.objects.link(obj)
return obj
def modifier_type_code(modifier):
items = bpy.types.Modifier.bl_rna.properties["type"].enum_items
return items[modifier.type].value
def evaluated_mesh(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,
"vertexCount": len(mesh.vertices),
"triangleCount": len(mesh.loop_triangles),
"positions": [value for vertex in mesh.vertices for value in vertex.co],
"indices": [index for triangle in mesh.loop_triangles for index in triangle.vertices],
}
finally:
evaluated.to_mesh_clear()
def main(output_dir):
bpy.ops.wm.read_factory_settings(use_empty=True)
edge_split = mesh_object(
"ExtendedEdgeSplit",
[(0, 0, 0), (2, 0, 0), (0, 2, 0), (0, 0, 2)],
[],
[(0, 1, 2), (0, 3, 1)],
(-3, 0, 0),
)
edge_modifier = edge_split.modifiers.new("Native Edge Split", "EDGE_SPLIT")
edge_modifier.use_edge_angle = True
edge_modifier.use_edge_sharp = False
edge_modifier.split_angle = math.radians(30)
screw = mesh_object(
"ExtendedScrew",
[(1, 0, -1), (1, 0, 1)],
[(0, 1)],
[],
(3, 0, 0),
)
screw_modifier = screw.modifiers.new("Native Screw", "SCREW")
screw_modifier.axis = "Z"
screw_modifier.angle = math.tau
screw_modifier.steps = 8
screw_modifier.render_steps = 12
screw_modifier.iterations = 1
screw_modifier.use_merge_vertices = False
disabled = screw.modifiers.new("Disabled Edge Split", "EDGE_SPLIT")
disabled.show_viewport = False
disabled.show_render = True
disabled.show_in_editmode = True
displace = mesh_object(
"ExtendedDisplace",
[(-1, -1, -1), (1, -1, -1), (1, 1, -1), (-1, 1, -1),
(-1, -1, 1), (1, -1, 1), (1, 1, 1), (-1, 1, 1)],
[],
[(0, 1, 2, 3), (4, 7, 6, 5), (0, 4, 5, 1),
(1, 5, 6, 2), (2, 6, 7, 3), (4, 0, 3, 7)],
(7, 0, 0),
)
displace_modifier = displace.modifiers.new("Native Constant Displace", "DISPLACE")
displace_modifier.direction = "Z"
displace_modifier.space = "LOCAL"
displace_modifier.strength = 0.75
displace_modifier.mid_level = 0.25
blocked_displace = mesh_object(
"ExtendedDisplaceBlocked",
[(-1, -1, 0), (1, -1, 0), (1, 1, 0), (-1, 1, 0)],
[],
[(0, 1, 2, 3)],
(11, 0, 0),
)
blocked_modifier = blocked_displace.modifiers.new("Blocked RGB Displace", "DISPLACE")
blocked_modifier.direction = "RGB_TO_XYZ"
mesh_object(
"ExtendedDisplaceBlockedBaseline",
[(-1, -1, 0), (1, -1, 0), (1, 1, 0), (-1, 1, 0)],
[],
[(0, 1, 2, 3)],
(15, 0, 0),
)
scene = bpy.context.scene
scene.frame_set(1)
depsgraph = bpy.context.evaluated_depsgraph_get()
objects = [edge_split, screw, displace, blocked_displace]
golden = {
"schemaVersion": 1,
"taskId": "N-002",
"blenderVersion": bpy.app.version_string,
"fixture": "modifier_extended_native.blend",
"frame": scene.frame_current,
"objects": [
{
"name": obj.name,
"modifiers": [
{
"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,
}
for modifier in obj.modifiers
],
}
for obj in objects
],
"meshes": [evaluated_mesh(obj, depsgraph) for obj in objects],
"tolerance": {"maxPositionError": 1e-5, "rmsPositionError": 1e-6},
}
os.makedirs(output_dir, exist_ok=True)
output_path = os.path.join(output_dir, golden["fixture"])
bpy.ops.wm.save_as_mainfile(filepath=output_path)
golden_dir = os.path.abspath(os.path.join(output_dir, "..", "..", "golden", "N-002"))
os.makedirs(golden_dir, exist_ok=True)
with open(os.path.join(golden_dir, "modifier_extended_native.json"), "w", encoding="utf-8") as handle:
json.dump(golden, handle, indent=2, sort_keys=True)
handle.write("\n")
print(f"modifier-extended-generated fixture={output_path}")
if __name__ == "__main__":
args = sys.argv[sys.argv.index("--") + 1:]
main(os.path.abspath(args[0]))