Adding Objects¶
In [87]:
Copied!
import bpy
bpy.app.version_string # current blender version
import bpy
bpy.app.version_string # current blender version
Out[87]:
'4.4.3'
In [88]:
Copied!
import runpy # Helper functions just for the docs
module = runpy.run_path("/Users/jan-hendrik/projects/bpy-gallery/docs/render_utils.py")
globals().update(module)
# Set render resolution
bpy.context.scene.render.resolution_x = 500
bpy.context.scene.render.resolution_y = 200
import runpy # Helper functions just for the docs
module = runpy.run_path("/Users/jan-hendrik/projects/bpy-gallery/docs/render_utils.py")
globals().update(module)
# Set render resolution
bpy.context.scene.render.resolution_x = 500
bpy.context.scene.render.resolution_y = 200
In [89]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_monkey_add(size=2.5, location=(0, 0, 0))
render_result()
fresh_scene()
bpy.ops.mesh.primitive_monkey_add(size=2.5, location=(0, 0, 0))
render_result()
In [90]:
Copied!
fresh_scene()
#bpy.ops.object.gpencil_add(location=(0, 0, 0), type='STROKE') # Blender 4.2
bpy.ops.object.grease_pencil_add(location=(0, 0, 0), type="STROKE") # Blender 4.3.1
gpencil_object = bpy.context.active_object
gpencil_object.scale = (3, 3, 3)
render_result()
fresh_scene()
#bpy.ops.object.gpencil_add(location=(0, 0, 0), type='STROKE') # Blender 4.2
bpy.ops.object.grease_pencil_add(location=(0, 0, 0), type="STROKE") # Blender 4.3.1
gpencil_object = bpy.context.active_object
gpencil_object.scale = (3, 3, 3)
render_result()
In [91]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_uv_sphere_add(radius=1.5, location=(0, 0, 0))
render_result()
fresh_scene()
bpy.ops.mesh.primitive_uv_sphere_add(radius=1.5, location=(0, 0, 0))
render_result()
In [92]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_cone_add(radius1=1, depth=2, location=(0, 0, 0))
render_result()
fresh_scene()
bpy.ops.mesh.primitive_cone_add(radius1=1, depth=2, location=(0, 0, 0))
render_result()
In [93]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_cylinder_add(radius=1, depth=2, location=(0, 0, 0))
render_result()
fresh_scene()
bpy.ops.mesh.primitive_cylinder_add(radius=1, depth=2, location=(0, 0, 0))
render_result()
In [94]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_torus_add(major_radius=2, minor_radius=0.3, location=(0,0, 0))
render_result()
fresh_scene()
bpy.ops.mesh.primitive_torus_add(major_radius=2, minor_radius=0.3, location=(0,0, 0))
render_result()
In [95]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_ico_sphere_add(radius=1, location=(0, 0, 0))
render_result()
fresh_scene()
bpy.ops.mesh.primitive_ico_sphere_add(radius=1, location=(0, 0, 0))
render_result()
In [96]:
Copied!
fresh_scene()
bpy.ops.object.text_add(location=(-4, 0, 0))
text = bpy.context.active_object
text.data.body = "Hello 😄"
text.scale = (2, 2, 2)
render_result()
fresh_scene()
bpy.ops.object.text_add(location=(-4, 0, 0))
text = bpy.context.active_object
text.data.body = "Hello 😄"
text.scale = (2, 2, 2)
render_result()
In [97]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_plane_add(size=3, location=(0, 0, 0))
render_result()
fresh_scene()
bpy.ops.mesh.primitive_plane_add(size=3, location=(0, 0, 0))
render_result()
In [98]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_circle_add(radius=2.5, location=(0, 0, 0), fill_type='NGON')
render_result()
fresh_scene()
bpy.ops.mesh.primitive_circle_add(radius=2.5, location=(0, 0, 0), fill_type='NGON')
render_result()
In [99]:
Copied!
fresh_scene()
bpy.ops.object.empty_add(type='PLAIN_AXES', location=(4, 0, 0)) # (This is not shown in the image, but it is there)
render_result()
fresh_scene()
bpy.ops.object.empty_add(type='PLAIN_AXES', location=(4, 0, 0)) # (This is not shown in the image, but it is there)
render_result()
In [100]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
render_result()
fresh_scene()
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
render_result()
In [101]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
light = bpy.data.objects.new("Light", bpy.data.lights.new("Light", 'POINT'))
light.location = (3, 0, 2)
light.data.energy = 8000
bpy.context.collection.objects.link(light)
render_result()
fresh_scene()
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
light = bpy.data.objects.new("Light", bpy.data.lights.new("Light", 'POINT'))
light.location = (3, 0, 2)
light.data.energy = 8000
bpy.context.collection.objects.link(light)
render_result()
Applying Modifiers¶
In [102]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
bevel_modifier = cube.modifiers.new(name="Bevel", type='BEVEL')
bevel_modifier.width = 0.4 # Adjust the bevel width
bevel_modifier.segments = 5 # Number of segments for a smoother bevel
# Optionally apply the modifier if needed (not necessary for visualization)
# bpy.ops.object.modifier_apply(modifier="Bevel")
render_result()
fresh_scene()
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
bevel_modifier = cube.modifiers.new(name="Bevel", type='BEVEL')
bevel_modifier.width = 0.4 # Adjust the bevel width
bevel_modifier.segments = 5 # Number of segments for a smoother bevel
# Optionally apply the modifier if needed (not necessary for visualization)
# bpy.ops.object.modifier_apply(modifier="Bevel")
render_result()
In [103]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
# Create the subdivision surface modifier and change it to 'SIMPLE'
subsurf_modifier = cube.modifiers.new(name="Subdivision", type='SUBSURF')
subsurf_modifier.subdivision_type = 'SIMPLE' # Change to 'SIMPLE' instead of 'CATMULL_CLARK'
subsurf_modifier.levels = 4 # Viewport subdivision level
subsurf_modifier.render_levels = 4 # Render subdivision level
displace_modifier = cube.modifiers.new(name="Displace", type='DISPLACE')
displace_modifier.strength = 0.5 # Adjust the displacement strength
texture = bpy.data.textures.new("DisplaceTexture", type='CLOUDS')
texture.noise_scale = 1 # Reduce the noise scale to make it more detailed
displace_modifier.texture = texture # Assign the texture to the modifier
render_result()
fresh_scene()
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
# Create the subdivision surface modifier and change it to 'SIMPLE'
subsurf_modifier = cube.modifiers.new(name="Subdivision", type='SUBSURF')
subsurf_modifier.subdivision_type = 'SIMPLE' # Change to 'SIMPLE' instead of 'CATMULL_CLARK'
subsurf_modifier.levels = 4 # Viewport subdivision level
subsurf_modifier.render_levels = 4 # Render subdivision level
displace_modifier = cube.modifiers.new(name="Displace", type='DISPLACE')
displace_modifier.strength = 0.5 # Adjust the displacement strength
texture = bpy.data.textures.new("DisplaceTexture", type='CLOUDS')
texture.noise_scale = 1 # Reduce the noise scale to make it more detailed
displace_modifier.texture = texture # Assign the texture to the modifier
render_result()
Settings¶
In [104]:
Copied!
# current blender version
bpy.app.version_string
# current blender version
bpy.app.version_string
Out[104]:
'4.4.3'
In [105]:
Copied!
# current blender version
bpy.context.scene.render.engine
# current blender version
bpy.context.scene.render.engine
Out[105]:
'BLENDER_EEVEE_NEXT'
In [106]:
Copied!
bpy.context.scene.render.resolution_x, bpy.context.scene.render.resolution_y
bpy.context.scene.render.resolution_x, bpy.context.scene.render.resolution_y
Out[106]:
(500, 200)
In [107]:
Copied!
bpy.context.scene.name
bpy.context.scene.name
Out[107]:
'Scene'
In [108]:
Copied!
bpy.context.active_object.name
bpy.context.active_object.name
Out[108]:
'Cube'
In [109]:
Copied!
bpy.context.active_object.location
bpy.context.active_object.location
Out[109]:
Vector((0.0, 0.0, 0.0))
In [110]:
Copied!
bpy.context.collection.objects.keys()
bpy.context.collection.objects.keys()
Out[110]:
['Camera', 'Sun', 'Cube']
In [111]:
Copied!
bpy.context.collection.objects.values()
bpy.context.collection.objects.values()
Out[111]:
[bpy.data.objects['Camera'], bpy.data.objects['Sun'], bpy.data.objects['Cube']]
Using colors¶
In [112]:
Copied!
fresh_scene()
# Add a cube
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
# Create and assign a green material to the cube without using nodes
mat = bpy.data.materials.new(name="GreenMaterial")
mat.diffuse_color = (0, 1, 0, 1) # Green color (R, G, B, A)
# Apply material to the cube
cube.data.materials.clear() # Clear any existing materials
cube.data.materials.append(mat)
render_result()
fresh_scene()
# Add a cube
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
# Create and assign a green material to the cube without using nodes
mat = bpy.data.materials.new(name="GreenMaterial")
mat.diffuse_color = (0, 1, 0, 1) # Green color (R, G, B, A)
# Apply material to the cube
cube.data.materials.clear() # Clear any existing materials
cube.data.materials.append(mat)
render_result()
In [113]:
Copied!
fresh_scene()
# colors with nodes
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
# Create and assign a blue material to the cube
mat = bpy.data.materials.new(name="BlueMaterial")
mat.use_nodes = True
bsdf = mat.node_tree.nodes.get('Principled BSDF')
bsdf.inputs['Base Color'].default_value = (0, 0, 1, 1) # Blue color (R, G, B, A)
# Apply material to the cube
cube.data.materials.clear() # Clear any existing materials
cube.data.materials.append(mat)
render_result()
fresh_scene()
# colors with nodes
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
# Create and assign a blue material to the cube
mat = bpy.data.materials.new(name="BlueMaterial")
mat.use_nodes = True
bsdf = mat.node_tree.nodes.get('Principled BSDF')
bsdf.inputs['Base Color'].default_value = (0, 0, 1, 1) # Blue color (R, G, B, A)
# Apply material to the cube
cube.data.materials.clear() # Clear any existing materials
cube.data.materials.append(mat)
render_result()
In [114]:
Copied!
fresh_scene()
bpy.ops.mesh.primitive_plane_add(size=6, location=(0, 0, 0))
# plane = bpy.context.object # only blender 4.1
plane = bpy.context.active_object #blender 4.3
material = bpy.data.materials.new(name="ImageMaterial")
material.use_nodes = True
bsdf = material.node_tree.nodes["Principled BSDF"]
tex_image = material.node_tree.nodes.new('ShaderNodeTexImage')
path = Path.home() / "projects/bpy-gallery/docs/cute_dog.jpg"
tex_image.image = bpy.data.images.load(str(path))
material.node_tree.links.new(bsdf.inputs['Base Color'], tex_image.outputs['Color'])
plane.data.materials.append(material)
render_result()
fresh_scene()
bpy.ops.mesh.primitive_plane_add(size=6, location=(0, 0, 0))
# plane = bpy.context.object # only blender 4.1
plane = bpy.context.active_object #blender 4.3
material = bpy.data.materials.new(name="ImageMaterial")
material.use_nodes = True
bsdf = material.node_tree.nodes["Principled BSDF"]
tex_image = material.node_tree.nodes.new('ShaderNodeTexImage')
path = Path.home() / "projects/bpy-gallery/docs/cute_dog.jpg"
tex_image.image = bpy.data.images.load(str(path))
material.node_tree.links.new(bsdf.inputs['Base Color'], tex_image.outputs['Color'])
plane.data.materials.append(material)
render_result()
Setting Up Shaders¶
Here's an example to generate the following shader tree
It's quite a lot of code, so I would recommend to better set up nodes in the GUI.
In [115]:
Copied!
fresh_scene()
# Working with shader nodes is possible, but get's quite involved quite quickly
# Add a cube
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
# Create a new material for the cube
material = bpy.data.materials.new(name="YellowToOrangeGradient")
material.use_nodes = True
nodes = material.node_tree.nodes
# Clear default nodes
for node in nodes:
nodes.remove(node)
# Add a Gradient Texture
gradient = nodes.new(type="ShaderNodeTexGradient")
gradient.gradient_type = "LINEAR"
gradient.location = (0, 0)
# Add a Color Ramp to control the gradient colors
ramp = nodes.new(type="ShaderNodeValToRGB")
ramp.color_ramp.interpolation = "LINEAR"
ramp.location = (300, 0)
ramp.color_ramp.elements[0].color = (1, 1, 0, 1) # Yellow (R, G, B, A)
ramp.color_ramp.elements[1].color = (1, 0.3, 0, 1) # Orange (R, G, B, A)
# Add the Principled BSDF shader
bsdf = nodes.new(type="ShaderNodeBsdfPrincipled")
bsdf.location = (600, 0)
# Create the output node
output = nodes.new(type="ShaderNodeOutputMaterial")
output.location = (900, 0)
# Link the nodes together
links = material.node_tree.links
links.new(gradient.outputs["Color"], ramp.inputs[0])
links.new(ramp.outputs["Color"], bsdf.inputs["Base Color"])
links.new(bsdf.outputs["BSDF"], output.inputs["Surface"])
# Apply the material to the cube
cube.data.materials.clear() # Clear any existing materials
cube.data.materials.append(material)
render_result()
fresh_scene()
# Working with shader nodes is possible, but get's quite involved quite quickly
# Add a cube
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
# Create a new material for the cube
material = bpy.data.materials.new(name="YellowToOrangeGradient")
material.use_nodes = True
nodes = material.node_tree.nodes
# Clear default nodes
for node in nodes:
nodes.remove(node)
# Add a Gradient Texture
gradient = nodes.new(type="ShaderNodeTexGradient")
gradient.gradient_type = "LINEAR"
gradient.location = (0, 0)
# Add a Color Ramp to control the gradient colors
ramp = nodes.new(type="ShaderNodeValToRGB")
ramp.color_ramp.interpolation = "LINEAR"
ramp.location = (300, 0)
ramp.color_ramp.elements[0].color = (1, 1, 0, 1) # Yellow (R, G, B, A)
ramp.color_ramp.elements[1].color = (1, 0.3, 0, 1) # Orange (R, G, B, A)
# Add the Principled BSDF shader
bsdf = nodes.new(type="ShaderNodeBsdfPrincipled")
bsdf.location = (600, 0)
# Create the output node
output = nodes.new(type="ShaderNodeOutputMaterial")
output.location = (900, 0)
# Link the nodes together
links = material.node_tree.links
links.new(gradient.outputs["Color"], ramp.inputs[0])
links.new(ramp.outputs["Color"], bsdf.inputs["Base Color"])
links.new(bsdf.outputs["BSDF"], output.inputs["Surface"])
# Apply the material to the cube
cube.data.materials.clear() # Clear any existing materials
cube.data.materials.append(material)
render_result()
Setting up Geometry Nodes¶
In [116]:
Copied!
fresh_scene()
# Setting up geonodes is possible, but get's quite involved quite quickly
# Add a cube
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
# Setup geometry nodes
geo_nodes = cube.modifiers.new(name="GeometryNodes", type="NODES")
node_group = bpy.data.node_groups.new("GeometryNodes", "GeometryNodeTree")
geo_nodes.node_group = node_group
# Create input/output and transformation nodes
inNode = node_group.nodes.new("NodeGroupInput")
inNode.location = (0, 0)
transformNode = node_group.nodes.new("GeometryNodeTransform")
transformNode.location = (300, 0)
transformNode.inputs["Scale"].default_value = (3, 2, 1)
outNode = node_group.nodes.new("NodeGroupOutput")
outNode.location = (600, 0)
# Define geometry input/output sockets
node_group.interface.new_socket(name="Geometry", in_out="INPUT", socket_type="NodeSocketGeometry")
node_group.interface.new_socket(name="Geometry", in_out="OUTPUT", socket_type="NodeSocketGeometry")
# Link the nodes together
node_group.links.new(inNode.outputs["Geometry"], transformNode.inputs["Geometry"])
node_group.links.new(transformNode.outputs["Geometry"], outNode.inputs["Geometry"])
render_result()
fresh_scene()
# Setting up geonodes is possible, but get's quite involved quite quickly
# Add a cube
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0))
cube = bpy.context.active_object
# Setup geometry nodes
geo_nodes = cube.modifiers.new(name="GeometryNodes", type="NODES")
node_group = bpy.data.node_groups.new("GeometryNodes", "GeometryNodeTree")
geo_nodes.node_group = node_group
# Create input/output and transformation nodes
inNode = node_group.nodes.new("NodeGroupInput")
inNode.location = (0, 0)
transformNode = node_group.nodes.new("GeometryNodeTransform")
transformNode.location = (300, 0)
transformNode.inputs["Scale"].default_value = (3, 2, 1)
outNode = node_group.nodes.new("NodeGroupOutput")
outNode.location = (600, 0)
# Define geometry input/output sockets
node_group.interface.new_socket(name="Geometry", in_out="INPUT", socket_type="NodeSocketGeometry")
node_group.interface.new_socket(name="Geometry", in_out="OUTPUT", socket_type="NodeSocketGeometry")
# Link the nodes together
node_group.links.new(inNode.outputs["Geometry"], transformNode.inputs["Geometry"])
node_group.links.new(transformNode.outputs["Geometry"], outNode.inputs["Geometry"])
render_result()
Save File¶
You can any time also save your Blender file like this:
In [117]:
Copied!
path = str(Path.home() / 'Downloads/temp_scene.blend')
bpy.ops.wm.save_as_mainfile(filepath=path)
path = str(Path.home() / 'Downloads/temp_scene.blend')
bpy.ops.wm.save_as_mainfile(filepath=path)
Info: Saved "temp_scene.blend"
Out[117]:
{'FINISHED'}
Load file¶
In [118]:
Copied!
fresh_scene()
#bpy.ops.wm.open_mainfile(filepath="donut.blend") # this will loose kernel connection
path = Path.home() / "projects/bpy-gallery/docs/donut.blend"
filepath= str(path)
# Import all objects from the .blend file
with bpy.data.libraries.load(filepath, link=False) as (data_from, data_to):
data_to.objects = data_from.objects
# Link imported objects to the current scene
for obj in data_to.objects:
if obj is not None:
bpy.context.collection.objects.link(obj)
fresh_scene()
#bpy.ops.wm.open_mainfile(filepath="donut.blend") # this will loose kernel connection
path = Path.home() / "projects/bpy-gallery/docs/donut.blend"
filepath= str(path)
# Import all objects from the .blend file
with bpy.data.libraries.load(filepath, link=False) as (data_from, data_to):
data_to.objects = data_from.objects
# Link imported objects to the current scene
for obj in data_to.objects:
if obj is not None:
bpy.context.collection.objects.link(obj)
In [119]:
Copied!
import bpy
# Name of the imported camera
camera_name = "Camera.001"
# Get the imported camera object
camera_object = bpy.data.objects.get(camera_name)
if camera_object:
# Set the camera as the active camera in the scene
bpy.context.scene.camera = camera_object
print(f"{camera_name} is now the main camera.")
else:
print(f"Camera '{camera_name}' not found.")
import bpy
# Name of the imported camera
camera_name = "Camera.001"
# Get the imported camera object
camera_object = bpy.data.objects.get(camera_name)
if camera_object:
# Set the camera as the active camera in the scene
bpy.context.scene.camera = camera_object
print(f"{camera_name} is now the main camera.")
else:
print(f"Camera '{camera_name}' not found.")
Camera.001 is now the main camera.
Choose render engine¶
In [120]:
Copied!
bpy.context.scene.render.engine = "BLENDER_WORKBENCH"
bpy.context.scene.render.resolution_x = 500
bpy.context.scene.render.resolution_y = 200
render_result()
bpy.context.scene.render.engine = "BLENDER_WORKBENCH"
bpy.context.scene.render.resolution_x = 500
bpy.context.scene.render.resolution_y = 200
render_result()
In [121]:
Copied!
bpy.context.scene.render.engine = "BLENDER_EEVEE_NEXT"
render_result()
bpy.context.scene.render.engine = "BLENDER_EEVEE_NEXT"
render_result()
In [122]:
Copied!
bpy.context.scene.render.engine = "CYCLES"
bpy.context.scene.cycles.samples = 10
render_result()
bpy.context.scene.render.engine = "CYCLES"
bpy.context.scene.cycles.samples = 10
render_result()
Manipulate geometry nodes¶
In [123]:
Copied!
bpy.data.objects['ICINGLong'].modifiers["GeometryNodes"]["Socket_3"] = 0.1
render_result()
bpy.data.objects['ICINGLong'].modifiers["GeometryNodes"]["Socket_3"] = 0.1
render_result()
In [124]:
Copied!
bpy.data.objects['ICINGLong'].modifiers["GeometryNodes"]["Socket_3"] = 2
render_result()
bpy.data.objects['ICINGLong'].modifiers["GeometryNodes"]["Socket_3"] = 2
render_result()
In [125]:
Copied!
bpy.data.objects['ICINGLong'].modifiers["GeometryNodes"]["Socket_3"] = 10
render_result()
bpy.data.objects['ICINGLong'].modifiers["GeometryNodes"]["Socket_3"] = 10
render_result()
In [ ]:
Copied!