7
$\begingroup$

I am creating a rotating knob in Blender for my GUI-project.

The knob has to be rendered in 64 different angles. Is there a way I can automate this extremely tedious process with a python script?

  1. Render the knob at 0° Z,
  2. Save the file
  3. Rotate knob 3°
  4. Render
  5. Save the file
  6. Repeat 64 times

I want to use the Cycles Render and a high-number of samples (1500-2000).

$\endgroup$
1
  • 5
    $\begingroup$ Why not animate the rotation and render an image sequence? $\endgroup$
    – gandalf3
    Commented Aug 3, 2014 at 23:30

3 Answers 3

8
$\begingroup$

After some trial and error I found that this python script works for me:

import bpy, math

knob = bpy.data.objects["MyBlenderKnob"]
knob.rotation_mode = 'XYZ'

rotate_by = 4.21875   #How many degrees to rotate the knob for every step
start_angle = 45      #What angle to start from

for x in range(1,65):
    angle = (start_angle * (math.pi/180)) + (x*-1) * (rotate_by * (math.pi/180))
    knob.rotation_euler = ( 0, 0, angle )

    bpy.context.scene.render.filepath = "/Users/myfolder/KnobFrame%d.png" % (x)
    bpy.ops.render.render(write_still=True, use_viewport=True)

It grabs my blender object called "MyBlenderKnob" and rotates it 4.21875° on the Z-axis, then it renders it according to the current render-settings in the project. Then it saves the files in "myfolder".

Beautiful! A real timesaver.

$\endgroup$
5
  • 3
    $\begingroup$ re: ` 2.356 + (x*-1) * 0.0736` - why use magic numbers here? math.radians can convert degrees for you. $\endgroup$
    – ideasman42
    Commented Aug 6, 2014 at 10:05
  • $\begingroup$ Ok, thank you! Will try to implement it and update this post. $\endgroup$ Commented Aug 6, 2014 at 10:08
  • 1
    $\begingroup$ Went to the time and trouble to recover my password to upvote you! $\endgroup$ Commented Nov 6, 2016 at 17:55
  • $\begingroup$ Thank you @SingleStepper ! I removed the magic numbers now: converting between degrees and radials in the script instead. :) $\endgroup$ Commented May 15, 2017 at 16:02
  • $\begingroup$ Or start_angle = math.radians(45) $\endgroup$
    – batFINGER
    Commented May 15, 2017 at 16:06
2
$\begingroup$

You don't need to use a script to get 64 individual images. When rendering an animation while the output filetype is set to an image format each frame will be saved to an individual file.

  1. Set end frame to 64
  2. Set filetype to single image eg. png, jpeg, tiff...
  3. Go to frame one and insert a keyframe for rotation
  4. Go to last frame and rotate the knob 189 degrees
  5. Insert keyframe for rotation
  6. Go to graph editor or dopesheet and select all keyframes
  7. Press T and select linear
  8. Render animation

Step 6 and 7 ensures the rotation is the same amount each frame. By default the interpolation will be bezier which will give less rotation at each end and faster in the middle (ease-in and ease-out). You can get around this step if you set the default interpolation to linear in the editing preferences.

$\endgroup$
1
  • $\begingroup$ Its possible the object is animated already - so its not necessarily a solution to render an animation. $\endgroup$
    – ideasman42
    Commented Aug 5, 2014 at 22:40
0
$\begingroup$

Copy and paste script for animated model (Still missing support for objects with animated actions), parameters go last in file..

"""
Dump rotated images of a single object in a scene with a single animation.
Support for animation actions missing ..

Rotate car in 45 degree offsets no animation to file in tmp named car*.png
rotate("car",45,output="/tmp/car{norder}.png")

Rotate car in 45 degree with animation frames
animate("car",output="/tmp/car{norder}-{frame}.png",startframe=1,endframe=8)

Error handling is huh suspicious ...

FreeBSD license on this code
"""
import bpy, math



def rotate(modelname,rotate_by=45,start_angle=0,output="/tmp/model{norder}.png",frame="1"):
    model = bpy.data.objects[modelname]
    model.rotation_mode = 'XYZ'
    
    rotation_euler = model.rotation_euler

    zang = (math.pi*start_angle) / 180.00
    norder = 0
    while zang < math.pi*2:
        model.rotation_euler = ( 0, 0, zang )

        bpy.context.scene.render.filepath = output.format(norder=norder,frame=frame)
        bpy.ops.render.render(write_still=True, use_viewport=True)

        zang += (math.pi*rotate_by) / 180.0
        norder +=1
        
    model.rotation_euler = rotation_euler #don't clobber model rotation...
        
    
    
def animate(modelname,rotate_by=45,start_angle=0,output="/tmp/model{norder}-{frame}.png",startframe=1,endframe=1):
    scene = bpy.data.scenes["Scene"]
    current_frame = scene.frame_current 
    scene.frame_current = startframe    
    while scene.frame_current <= endframe:
        rotate(modelname,rotate_by=rotate_by,start_angle=start_angle,output=output,frame=scene.frame_current)
        scene.frame_current += 1

    #don't clobber scene frame
    scene.frame_current = current_frame


#rotate the car by 45
#rotate("car",45,output="/tmp/car{norder}.png")
#animate the car
animate("car",output="/tmp/car{norder}-{frame}.png",startframe=1,endframe=8)

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .