Python: About dynamic simulations

I think about making a rendered simulation but I have just started figuring things out.

Is there a way to dynamically create objects with Python?
From what I know so far something like this is not supported yet.

So a good workaround would be to allocate all of the needed objects in a different layer, and then with python place them at the correct layer to be rendered.

Also I consider of using particles, though I don’t know if I can code their behaviour and I will have to rely on particle systems.

Any ideas or recommendations?

Yes, you can add new objects to a scene using the Python API. I’m pretty sure that anything you can do in the UI with the mouse+keyboard, you can also do with the Python API.

I have studied this script but it does not work for some reason. Can this be rendered as well? Do you know where can I find a script like this or a tutorial?

why does is need to be run in realtime? could sort of bake out objects and show/hide using a frame handler. That’s still better than a file handler in which you create/remove the meshes.

It’s that I like dynamic simulations better rather than pre-calculated ones, practically it’s the same, the only difference is that you can save some extra gigs of data. :slight_smile:

I would like to ask this, so if anyone knows could please answer.

I have found that you can use these application handlers.
http://www.blender.org/documentation/blender_python_api_2_60_6/bpy.app.handlers.html

However the local-guru fella uses bpy.ops.anim.change_frame which does not work
bpy.ops.anim.change_frame(10)

RuntimeError: Operator bpy.ops.anim.change_frame.poll() Expected an timeline/animation area to be active

Also there is bpy.context.scene.frame_set(10) which works.

Why are there three different options?
Is there any difference between these two?
context.scene.frame_set
ops.anim.change_frame

Scene.frame_set(…) is low level and updates all dependencies

Scene.frame_current = # is also low level, but does not update everything (leaves out matrices afaik)

all others are operators for certain areas, they rely on a certain context. They are mostly used for keybindings, some provide extra functionality like jumping to the next keyframe point (considering all fcurves). Whenever possible, use the low level methods. Not sure why you would use them in conjunction with app handler for frame change event

I have managed to create this script, the only problem is that Blender does not support objects created at rendered time. But having them generated right before the animation time is no problem.

With the both ways of writing I had the same result ( under blender 2.64 with one of my scripts )

Now with the 2.68 ops.anim.change_frame gives me the same error as you
the second one with _set works
ty for the info :slight_smile:

Hello, thanks for bumping the thread. I had progressed my research and created something with it. I don’t know if anyone is interested. But I would let you know about the results. https://drive.google.com/file/d/0B0YtvOk65FM1SGZ6eUN1MFhJVjQ/edit?usp=sharing

For the sake of the example, when you try to render the scene, a random cube will appear, at a random location, with random rotation.


import bpy
import random




anim_interval = 0
cube_list = []
cube_curr = 0
cube_total = 50




def my_handler(scene):
    global cube_list, cube_curr
    global anim_interval
        
    if scene.frame_current % anim_interval == 0:
                
        # Grab the current object (shortcut)
        obj = cube_list[cube_curr]
    
        # Bring the current cube index in rendered layer (1)
        bpy.data.objects[obj].layers = (
            True, False, False, False, False,
            False, False, False, False, False,
            False, False, False, False, False,
            False, False, False, False, False
        )
        
        # Update it's position random
        r = 30
        x = (random.random()*r) - (r/2)
        y = (random.random()*r) - (r/2)        
        scene.objects[obj].location = (x, y, 0)
        
        # Update it's rotation random
        bpy.data.objects[obj].rotation_euler = (
            random.random()*360,
            random.random()*360,
            random.random()*360
        )
        
        # Increment the current cube index
        cube_curr = cube_curr + 1
    
    # Bonus: Loop through all of the previously create cubes
    # and rotate them to maximize the pleasure
    for i in range(cube_curr):
        bpy.data.objects[cube_list[i]].rotation_euler[2] += 0.25




def construct_scene():
    # Delete all cubes
    bpy.ops.object.select_all(action='DESELECT')    
    cubes = [i.name for i in bpy.data.objects if i.name.find("Cube") > -1]
    for i in cubes:
        bpy.data.objects[i].select = True
    bpy.ops.object.delete()
    
    # Create cubes in layer 11
    global cube_total
    for i in range(cube_total):
        bpy.ops.mesh.primitive_cube_add(
            location = (0, 0, 0),
            layers = (
                False, False, False, False, False,
                False, False, False, False, False,
                True, False, False, False, False,
                False, False, False, False, False
            )
        )
        
    # Get new cubes
    global cube_list
    cube_list = [i.name for i in bpy.data.objects if i.name.find("Cube") > -1]


    # Calculate animation interval
    global anim_interval
    anim_interval = bpy.context.scene.frame_end / cube_total




def register_handler():
    handlers = bpy.app.handlers.render_pre
    if len(handlers) > 0:
        for i in range(len(handlers)):
            if handlers[i].__name__ == my_handler.__name__:
                handlers.pop(i)
    
    handlers.append(my_handler)




construct_scene()
register_handler()