Загрузка данных


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)