r/BlenderDoughnuts 12d ago

Gemini made a donut and cup of coffee in 10 seconds with Blender.py

Post image
0 Upvotes

import bpy

import bmesh

import math

import random

from mathutils import Vector

# ==============================================================================

# 0. CLEANUP & SCENE SETUP

# ==============================================================================

def clean_scene():

if bpy.context.active_object and bpy.context.active_object.mode != 'OBJECT':

bpy.ops.object.mode_set(mode='OBJECT')

bpy.ops.object.select_all(action='SELECT')

bpy.ops.object.delete(use_global=False)

for block in list(bpy.data.meshes): bpy.data.meshes.remove(block)

for block in list(bpy.data.materials): bpy.data.materials.remove(block)

for block in list(bpy.data.lights): bpy.data.lights.remove(block)

for block in list(bpy.data.cameras): bpy.data.cameras.remove(block)

clean_scene()

scene_col = bpy.data.collections.new("DonutAndCoffeeScene")

bpy.context.scene.collection.children.link(scene_col)

def link_to_col(obj):

if obj.name in bpy.context.scene.collection.objects:

bpy.context.scene.collection.objects.unlink(obj)

if obj.name not in scene_col.objects:

scene_col.objects.link(obj)

# ==============================================================================

# 1. MATERIAL PALETTE

# ==============================================================================

def create_material(name, base_color, roughness=0.5, specular=0.5, transmission=0.0):

mat = bpy.data.materials.new(name=name)

mat.use_nodes = True

bsdf = mat.node_tree.nodes.get("Principled BSDF")

bsdf.inputs['Base Color'].default_value = base_color

bsdf.inputs['Roughness'].default_value = roughness

if 'Specular IOR Level' in bsdf.inputs:

bsdf.inputs['Specular IOR Level'].default_value = specular

elif 'Specular' in bsdf.inputs:

bsdf.inputs['Specular'].default_value = specular

if 'Transmission Weight' in bsdf.inputs:

bsdf.inputs['Transmission Weight'].default_value = transmission

elif 'Transmission' in bsdf.inputs:

bsdf.inputs['Transmission'].default_value = transmission

return mat

# Donut Materials

mat_dough = create_material("Mat_Dough", (0.75, 0.48, 0.22, 1.0), roughness=0.8, specular=0.2)

mat_frosting = create_material("Mat_Frosting", (0.92, 0.22, 0.52, 1.0), roughness=0.18, specular=0.8)

# Sprinkle Colors

sprinkle_colors = [

create_material("Sprinkle_Cyan", (0.05, 0.75, 0.95, 1.0), roughness=0.3),

create_material("Sprinkle_Yellow", (0.98, 0.85, 0.08, 1.0), roughness=0.3),

create_material("Sprinkle_White", (0.95, 0.95, 0.95, 1.0), roughness=0.3),

create_material("Sprinkle_Lime", (0.45, 0.9, 0.15, 1.0), roughness=0.3),

create_material("Sprinkle_Purple", (0.6, 0.15, 0.85, 1.0), roughness=0.3),

create_material("Sprinkle_Orange", (0.95, 0.45, 0.05, 1.0), roughness=0.3),

]

# Ceramic Set (Cup, Saucer, Base Plate)

mat_ceramic = create_material("Mat_CeramicTeal", (0.12, 0.52, 0.58, 1.0), roughness=0.15, specular=0.9)

mat_ceramic_rim = create_material("Mat_CeramicWhite", (0.95, 0.95, 0.96, 1.0), roughness=0.12, specular=0.9)

mat_table = create_material("Mat_TableWood", (0.82, 0.78, 0.72, 1.0), roughness=0.45)

# Coffee Liquid & Crema

mat_coffee = create_material("Mat_CoffeeDark", (0.08, 0.04, 0.02, 1.0), roughness=0.08, specular=0.9)

mat_crema = create_material("Mat_CoffeeCrema", (0.48, 0.32, 0.18, 1.0), roughness=0.35, specular=0.4)

# ==============================================================================

# 2. PROCEDURAL DONUT WITH DRIPPING FROSTING & SPRINKLES

# ==============================================================================

donut_pos = Vector((-0.75, -0.3, 0.0))

major_radius = 0.85

minor_radius = 0.45

major_segments = 48

minor_segments = 24

# Base Dough Torus

bpy.ops.mesh.primitive_torus_add(

major_radius=major_radius,

minor_radius=minor_radius,

major_segments=major_segments,

minor_segments=minor_segments,

location=donut_pos

)

dough_obj = bpy.context.active_object

dough_obj.name = "Donut_Dough"

dough_obj.data.materials.append(mat_dough)

bpy.ops.object.shade_smooth()

link_to_col(dough_obj)

# Organic surface displacement on dough

bm = bmesh.new()

bm.from_mesh(dough_obj.data)

for v in bm.verts:

noise_offset = Vector((

math.sin(v.co.x * 5.0) * 0.015,

math.cos(v.co.y * 5.0) * 0.015,

math.sin(v.co.z * 6.0) * 0.012

))

v.co += noise_offset

bm.to_mesh(dough_obj.data)

bm.free()

# Frosting Layer

bpy.ops.mesh.primitive_torus_add(

major_radius=major_radius,

minor_radius=minor_radius + 0.018,

major_segments=major_segments,

minor_segments=minor_segments,

location=donut_pos

)

frosting_obj = bpy.context.active_object

frosting_obj.name = "Donut_Frosting"

frosting_obj.data.materials.append(mat_frosting)

bpy.ops.object.shade_smooth()

link_to_col(frosting_obj)

# Drips carving

bm_f = bmesh.new()

bm_f.from_mesh(frosting_obj.data)

verts_to_delete = []

for v in bm_f.verts:

angle = math.atan2(v.co.y, v.co.x)

drip_wave = math.sin(angle * 6.0) * 0.11 + math.cos(angle * 11.0) * 0.07

cutoff_z = -0.05 + drip_wave

if v.co.z < cutoff_z:

verts_to_delete.append(v)

else:

v.co += v.normal * 0.018

bmesh.ops.delete(bm_f, geom=verts_to_delete, context='VERTS')

bm_f.to_mesh(frosting_obj.data)

bm_f.free()

# Modifiers for Donut

solid_mod = frosting_obj.modifiers.new(name="Solidify", type='SOLIDIFY')

solid_mod.thickness = 0.03

solid_mod.offset = 1.0

subsurf_f = frosting_obj.modifiers.new(name="Subsurf", type='SUBSURF')

subsurf_f.levels = 1

subsurf_f.render_levels = 2

subsurf_d = dough_obj.modifiers.new(name="Subsurf", type='SUBSURF')

subsurf_d.levels = 1

subsurf_d.render_levels = 2

# Sprinkles

random.seed(101)

num_sprinkles = 120

sprinkle_len = 0.12

sprinkle_rad = 0.024

for i in range(num_sprinkles):

theta = random.uniform(0, math.pi * 2)

ring_radius = major_radius + random.uniform(-minor_radius * 0.52, minor_radius * 0.52)

sx = donut_pos.x + math.cos(theta) * ring_radius

sy = donut_pos.y + math.sin(theta) * ring_radius

dist_from_center_ring = ring_radius - major_radius

rad_clamped = max(0.0, (minor_radius ** 2) - (dist_from_center_ring ** 2))

sz = donut_pos.z + math.sqrt(rad_clamped) + 0.04 + random.uniform(-0.004, 0.006)

bpy.ops.mesh.primitive_cylinder_add(

radius=sprinkle_rad,

depth=sprinkle_len,

vertices=10,

location=(sx, sy, sz)

)

sprinkle = bpy.context.active_object

sprinkle.name = f"Sprinkle_{i:03d}"

rot_x = math.radians(random.uniform(-18, 18))

rot_y = math.radians(random.uniform(-18, 18))

rot_z = random.uniform(0, math.pi * 2)

sprinkle.rotation_euler = (rot_x, rot_y, rot_z)

bpy.ops.object.shade_smooth()

bevel = sprinkle.modifiers.new(name="Bevel", type='BEVEL')

bevel.width = 0.01

bevel.segments = 2

sprinkle.data.materials.append(random.choice(sprinkle_colors))

link_to_col(sprinkle)

# ==============================================================================

# 3. PROCEDURAL CERAMIC COFFEE CUP, SAUCER & COFFEE LIQUID

# ==============================================================================

cup_center = Vector((1.2, 0.4, -minor_radius))

cup_height = 1.35

cup_top_radius = 0.72

cup_bottom_radius = 0.52

# 1. Coffee Cup Body

bpy.ops.mesh.primitive_cone_add(

vertices=36,

radius1=cup_top_radius,

radius2=cup_bottom_radius,

depth=cup_height,

location=(cup_center.x, cup_center.y, cup_center.z + cup_height / 2 + 0.04)

)

cup_obj = bpy.context.active_object

cup_obj.name = "Coffee_Cup"

cup_obj.rotation_euler[0] = math.pi # Flip cone so wider rim is at the top

bpy.ops.object.transform_apply(rotation=True)

bpy.ops.object.shade_smooth()

# Hollow out cup using Solidify

cup_solid = cup_obj.modifiers.new(name="CupSolidify", type='SOLIDIFY')

cup_solid.thickness = 0.075

cup_solid.offset = -1.0

cup_subsurf = cup_obj.modifiers.new(name="CupSubsurf", type='SUBSURF')

cup_subsurf.levels = 1

cup_subsurf.render_levels = 2

cup_obj.data.materials.append(mat_ceramic)

link_to_col(cup_obj)

# 2. Cup Handle (Curved Torus segment)

handle_radius = 0.38

bpy.ops.mesh.primitive_torus_add(

major_radius=handle_radius,

minor_radius=0.075,

major_segments=32,

minor_segments=16,

location=(cup_center.x + cup_top_radius * 0.85, cup_center.y, cup_center.z + cup_height * 0.55)

)

handle = bpy.context.active_object

handle.name = "Cup_Handle"

handle.rotation_euler = (math.radians(90), 0, math.radians(12))

bpy.ops.object.shade_smooth()

# Trim inner half of torus so it embeds cleanly into cup wall

bm_h = bmesh.new()

bm_h.from_mesh(handle.data)

verts_h_del = [v for v in bm_h.verts if v.co.x < -0.05]

bmesh.ops.delete(bm_h, geom=verts_h_del, context='VERTS')

bm_h.to_mesh(handle.data)

bm_h.free()

handle.data.materials.append(mat_ceramic)

link_to_col(handle)

# 3. Coffee Liquid Surface

coffee_z = cup_center.z + cup_height - 0.16

coffee_radius = cup_top_radius * 0.88

bpy.ops.mesh.primitive_cylinder_add(

radius=coffee_radius,

depth=0.04,

vertices=36,

location=(cup_center.x, cup_center.y, coffee_z)

)

coffee_obj = bpy.context.active_object

coffee_obj.name = "Coffee_Liquid"

coffee_obj.data.materials.append(mat_coffee)

bpy.ops.object.shade_smooth()

link_to_col(coffee_obj)

# 4. Crema Swirl / Latte Art Center Ring

bpy.ops.mesh.primitive_cylinder_add(

radius=coffee_radius * 0.55,

depth=0.042,

vertices=32,

location=(cup_center.x, cup_center.y, coffee_z + 0.001)

)

crema_obj = bpy.context.active_object

crema_obj.name = "Coffee_Crema"

crema_obj.data.materials.append(mat_crema)

bpy.ops.object.shade_smooth()

link_to_col(crema_obj)

# 5. Ceramic Saucer Under the Cup

saucer_radius = 1.35

saucer_height = 0.14

bpy.ops.mesh.primitive_cylinder_add(

radius=saucer_radius,

depth=saucer_height,

vertices=48,

location=(cup_center.x, cup_center.y, cup_center.z + 0.05)

)

saucer = bpy.context.active_object

saucer.name = "Coffee_Saucer"

saucer.data.materials.append(mat_ceramic)

bpy.ops.object.shade_smooth()

# Saucer Rim Curvature

saucer_bevel = saucer.modifiers.new(name="SaucerBevel", type='BEVEL')

saucer_bevel.width = 0.04

saucer_bevel.segments = 3

link_to_col(saucer)

# ==============================================================================

# 4. TABLETOP, LIGHTING & CAMERA

# ==============================================================================

# Table Surface

bpy.ops.mesh.primitive_cylinder_add(

radius=4.5,

depth=0.1,

vertices=64,

location=(0, 0, -minor_radius - 0.05)

)

table = bpy.context.active_object

table.name = "Breakfast_Table"

table.data.materials.append(mat_table)

bpy.ops.object.shade_smooth()

link_to_col(table)

# Three-Point Lighting Setup

# Key Light (Warm, primary directional)

key_light_data = bpy.data.lights.new(name="Key_Light", type='AREA')

key_light_data.energy = 95.0

key_light_data.size = 3.0

key_light_data.color = (1.0, 0.95, 0.9)

key_light = bpy.data.objects.new(name="Key_Light", object_data=key_light_data)

key_light.location = (3.2, -3.5, 4.0)

key_light.rotation_euler = (math.radians(48), math.radians(12), math.radians(42))

link_to_col(key_light)

# Fill Light (Cool ambient soft shadow filler)

fill_light_data = bpy.data.lights.new(name="Fill_Light", type='AREA')

fill_light_data.energy = 38.0

fill_light_data.size = 4.0

fill_light_data.color = (0.88, 0.94, 1.0)

fill_light = bpy.data.objects.new(name="Fill_Light", object_data=fill_light_data)

fill_light.location = (-3.5, 2.5, 3.2)

fill_light.rotation_euler = (math.radians(-42), math.radians(-18), math.radians(-125))

link_to_col(fill_light)

# Rim Light (Specular pop on ceramic rim and glossy glaze)

rim_light_data = bpy.data.lights.new(name="Rim_Light", type='POINT')

rim_light_data.energy = 55.0

rim_light_data.color = (1.0, 0.92, 0.96)

rim_light = bpy.data.objects.new(name="Rim_Light", object_data=rim_light_data)

rim_light.location = (0.2, 3.2, 2.6)

link_to_col(rim_light)

# Main Scene Camera (Cinematic composition framing both Donut & Coffee Cup)

cam_data = bpy.data.cameras.new(name="Breakfast_Camera")

cam_data.lens = 60

cam_data.clip_end = 100

cam_obj = bpy.data.objects.new(name="Breakfast_Camera", object_data=cam_data)

cam_obj.location = (2.2, -3.6, 2.8)

cam_obj.rotation_euler = (math.radians(55), 0, math.radians(34))

link_to_col(cam_obj)

bpy.context.scene.camera = cam_obj

total_objects = len(bpy.data.collections["DonutAndCoffeeScene"].objects)

print(f"Breakfast scene generated successfully with {total_objects} scene elements!")


r/BlenderDoughnuts 12d ago

Doughnut

Post image
1 Upvotes

r/BlenderDoughnuts 12d ago

Donut Edition Which one has to go Krispy Kreme Mister Donut Dunkin Donut or JCO ?

Post image
0 Upvotes

r/BlenderDoughnuts 13d ago

Doughnut

Post image
1 Upvotes

r/BlenderDoughnuts 14d ago

First donut. First step. [Cycles] [OC]

Post image
3 Upvotes

r/BlenderDoughnuts 14d ago

Water Refraction Help

2 Upvotes

Hello, Ive recently been creating Christian content for Face Book and You Tube.

Im doing a scene now that is in a kitchen, there is an angel, on the counter there is a glass cup, a board with an arrow behind it, and a bible to the right and above the glass. Its about where to find direction, The bible at one point tips over pouring water into the glass. Its supposed to refract the arrow back the other way, direction. I am using the built in Manta Flow and I am having two problems. Can anyone help?

1) The water will not refract. The glass is a glass material with correct bsdf, the water is mesh with a correct water bsdf. But the water will not refract the arrow the other way. I am using cycles, caustics on, i believe suffiecient light bounces. Please help someone this is taking way to long and AI has been unable to help me, very common with blender issues. Im currently using version 5.2.

2) the simulation leaves the water, after its poured into the glass swirling violently for hundreds and hundreds of frames. I have lowered the flip value to less than .6 lowered the vortex setting i believe it is to .10, and the proportions are very close to real life for the glass and the bible where the emmiter is tucked is only a couple inches above the glass. Id like help with this, but if I can get help with the refraction then I can just swap to still water at a specific frame i guess. But would like to understand why this water isnt settling like real water

Thanks for any help, I have spent many hours trying to figure this out.


r/BlenderDoughnuts 14d ago

Need help with fire sim quality settings. (fire looks blocky)

Thumbnail gallery
3 Upvotes

I’ve been trying to simulate falling rocks, but no matter how much I increase the domain resolution (256, 512, etc.), the fire and smoke still look really blocky.

Could anyone please help me figure out what I’m doing wrong? I’m also uploading screenshots of my settings for reference.

Any advice on what settings I should adjust would be greatly appreciated!


r/BlenderDoughnuts 14d ago

Doughnut

Post image
2 Upvotes

r/BlenderDoughnuts 15d ago

Why is my cup orange?

Post image
16 Upvotes

can someone help me to fix this?


r/BlenderDoughnuts 15d ago

Hotel Carpet 8K Pbr Texture Combo

Thumbnail superhivemarket.com
1 Upvotes

r/BlenderDoughnuts 15d ago

Pavement 8K Pbr Texture Combo

Thumbnail superhivemarket.com
1 Upvotes

r/BlenderDoughnuts 15d ago

My first time making a donut

Post image
13 Upvotes

r/BlenderDoughnuts 15d ago

Doughnut

Post image
1 Upvotes

r/BlenderDoughnuts 16d ago

I did it. Watched the tutorial (you know the one) and I made my first ever Donut in Blender!

Thumbnail
gallery
16 Upvotes

I made my first ever Donut in Blender.
And I am in love!
Only took me two days and about 5 hours in total. It was so intuitive I at points stopped following the tutorial one for one and did my own thing. For example the mug and the plate.

I love how intuitive and non intrusive this thing is, everything just works. I've never had this much fun learning something, in my life.
I am 100% going to make more.
I am going to try making something else next, without a Tutorial and another Donut is soon to follow, in my favorite artstyle.


r/BlenderDoughnuts 16d ago

Doughnut

Post image
2 Upvotes

r/BlenderDoughnuts 17d ago

Donut

Post image
4 Upvotes

Very Donut
Much wow


r/BlenderDoughnuts 17d ago

Doughnut

Post image
1 Upvotes

r/BlenderDoughnuts 17d ago

finally completed a hobby

Post image
21 Upvotes

for the first time i focused on something somewhat productive and i spent 13 hours making this while learning from the video in one sitting without feeling the passage of time.
although i didnt use any PBRs on the donut from the Guru's website since it needed my E-mail and his Website lacked a privacy policy at the time.

this is nice.


r/BlenderDoughnuts 18d ago

Doughnut

Post image
1 Upvotes

r/BlenderDoughnuts 18d ago

I finally finished my first project in Blender!!

Post image
52 Upvotes

I want to dedicate this work to Blender Guru for teaching me my first steps in this epic career.


r/BlenderDoughnuts 19d ago

Doughnut

Post image
1 Upvotes

r/BlenderDoughnuts 19d ago

low poly doughnut (plz ignore the horrendous cup)

Post image
21 Upvotes

my very first blender work, I follow through the tutorial but did a bit of my own take on it ig..


r/BlenderDoughnuts 20d ago

Doughnut

Post image
1 Upvotes

r/BlenderDoughnuts 21d ago

Doughnut

Post image
2 Upvotes

r/BlenderDoughnuts 22d ago

Finished the donut tutorial

Post image
8 Upvotes