import bpy
import bmesh
import math
def create_macaw_material(name, color, roughness=0.5, use_feather_pattern=False):
mat = bpy.data.materials.new(name=name)
mat.use_nodes = True
nodes = mat.node_tree.nodes
links = mat.node_tree.links
nodes.clear()
node_output = nodes.new('ShaderNodeOutputMaterial')
node_principled = nodes.new('ShaderNodeBsdfPrincipled')
node_principled.inputs['Base Color'].default_value = color
node_principled.inputs['Roughness'].default_value = roughness
links.new(node_principled.outputs['BSDF'], node_output.inputs['Surface'])
if use_feather_pattern:
tex_coord = nodes.new('ShaderNodeTexCoord')
mapping = nodes.new('ShaderNodeMapping')
voronoi = nodes.new('ShaderNodeTexVoronoi')
bump = nodes.new('ShaderNodeBump')
voronoi.voronoi_dimensions = '3D'
voronoi.feature = 'F1'
voronoi.inputs['Scale'].default_value = 15.0
bump.inputs['Strength'].default_value = 0.15
links.new(tex_coord.outputs['Object'], mapping.inputs['Vector'])
links.new(mapping.outputs['Vector'], voronoi.inputs['Vector'])
links.new(voronoi.outputs['Distance'], bump.inputs['Height'])
links.new(bump.outputs['Normal'], node_principled.inputs['Normal'])
return mat
def create_part(name, location, scale, material, type='SPHERE', rotation=(0,0,0)):
if type == 'SPHERE':
bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=location)
elif type == 'CYLINDER':
bpy.ops.mesh.primitive_cylinder_add(radius=1, depth=2, location=location)
elif type == 'CURVED_BEAK':
bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=location)
obj = bpy.context.active_object
bm = bmesh.new()
bm.from_mesh(obj.data)
for v in bm.verts:
if v.co.y > 0:
v.co.z -= (v.co.y ** 2) * 0.8
bm.to_mesh(obj.data)
bm.free()
obj = bpy.context.active_object
obj.name = name
obj.scale = scale
obj.rotation_euler = rotation
obj.data.materials.append(material)
bpy.ops.object.shade_smooth()
mod = obj.modifiers.new(name="Subdiv", type='SUBSURF')
mod.levels = 2
return obj
# --- Scene Setup ---
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
cobalt_blue = (0.0, 0.28, 0.67, 1.0)
pale_yellow = (0.95, 0.9, 0.4, 1.0)
beak_black = (0.02, 0.02, 0.02, 1.0)
leg_gray = (0.12, 0.12, 0.12, 1.0)
# --- Materials ---
mat_plumage = create_macaw_material("Mat_Plumage", cobalt_blue, use_feather_pattern=True)
mat_skin = create_macaw_material("Mat_YellowSkin", pale_yellow)
mat_beak = create_macaw_material("Mat_Beak", beak_black, roughness=0.1)
mat_leg = create_macaw_material("Mat_Leg", leg_gray, roughness=0.9)
mat_pupil = create_macaw_material("Mat_Pupil", (0, 0, 0, 1), roughness=0.1)
rot_30_rad = math.radians(-30)
# --- Build the Macaw ---
create_part("Body", (0, -0.1, 0.2), (1, 0.8, 1.2), mat_plumage, rotation=(rot_30_rad, 0, 0))
create_part("Neck", (0, 0.15, 1.25), (0.65, 0.6, 0.45), mat_plumage, type='SPHERE', rotation=(rot_30_rad, 0, 0))
create_part("Head", (0, 0.25, 1.45), (0.7, 0.7, 0.7), mat_plumage)
create_part("Upper_Beak", (0, 0.75, 1.55), (0.35, 0.6, 0.5), mat_beak, type='CURVED_BEAK')
create_part("Lower_Beak", (0, 0.55, 1.2), (0.25, 0.3, 0.2), mat_beak, rotation=(0.5, 0, 0))
create_part("Mandible_Patch_L", (0.35, 0.6, 1.35), (0.1, 0.15, 0.2), mat_skin, rotation=(0, 0.3, 0))
create_part("Mandible_Patch_R", (-0.35, 0.6, 1.35), (0.1, 0.15, 0.2), mat_skin, rotation=(0, -0.3, 0))
ring_loc_y = 0.62657
ring_loc_z = 1.55
create_part("Left_Eye_Ring", (0.5, ring_loc_y, ring_loc_z), (0.15, 0.1, 0.15), mat_skin,
rotation=(math.radians(-25), math.radians(-153.35), math.radians(-45)))
create_part("Right_Eye_Ring", (-0.5, ring_loc_y, ring_loc_z), (0.15, 0.1, 0.15), mat_skin,
rotation=(math.radians(-25), math.radians(153.35), math.radians(45)))
pupil_scale = (0.105, 0.075, 0.105)
pupil_rot_z = math.radians(-45)
pupil_loc_y = 0.68657
pupil_loc_z = 1.5437
create_part("Left_Pupil", (0.53, pupil_loc_y, pupil_loc_z), pupil_scale, mat_pupil, rotation=(0, 0, pupil_rot_z))
create_part("Right_Pupil", (-0.53, pupil_loc_y, pupil_loc_z), pupil_scale, mat_pupil, rotation=(0, 0, -pupil_rot_z))
create_part("Leg_L", (0.35, -0.1, -0.8), (0.22, 0.22, 0.45), mat_leg, type='CYLINDER')
create_part("Leg_R", (-0.35, -0.1, -0.8), (0.22, 0.22, 0.45), mat_leg, type='CYLINDER')
create_part("Toe_L_F", (0.35, 0.15, -1.3), (0.15, 0.3, 0.2), mat_leg, type='CYLINDER', rotation=(math.radians(80.214), 0, 0))
create_part("Toe_L_B", (0.35, -0.25, -1.3), (0.1, 0.25, 0.1), mat_leg, type='CYLINDER', rotation=(math.radians(97.403), 0, 0))
create_part("Toe_R_F", (-0.35, 0.15, -1.3), (0.15, 0.3, 0.2), mat_leg, type='CYLINDER', rotation=(math.radians(80.214), 0, 0))
create_part("Toe_R_B", (-0.35, -0.25, -1.3), (0.1, 0.25, 0.1), mat_leg, type='CYLINDER', rotation=(math.radians(97.403), 0, 0))
create_part("Left_Wing", (0.85, -0.4, -0.2), (0.2, 0.7, 1.3), mat_plumage, rotation=(rot_30_rad, 0, 0))
create_part("Right_Wing", (-0.85, -0.4, -0.2), (0.2, 0.7, 1.3), mat_plumage, rotation=(rot_30_rad, 0, 0))
create_part("Tail", (0, -1.0, -0.3), (0.4, 0.2, 1.8), mat_plumage, rotation=(math.radians(-45), 0, 0))
Comments
Post a Comment