mcp__blender__execute_blender_code
{
"code": "\nimport bpy, bmesh\n\nfor nm in (\"CarBody\", \"Greenhouse\"):\n if nm in bpy.data.objects:\n bpy.data.objects.remove(bpy.data.objects[nm], do_unlink=True)\n\ndef build_loft(name, rings, crease_idx, mat_name, subsurf=2):\n me = bpy.data.meshes.new(name)\n bm = bmesh.new()\n cl = bm.edges.layers.float.new('crease_edge') if hasattr(bm.edges.layers, 'float') else None\n try:\n crease = bm.edges.layers.crease.verify()\n except AttributeError:\n crease = bm.edges.layers.float.new('crease_edge')\n ring_verts = [[bm.verts.new(co) for co in ring] for ring in rings]\n n = len(rings[0])\n for a, b in zip(ring_verts[:-1], ring_verts[1:]):\n for i in range(n):\n j = (i+1) % n\n bm.faces.new((a[i], a[j], b[j], b[i]))\n bm.faces.new(reversed(ring_verts[0]))\n bm.faces.new(ring_verts[-1])\n # crease longitudinal edges at given ring indices\n for e in bm.edges:\n v1, v2 = e.verts\n for ridx in range(len(ring_verts)-1):\n for i in crease_idx:\n if (v1 == ring_verts[ridx][i] and v2 == ring_verts[ridx+1][i]):\n e[crease] = crease_idx[i]\n bm.normal_update()\n bm.to_mesh(me); bm.free()\n ob = bpy.data.objects.new(name, me)\n bpy.context.collection.objects.link(ob)\n ob.data.materials.append(bpy.data.materials[mat_name])\n for p in me.polygons: p.use_smooth = True\n if subsurf:\n s = ob.modifiers.new(\"Subsurf\", 'SUBSURF'); s.levels = subsurf; s.render_levels = subsurf\n return ob\n\ndef body_ring(x, yo, zb, zt):\n pts = [\n (0.0, zb), # 0 bottom center\n (0.80*yo, zb), # 1 rocker\n (yo, zb + 0.55*(zt-zb)), # 2 side bulge\n (0.98*yo, zt), # 3 beltline crest (crease)\n (0.60*yo, zt+0.02), # 4 hood/deck\n (0.0, zt+0.04), # 5 center top\n ]\n full = pts + [(-y, z) for (y, z) in reversed(pts[1:-1])]\n return [(x, y, z) for (y, z) in full]\n\nstations = [\n ( 2.38, 0.80, 1.10, 1.38),\n ( 2.30, 0.86, 1.04, 1.44),\n ( 2.00, 0.90, 1.00, 1.50),\n ( 1.75, 0.94, 0.99, 1.54),\n ( 1.45, 0.96, 0.99, 1.56), # front wheel\n ( 1.10, 0.94, 0.99, 1.55),\n ( 0.55, 0.91, 1.01, 1.57), # cowl\n ( 0.00, 0.90, 1.01, 1.55),\n (-0.60, 0.93, 1.01, 1.58),\n (-1.00, 0.97, 1.00, 1.64), # rear haunch\n (-1.35, 0.98, 1.00, 1.66), # rear wheel\n (-1.75, 0.94, 1.04, 1.64),\n (-2.15, 0.85, 1.12, 1.62),\n (-2.22, 0.83, 1.14, 1.61),\n]\n# crease map: ring index -> crease value ; ring has 10 pts: idx3 & mirrored idx7 = beltline, idx1 & idx9 = rocker\ncrease_idx = {3: 1.0, 7: 1.0, 1: 0.7, 9: 0.7}\nbody = build_loft(\"CarBody\", [body_ring(*s) for s in stations], crease_idx, \"BodyYellow\")\n\n# wheel arch cutters again on new body\nimport math\nfor name, wx in ((\"ArchF2\", 1.45), (\"ArchR2\", -1.35)):\n if name not in bpy.data.objects:\n bpy.ops.mesh.primitive_cylinder_add(vertices=48, radius=0.68, depth=2.6,\n location=(wx, 0, 0.78), rotation=(math.pi/2, 0, 0))\n cut = bpy.context.active_object; cut.name = name\n cut.display_type = 'WIRE'; cut.hide_render = True\n m = body.modifiers.new(name, 'BOOLEAN'); m.object = bpy.data.objects[name]; m.operation = 'DIFFERENCE'\n# remove old cutters\nfor nm in (\"ArchF\", \"ArchR\"):\n if nm in bpy.data.objects: bpy.data.objects.remove(bpy.data.objects[nm], do_unlink=True)\n\ndef cab_ring(x, yc, zt):\n zb = 1.48\n pts = [(yc, zb), (0.86*yc, zt), (0.0, zt+0.03), (-0.86*yc, zt), (-yc, zb), (0.0, zb-0.05)]\n return [(x, y, z) for (y, z) in pts]\n\ncab_st = [\n ( 0.60, 0.76, 1.50),\n ( 0.50, 0.75, 1.54), # windshield base\n (-0.10, 0.66, 2.10), # roof front\n (-0.50, 0.66, 2.09), # roof rear\n (-1.30, 0.76, 1.70), # fastback\n (-1.70, 0.82, 1.58),\n]\ncab = build_loft(\"Greenhouse\", [cab_ring(*s) for s in cab_st], {0: 1.0, 1: 1.0, 3: 1.0, 4: 1.0}, \"BodyYellow\", subsurf=1)\nb = cab.modifiers.new(\"Bevel\", 'BEVEL'); b.width = 0.02; b.segments = 2\nprint(\"shells rebuilt\")\n",
"user_prompt": "Rebuild crisper body and faceted greenhouse"
}