Capture turntable as you model or sculpt or whatever else

Ive created this relatively simple script to record a turntable while you model or sculpt.
I have updated the script to zoom out as your object grows, or zoom in as it shrinks.

I suggest only running this once per blender instance (quit after each time). It creates a callback for every time the scene updates.

Have Fun and post video links of your trys. Feedback too!
Again, I hope someone picks this up and improves upon it.


import bpy


########################################################
##  Settings You Can Change                           ##
########################################################




OUTPUT = "/tmp/test"        # Where to save Images
FILE_FORMAT = 'PNG'         # What Type of Image to save
IMAGE_SIZE = 256            # Size of picture (Output images are squares)
SKIP = 200                  # Higher numbers mean longer wait between pictures


CAMERA_ANGLE = -30          # Angle pivot is rotated to see from above or below
ROT_SPEED = 3               # How far to rotate camera around object
DISTANCE_MULTIPLYER = 3     # Effects how far the camera stays from the object
CAMERA_SPEED = 2            
HIDDEN_CAM = False          # Set True to hide camera 


FOLLOW_SELECTION = True     # "True" Follows Selection, "False" stays with initial Selection 
FALLBACK_DISTANCE = 20
########################################################
##  Other things for script                           ##
########################################################
camera = ''
camDistance = 0
pivot = ''




counter = 0
nextPic = SKIP
picsTaken = 0




#BTW
DEGREE = 0.017453333333333335
INITIAL_SELECTION = bpy.context.active_object
objectOfInterest = INITIAL_SELECTION




########################################################
##  Definitions                                       ##
########################################################








def setUpCamera():
    global objectOfInterest
    global pivot
    global camera
    global camDistance
    global HIDDEN_CAM
    
    # Create Camera and Empty
    bpy.ops.object.camera_add(location=(0, 0, 0), rotation=((90*DEGREE),0,0))
    camera = bpy.context.active_object
    
    bpy.ops.object.add(type='EMPTY')
    pivot = bpy.context.active_object
    
    # Parent
    bpy.ops.object.select_all(action='DESELECT')
    camera.select = True
    pivot.select = True
    bpy.ops.object.parent_set(type='OBJECT')
    
    # Get Cam distance
    getCamDistance()
     
    # Move things
    moveCamera()
    


    # Hide Things
    if HIDDEN_CAM == True:
        camera.hide = True
        pivot.hide = True


def getCamDistance():
    global camDistance
    global objectOfInterest
    global fallbackDistance
    
    try:
        camDistance = objectOfInterest.dimensions[0]
        for each in objectOfInterest.dimensions:
            if each > camDistance:
                camDistance = each
    except:
        print("Selection Issue - using FALLBACK_DISTANCE")
        camDistance = FALLBACK_DISTANCE
        
def moveCamera():
    global objectOfInterest
    global camera
    global DISTANCE_MULTIPLYER
    global camDistance
    global pivot
    global CAMERA_SPEED
    global CAMERA_ANGLE
    global DEGREE
    global ROT_SPEED
    
    
    # Follow Selection
    if FOLLOW_SELECTION == True:
        objectOfInterest = bpy.context.active_object
        
    # Set Camera Zoom    
    getCamDistance()
    idealDistance = (camDistance * DISTANCE_MULTIPLYER * -1)
    currentDistance = camera.location.y
    distanceLeft = abs(idealDistance - currentDistance)
        
    if distanceLeft > CAMERA_SPEED:
        if currentDistance > idealDistance: # Move in
            camera.location.y = currentDistance - CAMERA_SPEED
        else: # Move out
            camera.location.y = currentDistance + CAMERA_SPEED
    else:
        camera.location.y = idealDistance
    
    # Move Pivot
    try:
        pivot.location = objectOfInterest.location
        pivot.rotation_euler.x = CAMERA_ANGLE * DEGREE
    except:
        print("Selection Issue - Using Origin")
        pivot.location = (0,0,0)
        
    # Rotate Pivot
    pivot.rotation_euler.z += (1 * DEGREE * ROT_SPEED)


def setUpRender():
    global camera
    
    # Set Render Settings
    bpy.context.scene.camera = camera
    bpy.context.scene.render.image_settings.file_format = FILE_FORMAT
    bpy.context.scene.render.resolution_x = IMAGE_SIZE
    bpy.context.scene.render.resolution_y = IMAGE_SIZE
    bpy.context.scene.render.resolution_percentage = 100




def moveAndRender(context):
    # Get Variables
    global OUTPUT




    global SKIP
    global counter
    global nextPic
    global picsTaken




    global ROT_SPEED
    global pivot
    
    
    
    #Test for Render
    if counter == nextPic:
        # Reset nextPic
        nextPic += SKIP
        
        # Set Render Output
        filepath = OUTPUT + "." + str(picsTaken)
        print(filepath)
        bpy.context.scene.render.filepath = filepath
    
    
        # Move Camera
        moveCamera()
        


        # Render    
        try:
            bpy.ops.render.opengl(animation=False, write_still=True, view_context=False)
            picsTaken += 1
        except:
            print("Couldnt GL Render!")
        
        
    #Counter
    counter += 1
    
    return(moveAndRender)
    


########################################################
##  Bulk of the script                                ##
########################################################
setUpCamera()
setUpRender()


try:
    bpy.ops.object.select_all(action='DESELECT')
    INITIAL_SELECTION.select = True
    bpy.context.scene.objects.active = INITIAL_SELECTION
except:
    print("Selection Issue") 






bpy.app.handlers.scene_update_post.append(moveAndRender)



a simple example of the result.
number of frames, resolution and other settings can be changed easily in the script.

Show some of your own examples.

very cool, +1 from me

Another simple example.

Awesome script - I’ll give it a try on my next modeling session.