1
$\begingroup$

I am new to Blender. I create a cube and want to render it. Since, we are later going to do this for large number of shapes, we are working with Blender's Python API. I want to save this rendering as a png.

I have the following code:

image = bpy.ops.mesh.primitive_cube_add(radius=1, location = (0,0,0))
image.save_render("/Users/tarun/Work/check.png")

But it gives an error :

AttributeError: 'set' object has no attribute 'save_render'

Although when I do only bpy.ops.mesh.primitive_cube_add(radius=1, location = (0,0,0)), it shows the cube in the scene.

How can I create and save a shape like cube from the Python console in Blender?

$\endgroup$
  • 1
    $\begingroup$ You would normally set up a camera and then render the view from camera and save the result. try bpy.ops.render.render() $\endgroup$ – rob Oct 15 '18 at 11:53
8
$\begingroup$

Please invest time into researching about the Blender API and Python interface, before asking questions!

image = bpy.ops.mesh.primitive_cube_add(radius=1, location = (0,0,0))

This line does not make any sense at all. primitive_cube_add is an operation, which returns a status set. In this case it returns {FINISHED}. {FINISHED} is most definitely not a python object with a save_render method.

To tackle the problem requires several steps.

  1. Avoid using ops.
  2. Create the cube.
  3. Avoid using ops.
  4. Create a camera, only cameras can render images.
  5. Avoid using ops.
  6. Create a light, otherwise your unlit cube is going to be black.
  7. Render an image (this can only by done with bpy.ops).

First import the necessary modules. Store the current scene inside a variable, that way we can access it later on.

import bpy
import mathutils

scene = bpy.context.scene

A method for creating the cube is found here. I have blatantly copied it. We will have to import the bmesh module.

# Create the cube
mesh = bpy.data.meshes.new('cube')
ob = bpy.data.objects.new('cube', mesh)

scene.objects.link(ob)

import bmesh
bm = bmesh.new()
bmesh.ops.create_cube(bm, size=1.0)
bm.to_mesh(mesh)
bm.free()

Creating the light need a lamp data-block and an object block as well. light.location changes the position of the lamp object. If it is at (0, 0, 0), it will not affect the result, because it will be stuck inside the cube.

# Create a light
light_data = bpy.data.lamps.new('light', type='POINT')
light = bpy.data.objects.new('light', light_data)
scene.objects.link(light)
light.location = mathutils.Vector((3, -4.2, 5))

The camera has to be repositioned and reoriented.

# Create the camera
cam_data = bpy.data.cameras.new('camera')
cam = bpy.data.objects.new('camera', cam_data)
scene.objects.link(cam)
scene.camera = cam

cam.location = mathutils.Vector((6, -3, 5))
cam.rotation_euler = mathutils.Euler((0.9, 0.0, 1.1))

Set the render settings of the current scene, and render it. write_still is necessary if you want the result to be written to the filepath. There will be no visual feedback during the render process.

# render settings
scene.render.image_settings.file_format = 'PNG'
scene.render.filepath = "F:/image.png"
bpy.ops.render.render(write_still = 1)

I'd post a result image, but it's just the default cube.

$\endgroup$
  • $\begingroup$ Nice answer! Could you briefly explain why you recommend to "avoid using ops"? The examples I've seen so far mostly rely on using bpy.ops and it seems to work fine in their cases. $\endgroup$ – bluenote10 Oct 7 at 5:54
  • 1
    $\begingroup$ This answer is as ridiculously polemic as the question's code is ridiculous. However, I have not yet seen a good addon relying on bpy.ops. The search for this kind query lists this this top-voted question. $\endgroup$ – Leander Oct 7 at 9:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.