import bpy, bmesh, math
def mat(name, c):
m = bpy.data.materials.new(name)
m.diffuse_color = (*c, 1)
m.use_nodes = True
m.node_tree.nodes["Principled BSDF"].inputs["Base Color"].default_value = (*c, 1)
return m
Blue = mat("Blue", (0.35, 0.7, 0.95))
Glass = mat("Glass", (0.9, 0.95, 1.0))
Black = mat("Black", (0.05, 0.06, 0.07))
Gray = mat("Gray", (0.5, 0.5, 0.5))
LGray = mat("LightGray", (0.78, 0.78, 0.78))
Beige = mat("Beige", (0.95, 0.85, 0.65))
def prism(name, m, poly, y0, y1):
n = len(poly)
v = [(x, y0, z) for x, z in poly] + [(x, y1, z) for x, z in poly]
f = [list(range(n)), list(range(2*n-1, n-1, -1))]
f += [[i, n+i, n+(i+1) % n, (i+1) % n] for i in range(n)]
me = bpy.data.meshes.new(name)
me.from_pydata(v, [], f)
me.update()
bm = bmesh.new(); bm.from_mesh(me)
bmesh.ops.recalc_face_normals(bm, faces=bm.faces)
bm.to_mesh(me); bm.free()
me.materials.append(m)
o = bpy.data.objects.new(name, me)
bpy.context.collection.objects.link(o)
def box(name, m, x0, x1, z0, z1, y0, y1):
prism(name, m, [(x0, z0), (x1, z0), (x1, z1), (x0, z1)], y0, y1)
def circle(r, cx, cz, n=32):
return [(cx + r*math.cos(2*math.pi*k/n), cz + r*math.sin(2*math.pi*k/n)) for k in range(n)]
# кузов и кабина
box("Body", Blue, -2, 2, 0.5, 1.2, -0.9, 0.9)
prism("Cabin", Blue, [(-1.2, 1.2), (1.3, 1.2), (0.8, 1.9), (-0.7, 1.9)], -0.85, 0.85)
# окна
for s, (a, b) in (("L", (-0.87, -0.84)), ("R", (0.84, 0.87))):
prism("WinA_"+s, Glass, [(-1.04, 1.28), (-0.03, 1.28), (-0.03, 1.8), (-0.69, 1.8)], a, b)
prism("WinB_"+s, Glass, [(0.08, 1.28), (1.16, 1.28), (0.79, 1.8), (0.08, 1.8)], a, b)
# колёса
for sx in (-1.25, 1.25):
for sy in (-0.8, 0.8):
prism("Tire", Black, circle(0.5, sx, 0.5), sy-0.2, sy+0.2)
prism("Hub", Gray, circle(0.28, sx, 0.5), sy-0.22, sy+0.22)
# бамперы и фары
box("BumperBack", LGray, -2.25, -1.95, 0.4, 0.95, -0.8, 0.8)
box("BumperFront", LGray, 1.95, 2.25, 0.4, 0.95, -0.8, 0.8)
for y0, y1 in ((-0.8, -0.5), (0.5, 0.8)):
box("LightBack", Beige, -2.1, -1.95, 1.0, 1.2, y0, y1)
box("LightFront", Beige, 1.95, 2.1, 1.0, 1.2, y0, y1)