import bpy
import mathutils
def create_bird_model():
# 1. Configuration Data
materials_config = {
"RedFactor": {"color": [1.0, 0.25, 0.0, 1.0], "roughness": 0.5},
"Beak": {"color": [0.9, 0.7, 0.6, 1.0], "roughness": 0.5},
"Leg": {"color": [0.7, 0.5, 0.4, 1.0], "roughness": 0.2},
"Eye": {"color": [0.01, 0.01, 0.01, 1.0], "roughness": 0.1}
}
parts_config = {
"Body": {"type": "uv_sphere", "params": {"radius": 1.0}, "scale": [1.2, 0.8, 0.9], "mat": "RedFactor", "subdiv": "CATMULL_CLARK"},
"Head": {"type": "uv_sphere", "params": {"radius": 0.6}, "scale": [1.1, 1.0, 1.0], "mat": "RedFactor", "subdiv": "CATMULL_CLARK"},
"Beak": {"type": "cone", "params": {"radius1": 0.2, "depth": 0.5}, "mat": "Beak", "subdiv": "SIMPLE"},
"Eye_L": {"type": "uv_sphere", "params": {"radius": 0.08}, "mat": "Eye", "subdiv": "CATMULL_CLARK"},
"Eye_R": {"type": "uv_sphere", "params": {"radius": 0.08}, "mat": "Eye", "subdiv": "CATMULL_CLARK"},
"Wing_L": {"type": "uv_sphere", "params": {"radius": 1.0}, "scale": [0.817, 0.201, 0.463], "mat": "RedFactor", "subdiv": "CATMULL_CLARK"},
"Wing_R": {"type": "uv_sphere", "params": {"radius": 1.0}, "scale": [0.817, 0.201, 0.463], "mat": "RedFactor", "subdiv": "CATMULL_CLARK"},
"Tail": {"type": "uv_sphere", "params": {"radius": 1.0}, "scale": [0.45, 0.45, 0.45], "mat": "RedFactor", "subdiv": "CATMULL_CLARK"},
"Feather1": {"type": "uv_sphere", "params": {"radius": 1.0}, "scale": [1.5, 0.45, 0.1], "mat": "RedFactor", "subdiv": "CATMULL_CLARK"},
"Feather2": {"type": "uv_sphere", "params": {"radius": 1.0}, "scale": [1.5, 0.45, 0.1], "mat": "RedFactor", "subdiv": "CATMULL_CLARK"},
"Leg_L": {"type": "cylinder", "params": {"radius": 0.03, "depth": 1.0}, "mat": "Leg", "subdiv": "SIMPLE"},
"Leg_R": {"type": "cylinder", "params": {"radius": 0.03, "depth": 1.0}, "mat": "Leg", "subdiv": "SIMPLE"},
"M_Toe_L": {"type": "cube", "params": {}, "scale": [0.4, 0.03, 0.02], "mat": "Leg", "subdiv": "SIMPLE"},
"M_Toe_R": {"type": "cube", "params": {}, "scale": [0.4, 0.03, 0.02], "mat": "Leg", "subdiv": "SIMPLE"},
"B_Toe_L": {"type": "cube", "params": {}, "scale": [0.3, 0.03, 0.02], "mat": "Leg", "subdiv": "SIMPLE"},
"B_Toe_R": {"type": "cube", "params": {}, "scale": [0.3, 0.03, 0.02], "mat": "Leg", "subdiv": "SIMPLE"},
"F_Toe_1_L": {"type": "cube", "params": {}, "scale": [0.4, 0.03, 0.02], "mat": "Leg", "subdiv": "SIMPLE"},
"F_Toe_1_R": {"type": "cube", "params": {}, "scale": [0.4, 0.03, 0.02], "mat": "Leg", "subdiv": "SIMPLE"},
"F_Toe_2_L": {"type": "cube", "params": {}, "scale": [0.4, 0.03, 0.02], "mat": "Leg", "subdiv": "SIMPLE"},
"F_Toe_2_R": {"type": "cube", "params": {}, "scale": [0.4, 0.03, 0.02], "mat": "Leg", "subdiv": "SIMPLE"}
}
hierarchy = [
{"name": "Body", "parent": None, "loc": [0.0, 0.0, 0.0], "rot": [0.0, 0.0, 0.0]},
{"name": "Head", "parent": "Body", "loc": [0.8, 0.0, 0.6], "rot": [0.0, 0.0, 0.0]},
{"name": "Beak", "parent": "Head", "loc": [1.45, 0.0, 0.6], "rot": [0.0, 1.57, 0.0]},
{"name": "Eye_L", "parent": "Head", "loc": [1.1, 0.45, 0.8], "rot": [0.0, 0.0, 0.0]},
{"name": "Eye_R", "parent": "Head", "loc": [1.1, -0.45, 0.8], "rot": [0.0, 0.0, 0.0]},
{"name": "Wing_L", "parent": "Body", "loc": [-0.382, 0.718, 0.130], "rot": [0.0, 0.0, 0.0]},
{"name": "Wing_R", "parent": "Body", "loc": [-0.382, -0.718, 0.130], "rot": [0.0, 0.0, 0.0]},
{"name": "Tail", "parent": "Body", "loc": [-1.0, 0.0, 0.1], "rot": [0.0, 0.0, 0.0]},
{"name": "Feather1", "parent": "Tail", "loc": [-1.5, 0.0, 0.3], "rot": [0.26, -0.26, -0.26]},
{"name": "Feather2", "parent": "Tail", "loc": [-1.5, 0.0, 0.3], "rot": [-0.26, -0.26, 0.26]},
{"name": "Leg_L", "parent": "Body", "loc": [-0.35, 0.25, -1.0], "rot": [0.0, -0.21, 0.0]},
{"name": "Leg_R", "parent": "Body", "loc": [-0.35, -0.25, -1.0], "rot": [0.0, -0.21, 0.0]},
{"name": "M_Toe_L", "parent": "Leg_L", "loc": [-0.05, 0.25, -1.499], "rot": [0.0, 0.12, 0.0]},
{"name": "M_Toe_R", "parent": "Leg_R", "loc": [-0.05, -0.25, -1.499], "rot": [0.0, 0.12, 0.0]},
{"name": "B_Toe_L", "parent": "Leg_L", "loc": [-0.392, 0.25, -1.502], "rot": [0.0, -0.21, 0.0]},
{"name": "B_Toe_R", "parent": "Leg_R", "loc": [-0.392, -0.25, -1.502], "rot": [0.0, -0.21, 0.0]},
{"name": "F_Toe_1_L", "parent": "Leg_L", "loc": [-0.068, 0.334, -1.5], "rot": [0.038, 0.128, 0.43]},
{"name": "F_Toe_1_R", "parent": "Leg_R", "loc": [-0.068, -0.334, -1.5], "rot": [0.038, 0.128, -0.43]},
{"name": "F_Toe_2_L", "parent": "Leg_L", "loc": [-0.068, 0.165, -1.5], "rot": [-0.038, 0.128, -0.43]},
{"name": "F_Toe_2_R", "parent": "Leg_R", "loc": [-0.068, -0.165, -1.5], "rot": [-0.038, 0.128, 0.43]}
]
col_name = "Collection_Canary"
if col_name in bpy.data.collections:
for obj in bpy.data.collections[col_name].objects:
bpy.data.objects.remove(obj, do_unlink=True)
else:
new_col = bpy.data.collections.new(col_name)
bpy.context.scene.collection.children.link(new_col)
target_col = bpy.data.collections[col_name]
mat_registry = {}
for name, cfg in materials_config.items():
mat = bpy.data.materials.new(name=name)
mat.use_nodes = True
bsdf = mat.node_tree.nodes["Principled BSDF"]
bsdf.inputs['Base Color'].default_value = cfg["color"]
bsdf.inputs['Roughness'].default_value = cfg["roughness"]
mat_registry[name] = mat
for name, cfg in parts_config.items():
if cfg["type"] == "uv_sphere": bpy.ops.mesh.primitive_uv_sphere_add(**cfg["params"])
elif cfg["type"] == "cone": bpy.ops.mesh.primitive_cone_add(**cfg["params"])
elif cfg["type"] == "cylinder": bpy.ops.mesh.primitive_cylinder_add(**cfg["params"])
elif cfg["type"] == "cube": bpy.ops.mesh.primitive_cube_add(size=1.0)
obj = bpy.context.active_object
obj.name = name
subsurf = obj.modifiers.new(name="Subdivision", type='SUBSURF')
subsurf.subdivision_type = cfg.get("subdiv", "CATMULL_CLARK")
subsurf.levels = 2
subsurf.render_levels = 2
bpy.context.view_layer.objects.active = obj
bpy.ops.object.modifier_apply(modifier=subsurf.name)
bpy.ops.object.shade_smooth()
if "scale" in cfg: obj.scale = cfg["scale"]
obj.data.materials.append(mat_registry[cfg["mat"]])
for col in obj.users_collection: col.objects.unlink(obj)
target_col.objects.link(obj)
for item in hierarchy:
obj = bpy.data.objects.get(item["name"])
if item["parent"]:
parent_obj = bpy.data.objects.get(item["parent"])
if parent_obj:
obj.parent = parent_obj
obj.matrix_parent_inverse = parent_obj.matrix_world.inverted()
for item in hierarchy:
obj = bpy.data.objects.get(item["name"])
loc = mathutils.Vector(item["loc"])
rot = mathutils.Euler(item["rot"]).to_matrix().to_4x4()
scale_vec = mathutils.Vector(parts_config[item["name"]].get("scale", [1.0, 1.0, 1.0]))
scale = mathutils.Matrix.Scale(scale_vec[0], 4, (1, 0, 0)) @ \
mathutils.Matrix.Scale(scale_vec[1], 4, (0, 1, 0)) @ \
mathutils.Matrix.Scale(scale_vec[2], 4, (0, 0, 1))
obj.matrix_world = mathutils.Matrix.Translation(loc) @ rot @ scale
create_bird_model()
Comments
Post a Comment